]> gcc.gnu.org Git - gcc.git/blame - gcc/f/com.c
function.c (assign_parms/STACK_BYTES): Revert last change, and that of 19 Nov.
[gcc.git] / gcc / f / com.c
CommitLineData
5ff904cd 1/* com.c -- Implementation File (module.c template V1.0)
44d2eabc 2 Copyright (C) 1995-1998 Free Software Foundation, Inc.
25d7717e 3 Contributed by James Craig Burley.
5ff904cd
JL
4
5This file is part of GNU Fortran.
6
7GNU Fortran is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU Fortran is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Fortran; see the file COPYING. If not, write to
19the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2002111-1307, USA.
21
22 Related Modules:
23 None
24
25 Description:
26 Contains compiler-specific functions.
27
28 Modifications:
29*/
30
31/* Understanding this module means understanding the interface between
32 the g77 front end and the gcc back end (or, perhaps, some other
33 back end). In here are the functions called by the front end proper
34 to notify whatever back end is in place about certain things, and
35 also the back-end-specific functions. It's a bear to deal with, so
36 lately I've been trying to simplify things, especially with regard
37 to the gcc-back-end-specific stuff.
38
39 Building expressions generally seems quite easy, but building decls
40 has been challenging and is undergoing revision. gcc has several
41 kinds of decls:
42
43 TYPE_DECL -- a type (int, float, struct, function, etc.)
44 CONST_DECL -- a constant of some type other than function
45 LABEL_DECL -- a variable or a constant?
46 PARM_DECL -- an argument to a function (a variable that is a dummy)
47 RESULT_DECL -- the return value of a function (a variable)
48 VAR_DECL -- other variable (can hold a ptr-to-function, struct, int, etc.)
49 FUNCTION_DECL -- a function (either the actual function or an extern ref)
50 FIELD_DECL -- a field in a struct or union (goes into types)
51
52 g77 has a set of functions that somewhat parallels the gcc front end
53 when it comes to building decls:
54
55 Internal Function (one we define, not just declare as extern):
56 int yes;
57 yes = suspend_momentary ();
58 if (is_nested) push_f_function_context ();
59 start_function (get_identifier ("function_name"), function_type,
60 is_nested, is_public);
61 // for each arg, build PARM_DECL and call push_parm_decl (decl) with it;
62 store_parm_decls (is_main_program);
c7e4ee3a 63 ffecom_start_compstmt ();
5ff904cd 64 // for stmts and decls inside function, do appropriate things;
c7e4ee3a 65 ffecom_end_compstmt ();
5ff904cd
JL
66 finish_function (is_nested);
67 if (is_nested) pop_f_function_context ();
68 if (is_nested) resume_momentary (yes);
69
70 Everything Else:
71 int yes;
72 tree d;
73 tree init;
74 yes = suspend_momentary ();
75 // fill in external, public, static, &c for decl, and
76 // set DECL_INITIAL to error_mark_node if going to initialize
77 // set is_top_level TRUE only if not at top level and decl
78 // must go in top level (i.e. not within current function decl context)
79 d = start_decl (decl, is_top_level);
80 init = ...; // if have initializer
81 finish_decl (d, init, is_top_level);
82 resume_momentary (yes);
83
84*/
85
86/* Include files. */
87
95a1b676 88#include "proj.h"
5ff904cd 89#if FFECOM_targetCURRENT == FFECOM_targetGCC
5ff904cd
JL
90#include "flags.j"
91#include "rtl.j"
8b45da67 92#include "toplev.j"
5ff904cd 93#include "tree.j"
95a1b676 94#include "output.j" /* Must follow tree.j so TREE_CODE is defined! */
5ff904cd
JL
95#include "convert.j"
96#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
97
98#define FFECOM_GCC_INCLUDE 1 /* Enable -I. */
99
100/* BEGIN stuff from gcc/cccp.c. */
101
102/* The following symbols should be autoconfigured:
103 HAVE_FCNTL_H
104 HAVE_STDLIB_H
105 HAVE_SYS_TIME_H
106 HAVE_UNISTD_H
107 STDC_HEADERS
108 TIME_WITH_SYS_TIME
109 In the mean time, we'll get by with approximations based
110 on existing GCC configuration symbols. */
111
112#ifdef POSIX
113# ifndef HAVE_STDLIB_H
114# define HAVE_STDLIB_H 1
115# endif
116# ifndef HAVE_UNISTD_H
117# define HAVE_UNISTD_H 1
118# endif
119# ifndef STDC_HEADERS
120# define STDC_HEADERS 1
121# endif
122#endif /* defined (POSIX) */
123
124#if defined (POSIX) || (defined (USG) && !defined (VMS))
125# ifndef HAVE_FCNTL_H
126# define HAVE_FCNTL_H 1
127# endif
128#endif
129
130#ifndef RLIMIT_STACK
131# include <time.h>
132#else
133# if TIME_WITH_SYS_TIME
134# include <sys/time.h>
135# include <time.h>
136# else
137# if HAVE_SYS_TIME_H
138# include <sys/time.h>
139# else
140# include <time.h>
141# endif
142# endif
143# include <sys/resource.h>
144#endif
145
146#if HAVE_FCNTL_H
147# include <fcntl.h>
148#endif
149
150/* This defines "errno" properly for VMS, and gives us EACCES. */
151#include <errno.h>
152
153#if HAVE_STDLIB_H
154# include <stdlib.h>
155#else
156char *getenv ();
157#endif
158
5ff904cd
JL
159#if HAVE_UNISTD_H
160# include <unistd.h>
161#endif
162
163/* VMS-specific definitions */
164#ifdef VMS
165#include <descrip.h>
166#define O_RDONLY 0 /* Open arg for Read/Only */
167#define O_WRONLY 1 /* Open arg for Write/Only */
168#define read(fd,buf,size) VMS_read (fd,buf,size)
169#define write(fd,buf,size) VMS_write (fd,buf,size)
170#define open(fname,mode,prot) VMS_open (fname,mode,prot)
171#define fopen(fname,mode) VMS_fopen (fname,mode)
172#define freopen(fname,mode,ofile) VMS_freopen (fname,mode,ofile)
173#define strncat(dst,src,cnt) VMS_strncat (dst,src,cnt)
174#define fstat(fd,stbuf) VMS_fstat (fd,stbuf)
175static int VMS_fstat (), VMS_stat ();
176static char * VMS_strncat ();
177static int VMS_read ();
178static int VMS_write ();
179static int VMS_open ();
180static FILE * VMS_fopen ();
181static FILE * VMS_freopen ();
182static void hack_vms_include_specification ();
183typedef struct { unsigned :16, :16, :16; } vms_ino_t;
184#define ino_t vms_ino_t
185#define INCLUDE_LEN_FUDGE 10 /* leave room for VMS syntax conversion */
186#ifdef __GNUC__
187#define BSTRING /* VMS/GCC supplies the bstring routines */
188#endif /* __GNUC__ */
189#endif /* VMS */
190
191#ifndef O_RDONLY
192#define O_RDONLY 0
193#endif
194
195/* END stuff from gcc/cccp.c. */
196
5ff904cd
JL
197#define FFECOM_DETERMINE_TYPES 1 /* for com.h */
198#include "com.h"
199#include "bad.h"
200#include "bld.h"
201#include "equiv.h"
202#include "expr.h"
203#include "implic.h"
204#include "info.h"
205#include "malloc.h"
206#include "src.h"
207#include "st.h"
208#include "storag.h"
209#include "symbol.h"
210#include "target.h"
211#include "top.h"
212#include "type.h"
213
214/* Externals defined here. */
215
216#define FFECOM_FASTER_ARRAY_REFS 0 /* Generates faster code? */
217
218#if FFECOM_targetCURRENT == FFECOM_targetGCC
219
220/* tree.h declares a bunch of stuff that it expects the front end to
221 define. Here are the definitions, which in the C front end are
222 found in the file c-decl.c. */
223
224tree integer_zero_node;
225tree integer_one_node;
226tree null_pointer_node;
227tree error_mark_node;
228tree void_type_node;
229tree integer_type_node;
230tree unsigned_type_node;
231tree char_type_node;
232tree current_function_decl;
233
c7e4ee3a
CB
234/* ~~gcc/tree.h *should* declare this, because toplev.c and dwarfout.c
235 reference it. */
5ff904cd
JL
236
237char *language_string = "GNU F77";
238
77f77701
DB
239/* Stream for reading from the input file. */
240FILE *finput;
241
5ff904cd
JL
242/* These definitions parallel those in c-decl.c so that code from that
243 module can be used pretty much as is. Much of these defs aren't
244 otherwise used, i.e. by g77 code per se, except some of them are used
245 to build some of them that are. The ones that are global (i.e. not
246 "static") are those that ste.c and such might use (directly
247 or by using com macros that reference them in their definitions). */
248
249static tree short_integer_type_node;
250tree long_integer_type_node;
251static tree long_long_integer_type_node;
252
253static tree short_unsigned_type_node;
254static tree long_unsigned_type_node;
255static tree long_long_unsigned_type_node;
256
257static tree unsigned_char_type_node;
258static tree signed_char_type_node;
259
260static tree float_type_node;
261static tree double_type_node;
262static tree complex_float_type_node;
263tree complex_double_type_node;
264static tree long_double_type_node;
265static tree complex_integer_type_node;
266static tree complex_long_double_type_node;
267
268tree string_type_node;
269
270static tree double_ftype_double;
271static tree float_ftype_float;
272static tree ldouble_ftype_ldouble;
273
274/* The rest of these are inventions for g77, though there might be
275 similar things in the C front end. As they are found, these
276 inventions should be renamed to be canonical. Note that only
277 the ones currently required to be global are so. */
278
279static tree ffecom_tree_fun_type_void;
280static tree ffecom_tree_ptr_to_fun_type_void;
281
282tree ffecom_integer_type_node; /* Abbrev for _tree_type[blah][blah]. */
283tree ffecom_integer_zero_node; /* Like *_*_* with g77's integer type. */
284tree ffecom_integer_one_node; /* " */
285tree ffecom_tree_type[FFEINFO_basictype][FFEINFO_kindtype];
286
287/* _fun_type things are the f2c-specific versions. For -fno-f2c,
288 just use build_function_type and build_pointer_type on the
289 appropriate _tree_type array element. */
290
291static tree ffecom_tree_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
292static tree ffecom_tree_ptr_to_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
293static tree ffecom_tree_subr_type;
294static tree ffecom_tree_ptr_to_subr_type;
295static tree ffecom_tree_blockdata_type;
296
297static tree ffecom_tree_xargc_;
298
299ffecomSymbol ffecom_symbol_null_
300=
301{
302 NULL_TREE,
303 NULL_TREE,
304 NULL_TREE,
0816ebdd
KG
305 NULL_TREE,
306 false
5ff904cd
JL
307};
308ffeinfoKindtype ffecom_pointer_kind_ = FFEINFO_basictypeNONE;
309ffeinfoKindtype ffecom_label_kind_ = FFEINFO_basictypeNONE;
310
311int ffecom_f2c_typecode_[FFEINFO_basictype][FFEINFO_kindtype];
312tree ffecom_f2c_integer_type_node;
313tree ffecom_f2c_ptr_to_integer_type_node;
314tree ffecom_f2c_address_type_node;
315tree ffecom_f2c_real_type_node;
316tree ffecom_f2c_ptr_to_real_type_node;
317tree ffecom_f2c_doublereal_type_node;
318tree ffecom_f2c_complex_type_node;
319tree ffecom_f2c_doublecomplex_type_node;
320tree ffecom_f2c_longint_type_node;
321tree ffecom_f2c_logical_type_node;
322tree ffecom_f2c_flag_type_node;
323tree ffecom_f2c_ftnlen_type_node;
324tree ffecom_f2c_ftnlen_zero_node;
325tree ffecom_f2c_ftnlen_one_node;
326tree ffecom_f2c_ftnlen_two_node;
327tree ffecom_f2c_ptr_to_ftnlen_type_node;
328tree ffecom_f2c_ftnint_type_node;
329tree ffecom_f2c_ptr_to_ftnint_type_node;
330#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
331
332/* Simple definitions and enumerations. */
333
334#ifndef FFECOM_sizeMAXSTACKITEM
335#define FFECOM_sizeMAXSTACKITEM 32*1024 /* Keep user-declared things
336 larger than this # bytes
337 off stack if possible. */
338#endif
339
340/* For systems that have large enough stacks, they should define
341 this to 0, and here, for ease of use later on, we just undefine
342 it if it is 0. */
343
344#if FFECOM_sizeMAXSTACKITEM == 0
345#undef FFECOM_sizeMAXSTACKITEM
346#endif
347
348typedef enum
349 {
350 FFECOM_rttypeVOID_,
6d433196 351 FFECOM_rttypeVOIDSTAR_, /* C's `void *' type. */
795232f7
JL
352 FFECOM_rttypeFTNINT_, /* f2c's `ftnint' type. */
353 FFECOM_rttypeINTEGER_, /* f2c's `integer' type. */
354 FFECOM_rttypeLONGINT_, /* f2c's `longint' type. */
355 FFECOM_rttypeLOGICAL_, /* f2c's `logical' type. */
356 FFECOM_rttypeREAL_F2C_, /* f2c's `real' returned as `double'. */
357 FFECOM_rttypeREAL_GNU_, /* `real' returned as such. */
5ff904cd 358 FFECOM_rttypeCOMPLEX_F2C_, /* f2c's `complex' returned via 1st arg. */
795232f7 359 FFECOM_rttypeCOMPLEX_GNU_, /* f2c's `complex' returned directly. */
5ff904cd 360 FFECOM_rttypeDOUBLE_, /* C's `double' type. */
795232f7 361 FFECOM_rttypeDOUBLEREAL_, /* f2c's `doublereal' type. */
5ff904cd 362 FFECOM_rttypeDBLCMPLX_F2C_, /* f2c's `doublecomplex' returned via 1st arg. */
795232f7 363 FFECOM_rttypeDBLCMPLX_GNU_, /* f2c's `doublecomplex' returned directly. */
5ff904cd
JL
364 FFECOM_rttypeCHARACTER_, /* f2c `char *'/`ftnlen' pair. */
365 FFECOM_rttype_
366 } ffecomRttype_;
367
368/* Internal typedefs. */
369
370#if FFECOM_targetCURRENT == FFECOM_targetGCC
371typedef struct _ffecom_concat_list_ ffecomConcatList_;
5ff904cd
JL
372#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
373
374/* Private include files. */
375
376
377/* Internal structure definitions. */
378
379#if FFECOM_targetCURRENT == FFECOM_targetGCC
380struct _ffecom_concat_list_
381 {
382 ffebld *exprs;
383 int count;
384 int max;
385 ffetargetCharacterSize minlen;
386 ffetargetCharacterSize maxlen;
387 };
5ff904cd
JL
388#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
389
390/* Static functions (internal). */
391
392#if FFECOM_targetCURRENT == FFECOM_targetGCC
26f096f9 393static tree ffecom_arglist_expr_ (const char *argstring, ffebld args);
5ff904cd
JL
394static tree ffecom_widest_expr_type_ (ffebld list);
395static bool ffecom_overlap_ (tree dest_decl, tree dest_offset,
396 tree dest_size, tree source_tree,
397 ffebld source, bool scalar_arg);
398static bool ffecom_args_overlapping_ (tree dest_tree, ffebld dest,
399 tree args, tree callee_commons,
400 bool scalar_args);
26f096f9 401static tree ffecom_build_f2c_string_ (int i, const char *s);
5ff904cd
JL
402static tree ffecom_call_ (tree fn, ffeinfoKindtype kt,
403 bool is_f2c_complex, tree type,
404 tree args, tree dest_tree,
405 ffebld dest, bool *dest_used,
c7e4ee3a 406 tree callee_commons, bool scalar_args, tree hook);
5ff904cd
JL
407static tree ffecom_call_binop_ (tree fn, ffeinfoKindtype kt,
408 bool is_f2c_complex, tree type,
409 ffebld left, ffebld right,
410 tree dest_tree, ffebld dest,
411 bool *dest_used, tree callee_commons,
c7e4ee3a 412 bool scalar_args, tree hook);
86fc7a6c
CB
413static void ffecom_char_args_x_ (tree *xitem, tree *length,
414 ffebld expr, bool with_null);
5ff904cd
JL
415static tree ffecom_check_size_overflow_ (ffesymbol s, tree type, bool dummy);
416static tree ffecom_char_enhance_arg_ (tree *xtype, ffesymbol s);
417static ffecomConcatList_
418 ffecom_concat_list_gather_ (ffecomConcatList_ catlist,
419 ffebld expr,
420 ffetargetCharacterSize max);
421static void ffecom_concat_list_kill_ (ffecomConcatList_ catlist);
422static ffecomConcatList_ ffecom_concat_list_new_ (ffebld expr,
423 ffetargetCharacterSize max);
26f096f9
KG
424static void ffecom_debug_kludge_ (tree aggr, const char *aggr_type,
425 ffesymbol member, tree member_type,
426 ffetargetOffset offset);
5ff904cd 427static void ffecom_do_entry_ (ffesymbol fn, int entrynum);
092a4ef8
RH
428static tree ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest,
429 bool *dest_used, bool assignp, bool widenp);
5ff904cd
JL
430static tree ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree,
431 ffebld dest, bool *dest_used);
c7e4ee3a 432static tree ffecom_expr_power_integer_ (ffebld expr);
5ff904cd 433static void ffecom_expr_transform_ (ffebld expr);
26f096f9 434static void ffecom_f2c_make_type_ (tree *type, int tcode, const char *name);
5ff904cd
JL
435static void ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size,
436 int code);
437static ffeglobal ffecom_finish_global_ (ffeglobal global);
438static ffesymbol ffecom_finish_symbol_transform_ (ffesymbol s);
26f096f9 439static tree ffecom_get_appended_identifier_ (char us, const char *text);
5ff904cd 440static tree ffecom_get_external_identifier_ (ffesymbol s);
26f096f9 441static tree ffecom_get_identifier_ (const char *text);
5ff904cd
JL
442static tree ffecom_gen_sfuncdef_ (ffesymbol s,
443 ffeinfoBasictype bt,
444 ffeinfoKindtype kt);
26f096f9 445static const char *ffecom_gfrt_args_ (ffecomGfrt ix);
5ff904cd
JL
446static tree ffecom_gfrt_tree_ (ffecomGfrt ix);
447static tree ffecom_init_zero_ (tree decl);
448static tree ffecom_intrinsic_ichar_ (tree tree_type, ffebld arg,
449 tree *maybe_tree);
450static tree ffecom_intrinsic_len_ (ffebld expr);
451static void ffecom_let_char_ (tree dest_tree,
452 tree dest_length,
453 ffetargetCharacterSize dest_size,
454 ffebld source);
455static void ffecom_make_gfrt_ (ffecomGfrt ix);
456static void ffecom_member_phase1_ (ffestorag mst, ffestorag st);
457#ifdef SOMEONE_GETS_DEBUG_SUPPORT_WORKING
458static void ffecom_member_phase2_ (ffestorag mst, ffestorag st);
459#endif
c7e4ee3a
CB
460static void ffecom_prepare_let_char_ (ffetargetCharacterSize dest_size,
461 ffebld source);
5ff904cd
JL
462static void ffecom_push_dummy_decls_ (ffebld dumlist,
463 bool stmtfunc);
464static void ffecom_start_progunit_ (void);
465static ffesymbol ffecom_sym_transform_ (ffesymbol s);
466static ffesymbol ffecom_sym_transform_assign_ (ffesymbol s);
467static void ffecom_transform_common_ (ffesymbol s);
468static void ffecom_transform_equiv_ (ffestorag st);
469static tree ffecom_transform_namelist_ (ffesymbol s);
470static void ffecom_tree_canonize_ptr_ (tree *decl, tree *offset,
471 tree t);
472static void ffecom_tree_canonize_ref_ (tree *decl, tree *offset,
473 tree *size, tree tree);
474static tree ffecom_tree_divide_ (tree tree_type, tree left, tree right,
475 tree dest_tree, ffebld dest,
c7e4ee3a 476 bool *dest_used, tree hook);
5ff904cd
JL
477static tree ffecom_type_localvar_ (ffesymbol s,
478 ffeinfoBasictype bt,
479 ffeinfoKindtype kt);
480static tree ffecom_type_namelist_ (void);
481#if 0
482static tree ffecom_type_permanent_copy_ (tree t);
483#endif
484static tree ffecom_type_vardesc_ (void);
485static tree ffecom_vardesc_ (ffebld expr);
486static tree ffecom_vardesc_array_ (ffesymbol s);
487static tree ffecom_vardesc_dims_ (ffesymbol s);
26f096f9
KG
488static tree ffecom_convert_narrow_ (tree type, tree expr);
489static tree ffecom_convert_widen_ (tree type, tree expr);
5ff904cd
JL
490#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
491
492/* These are static functions that parallel those found in the C front
493 end and thus have the same names. */
494
495#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a 496static tree bison_rule_compstmt_ (void);
5ff904cd 497static void bison_rule_pushlevel_ (void);
26f096f9 498static tree builtin_function (const char *name, tree type,
5ff904cd 499 enum built_in_function function_code,
26f096f9 500 const char *library_name);
c7e4ee3a 501static void delete_block (tree block);
5ff904cd
JL
502static int duplicate_decls (tree newdecl, tree olddecl);
503static void finish_decl (tree decl, tree init, bool is_top_level);
504static void finish_function (int nested);
8f87a563 505static char *lang_printable_name (tree decl, int v);
5ff904cd
JL
506static tree lookup_name_current_level (tree name);
507static struct binding_level *make_binding_level (void);
508static void pop_f_function_context (void);
509static void push_f_function_context (void);
510static void push_parm_decl (tree parm);
511static tree pushdecl_top_level (tree decl);
c7e4ee3a 512static int kept_level_p (void);
5ff904cd
JL
513static tree storedecls (tree decls);
514static void store_parm_decls (int is_main_program);
515static tree start_decl (tree decl, bool is_top_level);
516static void start_function (tree name, tree type, int nested, int public);
517#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
518#if FFECOM_GCC_INCLUDE
519static void ffecom_file_ (char *name);
520static void ffecom_initialize_char_syntax_ (void);
521static void ffecom_close_include_ (FILE *f);
522static int ffecom_decode_include_option_ (char *spec);
523static FILE *ffecom_open_include_ (char *name, ffewhereLine l,
524 ffewhereColumn c);
525#endif /* FFECOM_GCC_INCLUDE */
526
527/* Static objects accessed by functions in this module. */
528
529static ffesymbol ffecom_primary_entry_ = NULL;
530static ffesymbol ffecom_nested_entry_ = NULL;
531static ffeinfoKind ffecom_primary_entry_kind_;
532static bool ffecom_primary_entry_is_proc_;
533#if FFECOM_targetCURRENT == FFECOM_targetGCC
534static tree ffecom_outer_function_decl_;
535static tree ffecom_previous_function_decl_;
536static tree ffecom_which_entrypoint_decl_;
5ff904cd
JL
537static tree ffecom_float_zero_ = NULL_TREE;
538static tree ffecom_float_half_ = NULL_TREE;
539static tree ffecom_double_zero_ = NULL_TREE;
540static tree ffecom_double_half_ = NULL_TREE;
541static tree ffecom_func_result_;/* For functions. */
542static tree ffecom_func_length_;/* For CHARACTER fns. */
543static ffebld ffecom_list_blockdata_;
544static ffebld ffecom_list_common_;
545static ffebld ffecom_master_arglist_;
546static ffeinfoBasictype ffecom_master_bt_;
547static ffeinfoKindtype ffecom_master_kt_;
548static ffetargetCharacterSize ffecom_master_size_;
549static int ffecom_num_fns_ = 0;
550static int ffecom_num_entrypoints_ = 0;
551static bool ffecom_is_altreturning_ = FALSE;
552static tree ffecom_multi_type_node_;
553static tree ffecom_multi_retval_;
554static tree
555 ffecom_multi_fields_[FFEINFO_basictype][FFEINFO_kindtype];
556static bool ffecom_member_namelisted_; /* _member_phase1_ namelisted? */
557static bool ffecom_doing_entry_ = FALSE;
558static bool ffecom_transform_only_dummies_ = FALSE;
559
560/* Holds pointer-to-function expressions. */
561
562static tree ffecom_gfrt_[FFECOM_gfrt]
563=
564{
565#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) NULL_TREE,
566#include "com-rt.def"
567#undef DEFGFRT
568};
569
570/* Holds the external names of the functions. */
571
26f096f9 572static const char *ffecom_gfrt_name_[FFECOM_gfrt]
5ff904cd
JL
573=
574{
575#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) NAME,
576#include "com-rt.def"
577#undef DEFGFRT
578};
579
580/* Whether the function returns. */
581
582static bool ffecom_gfrt_volatile_[FFECOM_gfrt]
583=
584{
585#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) VOLATILE,
586#include "com-rt.def"
587#undef DEFGFRT
588};
589
590/* Whether the function returns type complex. */
591
592static bool ffecom_gfrt_complex_[FFECOM_gfrt]
593=
594{
595#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) COMPLEX,
596#include "com-rt.def"
597#undef DEFGFRT
598};
599
600/* Type code for the function return value. */
601
602static ffecomRttype_ ffecom_gfrt_type_[FFECOM_gfrt]
603=
604{
605#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) TYPE,
606#include "com-rt.def"
607#undef DEFGFRT
608};
609
610/* String of codes for the function's arguments. */
611
26f096f9 612static const char *ffecom_gfrt_argstring_[FFECOM_gfrt]
5ff904cd
JL
613=
614{
615#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) ARGS,
616#include "com-rt.def"
617#undef DEFGFRT
618};
619#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
620
621/* Internal macros. */
622
623#if FFECOM_targetCURRENT == FFECOM_targetGCC
624
625/* We let tm.h override the types used here, to handle trivial differences
626 such as the choice of unsigned int or long unsigned int for size_t.
627 When machines start needing nontrivial differences in the size type,
628 it would be best to do something here to figure out automatically
629 from other information what type to use. */
630
631/* NOTE: g77 currently doesn't use these; see setting of sizetype and
632 change that if you need to. -- jcb 09/01/91. */
633
5ff904cd
JL
634#define ffecom_concat_list_count_(catlist) ((catlist).count)
635#define ffecom_concat_list_expr_(catlist,i) ((catlist).exprs[(i)])
636#define ffecom_concat_list_maxlen_(catlist) ((catlist).maxlen)
637#define ffecom_concat_list_minlen_(catlist) ((catlist).minlen)
638
86fc7a6c
CB
639#define ffecom_char_args_(i,l,e) ffecom_char_args_x_((i),(l),(e),FALSE)
640#define ffecom_char_args_with_null_(i,l,e) ffecom_char_args_x_((i),(l),(e),TRUE)
641
5ff904cd
JL
642/* For each binding contour we allocate a binding_level structure
643 * which records the names defined in that contour.
644 * Contours include:
645 * 0) the global one
646 * 1) one for each function definition,
647 * where internal declarations of the parameters appear.
648 *
649 * The current meaning of a name can be found by searching the levels from
650 * the current one out to the global one.
651 */
652
653/* Note that the information in the `names' component of the global contour
654 is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */
655
656struct binding_level
657 {
c7e4ee3a
CB
658 /* A chain of _DECL nodes for all variables, constants, functions,
659 and typedef types. These are in the reverse of the order supplied.
660 */
5ff904cd
JL
661 tree names;
662
c7e4ee3a
CB
663 /* For each level (except not the global one),
664 a chain of BLOCK nodes for all the levels
665 that were entered and exited one level down. */
5ff904cd
JL
666 tree blocks;
667
c7e4ee3a
CB
668 /* The BLOCK node for this level, if one has been preallocated.
669 If 0, the BLOCK is allocated (if needed) when the level is popped. */
5ff904cd
JL
670 tree this_block;
671
672 /* The binding level which this one is contained in (inherits from). */
673 struct binding_level *level_chain;
c7e4ee3a
CB
674
675 /* 0: no ffecom_prepare_* functions called at this level yet;
676 1: ffecom_prepare* functions called, except not ffecom_prepare_end;
677 2: ffecom_prepare_end called. */
678 int prep_state;
5ff904cd
JL
679 };
680
681#define NULL_BINDING_LEVEL (struct binding_level *) NULL
682
683/* The binding level currently in effect. */
684
685static struct binding_level *current_binding_level;
686
687/* A chain of binding_level structures awaiting reuse. */
688
689static struct binding_level *free_binding_level;
690
691/* The outermost binding level, for names of file scope.
692 This is created when the compiler is started and exists
693 through the entire run. */
694
695static struct binding_level *global_binding_level;
696
697/* Binding level structures are initialized by copying this one. */
698
699static struct binding_level clear_binding_level
700=
c7e4ee3a 701{NULL, NULL, NULL, NULL_BINDING_LEVEL, 0};
5ff904cd
JL
702
703/* Language-dependent contents of an identifier. */
704
705struct lang_identifier
706 {
707 struct tree_identifier ignore;
708 tree global_value, local_value, label_value;
709 bool invented;
710 };
711
712/* Macros for access to language-specific slots in an identifier. */
713/* Each of these slots contains a DECL node or null. */
714
715/* This represents the value which the identifier has in the
716 file-scope namespace. */
717#define IDENTIFIER_GLOBAL_VALUE(NODE) \
718 (((struct lang_identifier *)(NODE))->global_value)
719/* This represents the value which the identifier has in the current
720 scope. */
721#define IDENTIFIER_LOCAL_VALUE(NODE) \
722 (((struct lang_identifier *)(NODE))->local_value)
723/* This represents the value which the identifier has as a label in
724 the current label scope. */
725#define IDENTIFIER_LABEL_VALUE(NODE) \
726 (((struct lang_identifier *)(NODE))->label_value)
727/* This is nonzero if the identifier was "made up" by g77 code. */
728#define IDENTIFIER_INVENTED(NODE) \
729 (((struct lang_identifier *)(NODE))->invented)
730
731/* In identifiers, C uses the following fields in a special way:
732 TREE_PUBLIC to record that there was a previous local extern decl.
733 TREE_USED to record that such a decl was used.
734 TREE_ADDRESSABLE to record that the address of such a decl was used. */
735
736/* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function
737 that have names. Here so we can clear out their names' definitions
738 at the end of the function. */
739
740static tree named_labels;
741
742/* A list of LABEL_DECLs from outer contexts that are currently shadowed. */
743
744static tree shadowed_labels;
745
746#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
747\f
6b55276e
CB
748/* Return the subscript expression, modified to do range-checking.
749
750 `array' is the array to be checked against.
751 `element' is the subscript expression to check.
752 `dim' is the dimension number (starting at 0).
753 `total_dims' is the total number of dimensions (0 for CHARACTER substring).
754*/
755
756static tree
757ffecom_subscript_check_ (tree array, tree element, int dim, int total_dims,
758 char *array_name)
759{
760 tree low = TYPE_MIN_VALUE (TYPE_DOMAIN (array));
761 tree high = TYPE_MAX_VALUE (TYPE_DOMAIN (array));
762 tree cond;
763 tree die;
764 tree args;
765
766 if (element == error_mark_node)
767 return element;
768
769 element = ffecom_save_tree (element);
770 cond = ffecom_2 (LE_EXPR, integer_type_node,
771 low,
772 element);
773 if (high)
774 {
775 cond = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
776 cond,
777 ffecom_2 (LE_EXPR, integer_type_node,
778 element,
779 high));
780 }
781
782 {
783 int len;
784 char *proc;
785 char *var;
786 tree arg3;
787 tree arg2;
788 tree arg1;
789 tree arg4;
790
791 switch (total_dims)
792 {
793 case 0:
794 var = xmalloc (strlen (array_name) + 20);
795 sprintf (&var[0], "%s[%s-substring]",
796 array_name,
797 dim ? "end" : "start");
798 len = strlen (var) + 1;
799 break;
800
801 case 1:
802 len = strlen (array_name) + 1;
803 var = array_name;
804 break;
805
806 default:
807 var = xmalloc (strlen (array_name) + 40);
808 sprintf (&var[0], "%s[subscript-%d-of-%d]",
809 array_name,
810 dim + 1, total_dims);
811 len = strlen (var) + 1;
812 break;
813 }
814
815 arg1 = build_string (len, var);
816
817 if (total_dims != 1)
818 free (var);
819
820 TREE_TYPE (arg1)
821 = build_type_variant (build_array_type (char_type_node,
822 build_range_type
823 (integer_type_node,
824 integer_one_node,
825 build_int_2 (len, 0))),
826 1, 0);
827 TREE_CONSTANT (arg1) = 1;
828 TREE_STATIC (arg1) = 1;
829 arg1 = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg1)),
830 arg1);
831
832 /* s_rnge adds one to the element to print it, so bias against
833 that -- want to print a faithful *subscript* value. */
834 arg2 = convert (ffecom_f2c_ftnint_type_node,
835 ffecom_2 (MINUS_EXPR,
836 TREE_TYPE (element),
837 element,
838 convert (TREE_TYPE (element),
839 integer_one_node)));
840
841 proc = xmalloc ((len = strlen (input_filename)
842 + IDENTIFIER_LENGTH (DECL_NAME (current_function_decl))
843 + 2));
844
845 sprintf (&proc[0], "%s/%s",
846 input_filename,
847 IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));
848 arg3 = build_string (len, proc);
849
850 free (proc);
851
852 TREE_TYPE (arg3)
853 = build_type_variant (build_array_type (char_type_node,
854 build_range_type
855 (integer_type_node,
856 integer_one_node,
857 build_int_2 (len, 0))),
858 1, 0);
859 TREE_CONSTANT (arg3) = 1;
860 TREE_STATIC (arg3) = 1;
861 arg3 = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg3)),
862 arg3);
863
864 arg4 = convert (ffecom_f2c_ftnint_type_node,
865 build_int_2 (lineno, 0));
866
867 arg1 = build_tree_list (NULL_TREE, arg1);
868 arg2 = build_tree_list (NULL_TREE, arg2);
869 arg3 = build_tree_list (NULL_TREE, arg3);
870 arg4 = build_tree_list (NULL_TREE, arg4);
871 TREE_CHAIN (arg3) = arg4;
872 TREE_CHAIN (arg2) = arg3;
873 TREE_CHAIN (arg1) = arg2;
874
875 args = arg1;
876 }
877 die = ffecom_call_gfrt (FFECOM_gfrtRANGE,
878 args, NULL_TREE);
879 TREE_SIDE_EFFECTS (die) = 1;
880
881 element = ffecom_3 (COND_EXPR,
882 TREE_TYPE (element),
883 cond,
884 element,
885 die);
886
887 return element;
888}
889
890/* Return the computed element of an array reference.
891
892 `item' is the array or a pointer to the array. It must be a pointer
893 to the array if ffe_is_flat_arrays ().
894 `expr' is the original opARRAYREF expression.
895 `want_ptr' is non-zero if `item' is a pointer to the element, instead of
896 the element itself, is to be returned. */
897
898static tree
899ffecom_arrayref_ (tree item, ffebld expr, int want_ptr)
900{
901 ffebld dims[FFECOM_dimensionsMAX];
902 int i;
903 int total_dims;
904 int flatten = 0 /* ~~~ ffe_is_flat_arrays () */;
905 int need_ptr = want_ptr || flatten;
906 tree array;
907 tree element;
908 char *array_name;
909
910 if (ffebld_op (ffebld_left (expr)) == FFEBLD_opSYMTER)
911 array_name = ffesymbol_text (ffebld_symter (ffebld_left (expr)));
912 else
913 array_name = "[expr?]";
914
915 /* Build up ARRAY_REFs in reverse order (since we're column major
916 here in Fortran land). */
917
918 for (i = 0, expr = ffebld_right (expr);
919 expr != NULL;
920 expr = ffebld_trail (expr))
921 dims[i++] = ffebld_head (expr);
922
923 total_dims = i;
924
925 if (need_ptr)
926 {
927 for (--i, array = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item)));
928 i >= 0;
929 --i, array = TYPE_MAIN_VARIANT (TREE_TYPE (array)))
930 {
931 element = ffecom_expr (dims[i]);
932 if (ffe_is_subscript_check ())
933 element = ffecom_subscript_check_ (array, element, i, total_dims,
934 array_name);
935 item = ffecom_2 (PLUS_EXPR,
936 build_pointer_type (TREE_TYPE (array)),
937 item,
938 size_binop (MULT_EXPR,
939 size_in_bytes (TREE_TYPE (array)),
940 convert (sizetype,
941 fold (build (MINUS_EXPR,
942 TREE_TYPE (TYPE_MIN_VALUE (TYPE_DOMAIN (array))),
943 element,
944 TYPE_MIN_VALUE (TYPE_DOMAIN (array)))))));
945 }
946 if (! want_ptr)
947 {
948 item = ffecom_1 (INDIRECT_REF,
949 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item))),
950 item);
951 }
952 }
953 else
954 {
955 for (--i;
956 i >= 0;
957 --i)
958 {
959 array = TYPE_MAIN_VARIANT (TREE_TYPE (item));
960
961 element = ffecom_expr_ (dims[i], NULL, NULL, NULL, FALSE, TRUE);
962 if (ffe_is_subscript_check ())
963 element = ffecom_subscript_check_ (array, element, i, total_dims,
964 array_name);
965 item = ffecom_2 (ARRAY_REF,
966 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item))),
967 item,
968 element);
969 }
970 }
971
972 return item;
973}
974
5ff904cd
JL
975/* This is like gcc's stabilize_reference -- in fact, most of the code
976 comes from that -- but it handles the situation where the reference
977 is going to have its subparts picked at, and it shouldn't change
978 (or trigger extra invocations of functions in the subtrees) due to
979 this. save_expr is a bit overzealous, because we don't need the
980 entire thing calculated and saved like a temp. So, for DECLs, no
981 change is needed, because these are stable aggregates, and ARRAY_REF
982 and such might well be stable too, but for things like calculations,
983 we do need to calculate a snapshot of a value before picking at it. */
984
985#if FFECOM_targetCURRENT == FFECOM_targetGCC
986static tree
987ffecom_stabilize_aggregate_ (tree ref)
988{
989 tree result;
990 enum tree_code code = TREE_CODE (ref);
991
992 switch (code)
993 {
994 case VAR_DECL:
995 case PARM_DECL:
996 case RESULT_DECL:
997 /* No action is needed in this case. */
998 return ref;
999
1000 case NOP_EXPR:
1001 case CONVERT_EXPR:
1002 case FLOAT_EXPR:
1003 case FIX_TRUNC_EXPR:
1004 case FIX_FLOOR_EXPR:
1005 case FIX_ROUND_EXPR:
1006 case FIX_CEIL_EXPR:
1007 result = build_nt (code, stabilize_reference (TREE_OPERAND (ref, 0)));
1008 break;
1009
1010 case INDIRECT_REF:
1011 result = build_nt (INDIRECT_REF,
1012 stabilize_reference_1 (TREE_OPERAND (ref, 0)));
1013 break;
1014
1015 case COMPONENT_REF:
1016 result = build_nt (COMPONENT_REF,
1017 stabilize_reference (TREE_OPERAND (ref, 0)),
1018 TREE_OPERAND (ref, 1));
1019 break;
1020
1021 case BIT_FIELD_REF:
1022 result = build_nt (BIT_FIELD_REF,
1023 stabilize_reference (TREE_OPERAND (ref, 0)),
1024 stabilize_reference_1 (TREE_OPERAND (ref, 1)),
1025 stabilize_reference_1 (TREE_OPERAND (ref, 2)));
1026 break;
1027
1028 case ARRAY_REF:
1029 result = build_nt (ARRAY_REF,
1030 stabilize_reference (TREE_OPERAND (ref, 0)),
1031 stabilize_reference_1 (TREE_OPERAND (ref, 1)));
1032 break;
1033
1034 case COMPOUND_EXPR:
1035 result = build_nt (COMPOUND_EXPR,
1036 stabilize_reference_1 (TREE_OPERAND (ref, 0)),
1037 stabilize_reference (TREE_OPERAND (ref, 1)));
1038 break;
1039
1040 case RTL_EXPR:
1041 result = build1 (INDIRECT_REF, TREE_TYPE (ref),
1042 save_expr (build1 (ADDR_EXPR,
1043 build_pointer_type (TREE_TYPE (ref)),
1044 ref)));
1045 break;
1046
1047
1048 default:
1049 return save_expr (ref);
1050
1051 case ERROR_MARK:
1052 return error_mark_node;
1053 }
1054
1055 TREE_TYPE (result) = TREE_TYPE (ref);
1056 TREE_READONLY (result) = TREE_READONLY (ref);
1057 TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (ref);
1058 TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (ref);
1059 TREE_RAISES (result) = TREE_RAISES (ref);
1060
1061 return result;
1062}
1063#endif
1064
1065/* A rip-off of gcc's convert.c convert_to_complex function,
1066 reworked to handle complex implemented as C structures
1067 (RECORD_TYPE with two fields, real and imaginary `r' and `i'). */
1068
1069#if FFECOM_targetCURRENT == FFECOM_targetGCC
1070static tree
1071ffecom_convert_to_complex_ (tree type, tree expr)
1072{
1073 register enum tree_code form = TREE_CODE (TREE_TYPE (expr));
1074 tree subtype;
1075
1076 assert (TREE_CODE (type) == RECORD_TYPE);
1077
1078 subtype = TREE_TYPE (TYPE_FIELDS (type));
1079
1080 if (form == REAL_TYPE || form == INTEGER_TYPE || form == ENUMERAL_TYPE)
1081 {
1082 expr = convert (subtype, expr);
1083 return ffecom_2 (COMPLEX_EXPR, type, expr,
1084 convert (subtype, integer_zero_node));
1085 }
1086
1087 if (form == RECORD_TYPE)
1088 {
1089 tree elt_type = TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr)));
1090 if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype))
1091 return expr;
1092 else
1093 {
1094 expr = save_expr (expr);
1095 return ffecom_2 (COMPLEX_EXPR,
1096 type,
1097 convert (subtype,
1098 ffecom_1 (REALPART_EXPR,
1099 TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))),
1100 expr)),
1101 convert (subtype,
1102 ffecom_1 (IMAGPART_EXPR,
1103 TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))),
1104 expr)));
1105 }
1106 }
1107
1108 if (form == POINTER_TYPE || form == REFERENCE_TYPE)
1109 error ("pointer value used where a complex was expected");
1110 else
1111 error ("aggregate value used where a complex was expected");
1112
1113 return ffecom_2 (COMPLEX_EXPR, type,
1114 convert (subtype, integer_zero_node),
1115 convert (subtype, integer_zero_node));
1116}
1117#endif
1118
1119/* Like gcc's convert(), but crashes if widening might happen. */
1120
1121#if FFECOM_targetCURRENT == FFECOM_targetGCC
1122static tree
1123ffecom_convert_narrow_ (type, expr)
1124 tree type, expr;
1125{
1126 register tree e = expr;
1127 register enum tree_code code = TREE_CODE (type);
1128
1129 if (type == TREE_TYPE (e)
1130 || TREE_CODE (e) == ERROR_MARK)
1131 return e;
1132 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
1133 return fold (build1 (NOP_EXPR, type, e));
1134 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
1135 || code == ERROR_MARK)
1136 return error_mark_node;
1137 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
1138 {
1139 assert ("void value not ignored as it ought to be" == NULL);
1140 return error_mark_node;
1141 }
1142 assert (code != VOID_TYPE);
1143 if ((code != RECORD_TYPE)
1144 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
1145 assert ("converting COMPLEX to REAL" == NULL);
1146 assert (code != ENUMERAL_TYPE);
1147 if (code == INTEGER_TYPE)
1148 {
a74de6ea
CB
1149 assert ((TREE_CODE (TREE_TYPE (e)) == INTEGER_TYPE
1150 && TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (e)))
1151 || (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE
1152 && (TYPE_PRECISION (type)
1153 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e))))));
5ff904cd
JL
1154 return fold (convert_to_integer (type, e));
1155 }
1156 if (code == POINTER_TYPE)
1157 {
1158 assert (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE);
1159 return fold (convert_to_pointer (type, e));
1160 }
1161 if (code == REAL_TYPE)
1162 {
1163 assert (TREE_CODE (TREE_TYPE (e)) == REAL_TYPE);
1164 assert (TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (e)));
1165 return fold (convert_to_real (type, e));
1166 }
1167 if (code == COMPLEX_TYPE)
1168 {
1169 assert (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE);
1170 assert (TYPE_PRECISION (TREE_TYPE (type)) <= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e))));
1171 return fold (convert_to_complex (type, e));
1172 }
1173 if (code == RECORD_TYPE)
1174 {
1175 assert (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE);
270fc4e8
CB
1176 /* Check that at least the first field name agrees. */
1177 assert (DECL_NAME (TYPE_FIELDS (type))
1178 == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e))));
5ff904cd
JL
1179 assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1180 <= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))));
270fc4e8
CB
1181 if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1182 == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))))
1183 return e;
5ff904cd
JL
1184 return fold (ffecom_convert_to_complex_ (type, e));
1185 }
1186
1187 assert ("conversion to non-scalar type requested" == NULL);
1188 return error_mark_node;
1189}
1190#endif
1191
1192/* Like gcc's convert(), but crashes if narrowing might happen. */
1193
1194#if FFECOM_targetCURRENT == FFECOM_targetGCC
1195static tree
1196ffecom_convert_widen_ (type, expr)
1197 tree type, expr;
1198{
1199 register tree e = expr;
1200 register enum tree_code code = TREE_CODE (type);
1201
1202 if (type == TREE_TYPE (e)
1203 || TREE_CODE (e) == ERROR_MARK)
1204 return e;
1205 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
1206 return fold (build1 (NOP_EXPR, type, e));
1207 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
1208 || code == ERROR_MARK)
1209 return error_mark_node;
1210 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
1211 {
1212 assert ("void value not ignored as it ought to be" == NULL);
1213 return error_mark_node;
1214 }
1215 assert (code != VOID_TYPE);
1216 if ((code != RECORD_TYPE)
1217 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
1218 assert ("narrowing COMPLEX to REAL" == NULL);
1219 assert (code != ENUMERAL_TYPE);
1220 if (code == INTEGER_TYPE)
1221 {
a74de6ea
CB
1222 assert ((TREE_CODE (TREE_TYPE (e)) == INTEGER_TYPE
1223 && TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (e)))
1224 || (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE
1225 && (TYPE_PRECISION (type)
1226 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e))))));
5ff904cd
JL
1227 return fold (convert_to_integer (type, e));
1228 }
1229 if (code == POINTER_TYPE)
1230 {
1231 assert (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE);
1232 return fold (convert_to_pointer (type, e));
1233 }
1234 if (code == REAL_TYPE)
1235 {
1236 assert (TREE_CODE (TREE_TYPE (e)) == REAL_TYPE);
1237 assert (TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (e)));
1238 return fold (convert_to_real (type, e));
1239 }
1240 if (code == COMPLEX_TYPE)
1241 {
1242 assert (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE);
1243 assert (TYPE_PRECISION (TREE_TYPE (type)) >= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e))));
1244 return fold (convert_to_complex (type, e));
1245 }
1246 if (code == RECORD_TYPE)
1247 {
1248 assert (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE);
270fc4e8
CB
1249 /* Check that at least the first field name agrees. */
1250 assert (DECL_NAME (TYPE_FIELDS (type))
1251 == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e))));
5ff904cd
JL
1252 assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1253 >= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))));
270fc4e8
CB
1254 if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1255 == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))))
1256 return e;
5ff904cd
JL
1257 return fold (ffecom_convert_to_complex_ (type, e));
1258 }
1259
1260 assert ("conversion to non-scalar type requested" == NULL);
1261 return error_mark_node;
1262}
1263#endif
1264
1265/* Handles making a COMPLEX type, either the standard
1266 (but buggy?) gbe way, or the safer (but less elegant?)
1267 f2c way. */
1268
1269#if FFECOM_targetCURRENT == FFECOM_targetGCC
1270static tree
1271ffecom_make_complex_type_ (tree subtype)
1272{
1273 tree type;
1274 tree realfield;
1275 tree imagfield;
1276
1277 if (ffe_is_emulate_complex ())
1278 {
1279 type = make_node (RECORD_TYPE);
1280 realfield = ffecom_decl_field (type, NULL_TREE, "r", subtype);
1281 imagfield = ffecom_decl_field (type, realfield, "i", subtype);
1282 TYPE_FIELDS (type) = realfield;
1283 layout_type (type);
1284 }
1285 else
1286 {
1287 type = make_node (COMPLEX_TYPE);
1288 TREE_TYPE (type) = subtype;
1289 layout_type (type);
1290 }
1291
1292 return type;
1293}
1294#endif
1295
1296/* Chooses either the gbe or the f2c way to build a
1297 complex constant. */
1298
1299#if FFECOM_targetCURRENT == FFECOM_targetGCC
1300static tree
1301ffecom_build_complex_constant_ (tree type, tree realpart, tree imagpart)
1302{
1303 tree bothparts;
1304
1305 if (ffe_is_emulate_complex ())
1306 {
1307 bothparts = build_tree_list (TYPE_FIELDS (type), realpart);
1308 TREE_CHAIN (bothparts) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), imagpart);
1309 bothparts = build (CONSTRUCTOR, type, NULL_TREE, bothparts);
1310 }
1311 else
1312 {
1313 bothparts = build_complex (type, realpart, imagpart);
1314 }
1315
1316 return bothparts;
1317}
1318#endif
1319
1320#if FFECOM_targetCURRENT == FFECOM_targetGCC
1321static tree
26f096f9 1322ffecom_arglist_expr_ (const char *c, ffebld expr)
5ff904cd
JL
1323{
1324 tree list;
1325 tree *plist = &list;
1326 tree trail = NULL_TREE; /* Append char length args here. */
1327 tree *ptrail = &trail;
1328 tree length;
1329 ffebld exprh;
1330 tree item;
1331 bool ptr = FALSE;
1332 tree wanted = NULL_TREE;
e2fa159e
JL
1333 static char zed[] = "0";
1334
1335 if (c == NULL)
1336 c = &zed[0];
5ff904cd
JL
1337
1338 while (expr != NULL)
1339 {
1340 if (*c != '\0')
1341 {
1342 ptr = FALSE;
1343 if (*c == '&')
1344 {
1345 ptr = TRUE;
1346 ++c;
1347 }
1348 switch (*(c++))
1349 {
1350 case '\0':
1351 ptr = TRUE;
1352 wanted = NULL_TREE;
1353 break;
1354
1355 case 'a':
1356 assert (ptr);
1357 wanted = NULL_TREE;
1358 break;
1359
1360 case 'c':
1361 wanted = ffecom_f2c_complex_type_node;
1362 break;
1363
1364 case 'd':
1365 wanted = ffecom_f2c_doublereal_type_node;
1366 break;
1367
1368 case 'e':
1369 wanted = ffecom_f2c_doublecomplex_type_node;
1370 break;
1371
1372 case 'f':
1373 wanted = ffecom_f2c_real_type_node;
1374 break;
1375
1376 case 'i':
1377 wanted = ffecom_f2c_integer_type_node;
1378 break;
1379
1380 case 'j':
1381 wanted = ffecom_f2c_longint_type_node;
1382 break;
1383
1384 default:
1385 assert ("bad argstring code" == NULL);
1386 wanted = NULL_TREE;
1387 break;
1388 }
1389 }
1390
1391 exprh = ffebld_head (expr);
1392 if (exprh == NULL)
1393 wanted = NULL_TREE;
1394
1395 if ((wanted == NULL_TREE)
1396 || (ptr
1397 && (TYPE_MODE
1398 (ffecom_tree_type[ffeinfo_basictype (ffebld_info (exprh))]
1399 [ffeinfo_kindtype (ffebld_info (exprh))])
1400 == TYPE_MODE (wanted))))
1401 *plist
1402 = build_tree_list (NULL_TREE,
1403 ffecom_arg_ptr_to_expr (exprh,
1404 &length));
1405 else
1406 {
1407 item = ffecom_arg_expr (exprh, &length);
1408 item = ffecom_convert_widen_ (wanted, item);
1409 if (ptr)
1410 {
1411 item = ffecom_1 (ADDR_EXPR,
1412 build_pointer_type (TREE_TYPE (item)),
1413 item);
1414 }
1415 *plist
1416 = build_tree_list (NULL_TREE,
1417 item);
1418 }
1419
1420 plist = &TREE_CHAIN (*plist);
1421 expr = ffebld_trail (expr);
1422 if (length != NULL_TREE)
1423 {
1424 *ptrail = build_tree_list (NULL_TREE, length);
1425 ptrail = &TREE_CHAIN (*ptrail);
1426 }
1427 }
1428
e2fa159e
JL
1429 /* We've run out of args in the call; if the implementation expects
1430 more, supply null pointers for them, which the implementation can
1431 check to see if an arg was omitted. */
1432
1433 while (*c != '\0' && *c != '0')
1434 {
1435 if (*c == '&')
1436 ++c;
1437 else
1438 assert ("missing arg to run-time routine!" == NULL);
1439
1440 switch (*(c++))
1441 {
1442 case '\0':
1443 case 'a':
1444 case 'c':
1445 case 'd':
1446 case 'e':
1447 case 'f':
1448 case 'i':
1449 case 'j':
1450 break;
1451
1452 default:
1453 assert ("bad arg string code" == NULL);
1454 break;
1455 }
1456 *plist
1457 = build_tree_list (NULL_TREE,
1458 null_pointer_node);
1459 plist = &TREE_CHAIN (*plist);
1460 }
1461
5ff904cd
JL
1462 *plist = trail;
1463
1464 return list;
1465}
1466#endif
1467
1468#if FFECOM_targetCURRENT == FFECOM_targetGCC
1469static tree
1470ffecom_widest_expr_type_ (ffebld list)
1471{
1472 ffebld item;
1473 ffebld widest = NULL;
1474 ffetype type;
1475 ffetype widest_type = NULL;
1476 tree t;
1477
1478 for (; list != NULL; list = ffebld_trail (list))
1479 {
1480 item = ffebld_head (list);
1481 if (item == NULL)
1482 continue;
1483 if ((widest != NULL)
1484 && (ffeinfo_basictype (ffebld_info (item))
1485 != ffeinfo_basictype (ffebld_info (widest))))
1486 continue;
1487 type = ffeinfo_type (ffeinfo_basictype (ffebld_info (item)),
1488 ffeinfo_kindtype (ffebld_info (item)));
1489 if ((widest == FFEINFO_kindtypeNONE)
1490 || (ffetype_size (type)
1491 > ffetype_size (widest_type)))
1492 {
1493 widest = item;
1494 widest_type = type;
1495 }
1496 }
1497
1498 assert (widest != NULL);
1499 t = ffecom_tree_type[ffeinfo_basictype (ffebld_info (widest))]
1500 [ffeinfo_kindtype (ffebld_info (widest))];
1501 assert (t != NULL_TREE);
1502 return t;
1503}
1504#endif
1505
1506/* Check whether dest and source might overlap. ffebld versions of these
1507 might or might not be passed, will be NULL if not.
1508
1509 The test is really whether source_tree is modifiable and, if modified,
1510 might overlap destination such that the value(s) in the destination might
1511 change before it is finally modified. dest_* are the canonized
1512 destination itself. */
1513
1514#if FFECOM_targetCURRENT == FFECOM_targetGCC
1515static bool
1516ffecom_overlap_ (tree dest_decl, tree dest_offset, tree dest_size,
1517 tree source_tree, ffebld source UNUSED,
1518 bool scalar_arg)
1519{
1520 tree source_decl;
1521 tree source_offset;
1522 tree source_size;
1523 tree t;
1524
1525 if (source_tree == NULL_TREE)
1526 return FALSE;
1527
1528 switch (TREE_CODE (source_tree))
1529 {
1530 case ERROR_MARK:
1531 case IDENTIFIER_NODE:
1532 case INTEGER_CST:
1533 case REAL_CST:
1534 case COMPLEX_CST:
1535 case STRING_CST:
1536 case CONST_DECL:
1537 case VAR_DECL:
1538 case RESULT_DECL:
1539 case FIELD_DECL:
1540 case MINUS_EXPR:
1541 case MULT_EXPR:
1542 case TRUNC_DIV_EXPR:
1543 case CEIL_DIV_EXPR:
1544 case FLOOR_DIV_EXPR:
1545 case ROUND_DIV_EXPR:
1546 case TRUNC_MOD_EXPR:
1547 case CEIL_MOD_EXPR:
1548 case FLOOR_MOD_EXPR:
1549 case ROUND_MOD_EXPR:
1550 case RDIV_EXPR:
1551 case EXACT_DIV_EXPR:
1552 case FIX_TRUNC_EXPR:
1553 case FIX_CEIL_EXPR:
1554 case FIX_FLOOR_EXPR:
1555 case FIX_ROUND_EXPR:
1556 case FLOAT_EXPR:
1557 case EXPON_EXPR:
1558 case NEGATE_EXPR:
1559 case MIN_EXPR:
1560 case MAX_EXPR:
1561 case ABS_EXPR:
1562 case FFS_EXPR:
1563 case LSHIFT_EXPR:
1564 case RSHIFT_EXPR:
1565 case LROTATE_EXPR:
1566 case RROTATE_EXPR:
1567 case BIT_IOR_EXPR:
1568 case BIT_XOR_EXPR:
1569 case BIT_AND_EXPR:
1570 case BIT_ANDTC_EXPR:
1571 case BIT_NOT_EXPR:
1572 case TRUTH_ANDIF_EXPR:
1573 case TRUTH_ORIF_EXPR:
1574 case TRUTH_AND_EXPR:
1575 case TRUTH_OR_EXPR:
1576 case TRUTH_XOR_EXPR:
1577 case TRUTH_NOT_EXPR:
1578 case LT_EXPR:
1579 case LE_EXPR:
1580 case GT_EXPR:
1581 case GE_EXPR:
1582 case EQ_EXPR:
1583 case NE_EXPR:
1584 case COMPLEX_EXPR:
1585 case CONJ_EXPR:
1586 case REALPART_EXPR:
1587 case IMAGPART_EXPR:
1588 case LABEL_EXPR:
1589 case COMPONENT_REF:
1590 return FALSE;
1591
1592 case COMPOUND_EXPR:
1593 return ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1594 TREE_OPERAND (source_tree, 1), NULL,
1595 scalar_arg);
1596
1597 case MODIFY_EXPR:
1598 return ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1599 TREE_OPERAND (source_tree, 0), NULL,
1600 scalar_arg);
1601
1602 case CONVERT_EXPR:
1603 case NOP_EXPR:
1604 case NON_LVALUE_EXPR:
1605 case PLUS_EXPR:
1606 if (TREE_CODE (TREE_TYPE (source_tree)) != POINTER_TYPE)
1607 return TRUE;
1608
1609 ffecom_tree_canonize_ptr_ (&source_decl, &source_offset,
1610 source_tree);
1611 source_size = TYPE_SIZE (TREE_TYPE (TREE_TYPE (source_tree)));
1612 break;
1613
1614 case COND_EXPR:
1615 return
1616 ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1617 TREE_OPERAND (source_tree, 1), NULL,
1618 scalar_arg)
1619 || ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1620 TREE_OPERAND (source_tree, 2), NULL,
1621 scalar_arg);
1622
1623
1624 case ADDR_EXPR:
1625 ffecom_tree_canonize_ref_ (&source_decl, &source_offset,
1626 &source_size,
1627 TREE_OPERAND (source_tree, 0));
1628 break;
1629
1630 case PARM_DECL:
1631 if (TREE_CODE (TREE_TYPE (source_tree)) != POINTER_TYPE)
1632 return TRUE;
1633
1634 source_decl = source_tree;
1635 source_offset = size_zero_node;
1636 source_size = TYPE_SIZE (TREE_TYPE (TREE_TYPE (source_tree)));
1637 break;
1638
1639 case SAVE_EXPR:
1640 case REFERENCE_EXPR:
1641 case PREDECREMENT_EXPR:
1642 case PREINCREMENT_EXPR:
1643 case POSTDECREMENT_EXPR:
1644 case POSTINCREMENT_EXPR:
1645 case INDIRECT_REF:
1646 case ARRAY_REF:
1647 case CALL_EXPR:
1648 default:
1649 return TRUE;
1650 }
1651
1652 /* Come here when source_decl, source_offset, and source_size filled
1653 in appropriately. */
1654
1655 if (source_decl == NULL_TREE)
1656 return FALSE; /* No decl involved, so no overlap. */
1657
1658 if (source_decl != dest_decl)
1659 return FALSE; /* Different decl, no overlap. */
1660
1661 if (TREE_CODE (dest_size) == ERROR_MARK)
1662 return TRUE; /* Assignment into entire assumed-size
1663 array? Shouldn't happen.... */
1664
1665 t = ffecom_2 (LE_EXPR, integer_type_node,
1666 ffecom_2 (PLUS_EXPR, TREE_TYPE (dest_offset),
1667 dest_offset,
1668 convert (TREE_TYPE (dest_offset),
1669 dest_size)),
1670 convert (TREE_TYPE (dest_offset),
1671 source_offset));
1672
1673 if (integer_onep (t))
1674 return FALSE; /* Destination precedes source. */
1675
1676 if (!scalar_arg
1677 || (source_size == NULL_TREE)
1678 || (TREE_CODE (source_size) == ERROR_MARK)
1679 || integer_zerop (source_size))
1680 return TRUE; /* No way to tell if dest follows source. */
1681
1682 t = ffecom_2 (LE_EXPR, integer_type_node,
1683 ffecom_2 (PLUS_EXPR, TREE_TYPE (source_offset),
1684 source_offset,
1685 convert (TREE_TYPE (source_offset),
1686 source_size)),
1687 convert (TREE_TYPE (source_offset),
1688 dest_offset));
1689
1690 if (integer_onep (t))
1691 return FALSE; /* Destination follows source. */
1692
1693 return TRUE; /* Destination and source overlap. */
1694}
1695#endif
1696
1697/* Check whether dest might overlap any of a list of arguments or is
1698 in a COMMON area the callee might know about (and thus modify). */
1699
1700#if FFECOM_targetCURRENT == FFECOM_targetGCC
1701static bool
1702ffecom_args_overlapping_ (tree dest_tree, ffebld dest UNUSED,
1703 tree args, tree callee_commons,
1704 bool scalar_args)
1705{
1706 tree arg;
1707 tree dest_decl;
1708 tree dest_offset;
1709 tree dest_size;
1710
1711 ffecom_tree_canonize_ref_ (&dest_decl, &dest_offset, &dest_size,
1712 dest_tree);
1713
1714 if (dest_decl == NULL_TREE)
1715 return FALSE; /* Seems unlikely! */
1716
1717 /* If the decl cannot be determined reliably, or if its in COMMON
1718 and the callee isn't known to not futz with COMMON via other
1719 means, overlap might happen. */
1720
1721 if ((TREE_CODE (dest_decl) == ERROR_MARK)
1722 || ((callee_commons != NULL_TREE)
1723 && TREE_PUBLIC (dest_decl)))
1724 return TRUE;
1725
1726 for (; args != NULL_TREE; args = TREE_CHAIN (args))
1727 {
1728 if (((arg = TREE_VALUE (args)) != NULL_TREE)
1729 && ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1730 arg, NULL, scalar_args))
1731 return TRUE;
1732 }
1733
1734 return FALSE;
1735}
1736#endif
1737
1738/* Build a string for a variable name as used by NAMELIST. This means that
1739 if we're using the f2c library, we build an uppercase string, since
1740 f2c does this. */
1741
1742#if FFECOM_targetCURRENT == FFECOM_targetGCC
1743static tree
26f096f9 1744ffecom_build_f2c_string_ (int i, const char *s)
5ff904cd
JL
1745{
1746 if (!ffe_is_f2c_library ())
1747 return build_string (i, s);
1748
1749 {
1750 char *tmp;
26f096f9 1751 const char *p;
5ff904cd
JL
1752 char *q;
1753 char space[34];
1754 tree t;
1755
1756 if (((size_t) i) > ARRAY_SIZE (space))
1757 tmp = malloc_new_ks (malloc_pool_image (), "f2c_string", i);
1758 else
1759 tmp = &space[0];
1760
1761 for (p = s, q = tmp; *p != '\0'; ++p, ++q)
1762 *q = ffesrc_toupper (*p);
1763 *q = '\0';
1764
1765 t = build_string (i, tmp);
1766
1767 if (((size_t) i) > ARRAY_SIZE (space))
1768 malloc_kill_ks (malloc_pool_image (), tmp, i);
1769
1770 return t;
1771 }
1772}
1773
1774#endif
1775/* Returns CALL_EXPR or equivalent with given type (pass NULL_TREE for
1776 type to just get whatever the function returns), handling the
1777 f2c value-returning convention, if required, by prepending
1778 to the arglist a pointer to a temporary to receive the return value. */
1779
1780#if FFECOM_targetCURRENT == FFECOM_targetGCC
1781static tree
1782ffecom_call_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex,
1783 tree type, tree args, tree dest_tree,
1784 ffebld dest, bool *dest_used, tree callee_commons,
c7e4ee3a 1785 bool scalar_args, tree hook)
5ff904cd
JL
1786{
1787 tree item;
1788 tree tempvar;
1789
1790 if (dest_used != NULL)
1791 *dest_used = FALSE;
1792
1793 if (is_f2c_complex)
1794 {
1795 if ((dest_used == NULL)
1796 || (dest == NULL)
1797 || (ffeinfo_basictype (ffebld_info (dest))
1798 != FFEINFO_basictypeCOMPLEX)
1799 || (ffeinfo_kindtype (ffebld_info (dest)) != kt)
1800 || ((type != NULL_TREE) && (TREE_TYPE (dest_tree) != type))
1801 || ffecom_args_overlapping_ (dest_tree, dest, args,
1802 callee_commons,
1803 scalar_args))
1804 {
c7e4ee3a
CB
1805#ifdef HOHO
1806 tempvar = ffecom_make_tempvar (ffecom_tree_type
5ff904cd
JL
1807 [FFEINFO_basictypeCOMPLEX][kt],
1808 FFETARGET_charactersizeNONE,
c7e4ee3a
CB
1809 -1);
1810#else
1811 tempvar = hook;
1812 assert (tempvar);
1813#endif
5ff904cd
JL
1814 }
1815 else
1816 {
1817 *dest_used = TRUE;
1818 tempvar = dest_tree;
1819 type = NULL_TREE;
1820 }
1821
1822 item
1823 = build_tree_list (NULL_TREE,
1824 ffecom_1 (ADDR_EXPR,
c7e4ee3a 1825 build_pointer_type (TREE_TYPE (tempvar)),
5ff904cd
JL
1826 tempvar));
1827 TREE_CHAIN (item) = args;
1828
1829 item = ffecom_3s (CALL_EXPR, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), fn,
1830 item, NULL_TREE);
1831
1832 if (tempvar != dest_tree)
1833 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), item, tempvar);
1834 }
1835 else
1836 item = ffecom_3s (CALL_EXPR, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), fn,
1837 args, NULL_TREE);
1838
1839 if ((type != NULL_TREE) && (TREE_TYPE (item) != type))
1840 item = ffecom_convert_narrow_ (type, item);
1841
1842 return item;
1843}
1844#endif
1845
1846/* Given two arguments, transform them and make a call to the given
1847 function via ffecom_call_. */
1848
1849#if FFECOM_targetCURRENT == FFECOM_targetGCC
1850static tree
1851ffecom_call_binop_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex,
1852 tree type, ffebld left, ffebld right,
1853 tree dest_tree, ffebld dest, bool *dest_used,
c7e4ee3a 1854 tree callee_commons, bool scalar_args, tree hook)
5ff904cd
JL
1855{
1856 tree left_tree;
1857 tree right_tree;
1858 tree left_length;
1859 tree right_length;
1860
5ff904cd
JL
1861 left_tree = ffecom_arg_ptr_to_expr (left, &left_length);
1862 right_tree = ffecom_arg_ptr_to_expr (right, &right_length);
5ff904cd
JL
1863
1864 left_tree = build_tree_list (NULL_TREE, left_tree);
1865 right_tree = build_tree_list (NULL_TREE, right_tree);
1866 TREE_CHAIN (left_tree) = right_tree;
1867
1868 if (left_length != NULL_TREE)
1869 {
1870 left_length = build_tree_list (NULL_TREE, left_length);
1871 TREE_CHAIN (right_tree) = left_length;
1872 }
1873
1874 if (right_length != NULL_TREE)
1875 {
1876 right_length = build_tree_list (NULL_TREE, right_length);
1877 if (left_length != NULL_TREE)
1878 TREE_CHAIN (left_length) = right_length;
1879 else
1880 TREE_CHAIN (right_tree) = right_length;
1881 }
1882
1883 return ffecom_call_ (fn, kt, is_f2c_complex, type, left_tree,
1884 dest_tree, dest, dest_used, callee_commons,
c7e4ee3a 1885 scalar_args, hook);
5ff904cd
JL
1886}
1887#endif
1888
c7e4ee3a 1889/* Return ptr/length args for char subexpression
5ff904cd
JL
1890
1891 Handles CHARACTER-type CONTER, SYMTER, SUBSTR, ARRAYREF, and FUNCREF
1892 subexpressions by constructing the appropriate trees for the ptr-to-
1893 character-text and length-of-character-text arguments in a calling
86fc7a6c
CB
1894 sequence.
1895
1896 Note that if with_null is TRUE, and the expression is an opCONTER,
1897 a null byte is appended to the string. */
5ff904cd
JL
1898
1899#if FFECOM_targetCURRENT == FFECOM_targetGCC
1900static void
86fc7a6c 1901ffecom_char_args_x_ (tree *xitem, tree *length, ffebld expr, bool with_null)
5ff904cd
JL
1902{
1903 tree item;
1904 tree high;
1905 ffetargetCharacter1 val;
86fc7a6c 1906 ffetargetCharacterSize newlen;
5ff904cd
JL
1907
1908 switch (ffebld_op (expr))
1909 {
1910 case FFEBLD_opCONTER:
1911 val = ffebld_constant_character1 (ffebld_conter (expr));
86fc7a6c
CB
1912 newlen = ffetarget_length_character1 (val);
1913 if (with_null)
1914 {
c7e4ee3a 1915 /* Begin FFETARGET-NULL-KLUDGE. */
86fc7a6c 1916 if (newlen != 0)
c7e4ee3a 1917 ++newlen;
86fc7a6c
CB
1918 }
1919 *length = build_int_2 (newlen, 0);
5ff904cd 1920 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
86fc7a6c 1921 high = build_int_2 (newlen, 0);
5ff904cd 1922 TREE_TYPE (high) = ffecom_f2c_ftnlen_type_node;
c7e4ee3a 1923 item = build_string (newlen,
5ff904cd 1924 ffetarget_text_character1 (val));
c7e4ee3a 1925 /* End FFETARGET-NULL-KLUDGE. */
5ff904cd
JL
1926 TREE_TYPE (item)
1927 = build_type_variant
1928 (build_array_type
1929 (char_type_node,
1930 build_range_type
1931 (ffecom_f2c_ftnlen_type_node,
1932 ffecom_f2c_ftnlen_one_node,
1933 high)),
1934 1, 0);
1935 TREE_CONSTANT (item) = 1;
1936 TREE_STATIC (item) = 1;
1937 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
1938 item);
1939 break;
1940
1941 case FFEBLD_opSYMTER:
1942 {
1943 ffesymbol s = ffebld_symter (expr);
1944
1945 item = ffesymbol_hook (s).decl_tree;
1946 if (item == NULL_TREE)
1947 {
1948 s = ffecom_sym_transform_ (s);
1949 item = ffesymbol_hook (s).decl_tree;
1950 }
1951 if (ffesymbol_kind (s) == FFEINFO_kindENTITY)
1952 {
1953 if (ffesymbol_size (s) == FFETARGET_charactersizeNONE)
1954 *length = ffesymbol_hook (s).length_tree;
1955 else
1956 {
1957 *length = build_int_2 (ffesymbol_size (s), 0);
1958 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
1959 }
1960 }
1961 else if (item == error_mark_node)
1962 *length = error_mark_node;
c7e4ee3a
CB
1963 else
1964 /* FFEINFO_kindFUNCTION. */
5ff904cd
JL
1965 *length = NULL_TREE;
1966 if (!ffesymbol_hook (s).addr
1967 && (item != error_mark_node))
1968 item = ffecom_1 (ADDR_EXPR,
1969 build_pointer_type (TREE_TYPE (item)),
1970 item);
1971 }
1972 break;
1973
1974 case FFEBLD_opARRAYREF:
1975 {
5ff904cd 1976 ffecom_char_args_ (&item, length, ffebld_left (expr));
5ff904cd
JL
1977
1978 if (item == error_mark_node || *length == error_mark_node)
1979 {
1980 item = *length = error_mark_node;
1981 break;
1982 }
1983
6b55276e 1984 item = ffecom_arrayref_ (item, expr, 1);
5ff904cd
JL
1985 }
1986 break;
1987
1988 case FFEBLD_opSUBSTR:
1989 {
1990 ffebld start;
1991 ffebld end;
1992 ffebld thing = ffebld_right (expr);
1993 tree start_tree;
1994 tree end_tree;
6b55276e
CB
1995 char *char_name;
1996 ffebld left_symter;
1997 tree array;
5ff904cd
JL
1998
1999 assert (ffebld_op (thing) == FFEBLD_opITEM);
2000 start = ffebld_head (thing);
2001 thing = ffebld_trail (thing);
2002 assert (ffebld_trail (thing) == NULL);
2003 end = ffebld_head (thing);
2004
6b55276e
CB
2005 /* Determine name for pretty-printing range-check errors. */
2006 for (left_symter = ffebld_left (expr);
2007 left_symter && ffebld_op (left_symter) == FFEBLD_opARRAYREF;
2008 left_symter = ffebld_left (left_symter))
2009 ;
2010 if (ffebld_op (left_symter) == FFEBLD_opSYMTER)
2011 char_name = ffesymbol_text (ffebld_symter (left_symter));
2012 else
2013 char_name = "[expr?]";
2014
5ff904cd 2015 ffecom_char_args_ (&item, length, ffebld_left (expr));
5ff904cd
JL
2016
2017 if (item == error_mark_node || *length == error_mark_node)
2018 {
2019 item = *length = error_mark_node;
2020 break;
2021 }
2022
6b55276e
CB
2023 array = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item)));
2024
5ff904cd
JL
2025 if (start == NULL)
2026 {
2027 if (end == NULL)
2028 ;
2029 else
2030 {
6b55276e
CB
2031 end_tree = ffecom_expr (end);
2032 if (ffe_is_subscript_check ())
2033 end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0,
2034 char_name);
5ff904cd 2035 end_tree = convert (ffecom_f2c_ftnlen_type_node,
6b55276e 2036 end_tree);
5ff904cd
JL
2037
2038 if (end_tree == error_mark_node)
2039 {
2040 item = *length = error_mark_node;
2041 break;
2042 }
2043
2044 *length = end_tree;
2045 }
2046 }
2047 else
2048 {
6b55276e
CB
2049 start_tree = ffecom_expr (start);
2050 if (ffe_is_subscript_check ())
2051 start_tree = ffecom_subscript_check_ (array, start_tree, 0, 0,
2052 char_name);
5ff904cd 2053 start_tree = convert (ffecom_f2c_ftnlen_type_node,
6b55276e 2054 start_tree);
5ff904cd
JL
2055
2056 if (start_tree == error_mark_node)
2057 {
2058 item = *length = error_mark_node;
2059 break;
2060 }
2061
2062 start_tree = ffecom_save_tree (start_tree);
2063
2064 item = ffecom_2 (PLUS_EXPR, TREE_TYPE (item),
2065 item,
2066 ffecom_2 (MINUS_EXPR,
2067 TREE_TYPE (start_tree),
2068 start_tree,
2069 ffecom_f2c_ftnlen_one_node));
2070
2071 if (end == NULL)
2072 {
2073 *length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
2074 ffecom_f2c_ftnlen_one_node,
2075 ffecom_2 (MINUS_EXPR,
2076 ffecom_f2c_ftnlen_type_node,
2077 *length,
2078 start_tree));
2079 }
2080 else
2081 {
6b55276e
CB
2082 end_tree = ffecom_expr (end);
2083 if (ffe_is_subscript_check ())
2084 end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0,
2085 char_name);
5ff904cd 2086 end_tree = convert (ffecom_f2c_ftnlen_type_node,
6b55276e 2087 end_tree);
5ff904cd
JL
2088
2089 if (end_tree == error_mark_node)
2090 {
2091 item = *length = error_mark_node;
2092 break;
2093 }
2094
2095 *length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
2096 ffecom_f2c_ftnlen_one_node,
2097 ffecom_2 (MINUS_EXPR,
2098 ffecom_f2c_ftnlen_type_node,
2099 end_tree, start_tree));
2100 }
2101 }
2102 }
2103 break;
2104
2105 case FFEBLD_opFUNCREF:
2106 {
2107 ffesymbol s = ffebld_symter (ffebld_left (expr));
2108 tree tempvar;
2109 tree args;
2110 ffetargetCharacterSize size = ffeinfo_size (ffebld_info (expr));
2111 ffecomGfrt ix;
2112
2113 if (size == FFETARGET_charactersizeNONE)
c7e4ee3a
CB
2114 /* ~~Kludge alert! This should someday be fixed. */
2115 size = 24;
5ff904cd
JL
2116
2117 *length = build_int_2 (size, 0);
2118 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
2119
2120 if (ffeinfo_where (ffebld_info (ffebld_left (expr)))
2121 == FFEINFO_whereINTRINSIC)
2122 {
2123 if (size == 1)
c7e4ee3a
CB
2124 {
2125 /* Invocation of an intrinsic returning CHARACTER*1. */
5ff904cd
JL
2126 item = ffecom_expr_intrinsic_ (expr, NULL_TREE,
2127 NULL, NULL);
2128 break;
2129 }
2130 ix = ffeintrin_gfrt_direct (ffebld_symter_implementation (ffebld_left (expr)));
2131 assert (ix != FFECOM_gfrt);
2132 item = ffecom_gfrt_tree_ (ix);
2133 }
2134 else
2135 {
2136 ix = FFECOM_gfrt;
2137 item = ffesymbol_hook (s).decl_tree;
2138 if (item == NULL_TREE)
2139 {
2140 s = ffecom_sym_transform_ (s);
2141 item = ffesymbol_hook (s).decl_tree;
2142 }
2143 if (item == error_mark_node)
2144 {
2145 item = *length = error_mark_node;
2146 break;
2147 }
2148
2149 if (!ffesymbol_hook (s).addr)
2150 item = ffecom_1_fn (item);
2151 }
2152
c7e4ee3a 2153#ifdef HOHO
5ff904cd 2154 tempvar = ffecom_push_tempvar (char_type_node, size, -1, TRUE);
c7e4ee3a
CB
2155#else
2156 tempvar = ffebld_nonter_hook (expr);
2157 assert (tempvar);
2158#endif
5ff904cd
JL
2159 tempvar = ffecom_1 (ADDR_EXPR,
2160 build_pointer_type (TREE_TYPE (tempvar)),
2161 tempvar);
2162
5ff904cd
JL
2163 args = build_tree_list (NULL_TREE, tempvar);
2164
2165 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT) /* Sfunc args by value. */
2166 TREE_CHAIN (args) = ffecom_list_expr (ffebld_right (expr));
2167 else
2168 {
2169 TREE_CHAIN (args) = build_tree_list (NULL_TREE, *length);
2170 if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC)
2171 {
2172 TREE_CHAIN (TREE_CHAIN (args))
2173 = ffecom_arglist_expr_ (ffecom_gfrt_args_ (ix),
2174 ffebld_right (expr));
2175 }
2176 else
2177 {
2178 TREE_CHAIN (TREE_CHAIN (args))
2179 = ffecom_list_ptr_to_expr (ffebld_right (expr));
2180 }
2181 }
2182
2183 item = ffecom_3s (CALL_EXPR,
2184 TREE_TYPE (TREE_TYPE (TREE_TYPE (item))),
2185 item, args, NULL_TREE);
2186 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), item,
2187 tempvar);
5ff904cd
JL
2188 }
2189 break;
2190
2191 case FFEBLD_opCONVERT:
2192
5ff904cd 2193 ffecom_char_args_ (&item, length, ffebld_left (expr));
5ff904cd
JL
2194
2195 if (item == error_mark_node || *length == error_mark_node)
2196 {
2197 item = *length = error_mark_node;
2198 break;
2199 }
2200
2201 if ((ffebld_size_known (ffebld_left (expr))
2202 == FFETARGET_charactersizeNONE)
2203 || (ffebld_size_known (ffebld_left (expr)) < (ffebld_size (expr))))
2204 { /* Possible blank-padding needed, copy into
2205 temporary. */
2206 tree tempvar;
2207 tree args;
2208 tree newlen;
2209
c7e4ee3a
CB
2210#ifdef HOHO
2211 tempvar = ffecom_make_tempvar (char_type_node,
2212 ffebld_size (expr), -1);
2213#else
2214 tempvar = ffebld_nonter_hook (expr);
2215 assert (tempvar);
2216#endif
5ff904cd
JL
2217 tempvar = ffecom_1 (ADDR_EXPR,
2218 build_pointer_type (TREE_TYPE (tempvar)),
2219 tempvar);
2220
2221 newlen = build_int_2 (ffebld_size (expr), 0);
2222 TREE_TYPE (newlen) = ffecom_f2c_ftnlen_type_node;
2223
2224 args = build_tree_list (NULL_TREE, tempvar);
2225 TREE_CHAIN (args) = build_tree_list (NULL_TREE, item);
2226 TREE_CHAIN (TREE_CHAIN (args)) = build_tree_list (NULL_TREE, newlen);
2227 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (args)))
2228 = build_tree_list (NULL_TREE, *length);
2229
c7e4ee3a 2230 item = ffecom_call_gfrt (FFECOM_gfrtCOPY, args, NULL_TREE);
5ff904cd
JL
2231 TREE_SIDE_EFFECTS (item) = 1;
2232 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), fold (item),
2233 tempvar);
2234 *length = newlen;
2235 }
2236 else
2237 { /* Just truncate the length. */
2238 *length = build_int_2 (ffebld_size (expr), 0);
2239 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
2240 }
2241 break;
2242
2243 default:
2244 assert ("bad op for single char arg expr" == NULL);
2245 item = NULL_TREE;
2246 break;
2247 }
2248
2249 *xitem = item;
2250}
2251#endif
2252
2253/* Check the size of the type to be sure it doesn't overflow the
2254 "portable" capacities of the compiler back end. `dummy' types
2255 can generally overflow the normal sizes as long as the computations
2256 themselves don't overflow. A particular target of the back end
2257 must still enforce its size requirements, though, and the back
2258 end takes care of this in stor-layout.c. */
2259
2260#if FFECOM_targetCURRENT == FFECOM_targetGCC
2261static tree
2262ffecom_check_size_overflow_ (ffesymbol s, tree type, bool dummy)
2263{
2264 if (TREE_CODE (type) == ERROR_MARK)
2265 return type;
2266
2267 if (TYPE_SIZE (type) == NULL_TREE)
2268 return type;
2269
2270 if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
2271 return type;
2272
2273 if ((tree_int_cst_sgn (TYPE_SIZE (type)) < 0)
2b0c2df0
CB
2274 || (!dummy && (((TREE_INT_CST_HIGH (TYPE_SIZE (type)) != 0))
2275 || TREE_OVERFLOW (TYPE_SIZE (type)))))
5ff904cd
JL
2276 {
2277 ffebad_start (FFEBAD_ARRAY_LARGE);
2278 ffebad_string (ffesymbol_text (s));
2279 ffebad_here (0, ffesymbol_where_line (s), ffesymbol_where_column (s));
2280 ffebad_finish ();
2281
2282 return error_mark_node;
2283 }
2284
2285 return type;
2286}
2287#endif
2288
2289/* Builds a length argument (PARM_DECL). Also wraps type in an array type
2290 where the dimension info is (1:size) where <size> is ffesymbol_size(s) if
2291 known, length_arg if not known (FFETARGET_charactersizeNONE). */
2292
2293#if FFECOM_targetCURRENT == FFECOM_targetGCC
2294static tree
2295ffecom_char_enhance_arg_ (tree *xtype, ffesymbol s)
2296{
2297 ffetargetCharacterSize sz = ffesymbol_size (s);
2298 tree highval;
2299 tree tlen;
2300 tree type = *xtype;
2301
2302 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT)
2303 tlen = NULL_TREE; /* A statement function, no length passed. */
2304 else
2305 {
2306 if (ffesymbol_where (s) == FFEINFO_whereDUMMY)
2307 tlen = ffecom_get_invented_identifier ("__g77_length_%s",
c7e4ee3a 2308 ffesymbol_text (s), -1);
5ff904cd
JL
2309 else
2310 tlen = ffecom_get_invented_identifier ("__g77_%s",
c7e4ee3a 2311 "length", -1);
5ff904cd
JL
2312 tlen = build_decl (PARM_DECL, tlen, ffecom_f2c_ftnlen_type_node);
2313#if BUILT_FOR_270
2314 DECL_ARTIFICIAL (tlen) = 1;
2315#endif
2316 }
2317
2318 if (sz == FFETARGET_charactersizeNONE)
2319 {
2320 assert (tlen != NULL_TREE);
2b0c2df0 2321 highval = variable_size (tlen);
5ff904cd
JL
2322 }
2323 else
2324 {
2325 highval = build_int_2 (sz, 0);
2326 TREE_TYPE (highval) = ffecom_f2c_ftnlen_type_node;
2327 }
2328
2329 type = build_array_type (type,
2330 build_range_type (ffecom_f2c_ftnlen_type_node,
2331 ffecom_f2c_ftnlen_one_node,
2332 highval));
2333
2334 *xtype = type;
2335 return tlen;
2336}
2337
2338#endif
2339/* ffecom_concat_list_gather_ -- Gather list of concatenated string exprs
2340
2341 ffecomConcatList_ catlist;
2342 ffebld expr; // expr of CHARACTER basictype.
2343 ffetargetCharacterSize max; // max chars to gather or _...NONE if no max
2344 catlist = ffecom_concat_list_gather_(catlist,expr,max);
2345
2346 Scans expr for character subexpressions, updates and returns catlist
2347 accordingly. */
2348
2349#if FFECOM_targetCURRENT == FFECOM_targetGCC
2350static ffecomConcatList_
2351ffecom_concat_list_gather_ (ffecomConcatList_ catlist, ffebld expr,
2352 ffetargetCharacterSize max)
2353{
2354 ffetargetCharacterSize sz;
2355
2356recurse: /* :::::::::::::::::::: */
2357
2358 if (expr == NULL)
2359 return catlist;
2360
2361 if ((max != FFETARGET_charactersizeNONE) && (catlist.minlen >= max))
2362 return catlist; /* Don't append any more items. */
2363
2364 switch (ffebld_op (expr))
2365 {
2366 case FFEBLD_opCONTER:
2367 case FFEBLD_opSYMTER:
2368 case FFEBLD_opARRAYREF:
2369 case FFEBLD_opFUNCREF:
2370 case FFEBLD_opSUBSTR:
2371 case FFEBLD_opCONVERT: /* Callers should strip this off beforehand
2372 if they don't need to preserve it. */
2373 if (catlist.count == catlist.max)
2374 { /* Make a (larger) list. */
2375 ffebld *newx;
2376 int newmax;
2377
2378 newmax = (catlist.max == 0) ? 8 : catlist.max * 2;
2379 newx = malloc_new_ks (malloc_pool_image (), "catlist",
2380 newmax * sizeof (newx[0]));
2381 if (catlist.max != 0)
2382 {
2383 memcpy (newx, catlist.exprs, catlist.max * sizeof (newx[0]));
2384 malloc_kill_ks (malloc_pool_image (), catlist.exprs,
2385 catlist.max * sizeof (newx[0]));
2386 }
2387 catlist.max = newmax;
2388 catlist.exprs = newx;
2389 }
2390 if ((sz = ffebld_size_known (expr)) != FFETARGET_charactersizeNONE)
2391 catlist.minlen += sz;
2392 else
2393 ++catlist.minlen; /* Not true for F90; can be 0 length. */
2394 if ((sz = ffebld_size_max (expr)) == FFETARGET_charactersizeNONE)
2395 catlist.maxlen = sz;
2396 else
2397 catlist.maxlen += sz;
2398 if ((max != FFETARGET_charactersizeNONE) && (catlist.minlen > max))
2399 { /* This item overlaps (or is beyond) the end
2400 of the destination. */
2401 switch (ffebld_op (expr))
2402 {
2403 case FFEBLD_opCONTER:
2404 case FFEBLD_opSYMTER:
2405 case FFEBLD_opARRAYREF:
2406 case FFEBLD_opFUNCREF:
2407 case FFEBLD_opSUBSTR:
c7e4ee3a
CB
2408 /* ~~Do useful truncations here. */
2409 break;
5ff904cd
JL
2410
2411 default:
2412 assert ("op changed or inconsistent switches!" == NULL);
2413 break;
2414 }
2415 }
2416 catlist.exprs[catlist.count++] = expr;
2417 return catlist;
2418
2419 case FFEBLD_opPAREN:
2420 expr = ffebld_left (expr);
2421 goto recurse; /* :::::::::::::::::::: */
2422
2423 case FFEBLD_opCONCATENATE:
2424 catlist = ffecom_concat_list_gather_ (catlist, ffebld_left (expr), max);
2425 expr = ffebld_right (expr);
2426 goto recurse; /* :::::::::::::::::::: */
2427
2428#if 0 /* Breaks passing small actual arg to larger
2429 dummy arg of sfunc */
2430 case FFEBLD_opCONVERT:
2431 expr = ffebld_left (expr);
2432 {
2433 ffetargetCharacterSize cmax;
2434
2435 cmax = catlist.len + ffebld_size_known (expr);
2436
2437 if ((max == FFETARGET_charactersizeNONE) || (max > cmax))
2438 max = cmax;
2439 }
2440 goto recurse; /* :::::::::::::::::::: */
2441#endif
2442
2443 case FFEBLD_opANY:
2444 return catlist;
2445
2446 default:
2447 assert ("bad op in _gather_" == NULL);
2448 return catlist;
2449 }
2450}
2451
2452#endif
2453/* ffecom_concat_list_kill_ -- Kill list of concatenated string exprs
2454
2455 ffecomConcatList_ catlist;
2456 ffecom_concat_list_kill_(catlist);
2457
2458 Anything allocated within the list info is deallocated. */
2459
2460#if FFECOM_targetCURRENT == FFECOM_targetGCC
2461static void
2462ffecom_concat_list_kill_ (ffecomConcatList_ catlist)
2463{
2464 if (catlist.max != 0)
2465 malloc_kill_ks (malloc_pool_image (), catlist.exprs,
2466 catlist.max * sizeof (catlist.exprs[0]));
2467}
2468
2469#endif
c7e4ee3a 2470/* Make list of concatenated string exprs.
5ff904cd
JL
2471
2472 Returns a flattened list of concatenated subexpressions given a
2473 tree of such expressions. */
2474
2475#if FFECOM_targetCURRENT == FFECOM_targetGCC
2476static ffecomConcatList_
2477ffecom_concat_list_new_ (ffebld expr, ffetargetCharacterSize max)
2478{
2479 ffecomConcatList_ catlist;
2480
2481 catlist.maxlen = catlist.minlen = catlist.max = catlist.count = 0;
2482 return ffecom_concat_list_gather_ (catlist, expr, max);
2483}
2484
2485#endif
2486
2487/* Provide some kind of useful info on member of aggregate area,
2488 since current g77/gcc technology does not provide debug info
2489 on these members. */
2490
2491#if FFECOM_targetCURRENT == FFECOM_targetGCC
2492static void
26f096f9 2493ffecom_debug_kludge_ (tree aggr, const char *aggr_type, ffesymbol member,
5ff904cd
JL
2494 tree member_type UNUSED, ffetargetOffset offset)
2495{
2496 tree value;
2497 tree decl;
2498 int len;
2499 char *buff;
2500 char space[120];
2501#if 0
2502 tree type_id;
2503
2504 for (type_id = member_type;
2505 TREE_CODE (type_id) != IDENTIFIER_NODE;
2506 )
2507 {
2508 switch (TREE_CODE (type_id))
2509 {
2510 case INTEGER_TYPE:
2511 case REAL_TYPE:
2512 type_id = TYPE_NAME (type_id);
2513 break;
2514
2515 case ARRAY_TYPE:
2516 case COMPLEX_TYPE:
2517 type_id = TREE_TYPE (type_id);
2518 break;
2519
2520 default:
2521 assert ("no IDENTIFIER_NODE for type!" == NULL);
2522 type_id = error_mark_node;
2523 break;
2524 }
2525 }
2526#endif
2527
2528 if (ffecom_transform_only_dummies_
2529 || !ffe_is_debug_kludge ())
2530 return; /* Can't do this yet, maybe later. */
2531
2532 len = 60
2533 + strlen (aggr_type)
2534 + IDENTIFIER_LENGTH (DECL_NAME (aggr));
2535#if 0
2536 + IDENTIFIER_LENGTH (type_id);
2537#endif
2538
2539 if (((size_t) len) >= ARRAY_SIZE (space))
2540 buff = malloc_new_ks (malloc_pool_image (), "debug_kludge", len + 1);
2541 else
2542 buff = &space[0];
2543
2544 sprintf (&buff[0], "At (%s) `%s' plus %ld bytes",
2545 aggr_type,
2546 IDENTIFIER_POINTER (DECL_NAME (aggr)),
2547 (long int) offset);
2548
2549 value = build_string (len, buff);
2550 TREE_TYPE (value)
2551 = build_type_variant (build_array_type (char_type_node,
2552 build_range_type
2553 (integer_type_node,
2554 integer_one_node,
2555 build_int_2 (strlen (buff), 0))),
2556 1, 0);
2557 decl = build_decl (VAR_DECL,
2558 ffecom_get_identifier_ (ffesymbol_text (member)),
2559 TREE_TYPE (value));
2560 TREE_CONSTANT (decl) = 1;
2561 TREE_STATIC (decl) = 1;
2562 DECL_INITIAL (decl) = error_mark_node;
2563 DECL_IN_SYSTEM_HEADER (decl) = 1; /* Don't let -Wunused complain. */
2564 decl = start_decl (decl, FALSE);
2565 finish_decl (decl, value, FALSE);
2566
2567 if (buff != &space[0])
2568 malloc_kill_ks (malloc_pool_image (), buff, len + 1);
2569}
2570#endif
2571
2572/* ffecom_do_entry_ -- Do compilation of a particular entrypoint
2573
2574 ffesymbol fn; // the SUBROUTINE, FUNCTION, or ENTRY symbol itself
2575 int i; // entry# for this entrypoint (used by master fn)
2576 ffecom_do_entrypoint_(s,i);
2577
2578 Makes a public entry point that calls our private master fn (already
2579 compiled). */
2580
2581#if FFECOM_targetCURRENT == FFECOM_targetGCC
2582static void
2583ffecom_do_entry_ (ffesymbol fn, int entrynum)
2584{
2585 ffebld item;
2586 tree type; /* Type of function. */
2587 tree multi_retval; /* Var holding return value (union). */
2588 tree result; /* Var holding result. */
2589 ffeinfoBasictype bt;
2590 ffeinfoKindtype kt;
2591 ffeglobal g;
2592 ffeglobalType gt;
2593 bool charfunc; /* All entry points return same type
2594 CHARACTER. */
2595 bool cmplxfunc; /* Use f2c way of returning COMPLEX. */
2596 bool multi; /* Master fn has multiple return types. */
2597 bool altreturning = FALSE; /* This entry point has alternate returns. */
2598 int yes;
44d2eabc
JL
2599 int old_lineno = lineno;
2600 char *old_input_filename = input_filename;
2601
2602 input_filename = ffesymbol_where_filename (fn);
2603 lineno = ffesymbol_where_filelinenum (fn);
5ff904cd
JL
2604
2605 /* c-parse.y indeed does call suspend_momentary and not only ignores the
2606 return value, but also never calls resume_momentary, when starting an
2607 outer function (see "fndef:", "setspecs:", and so on). So g77 does the
2608 same thing. It shouldn't be a problem since start_function calls
2609 temporary_allocation, but it might be necessary. If it causes a problem
2610 here, then maybe there's a bug lurking in gcc. NOTE: This identical
2611 comment appears twice in thist file. */
2612
2613 suspend_momentary ();
2614
2615 ffecom_doing_entry_ = TRUE; /* Don't bother with array dimensions. */
2616
2617 switch (ffecom_primary_entry_kind_)
2618 {
2619 case FFEINFO_kindFUNCTION:
2620
2621 /* Determine actual return type for function. */
2622
2623 gt = FFEGLOBAL_typeFUNC;
2624 bt = ffesymbol_basictype (fn);
2625 kt = ffesymbol_kindtype (fn);
2626 if (bt == FFEINFO_basictypeNONE)
2627 {
2628 ffeimplic_establish_symbol (fn);
2629 if (ffesymbol_funcresult (fn) != NULL)
2630 ffeimplic_establish_symbol (ffesymbol_funcresult (fn));
2631 bt = ffesymbol_basictype (fn);
2632 kt = ffesymbol_kindtype (fn);
2633 }
2634
2635 if (bt == FFEINFO_basictypeCHARACTER)
2636 charfunc = TRUE, cmplxfunc = FALSE;
2637 else if ((bt == FFEINFO_basictypeCOMPLEX)
2638 && ffesymbol_is_f2c (fn))
2639 charfunc = FALSE, cmplxfunc = TRUE;
2640 else
2641 charfunc = cmplxfunc = FALSE;
2642
2643 if (charfunc)
2644 type = ffecom_tree_fun_type_void;
2645 else if (ffesymbol_is_f2c (fn))
2646 type = ffecom_tree_fun_type[bt][kt];
2647 else
2648 type = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
2649
2650 if ((type == NULL_TREE)
2651 || (TREE_TYPE (type) == NULL_TREE))
2652 type = ffecom_tree_fun_type_void; /* _sym_exec_transition. */
2653
2654 multi = (ffecom_master_bt_ == FFEINFO_basictypeNONE);
2655 break;
2656
2657 case FFEINFO_kindSUBROUTINE:
2658 gt = FFEGLOBAL_typeSUBR;
2659 bt = FFEINFO_basictypeNONE;
2660 kt = FFEINFO_kindtypeNONE;
2661 if (ffecom_is_altreturning_)
2662 { /* Am _I_ altreturning? */
2663 for (item = ffesymbol_dummyargs (fn);
2664 item != NULL;
2665 item = ffebld_trail (item))
2666 {
2667 if (ffebld_op (ffebld_head (item)) == FFEBLD_opSTAR)
2668 {
2669 altreturning = TRUE;
2670 break;
2671 }
2672 }
2673 if (altreturning)
2674 type = ffecom_tree_subr_type;
2675 else
2676 type = ffecom_tree_fun_type_void;
2677 }
2678 else
2679 type = ffecom_tree_fun_type_void;
2680 charfunc = FALSE;
2681 cmplxfunc = FALSE;
2682 multi = FALSE;
2683 break;
2684
2685 default:
2686 assert ("say what??" == NULL);
2687 /* Fall through. */
2688 case FFEINFO_kindANY:
2689 gt = FFEGLOBAL_typeANY;
2690 bt = FFEINFO_basictypeNONE;
2691 kt = FFEINFO_kindtypeNONE;
2692 type = error_mark_node;
2693 charfunc = FALSE;
2694 cmplxfunc = FALSE;
2695 multi = FALSE;
2696 break;
2697 }
2698
2699 /* build_decl uses the current lineno and input_filename to set the decl
2700 source info. So, I've putzed with ffestd and ffeste code to update that
2701 source info to point to the appropriate statement just before calling
2702 ffecom_do_entrypoint (which calls this fn). */
2703
2704 start_function (ffecom_get_external_identifier_ (fn),
2705 type,
2706 0, /* nested/inline */
2707 1); /* TREE_PUBLIC */
2708
2709 if (((g = ffesymbol_global (fn)) != NULL)
2710 && ((ffeglobal_type (g) == gt)
2711 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
2712 {
2713 ffeglobal_set_hook (g, current_function_decl);
2714 }
2715
2716 /* Reset args in master arg list so they get retransitioned. */
2717
2718 for (item = ffecom_master_arglist_;
2719 item != NULL;
2720 item = ffebld_trail (item))
2721 {
2722 ffebld arg;
2723 ffesymbol s;
2724
2725 arg = ffebld_head (item);
2726 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2727 continue; /* Alternate return or some such thing. */
2728 s = ffebld_symter (arg);
2729 ffesymbol_hook (s).decl_tree = NULL_TREE;
2730 ffesymbol_hook (s).length_tree = NULL_TREE;
2731 }
2732
2733 /* Build dummy arg list for this entry point. */
2734
2735 yes = suspend_momentary ();
2736
2737 if (charfunc || cmplxfunc)
2738 { /* Prepend arg for where result goes. */
2739 tree type;
2740 tree length;
2741
2742 if (charfunc)
2743 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
2744 else
2745 type = ffecom_tree_type[FFEINFO_basictypeCOMPLEX][kt];
2746
2747 result = ffecom_get_invented_identifier ("__g77_%s",
c7e4ee3a 2748 "result", -1);
5ff904cd
JL
2749
2750 /* Make length arg _and_ enhance type info for CHAR arg itself. */
2751
2752 if (charfunc)
2753 length = ffecom_char_enhance_arg_ (&type, fn);
2754 else
2755 length = NULL_TREE; /* Not ref'd if !charfunc. */
2756
2757 type = build_pointer_type (type);
2758 result = build_decl (PARM_DECL, result, type);
2759
2760 push_parm_decl (result);
2761 ffecom_func_result_ = result;
2762
2763 if (charfunc)
2764 {
2765 push_parm_decl (length);
2766 ffecom_func_length_ = length;
2767 }
2768 }
2769 else
2770 result = DECL_RESULT (current_function_decl);
2771
2772 ffecom_push_dummy_decls_ (ffesymbol_dummyargs (fn), FALSE);
2773
2774 resume_momentary (yes);
2775
2776 store_parm_decls (0);
2777
c7e4ee3a
CB
2778 ffecom_start_compstmt ();
2779 /* Disallow temp vars at this level. */
2780 current_binding_level->prep_state = 2;
5ff904cd
JL
2781
2782 /* Make local var to hold return type for multi-type master fn. */
2783
2784 if (multi)
2785 {
2786 yes = suspend_momentary ();
2787
2788 multi_retval = ffecom_get_invented_identifier ("__g77_%s",
c7e4ee3a 2789 "multi_retval", -1);
5ff904cd
JL
2790 multi_retval = build_decl (VAR_DECL, multi_retval,
2791 ffecom_multi_type_node_);
2792 multi_retval = start_decl (multi_retval, FALSE);
2793 finish_decl (multi_retval, NULL_TREE, FALSE);
2794
2795 resume_momentary (yes);
2796 }
2797 else
2798 multi_retval = NULL_TREE; /* Not actually ref'd if !multi. */
2799
2800 /* Here we emit the actual code for the entry point. */
2801
2802 {
2803 ffebld list;
2804 ffebld arg;
2805 ffesymbol s;
2806 tree arglist = NULL_TREE;
2807 tree *plist = &arglist;
2808 tree prepend;
2809 tree call;
2810 tree actarg;
2811 tree master_fn;
2812
2813 /* Prepare actual arg list based on master arg list. */
2814
2815 for (list = ffecom_master_arglist_;
2816 list != NULL;
2817 list = ffebld_trail (list))
2818 {
2819 arg = ffebld_head (list);
2820 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2821 continue;
2822 s = ffebld_symter (arg);
702edf1d
CB
2823 if (ffesymbol_hook (s).decl_tree == NULL_TREE
2824 || ffesymbol_hook (s).decl_tree == error_mark_node)
5ff904cd
JL
2825 actarg = null_pointer_node; /* We don't have this arg. */
2826 else
2827 actarg = ffesymbol_hook (s).decl_tree;
2828 *plist = build_tree_list (NULL_TREE, actarg);
2829 plist = &TREE_CHAIN (*plist);
2830 }
2831
2832 /* This code appends the length arguments for character
2833 variables/arrays. */
2834
2835 for (list = ffecom_master_arglist_;
2836 list != NULL;
2837 list = ffebld_trail (list))
2838 {
2839 arg = ffebld_head (list);
2840 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2841 continue;
2842 s = ffebld_symter (arg);
2843 if (ffesymbol_basictype (s) != FFEINFO_basictypeCHARACTER)
2844 continue; /* Only looking for CHARACTER arguments. */
2845 if (ffesymbol_kind (s) != FFEINFO_kindENTITY)
2846 continue; /* Only looking for variables and arrays. */
702edf1d
CB
2847 if (ffesymbol_hook (s).length_tree == NULL_TREE
2848 || ffesymbol_hook (s).length_tree == error_mark_node)
5ff904cd
JL
2849 actarg = ffecom_f2c_ftnlen_zero_node; /* We don't have this arg. */
2850 else
2851 actarg = ffesymbol_hook (s).length_tree;
2852 *plist = build_tree_list (NULL_TREE, actarg);
2853 plist = &TREE_CHAIN (*plist);
2854 }
2855
2856 /* Prepend character-value return info to actual arg list. */
2857
2858 if (charfunc)
2859 {
2860 prepend = build_tree_list (NULL_TREE, ffecom_func_result_);
2861 TREE_CHAIN (prepend)
2862 = build_tree_list (NULL_TREE, ffecom_func_length_);
2863 TREE_CHAIN (TREE_CHAIN (prepend)) = arglist;
2864 arglist = prepend;
2865 }
2866
2867 /* Prepend multi-type return value to actual arg list. */
2868
2869 if (multi)
2870 {
2871 prepend
2872 = build_tree_list (NULL_TREE,
2873 ffecom_1 (ADDR_EXPR,
2874 build_pointer_type (TREE_TYPE (multi_retval)),
2875 multi_retval));
2876 TREE_CHAIN (prepend) = arglist;
2877 arglist = prepend;
2878 }
2879
2880 /* Prepend my entry-point number to the actual arg list. */
2881
2882 prepend = build_tree_list (NULL_TREE, build_int_2 (entrynum, 0));
2883 TREE_CHAIN (prepend) = arglist;
2884 arglist = prepend;
2885
2886 /* Build the call to the master function. */
2887
2888 master_fn = ffecom_1_fn (ffecom_previous_function_decl_);
2889 call = ffecom_3s (CALL_EXPR,
2890 TREE_TYPE (TREE_TYPE (TREE_TYPE (master_fn))),
2891 master_fn, arglist, NULL_TREE);
2892
2893 /* Decide whether the master function is a function or subroutine, and
2894 handle the return value for my entry point. */
2895
2896 if (charfunc || ((ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE)
2897 && !altreturning))
2898 {
2899 expand_expr_stmt (call);
2900 expand_null_return ();
2901 }
2902 else if (multi && cmplxfunc)
2903 {
2904 expand_expr_stmt (call);
2905 result
2906 = ffecom_1 (INDIRECT_REF,
2907 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result))),
2908 result);
2909 result = ffecom_modify (NULL_TREE, result,
2910 ffecom_2 (COMPONENT_REF, TREE_TYPE (result),
2911 multi_retval,
2912 ffecom_multi_fields_[bt][kt]));
2913 expand_expr_stmt (result);
2914 expand_null_return ();
2915 }
2916 else if (multi)
2917 {
2918 expand_expr_stmt (call);
2919 result
2920 = ffecom_modify (NULL_TREE, result,
2921 convert (TREE_TYPE (result),
2922 ffecom_2 (COMPONENT_REF,
2923 ffecom_tree_type[bt][kt],
2924 multi_retval,
2925 ffecom_multi_fields_[bt][kt])));
2926 expand_return (result);
2927 }
2928 else if (cmplxfunc)
2929 {
2930 result
2931 = ffecom_1 (INDIRECT_REF,
2932 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result))),
2933 result);
2934 result = ffecom_modify (NULL_TREE, result, call);
2935 expand_expr_stmt (result);
2936 expand_null_return ();
2937 }
2938 else
2939 {
2940 result = ffecom_modify (NULL_TREE,
2941 result,
2942 convert (TREE_TYPE (result),
2943 call));
2944 expand_return (result);
2945 }
2946
2947 clear_momentary ();
2948 }
2949
c7e4ee3a 2950 ffecom_end_compstmt ();
5ff904cd
JL
2951
2952 finish_function (0);
2953
44d2eabc
JL
2954 lineno = old_lineno;
2955 input_filename = old_input_filename;
2956
5ff904cd
JL
2957 ffecom_doing_entry_ = FALSE;
2958}
2959
2960#endif
2961/* Transform expr into gcc tree with possible destination
2962
2963 Recursive descent on expr while making corresponding tree nodes and
2964 attaching type info and such. If destination supplied and compatible
2965 with temporary that would be made in certain cases, temporary isn't
092a4ef8 2966 made, destination used instead, and dest_used flag set TRUE. */
5ff904cd
JL
2967
2968#if FFECOM_targetCURRENT == FFECOM_targetGCC
2969static tree
092a4ef8
RH
2970ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest,
2971 bool *dest_used, bool assignp, bool widenp)
5ff904cd
JL
2972{
2973 tree item;
2974 tree list;
2975 tree args;
2976 ffeinfoBasictype bt;
2977 ffeinfoKindtype kt;
2978 tree t;
5ff904cd 2979 tree dt; /* decl_tree for an ffesymbol. */
092a4ef8 2980 tree tree_type, tree_type_x;
af752698 2981 tree left, right;
5ff904cd
JL
2982 ffesymbol s;
2983 enum tree_code code;
2984
2985 assert (expr != NULL);
2986
2987 if (dest_used != NULL)
2988 *dest_used = FALSE;
2989
2990 bt = ffeinfo_basictype (ffebld_info (expr));
2991 kt = ffeinfo_kindtype (ffebld_info (expr));
af752698 2992 tree_type = ffecom_tree_type[bt][kt];
5ff904cd 2993
092a4ef8
RH
2994 /* Widen integral arithmetic as desired while preserving signedness. */
2995 tree_type_x = NULL_TREE;
2996 if (widenp && tree_type
2997 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
2998 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
2999 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
3000
5ff904cd
JL
3001 switch (ffebld_op (expr))
3002 {
3003 case FFEBLD_opACCTER:
5ff904cd
JL
3004 {
3005 ffebitCount i;
3006 ffebit bits = ffebld_accter_bits (expr);
3007 ffetargetOffset source_offset = 0;
a6fa6420 3008 ffetargetOffset dest_offset = ffebld_accter_pad (expr);
5ff904cd
JL
3009 tree purpose;
3010
a6fa6420
CB
3011 assert (dest_offset == 0
3012 || (bt == FFEINFO_basictypeCHARACTER
3013 && kt == FFEINFO_kindtypeCHARACTER1));
5ff904cd
JL
3014
3015 list = item = NULL;
3016 for (;;)
3017 {
3018 ffebldConstantUnion cu;
3019 ffebitCount length;
3020 bool value;
3021 ffebldConstantArray ca = ffebld_accter (expr);
3022
3023 ffebit_test (bits, source_offset, &value, &length);
3024 if (length == 0)
3025 break;
3026
3027 if (value)
3028 {
3029 for (i = 0; i < length; ++i)
3030 {
3031 cu = ffebld_constantarray_get (ca, bt, kt,
3032 source_offset + i);
3033
3034 t = ffecom_constantunion (&cu, bt, kt, tree_type);
3035
a6fa6420
CB
3036 if (i == 0
3037 && dest_offset != 0)
3038 purpose = build_int_2 (dest_offset, 0);
5ff904cd
JL
3039 else
3040 purpose = NULL_TREE;
3041
3042 if (list == NULL_TREE)
3043 list = item = build_tree_list (purpose, t);
3044 else
3045 {
3046 TREE_CHAIN (item) = build_tree_list (purpose, t);
3047 item = TREE_CHAIN (item);
3048 }
3049 }
3050 }
3051 source_offset += length;
a6fa6420 3052 dest_offset += length;
5ff904cd
JL
3053 }
3054 }
3055
a6fa6420
CB
3056 item = build_int_2 ((ffebld_accter_size (expr)
3057 + ffebld_accter_pad (expr)) - 1, 0);
5ff904cd
JL
3058 ffebit_kill (ffebld_accter_bits (expr));
3059 TREE_TYPE (item) = ffecom_integer_type_node;
3060 item
3061 = build_array_type
3062 (tree_type,
3063 build_range_type (ffecom_integer_type_node,
3064 ffecom_integer_zero_node,
3065 item));
3066 list = build (CONSTRUCTOR, item, NULL_TREE, list);
3067 TREE_CONSTANT (list) = 1;
3068 TREE_STATIC (list) = 1;
3069 return list;
3070
3071 case FFEBLD_opARRTER:
5ff904cd
JL
3072 {
3073 ffetargetOffset i;
3074
a6fa6420
CB
3075 list = NULL_TREE;
3076 if (ffebld_arrter_pad (expr) == 0)
3077 item = NULL_TREE;
3078 else
3079 {
3080 assert (bt == FFEINFO_basictypeCHARACTER
3081 && kt == FFEINFO_kindtypeCHARACTER1);
3082
3083 /* Becomes PURPOSE first time through loop. */
3084 item = build_int_2 (ffebld_arrter_pad (expr), 0);
3085 }
3086
5ff904cd
JL
3087 for (i = 0; i < ffebld_arrter_size (expr); ++i)
3088 {
3089 ffebldConstantUnion cu
3090 = ffebld_constantarray_get (ffebld_arrter (expr), bt, kt, i);
3091
3092 t = ffecom_constantunion (&cu, bt, kt, tree_type);
3093
3094 if (list == NULL_TREE)
a6fa6420
CB
3095 /* Assume item is PURPOSE first time through loop. */
3096 list = item = build_tree_list (item, t);
5ff904cd
JL
3097 else
3098 {
3099 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
3100 item = TREE_CHAIN (item);
3101 }
3102 }
3103 }
3104
a6fa6420
CB
3105 item = build_int_2 ((ffebld_arrter_size (expr)
3106 + ffebld_arrter_pad (expr)) - 1, 0);
5ff904cd
JL
3107 TREE_TYPE (item) = ffecom_integer_type_node;
3108 item
3109 = build_array_type
3110 (tree_type,
3111 build_range_type (ffecom_integer_type_node,
a6fa6420 3112 ffecom_integer_zero_node,
5ff904cd
JL
3113 item));
3114 list = build (CONSTRUCTOR, item, NULL_TREE, list);
3115 TREE_CONSTANT (list) = 1;
3116 TREE_STATIC (list) = 1;
3117 return list;
3118
3119 case FFEBLD_opCONTER:
c264f113 3120 assert (ffebld_conter_pad (expr) == 0);
5ff904cd
JL
3121 item
3122 = ffecom_constantunion (&ffebld_constant_union (ffebld_conter (expr)),
3123 bt, kt, tree_type);
3124 return item;
3125
3126 case FFEBLD_opSYMTER:
3127 if ((ffebld_symter_generic (expr) != FFEINTRIN_genNONE)
3128 || (ffebld_symter_specific (expr) != FFEINTRIN_specNONE))
3129 return ffecom_ptr_to_expr (expr); /* Same as %REF(intrinsic). */
3130 s = ffebld_symter (expr);
3131 t = ffesymbol_hook (s).decl_tree;
3132
3133 if (assignp)
3134 { /* ASSIGN'ed-label expr. */
3135 if (ffe_is_ugly_assign ())
3136 {
3137 /* User explicitly wants ASSIGN'ed variables to be at the same
3138 memory address as the variables when used in non-ASSIGN
3139 contexts. That can make old, arcane, non-standard code
3140 work, but don't try to do it when a pointer wouldn't fit
3141 in the normal variable (take other approach, and warn,
3142 instead). */
3143
3144 if (t == NULL_TREE)
3145 {
3146 s = ffecom_sym_transform_ (s);
3147 t = ffesymbol_hook (s).decl_tree;
3148 assert (t != NULL_TREE);
3149 }
3150
3151 if (t == error_mark_node)
3152 return t;
3153
3154 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (t)))
3155 >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
3156 {
3157 if (ffesymbol_hook (s).addr)
3158 t = ffecom_1 (INDIRECT_REF,
3159 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), t);
3160 return t;
3161 }
3162
3163 if (ffesymbol_hook (s).assign_tree == NULL_TREE)
3164 {
3165 ffebad_start_msg ("ASSIGN'ed label cannot fit into `%A' at %0 -- using wider sibling",
3166 FFEBAD_severityWARNING);
3167 ffebad_string (ffesymbol_text (s));
3168 ffebad_here (0, ffesymbol_where_line (s),
3169 ffesymbol_where_column (s));
3170 ffebad_finish ();
3171 }
3172 }
3173
3174 /* Don't use the normal variable's tree for ASSIGN, though mark
3175 it as in the system header (housekeeping). Use an explicit,
3176 specially created sibling that is known to be wide enough
3177 to hold pointers to labels. */
3178
3179 if (t != NULL_TREE
3180 && TREE_CODE (t) == VAR_DECL)
3181 DECL_IN_SYSTEM_HEADER (t) = 1; /* Don't let -Wunused complain. */
3182
3183 t = ffesymbol_hook (s).assign_tree;
3184 if (t == NULL_TREE)
3185 {
3186 s = ffecom_sym_transform_assign_ (s);
3187 t = ffesymbol_hook (s).assign_tree;
3188 assert (t != NULL_TREE);
3189 }
3190 }
3191 else
3192 {
3193 if (t == NULL_TREE)
3194 {
3195 s = ffecom_sym_transform_ (s);
3196 t = ffesymbol_hook (s).decl_tree;
3197 assert (t != NULL_TREE);
3198 }
3199 if (ffesymbol_hook (s).addr)
3200 t = ffecom_1 (INDIRECT_REF,
3201 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), t);
3202 }
3203 return t;
3204
3205 case FFEBLD_opARRAYREF:
3206 {
6b55276e
CB
3207 if (0 /* ~~~~~ ffe_is_flat_arrays () */)
3208 t = ffecom_ptr_to_expr (ffebld_left (expr));
3209 else
3210 t = ffecom_expr (ffebld_left (expr));
5ff904cd 3211
5ff904cd
JL
3212 if (t == error_mark_node)
3213 return t;
3214
3215 if ((ffeinfo_where (ffebld_info (expr)) == FFEINFO_whereFLEETING)
3216 && !mark_addressable (t))
3217 return error_mark_node; /* Make sure non-const ref is to
3218 non-reg. */
3219
6b55276e 3220 t = ffecom_arrayref_ (t, expr, 0);
5ff904cd
JL
3221
3222 return t;
3223 }
3224
3225 case FFEBLD_opUPLUS:
092a4ef8 3226 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
af752698 3227 return ffecom_1 (NOP_EXPR, tree_type, left);
5ff904cd 3228
c7e4ee3a
CB
3229 case FFEBLD_opPAREN:
3230 /* ~~~Make sure Fortran rules respected here */
092a4ef8 3231 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
af752698 3232 return ffecom_1 (NOP_EXPR, tree_type, left);
5ff904cd
JL
3233
3234 case FFEBLD_opUMINUS:
092a4ef8 3235 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
af752698
RH
3236 if (tree_type_x)
3237 {
3238 tree_type = tree_type_x;
3239 left = convert (tree_type, left);
3240 }
3241 return ffecom_1 (NEGATE_EXPR, tree_type, left);
5ff904cd
JL
3242
3243 case FFEBLD_opADD:
092a4ef8
RH
3244 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3245 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
af752698
RH
3246 if (tree_type_x)
3247 {
3248 tree_type = tree_type_x;
3249 left = convert (tree_type, left);
3250 right = convert (tree_type, right);
3251 }
3252 return ffecom_2 (PLUS_EXPR, tree_type, left, right);
5ff904cd
JL
3253
3254 case FFEBLD_opSUBTRACT:
092a4ef8
RH
3255 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3256 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
af752698
RH
3257 if (tree_type_x)
3258 {
3259 tree_type = tree_type_x;
3260 left = convert (tree_type, left);
3261 right = convert (tree_type, right);
3262 }
3263 return ffecom_2 (MINUS_EXPR, tree_type, left, right);
5ff904cd
JL
3264
3265 case FFEBLD_opMULTIPLY:
092a4ef8
RH
3266 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3267 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
af752698
RH
3268 if (tree_type_x)
3269 {
3270 tree_type = tree_type_x;
3271 left = convert (tree_type, left);
3272 right = convert (tree_type, right);
3273 }
3274 return ffecom_2 (MULT_EXPR, tree_type, left, right);
5ff904cd
JL
3275
3276 case FFEBLD_opDIVIDE:
092a4ef8
RH
3277 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3278 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
af752698
RH
3279 if (tree_type_x)
3280 {
3281 tree_type = tree_type_x;
3282 left = convert (tree_type, left);
3283 right = convert (tree_type, right);
3284 }
3285 return ffecom_tree_divide_ (tree_type, left, right,
c7e4ee3a
CB
3286 dest_tree, dest, dest_used,
3287 ffebld_nonter_hook (expr));
5ff904cd
JL
3288
3289 case FFEBLD_opPOWER:
5ff904cd
JL
3290 {
3291 ffebld left = ffebld_left (expr);
3292 ffebld right = ffebld_right (expr);
3293 ffecomGfrt code;
3294 ffeinfoKindtype rtkt;
270fc4e8 3295 ffeinfoKindtype ltkt;
5ff904cd
JL
3296
3297 switch (ffeinfo_basictype (ffebld_info (right)))
3298 {
3299 case FFEINFO_basictypeINTEGER:
3300 if (1 || optimize)
3301 {
c7e4ee3a 3302 item = ffecom_expr_power_integer_ (expr);
5ff904cd
JL
3303 if (item != NULL_TREE)
3304 return item;
3305 }
3306
3307 rtkt = FFEINFO_kindtypeINTEGER1;
3308 switch (ffeinfo_basictype (ffebld_info (left)))
3309 {
3310 case FFEINFO_basictypeINTEGER:
3311 if ((ffeinfo_kindtype (ffebld_info (left))
3312 == FFEINFO_kindtypeINTEGER4)
3313 || (ffeinfo_kindtype (ffebld_info (right))
3314 == FFEINFO_kindtypeINTEGER4))
3315 {
3316 code = FFECOM_gfrtPOW_QQ;
270fc4e8 3317 ltkt = FFEINFO_kindtypeINTEGER4;
5ff904cd
JL
3318 rtkt = FFEINFO_kindtypeINTEGER4;
3319 }
3320 else
6a047254
CB
3321 {
3322 code = FFECOM_gfrtPOW_II;
3323 ltkt = FFEINFO_kindtypeINTEGER1;
3324 }
5ff904cd
JL
3325 break;
3326
3327 case FFEINFO_basictypeREAL:
3328 if (ffeinfo_kindtype (ffebld_info (left))
3329 == FFEINFO_kindtypeREAL1)
6a047254
CB
3330 {
3331 code = FFECOM_gfrtPOW_RI;
3332 ltkt = FFEINFO_kindtypeREAL1;
3333 }
5ff904cd 3334 else
6a047254
CB
3335 {
3336 code = FFECOM_gfrtPOW_DI;
3337 ltkt = FFEINFO_kindtypeREAL2;
3338 }
5ff904cd
JL
3339 break;
3340
3341 case FFEINFO_basictypeCOMPLEX:
3342 if (ffeinfo_kindtype (ffebld_info (left))
3343 == FFEINFO_kindtypeREAL1)
6a047254
CB
3344 {
3345 code = FFECOM_gfrtPOW_CI; /* Overlapping result okay. */
3346 ltkt = FFEINFO_kindtypeREAL1;
3347 }
5ff904cd 3348 else
6a047254
CB
3349 {
3350 code = FFECOM_gfrtPOW_ZI; /* Overlapping result okay. */
3351 ltkt = FFEINFO_kindtypeREAL2;
3352 }
5ff904cd
JL
3353 break;
3354
3355 default:
3356 assert ("bad pow_*i" == NULL);
3357 code = FFECOM_gfrtPOW_CI; /* Overlapping result okay. */
6a047254 3358 ltkt = FFEINFO_kindtypeREAL1;
5ff904cd
JL
3359 break;
3360 }
270fc4e8 3361 if (ffeinfo_kindtype (ffebld_info (left)) != ltkt)
5ff904cd 3362 left = ffeexpr_convert (left, NULL, NULL,
6a047254 3363 ffeinfo_basictype (ffebld_info (left)),
270fc4e8 3364 ltkt, 0,
5ff904cd
JL
3365 FFETARGET_charactersizeNONE,
3366 FFEEXPR_contextLET);
3367 if (ffeinfo_kindtype (ffebld_info (right)) != rtkt)
3368 right = ffeexpr_convert (right, NULL, NULL,
3369 FFEINFO_basictypeINTEGER,
3370 rtkt, 0,
3371 FFETARGET_charactersizeNONE,
3372 FFEEXPR_contextLET);
3373 break;
3374
3375 case FFEINFO_basictypeREAL:
3376 if (ffeinfo_kindtype (ffebld_info (left)) == FFEINFO_kindtypeREAL1)
3377 left = ffeexpr_convert (left, NULL, NULL, FFEINFO_basictypeREAL,
3378 FFEINFO_kindtypeREALDOUBLE, 0,
3379 FFETARGET_charactersizeNONE,
3380 FFEEXPR_contextLET);
3381 if (ffeinfo_kindtype (ffebld_info (right))
3382 == FFEINFO_kindtypeREAL1)
3383 right = ffeexpr_convert (right, NULL, NULL,
3384 FFEINFO_basictypeREAL,
3385 FFEINFO_kindtypeREALDOUBLE, 0,
3386 FFETARGET_charactersizeNONE,
3387 FFEEXPR_contextLET);
3388 code = FFECOM_gfrtPOW_DD;
3389 break;
3390
3391 case FFEINFO_basictypeCOMPLEX:
3392 if (ffeinfo_kindtype (ffebld_info (left)) == FFEINFO_kindtypeREAL1)
3393 left = ffeexpr_convert (left, NULL, NULL,
3394 FFEINFO_basictypeCOMPLEX,
3395 FFEINFO_kindtypeREALDOUBLE, 0,
3396 FFETARGET_charactersizeNONE,
3397 FFEEXPR_contextLET);
3398 if (ffeinfo_kindtype (ffebld_info (right))
3399 == FFEINFO_kindtypeREAL1)
3400 right = ffeexpr_convert (right, NULL, NULL,
3401 FFEINFO_basictypeCOMPLEX,
3402 FFEINFO_kindtypeREALDOUBLE, 0,
3403 FFETARGET_charactersizeNONE,
3404 FFEEXPR_contextLET);
3405 code = FFECOM_gfrtPOW_ZZ; /* Overlapping result okay. */
3406 break;
3407
3408 default:
3409 assert ("bad pow_x*" == NULL);
3410 code = FFECOM_gfrtPOW_II;
3411 break;
3412 }
3413 return ffecom_call_binop_ (ffecom_gfrt_tree_ (code),
3414 ffecom_gfrt_kindtype (code),
3415 (ffe_is_f2c_library ()
3416 && ffecom_gfrt_complex_[code]),
3417 tree_type, left, right,
3418 dest_tree, dest, dest_used,
c7e4ee3a
CB
3419 NULL_TREE, FALSE,
3420 ffebld_nonter_hook (expr));
5ff904cd
JL
3421 }
3422
3423 case FFEBLD_opNOT:
5ff904cd
JL
3424 switch (bt)
3425 {
3426 case FFEINFO_basictypeLOGICAL:
83ffecd2 3427 item = ffecom_truth_value_invert (ffecom_expr (ffebld_left (expr)));
5ff904cd
JL
3428 return convert (tree_type, item);
3429
3430 case FFEINFO_basictypeINTEGER:
3431 return ffecom_1 (BIT_NOT_EXPR, tree_type,
3432 ffecom_expr (ffebld_left (expr)));
3433
3434 default:
3435 assert ("NOT bad basictype" == NULL);
3436 /* Fall through. */
3437 case FFEINFO_basictypeANY:
3438 return error_mark_node;
3439 }
3440 break;
3441
3442 case FFEBLD_opFUNCREF:
3443 assert (ffeinfo_basictype (ffebld_info (expr))
3444 != FFEINFO_basictypeCHARACTER);
3445 /* Fall through. */
3446 case FFEBLD_opSUBRREF:
5ff904cd
JL
3447 if (ffeinfo_where (ffebld_info (ffebld_left (expr)))
3448 == FFEINFO_whereINTRINSIC)
3449 { /* Invocation of an intrinsic. */
3450 item = ffecom_expr_intrinsic_ (expr, dest_tree, dest,
3451 dest_used);
3452 return item;
3453 }
3454 s = ffebld_symter (ffebld_left (expr));
3455 dt = ffesymbol_hook (s).decl_tree;
3456 if (dt == NULL_TREE)
3457 {
3458 s = ffecom_sym_transform_ (s);
3459 dt = ffesymbol_hook (s).decl_tree;
3460 }
3461 if (dt == error_mark_node)
3462 return dt;
3463
3464 if (ffesymbol_hook (s).addr)
3465 item = dt;
3466 else
3467 item = ffecom_1_fn (dt);
3468
5ff904cd
JL
3469 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT)
3470 args = ffecom_list_expr (ffebld_right (expr));
3471 else
3472 args = ffecom_list_ptr_to_expr (ffebld_right (expr));
5ff904cd 3473
702edf1d
CB
3474 if (args == error_mark_node)
3475 return error_mark_node;
3476
5ff904cd
JL
3477 item = ffecom_call_ (item, kt,
3478 ffesymbol_is_f2c (s)
3479 && (bt == FFEINFO_basictypeCOMPLEX)
3480 && (ffesymbol_where (s)
3481 != FFEINFO_whereCONSTANT),
3482 tree_type,
3483 args,
3484 dest_tree, dest, dest_used,
c7e4ee3a
CB
3485 error_mark_node, FALSE,
3486 ffebld_nonter_hook (expr));
5ff904cd
JL
3487 TREE_SIDE_EFFECTS (item) = 1;
3488 return item;
3489
3490 case FFEBLD_opAND:
5ff904cd
JL
3491 switch (bt)
3492 {
3493 case FFEINFO_basictypeLOGICAL:
3494 item
3495 = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
3496 ffecom_truth_value (ffecom_expr (ffebld_left (expr))),
3497 ffecom_truth_value (ffecom_expr (ffebld_right (expr))));
3498 return convert (tree_type, item);
3499
3500 case FFEINFO_basictypeINTEGER:
3501 return ffecom_2 (BIT_AND_EXPR, tree_type,
3502 ffecom_expr (ffebld_left (expr)),
3503 ffecom_expr (ffebld_right (expr)));
3504
3505 default:
3506 assert ("AND bad basictype" == NULL);
3507 /* Fall through. */
3508 case FFEINFO_basictypeANY:
3509 return error_mark_node;
3510 }
3511 break;
3512
3513 case FFEBLD_opOR:
5ff904cd
JL
3514 switch (bt)
3515 {
3516 case FFEINFO_basictypeLOGICAL:
3517 item
3518 = ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
3519 ffecom_truth_value (ffecom_expr (ffebld_left (expr))),
3520 ffecom_truth_value (ffecom_expr (ffebld_right (expr))));
3521 return convert (tree_type, item);
3522
3523 case FFEINFO_basictypeINTEGER:
3524 return ffecom_2 (BIT_IOR_EXPR, tree_type,
3525 ffecom_expr (ffebld_left (expr)),
3526 ffecom_expr (ffebld_right (expr)));
3527
3528 default:
3529 assert ("OR bad basictype" == NULL);
3530 /* Fall through. */
3531 case FFEINFO_basictypeANY:
3532 return error_mark_node;
3533 }
3534 break;
3535
3536 case FFEBLD_opXOR:
3537 case FFEBLD_opNEQV:
5ff904cd
JL
3538 switch (bt)
3539 {
3540 case FFEINFO_basictypeLOGICAL:
3541 item
3542 = ffecom_2 (NE_EXPR, integer_type_node,
3543 ffecom_expr (ffebld_left (expr)),
3544 ffecom_expr (ffebld_right (expr)));
3545 return convert (tree_type, ffecom_truth_value (item));
3546
3547 case FFEINFO_basictypeINTEGER:
3548 return ffecom_2 (BIT_XOR_EXPR, tree_type,
3549 ffecom_expr (ffebld_left (expr)),
3550 ffecom_expr (ffebld_right (expr)));
3551
3552 default:
3553 assert ("XOR/NEQV bad basictype" == NULL);
3554 /* Fall through. */
3555 case FFEINFO_basictypeANY:
3556 return error_mark_node;
3557 }
3558 break;
3559
3560 case FFEBLD_opEQV:
5ff904cd
JL
3561 switch (bt)
3562 {
3563 case FFEINFO_basictypeLOGICAL:
3564 item
3565 = ffecom_2 (EQ_EXPR, integer_type_node,
3566 ffecom_expr (ffebld_left (expr)),
3567 ffecom_expr (ffebld_right (expr)));
3568 return convert (tree_type, ffecom_truth_value (item));
3569
3570 case FFEINFO_basictypeINTEGER:
3571 return
3572 ffecom_1 (BIT_NOT_EXPR, tree_type,
3573 ffecom_2 (BIT_XOR_EXPR, tree_type,
3574 ffecom_expr (ffebld_left (expr)),
3575 ffecom_expr (ffebld_right (expr))));
3576
3577 default:
3578 assert ("EQV bad basictype" == NULL);
3579 /* Fall through. */
3580 case FFEINFO_basictypeANY:
3581 return error_mark_node;
3582 }
3583 break;
3584
3585 case FFEBLD_opCONVERT:
3586 if (ffebld_op (ffebld_left (expr)) == FFEBLD_opANY)
3587 return error_mark_node;
3588
5ff904cd
JL
3589 switch (bt)
3590 {
3591 case FFEINFO_basictypeLOGICAL:
3592 case FFEINFO_basictypeINTEGER:
3593 case FFEINFO_basictypeREAL:
3594 return convert (tree_type, ffecom_expr (ffebld_left (expr)));
3595
3596 case FFEINFO_basictypeCOMPLEX:
3597 switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr))))
3598 {
3599 case FFEINFO_basictypeINTEGER:
3600 case FFEINFO_basictypeLOGICAL:
3601 case FFEINFO_basictypeREAL:
3602 item = ffecom_expr (ffebld_left (expr));
3603 if (item == error_mark_node)
3604 return error_mark_node;
3605 /* convert() takes care of converting to the subtype first,
3606 at least in gcc-2.7.2. */
3607 item = convert (tree_type, item);
3608 return item;
3609
3610 case FFEINFO_basictypeCOMPLEX:
3611 return convert (tree_type, ffecom_expr (ffebld_left (expr)));
3612
3613 default:
3614 assert ("CONVERT COMPLEX bad basictype" == NULL);
3615 /* Fall through. */
3616 case FFEINFO_basictypeANY:
3617 return error_mark_node;
3618 }
3619 break;
3620
3621 default:
3622 assert ("CONVERT bad basictype" == NULL);
3623 /* Fall through. */
3624 case FFEINFO_basictypeANY:
3625 return error_mark_node;
3626 }
3627 break;
3628
3629 case FFEBLD_opLT:
3630 code = LT_EXPR;
3631 goto relational; /* :::::::::::::::::::: */
3632
3633 case FFEBLD_opLE:
3634 code = LE_EXPR;
3635 goto relational; /* :::::::::::::::::::: */
3636
3637 case FFEBLD_opEQ:
3638 code = EQ_EXPR;
3639 goto relational; /* :::::::::::::::::::: */
3640
3641 case FFEBLD_opNE:
3642 code = NE_EXPR;
3643 goto relational; /* :::::::::::::::::::: */
3644
3645 case FFEBLD_opGT:
3646 code = GT_EXPR;
3647 goto relational; /* :::::::::::::::::::: */
3648
3649 case FFEBLD_opGE:
3650 code = GE_EXPR;
3651
3652 relational: /* :::::::::::::::::::: */
5ff904cd
JL
3653 switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr))))
3654 {
3655 case FFEINFO_basictypeLOGICAL:
3656 case FFEINFO_basictypeINTEGER:
3657 case FFEINFO_basictypeREAL:
3658 item = ffecom_2 (code, integer_type_node,
3659 ffecom_expr (ffebld_left (expr)),
3660 ffecom_expr (ffebld_right (expr)));
3661 return convert (tree_type, item);
3662
3663 case FFEINFO_basictypeCOMPLEX:
3664 assert (code == EQ_EXPR || code == NE_EXPR);
3665 {
3666 tree real_type;
3667 tree arg1 = ffecom_expr (ffebld_left (expr));
3668 tree arg2 = ffecom_expr (ffebld_right (expr));
3669
3670 if (arg1 == error_mark_node || arg2 == error_mark_node)
3671 return error_mark_node;
3672
3673 arg1 = ffecom_save_tree (arg1);
3674 arg2 = ffecom_save_tree (arg2);
3675
3676 if (TREE_CODE (TREE_TYPE (arg1)) == COMPLEX_TYPE)
3677 {
3678 real_type = TREE_TYPE (TREE_TYPE (arg1));
3679 assert (real_type == TREE_TYPE (TREE_TYPE (arg2)));
3680 }
3681 else
3682 {
3683 real_type = TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg1)));
3684 assert (real_type == TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg2))));
3685 }
3686
3687 item
3688 = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
3689 ffecom_2 (EQ_EXPR, integer_type_node,
3690 ffecom_1 (REALPART_EXPR, real_type, arg1),
3691 ffecom_1 (REALPART_EXPR, real_type, arg2)),
3692 ffecom_2 (EQ_EXPR, integer_type_node,
3693 ffecom_1 (IMAGPART_EXPR, real_type, arg1),
3694 ffecom_1 (IMAGPART_EXPR, real_type,
3695 arg2)));
3696 if (code == EQ_EXPR)
3697 item = ffecom_truth_value (item);
3698 else
3699 item = ffecom_truth_value_invert (item);
3700 return convert (tree_type, item);
3701 }
3702
3703 case FFEINFO_basictypeCHARACTER:
5ff904cd
JL
3704 {
3705 ffebld left = ffebld_left (expr);
3706 ffebld right = ffebld_right (expr);
3707 tree left_tree;
3708 tree right_tree;
3709 tree left_length;
3710 tree right_length;
3711
3712 /* f2c run-time functions do the implicit blank-padding for us,
3713 so we don't usually have to implement blank-padding ourselves.
3714 (The exception is when we pass an argument to a separately
3715 compiled statement function -- if we know the arg is not the
3716 same length as the dummy, we must truncate or extend it. If
3717 we "inline" statement functions, that necessity goes away as
3718 well.)
3719
3720 Strip off the CONVERT operators that blank-pad. (Truncation by
3721 CONVERT shouldn't happen here, but it can happen in
3722 assignments.) */
3723
3724 while (ffebld_op (left) == FFEBLD_opCONVERT)
3725 left = ffebld_left (left);
3726 while (ffebld_op (right) == FFEBLD_opCONVERT)
3727 right = ffebld_left (right);
3728
3729 left_tree = ffecom_arg_ptr_to_expr (left, &left_length);
3730 right_tree = ffecom_arg_ptr_to_expr (right, &right_length);
3731
3732 if (left_tree == error_mark_node || left_length == error_mark_node
3733 || right_tree == error_mark_node
3734 || right_length == error_mark_node)
c7e4ee3a 3735 return error_mark_node;
5ff904cd
JL
3736
3737 if ((ffebld_size_known (left) == 1)
3738 && (ffebld_size_known (right) == 1))
3739 {
3740 left_tree
3741 = ffecom_1 (INDIRECT_REF,
3742 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree))),
3743 left_tree);
3744 right_tree
3745 = ffecom_1 (INDIRECT_REF,
3746 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree))),
3747 right_tree);
3748
3749 item
3750 = ffecom_2 (code, integer_type_node,
3751 ffecom_2 (ARRAY_REF,
3752 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree))),
3753 left_tree,
3754 integer_one_node),
3755 ffecom_2 (ARRAY_REF,
3756 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree))),
3757 right_tree,
3758 integer_one_node));
3759 }
3760 else
3761 {
3762 item = build_tree_list (NULL_TREE, left_tree);
3763 TREE_CHAIN (item) = build_tree_list (NULL_TREE, right_tree);
3764 TREE_CHAIN (TREE_CHAIN (item)) = build_tree_list (NULL_TREE,
3765 left_length);
3766 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item)))
3767 = build_tree_list (NULL_TREE, right_length);
c7e4ee3a 3768 item = ffecom_call_gfrt (FFECOM_gfrtCMP, item, NULL_TREE);
5ff904cd
JL
3769 item = ffecom_2 (code, integer_type_node,
3770 item,
3771 convert (TREE_TYPE (item),
3772 integer_zero_node));
3773 }
3774 item = convert (tree_type, item);
3775 }
3776
5ff904cd
JL
3777 return item;
3778
3779 default:
3780 assert ("relational bad basictype" == NULL);
3781 /* Fall through. */
3782 case FFEINFO_basictypeANY:
3783 return error_mark_node;
3784 }
3785 break;
3786
3787 case FFEBLD_opPERCENT_LOC:
5ff904cd
JL
3788 item = ffecom_arg_ptr_to_expr (ffebld_left (expr), &list);
3789 return convert (tree_type, item);
3790
3791 case FFEBLD_opITEM:
3792 case FFEBLD_opSTAR:
3793 case FFEBLD_opBOUNDS:
3794 case FFEBLD_opREPEAT:
3795 case FFEBLD_opLABTER:
3796 case FFEBLD_opLABTOK:
3797 case FFEBLD_opIMPDO:
3798 case FFEBLD_opCONCATENATE:
3799 case FFEBLD_opSUBSTR:
3800 default:
3801 assert ("bad op" == NULL);
3802 /* Fall through. */
3803 case FFEBLD_opANY:
3804 return error_mark_node;
3805 }
3806
3807#if 1
3808 assert ("didn't think anything got here anymore!!" == NULL);
3809#else
3810 switch (ffebld_arity (expr))
3811 {
3812 case 2:
3813 TREE_OPERAND (item, 0) = ffecom_expr (ffebld_left (expr));
3814 TREE_OPERAND (item, 1) = ffecom_expr (ffebld_right (expr));
3815 if (TREE_OPERAND (item, 0) == error_mark_node
3816 || TREE_OPERAND (item, 1) == error_mark_node)
3817 return error_mark_node;
3818 break;
3819
3820 case 1:
3821 TREE_OPERAND (item, 0) = ffecom_expr (ffebld_left (expr));
3822 if (TREE_OPERAND (item, 0) == error_mark_node)
3823 return error_mark_node;
3824 break;
3825
3826 default:
3827 break;
3828 }
3829
3830 return fold (item);
3831#endif
3832}
3833
3834#endif
3835/* Returns the tree that does the intrinsic invocation.
3836
3837 Note: this function applies only to intrinsics returning
3838 CHARACTER*1 or non-CHARACTER results, and to intrinsic
3839 subroutines. */
3840
3841#if FFECOM_targetCURRENT == FFECOM_targetGCC
3842static tree
3843ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree,
3844 ffebld dest, bool *dest_used)
3845{
3846 tree expr_tree;
3847 tree saved_expr1; /* For those who need it. */
3848 tree saved_expr2; /* For those who need it. */
3849 ffeinfoBasictype bt;
3850 ffeinfoKindtype kt;
3851 tree tree_type;
3852 tree arg1_type;
3853 tree real_type; /* REAL type corresponding to COMPLEX. */
3854 tree tempvar;
3855 ffebld list = ffebld_right (expr); /* List of (some) args. */
3856 ffebld arg1; /* For handy reference. */
3857 ffebld arg2;
3858 ffebld arg3;
3859 ffeintrinImp codegen_imp;
3860 ffecomGfrt gfrt;
3861
3862 assert (ffebld_op (ffebld_left (expr)) == FFEBLD_opSYMTER);
3863
3864 if (dest_used != NULL)
3865 *dest_used = FALSE;
3866
3867 bt = ffeinfo_basictype (ffebld_info (expr));
3868 kt = ffeinfo_kindtype (ffebld_info (expr));
3869 tree_type = ffecom_tree_type[bt][kt];
3870
3871 if (list != NULL)
3872 {
3873 arg1 = ffebld_head (list);
3874 if (arg1 != NULL && ffebld_op (arg1) == FFEBLD_opANY)
3875 return error_mark_node;
3876 if ((list = ffebld_trail (list)) != NULL)
3877 {
3878 arg2 = ffebld_head (list);
3879 if (arg2 != NULL && ffebld_op (arg2) == FFEBLD_opANY)
3880 return error_mark_node;
3881 if ((list = ffebld_trail (list)) != NULL)
3882 {
3883 arg3 = ffebld_head (list);
3884 if (arg3 != NULL && ffebld_op (arg3) == FFEBLD_opANY)
3885 return error_mark_node;
3886 }
3887 else
3888 arg3 = NULL;
3889 }
3890 else
3891 arg2 = arg3 = NULL;
3892 }
3893 else
3894 arg1 = arg2 = arg3 = NULL;
3895
3896 /* <list> ends up at the opITEM of the 3rd arg, or NULL if there are < 3
3897 args. This is used by the MAX/MIN expansions. */
3898
3899 if (arg1 != NULL)
3900 arg1_type = ffecom_tree_type
3901 [ffeinfo_basictype (ffebld_info (arg1))]
3902 [ffeinfo_kindtype (ffebld_info (arg1))];
3903 else
3904 arg1_type = NULL_TREE; /* Really not needed, but might catch bugs
3905 here. */
3906
3907 /* There are several ways for each of the cases in the following switch
3908 statements to exit (from simplest to use to most complicated):
3909
3910 break; (when expr_tree == NULL)
3911
3912 A standard call is made to the specific intrinsic just as if it had been
3913 passed in as a dummy procedure and called as any old procedure. This
3914 method can produce slower code but in some cases it's the easiest way for
3915 now. However, if a (presumably faster) direct call is available,
3916 that is used, so this is the easiest way in many more cases now.
3917
3918 gfrt = FFECOM_gfrtWHATEVER;
3919 break;
3920
3921 gfrt contains the gfrt index of a library function to call, passing the
3922 argument(s) by value rather than by reference. Used when a more
3923 careful choice of library function is needed than that provided
3924 by the vanilla `break;'.
3925
3926 return expr_tree;
3927
3928 The expr_tree has been completely set up and is ready to be returned
3929 as is. No further actions are taken. Use this when the tree is not
3930 in the simple form for one of the arity_n labels. */
3931
3932 /* For info on how the switch statement cases were written, see the files
3933 enclosed in comments below the switch statement. */
3934
3935 codegen_imp = ffebld_symter_implementation (ffebld_left (expr));
3936 gfrt = ffeintrin_gfrt_direct (codegen_imp);
3937 if (gfrt == FFECOM_gfrt)
3938 gfrt = ffeintrin_gfrt_indirect (codegen_imp);
3939
3940 switch (codegen_imp)
3941 {
3942 case FFEINTRIN_impABS:
3943 case FFEINTRIN_impCABS:
3944 case FFEINTRIN_impCDABS:
3945 case FFEINTRIN_impDABS:
3946 case FFEINTRIN_impIABS:
3947 if (ffeinfo_basictype (ffebld_info (arg1))
3948 == FFEINFO_basictypeCOMPLEX)
3949 {
3950 if (kt == FFEINFO_kindtypeREAL1)
3951 gfrt = FFECOM_gfrtCABS;
3952 else if (kt == FFEINFO_kindtypeREAL2)
3953 gfrt = FFECOM_gfrtCDABS;
3954 break;
3955 }
3956 return ffecom_1 (ABS_EXPR, tree_type,
3957 convert (tree_type, ffecom_expr (arg1)));
3958
3959 case FFEINTRIN_impACOS:
3960 case FFEINTRIN_impDACOS:
3961 break;
3962
3963 case FFEINTRIN_impAIMAG:
3964 case FFEINTRIN_impDIMAG:
3965 case FFEINTRIN_impIMAGPART:
3966 if (TREE_CODE (arg1_type) == COMPLEX_TYPE)
3967 arg1_type = TREE_TYPE (arg1_type);
3968 else
3969 arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type));
3970
3971 return
3972 convert (tree_type,
3973 ffecom_1 (IMAGPART_EXPR, arg1_type,
3974 ffecom_expr (arg1)));
3975
3976 case FFEINTRIN_impAINT:
3977 case FFEINTRIN_impDINT:
c7e4ee3a
CB
3978#if 0
3979 /* ~~Someday implement FIX_TRUNC_EXPR yielding same type as arg. */
5ff904cd
JL
3980 return ffecom_1 (FIX_TRUNC_EXPR, tree_type, ffecom_expr (arg1));
3981#else /* in the meantime, must use floor to avoid range problems with ints */
3982 /* r__1 = r1 >= 0 ? floor(r1) : -floor(-r1); */
3983 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
3984 return
3985 convert (tree_type,
3986 ffecom_3 (COND_EXPR, double_type_node,
3987 ffecom_truth_value
3988 (ffecom_2 (GE_EXPR, integer_type_node,
3989 saved_expr1,
3990 convert (arg1_type,
3991 ffecom_float_zero_))),
3992 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
3993 build_tree_list (NULL_TREE,
3994 convert (double_type_node,
c7e4ee3a
CB
3995 saved_expr1)),
3996 NULL_TREE),
5ff904cd
JL
3997 ffecom_1 (NEGATE_EXPR, double_type_node,
3998 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
3999 build_tree_list (NULL_TREE,
4000 convert (double_type_node,
4001 ffecom_1 (NEGATE_EXPR,
4002 arg1_type,
c7e4ee3a
CB
4003 saved_expr1))),
4004 NULL_TREE)
5ff904cd
JL
4005 ))
4006 );
4007#endif
4008
4009 case FFEINTRIN_impANINT:
4010 case FFEINTRIN_impDNINT:
4011#if 0 /* This way of doing it won't handle real
4012 numbers of large magnitudes. */
4013 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
4014 expr_tree = convert (tree_type,
4015 convert (integer_type_node,
4016 ffecom_3 (COND_EXPR, tree_type,
4017 ffecom_truth_value
4018 (ffecom_2 (GE_EXPR,
4019 integer_type_node,
4020 saved_expr1,
4021 ffecom_float_zero_)),
4022 ffecom_2 (PLUS_EXPR,
4023 tree_type,
4024 saved_expr1,
4025 ffecom_float_half_),
4026 ffecom_2 (MINUS_EXPR,
4027 tree_type,
4028 saved_expr1,
4029 ffecom_float_half_))));
4030 return expr_tree;
4031#else /* So we instead call floor. */
4032 /* r__1 = r1 >= 0 ? floor(r1 + .5) : -floor(.5 - r1) */
4033 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
4034 return
4035 convert (tree_type,
4036 ffecom_3 (COND_EXPR, double_type_node,
4037 ffecom_truth_value
4038 (ffecom_2 (GE_EXPR, integer_type_node,
4039 saved_expr1,
4040 convert (arg1_type,
4041 ffecom_float_zero_))),
4042 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
4043 build_tree_list (NULL_TREE,
4044 convert (double_type_node,
4045 ffecom_2 (PLUS_EXPR,
4046 arg1_type,
4047 saved_expr1,
4048 convert (arg1_type,
c7e4ee3a
CB
4049 ffecom_float_half_)))),
4050 NULL_TREE),
5ff904cd
JL
4051 ffecom_1 (NEGATE_EXPR, double_type_node,
4052 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
4053 build_tree_list (NULL_TREE,
4054 convert (double_type_node,
4055 ffecom_2 (MINUS_EXPR,
4056 arg1_type,
4057 convert (arg1_type,
4058 ffecom_float_half_),
c7e4ee3a
CB
4059 saved_expr1))),
4060 NULL_TREE))
5ff904cd
JL
4061 )
4062 );
4063#endif
4064
4065 case FFEINTRIN_impASIN:
4066 case FFEINTRIN_impDASIN:
4067 case FFEINTRIN_impATAN:
4068 case FFEINTRIN_impDATAN:
4069 case FFEINTRIN_impATAN2:
4070 case FFEINTRIN_impDATAN2:
4071 break;
4072
4073 case FFEINTRIN_impCHAR:
4074 case FFEINTRIN_impACHAR:
c7e4ee3a
CB
4075#ifdef HOHO
4076 tempvar = ffecom_make_tempvar (char_type_node, 1, -1);
4077#else
4078 tempvar = ffebld_nonter_hook (expr);
4079 assert (tempvar);
4080#endif
5ff904cd
JL
4081 {
4082 tree tmv = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (tempvar)));
4083
4084 expr_tree = ffecom_modify (tmv,
4085 ffecom_2 (ARRAY_REF, tmv, tempvar,
4086 integer_one_node),
4087 convert (tmv, ffecom_expr (arg1)));
4088 }
4089 expr_tree = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar),
4090 expr_tree,
4091 tempvar);
4092 expr_tree = ffecom_1 (ADDR_EXPR,
4093 build_pointer_type (TREE_TYPE (expr_tree)),
4094 expr_tree);
4095 return expr_tree;
4096
4097 case FFEINTRIN_impCMPLX:
4098 case FFEINTRIN_impDCMPLX:
4099 if (arg2 == NULL)
4100 return
4101 convert (tree_type, ffecom_expr (arg1));
4102
4103 real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
4104 return
4105 ffecom_2 (COMPLEX_EXPR, tree_type,
4106 convert (real_type, ffecom_expr (arg1)),
4107 convert (real_type,
4108 ffecom_expr (arg2)));
4109
4110 case FFEINTRIN_impCOMPLEX:
4111 return
4112 ffecom_2 (COMPLEX_EXPR, tree_type,
4113 ffecom_expr (arg1),
4114 ffecom_expr (arg2));
4115
4116 case FFEINTRIN_impCONJG:
4117 case FFEINTRIN_impDCONJG:
4118 {
4119 tree arg1_tree;
4120
4121 real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
4122 arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4123 return
4124 ffecom_2 (COMPLEX_EXPR, tree_type,
4125 ffecom_1 (REALPART_EXPR, real_type, arg1_tree),
4126 ffecom_1 (NEGATE_EXPR, real_type,
4127 ffecom_1 (IMAGPART_EXPR, real_type, arg1_tree)));
4128 }
4129
4130 case FFEINTRIN_impCOS:
4131 case FFEINTRIN_impCCOS:
4132 case FFEINTRIN_impCDCOS:
4133 case FFEINTRIN_impDCOS:
4134 if (bt == FFEINFO_basictypeCOMPLEX)
4135 {
4136 if (kt == FFEINFO_kindtypeREAL1)
4137 gfrt = FFECOM_gfrtCCOS; /* Overlapping result okay. */
4138 else if (kt == FFEINFO_kindtypeREAL2)
4139 gfrt = FFECOM_gfrtCDCOS; /* Overlapping result okay. */
4140 }
4141 break;
4142
4143 case FFEINTRIN_impCOSH:
4144 case FFEINTRIN_impDCOSH:
4145 break;
4146
4147 case FFEINTRIN_impDBLE:
4148 case FFEINTRIN_impDFLOAT:
4149 case FFEINTRIN_impDREAL:
4150 case FFEINTRIN_impFLOAT:
4151 case FFEINTRIN_impIDINT:
4152 case FFEINTRIN_impIFIX:
4153 case FFEINTRIN_impINT2:
4154 case FFEINTRIN_impINT8:
4155 case FFEINTRIN_impINT:
4156 case FFEINTRIN_impLONG:
4157 case FFEINTRIN_impREAL:
4158 case FFEINTRIN_impSHORT:
4159 case FFEINTRIN_impSNGL:
4160 return convert (tree_type, ffecom_expr (arg1));
4161
4162 case FFEINTRIN_impDIM:
4163 case FFEINTRIN_impDDIM:
4164 case FFEINTRIN_impIDIM:
4165 saved_expr1 = ffecom_save_tree (convert (tree_type,
4166 ffecom_expr (arg1)));
4167 saved_expr2 = ffecom_save_tree (convert (tree_type,
4168 ffecom_expr (arg2)));
4169 return
4170 ffecom_3 (COND_EXPR, tree_type,
4171 ffecom_truth_value
4172 (ffecom_2 (GT_EXPR, integer_type_node,
4173 saved_expr1,
4174 saved_expr2)),
4175 ffecom_2 (MINUS_EXPR, tree_type,
4176 saved_expr1,
4177 saved_expr2),
4178 convert (tree_type, ffecom_float_zero_));
4179
4180 case FFEINTRIN_impDPROD:
4181 return
4182 ffecom_2 (MULT_EXPR, tree_type,
4183 convert (tree_type, ffecom_expr (arg1)),
4184 convert (tree_type, ffecom_expr (arg2)));
4185
4186 case FFEINTRIN_impEXP:
4187 case FFEINTRIN_impCDEXP:
4188 case FFEINTRIN_impCEXP:
4189 case FFEINTRIN_impDEXP:
4190 if (bt == FFEINFO_basictypeCOMPLEX)
4191 {
4192 if (kt == FFEINFO_kindtypeREAL1)
4193 gfrt = FFECOM_gfrtCEXP; /* Overlapping result okay. */
4194 else if (kt == FFEINFO_kindtypeREAL2)
4195 gfrt = FFECOM_gfrtCDEXP; /* Overlapping result okay. */
4196 }
4197 break;
4198
4199 case FFEINTRIN_impICHAR:
4200 case FFEINTRIN_impIACHAR:
4201#if 0 /* The simple approach. */
4202 ffecom_char_args_ (&expr_tree, &saved_expr1 /* Ignored */ , arg1);
4203 expr_tree
4204 = ffecom_1 (INDIRECT_REF,
4205 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
4206 expr_tree);
4207 expr_tree
4208 = ffecom_2 (ARRAY_REF,
4209 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
4210 expr_tree,
4211 integer_one_node);
4212 return convert (tree_type, expr_tree);
4213#else /* The more interesting (and more optimal) approach. */
4214 expr_tree = ffecom_intrinsic_ichar_ (tree_type, arg1, &saved_expr1);
4215 expr_tree = ffecom_3 (COND_EXPR, tree_type,
4216 saved_expr1,
4217 expr_tree,
4218 convert (tree_type, integer_zero_node));
4219 return expr_tree;
4220#endif
4221
4222 case FFEINTRIN_impINDEX:
4223 break;
4224
4225 case FFEINTRIN_impLEN:
4226#if 0
4227 break; /* The simple approach. */
4228#else
4229 return ffecom_intrinsic_len_ (arg1); /* The more optimal approach. */
4230#endif
4231
4232 case FFEINTRIN_impLGE:
4233 case FFEINTRIN_impLGT:
4234 case FFEINTRIN_impLLE:
4235 case FFEINTRIN_impLLT:
4236 break;
4237
4238 case FFEINTRIN_impLOG:
4239 case FFEINTRIN_impALOG:
4240 case FFEINTRIN_impCDLOG:
4241 case FFEINTRIN_impCLOG:
4242 case FFEINTRIN_impDLOG:
4243 if (bt == FFEINFO_basictypeCOMPLEX)
4244 {
4245 if (kt == FFEINFO_kindtypeREAL1)
4246 gfrt = FFECOM_gfrtCLOG; /* Overlapping result okay. */
4247 else if (kt == FFEINFO_kindtypeREAL2)
4248 gfrt = FFECOM_gfrtCDLOG; /* Overlapping result okay. */
4249 }
4250 break;
4251
4252 case FFEINTRIN_impLOG10:
4253 case FFEINTRIN_impALOG10:
4254 case FFEINTRIN_impDLOG10:
4255 if (gfrt != FFECOM_gfrt)
4256 break; /* Already picked one, stick with it. */
4257
4258 if (kt == FFEINFO_kindtypeREAL1)
4259 gfrt = FFECOM_gfrtALOG10;
4260 else if (kt == FFEINFO_kindtypeREAL2)
4261 gfrt = FFECOM_gfrtDLOG10;
4262 break;
4263
4264 case FFEINTRIN_impMAX:
4265 case FFEINTRIN_impAMAX0:
4266 case FFEINTRIN_impAMAX1:
4267 case FFEINTRIN_impDMAX1:
4268 case FFEINTRIN_impMAX0:
4269 case FFEINTRIN_impMAX1:
4270 if (bt != ffeinfo_basictype (ffebld_info (arg1)))
4271 arg1_type = ffecom_widest_expr_type_ (ffebld_right (expr));
4272 else
4273 arg1_type = tree_type;
4274 expr_tree = ffecom_2 (MAX_EXPR, arg1_type,
4275 convert (arg1_type, ffecom_expr (arg1)),
4276 convert (arg1_type, ffecom_expr (arg2)));
4277 for (; list != NULL; list = ffebld_trail (list))
4278 {
4279 if ((ffebld_head (list) == NULL)
4280 || (ffebld_op (ffebld_head (list)) == FFEBLD_opANY))
4281 continue;
4282 expr_tree = ffecom_2 (MAX_EXPR, arg1_type,
4283 expr_tree,
4284 convert (arg1_type,
4285 ffecom_expr (ffebld_head (list))));
4286 }
4287 return convert (tree_type, expr_tree);
4288
4289 case FFEINTRIN_impMIN:
4290 case FFEINTRIN_impAMIN0:
4291 case FFEINTRIN_impAMIN1:
4292 case FFEINTRIN_impDMIN1:
4293 case FFEINTRIN_impMIN0:
4294 case FFEINTRIN_impMIN1:
4295 if (bt != ffeinfo_basictype (ffebld_info (arg1)))
4296 arg1_type = ffecom_widest_expr_type_ (ffebld_right (expr));
4297 else
4298 arg1_type = tree_type;
4299 expr_tree = ffecom_2 (MIN_EXPR, arg1_type,
4300 convert (arg1_type, ffecom_expr (arg1)),
4301 convert (arg1_type, ffecom_expr (arg2)));
4302 for (; list != NULL; list = ffebld_trail (list))
4303 {
4304 if ((ffebld_head (list) == NULL)
4305 || (ffebld_op (ffebld_head (list)) == FFEBLD_opANY))
4306 continue;
4307 expr_tree = ffecom_2 (MIN_EXPR, arg1_type,
4308 expr_tree,
4309 convert (arg1_type,
4310 ffecom_expr (ffebld_head (list))));
4311 }
4312 return convert (tree_type, expr_tree);
4313
4314 case FFEINTRIN_impMOD:
4315 case FFEINTRIN_impAMOD:
4316 case FFEINTRIN_impDMOD:
4317 if (bt != FFEINFO_basictypeREAL)
4318 return ffecom_2 (TRUNC_MOD_EXPR, tree_type,
4319 convert (tree_type, ffecom_expr (arg1)),
4320 convert (tree_type, ffecom_expr (arg2)));
4321
4322 if (kt == FFEINFO_kindtypeREAL1)
4323 gfrt = FFECOM_gfrtAMOD;
4324 else if (kt == FFEINFO_kindtypeREAL2)
4325 gfrt = FFECOM_gfrtDMOD;
4326 break;
4327
4328 case FFEINTRIN_impNINT:
4329 case FFEINTRIN_impIDNINT:
c7e4ee3a
CB
4330#if 0
4331 /* ~~Ideally FIX_ROUND_EXPR would be implemented, but it ain't yet. */
5ff904cd
JL
4332 return ffecom_1 (FIX_ROUND_EXPR, tree_type, ffecom_expr (arg1));
4333#else
4334 /* i__1 = r1 >= 0 ? floor(r1 + .5) : -floor(.5 - r1); */
4335 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
4336 return
4337 convert (ffecom_integer_type_node,
4338 ffecom_3 (COND_EXPR, arg1_type,
4339 ffecom_truth_value
4340 (ffecom_2 (GE_EXPR, integer_type_node,
4341 saved_expr1,
4342 convert (arg1_type,
4343 ffecom_float_zero_))),
4344 ffecom_2 (PLUS_EXPR, arg1_type,
4345 saved_expr1,
4346 convert (arg1_type,
4347 ffecom_float_half_)),
4348 ffecom_2 (MINUS_EXPR, arg1_type,
4349 saved_expr1,
4350 convert (arg1_type,
4351 ffecom_float_half_))));
4352#endif
4353
4354 case FFEINTRIN_impSIGN:
4355 case FFEINTRIN_impDSIGN:
4356 case FFEINTRIN_impISIGN:
4357 {
4358 tree arg2_tree = ffecom_expr (arg2);
4359
4360 saved_expr1
4361 = ffecom_save_tree
4362 (ffecom_1 (ABS_EXPR, tree_type,
4363 convert (tree_type,
4364 ffecom_expr (arg1))));
4365 expr_tree
4366 = ffecom_3 (COND_EXPR, tree_type,
4367 ffecom_truth_value
4368 (ffecom_2 (GE_EXPR, integer_type_node,
4369 arg2_tree,
4370 convert (TREE_TYPE (arg2_tree),
4371 integer_zero_node))),
4372 saved_expr1,
4373 ffecom_1 (NEGATE_EXPR, tree_type, saved_expr1));
4374 /* Make sure SAVE_EXPRs get referenced early enough. */
4375 expr_tree
4376 = ffecom_2 (COMPOUND_EXPR, tree_type,
4377 convert (void_type_node, saved_expr1),
4378 expr_tree);
4379 }
4380 return expr_tree;
4381
4382 case FFEINTRIN_impSIN:
4383 case FFEINTRIN_impCDSIN:
4384 case FFEINTRIN_impCSIN:
4385 case FFEINTRIN_impDSIN:
4386 if (bt == FFEINFO_basictypeCOMPLEX)
4387 {
4388 if (kt == FFEINFO_kindtypeREAL1)
4389 gfrt = FFECOM_gfrtCSIN; /* Overlapping result okay. */
4390 else if (kt == FFEINFO_kindtypeREAL2)
4391 gfrt = FFECOM_gfrtCDSIN; /* Overlapping result okay. */
4392 }
4393 break;
4394
4395 case FFEINTRIN_impSINH:
4396 case FFEINTRIN_impDSINH:
4397 break;
4398
4399 case FFEINTRIN_impSQRT:
4400 case FFEINTRIN_impCDSQRT:
4401 case FFEINTRIN_impCSQRT:
4402 case FFEINTRIN_impDSQRT:
4403 if (bt == FFEINFO_basictypeCOMPLEX)
4404 {
4405 if (kt == FFEINFO_kindtypeREAL1)
4406 gfrt = FFECOM_gfrtCSQRT; /* Overlapping result okay. */
4407 else if (kt == FFEINFO_kindtypeREAL2)
4408 gfrt = FFECOM_gfrtCDSQRT; /* Overlapping result okay. */
4409 }
4410 break;
4411
4412 case FFEINTRIN_impTAN:
4413 case FFEINTRIN_impDTAN:
4414 case FFEINTRIN_impTANH:
4415 case FFEINTRIN_impDTANH:
4416 break;
4417
4418 case FFEINTRIN_impREALPART:
4419 if (TREE_CODE (arg1_type) == COMPLEX_TYPE)
4420 arg1_type = TREE_TYPE (arg1_type);
4421 else
4422 arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type));
4423
4424 return
4425 convert (tree_type,
4426 ffecom_1 (REALPART_EXPR, arg1_type,
4427 ffecom_expr (arg1)));
4428
4429 case FFEINTRIN_impIAND:
4430 case FFEINTRIN_impAND:
4431 return ffecom_2 (BIT_AND_EXPR, tree_type,
4432 convert (tree_type,
4433 ffecom_expr (arg1)),
4434 convert (tree_type,
4435 ffecom_expr (arg2)));
4436
4437 case FFEINTRIN_impIOR:
4438 case FFEINTRIN_impOR:
4439 return ffecom_2 (BIT_IOR_EXPR, tree_type,
4440 convert (tree_type,
4441 ffecom_expr (arg1)),
4442 convert (tree_type,
4443 ffecom_expr (arg2)));
4444
4445 case FFEINTRIN_impIEOR:
4446 case FFEINTRIN_impXOR:
4447 return ffecom_2 (BIT_XOR_EXPR, tree_type,
4448 convert (tree_type,
4449 ffecom_expr (arg1)),
4450 convert (tree_type,
4451 ffecom_expr (arg2)));
4452
4453 case FFEINTRIN_impLSHIFT:
4454 return ffecom_2 (LSHIFT_EXPR, tree_type,
4455 ffecom_expr (arg1),
4456 convert (integer_type_node,
4457 ffecom_expr (arg2)));
4458
4459 case FFEINTRIN_impRSHIFT:
4460 return ffecom_2 (RSHIFT_EXPR, tree_type,
4461 ffecom_expr (arg1),
4462 convert (integer_type_node,
4463 ffecom_expr (arg2)));
4464
4465 case FFEINTRIN_impNOT:
4466 return ffecom_1 (BIT_NOT_EXPR, tree_type, ffecom_expr (arg1));
4467
4468 case FFEINTRIN_impBIT_SIZE:
4469 return convert (tree_type, TYPE_SIZE (arg1_type));
4470
4471 case FFEINTRIN_impBTEST:
4472 {
4473 ffetargetLogical1 true;
4474 ffetargetLogical1 false;
4475 tree true_tree;
4476 tree false_tree;
4477
4478 ffetarget_logical1 (&true, TRUE);
4479 ffetarget_logical1 (&false, FALSE);
4480 if (true == 1)
4481 true_tree = convert (tree_type, integer_one_node);
4482 else
4483 true_tree = convert (tree_type, build_int_2 (true, 0));
4484 if (false == 0)
4485 false_tree = convert (tree_type, integer_zero_node);
4486 else
4487 false_tree = convert (tree_type, build_int_2 (false, 0));
4488
4489 return
4490 ffecom_3 (COND_EXPR, tree_type,
4491 ffecom_truth_value
4492 (ffecom_2 (EQ_EXPR, integer_type_node,
4493 ffecom_2 (BIT_AND_EXPR, arg1_type,
4494 ffecom_expr (arg1),
4495 ffecom_2 (LSHIFT_EXPR, arg1_type,
4496 convert (arg1_type,
4497 integer_one_node),
4498 convert (integer_type_node,
4499 ffecom_expr (arg2)))),
4500 convert (arg1_type,
4501 integer_zero_node))),
4502 false_tree,
4503 true_tree);
4504 }
4505
4506 case FFEINTRIN_impIBCLR:
4507 return
4508 ffecom_2 (BIT_AND_EXPR, tree_type,
4509 ffecom_expr (arg1),
4510 ffecom_1 (BIT_NOT_EXPR, tree_type,
4511 ffecom_2 (LSHIFT_EXPR, tree_type,
4512 convert (tree_type,
4513 integer_one_node),
4514 convert (integer_type_node,
4515 ffecom_expr (arg2)))));
4516
4517 case FFEINTRIN_impIBITS:
4518 {
4519 tree arg3_tree = ffecom_save_tree (convert (integer_type_node,
4520 ffecom_expr (arg3)));
4521 tree uns_type
4522 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4523
4524 expr_tree
4525 = ffecom_2 (BIT_AND_EXPR, tree_type,
4526 ffecom_2 (RSHIFT_EXPR, tree_type,
4527 ffecom_expr (arg1),
4528 convert (integer_type_node,
4529 ffecom_expr (arg2))),
4530 convert (tree_type,
4531 ffecom_2 (RSHIFT_EXPR, uns_type,
4532 ffecom_1 (BIT_NOT_EXPR,
4533 uns_type,
4534 convert (uns_type,
4535 integer_zero_node)),
4536 ffecom_2 (MINUS_EXPR,
4537 integer_type_node,
4538 TYPE_SIZE (uns_type),
4539 arg3_tree))));
4540#if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4541 expr_tree
4542 = ffecom_3 (COND_EXPR, tree_type,
4543 ffecom_truth_value
4544 (ffecom_2 (NE_EXPR, integer_type_node,
4545 arg3_tree,
4546 integer_zero_node)),
4547 expr_tree,
4548 convert (tree_type, integer_zero_node));
4549#endif
4550 }
4551 return expr_tree;
4552
4553 case FFEINTRIN_impIBSET:
4554 return
4555 ffecom_2 (BIT_IOR_EXPR, tree_type,
4556 ffecom_expr (arg1),
4557 ffecom_2 (LSHIFT_EXPR, tree_type,
4558 convert (tree_type, integer_one_node),
4559 convert (integer_type_node,
4560 ffecom_expr (arg2))));
4561
4562 case FFEINTRIN_impISHFT:
4563 {
4564 tree arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4565 tree arg2_tree = ffecom_save_tree (convert (integer_type_node,
4566 ffecom_expr (arg2)));
4567 tree uns_type
4568 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4569
4570 expr_tree
4571 = ffecom_3 (COND_EXPR, tree_type,
4572 ffecom_truth_value
4573 (ffecom_2 (GE_EXPR, integer_type_node,
4574 arg2_tree,
4575 integer_zero_node)),
4576 ffecom_2 (LSHIFT_EXPR, tree_type,
4577 arg1_tree,
4578 arg2_tree),
4579 convert (tree_type,
4580 ffecom_2 (RSHIFT_EXPR, uns_type,
4581 convert (uns_type, arg1_tree),
4582 ffecom_1 (NEGATE_EXPR,
4583 integer_type_node,
4584 arg2_tree))));
4585#if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4586 expr_tree
4587 = ffecom_3 (COND_EXPR, tree_type,
4588 ffecom_truth_value
4589 (ffecom_2 (NE_EXPR, integer_type_node,
4590 arg2_tree,
4591 TYPE_SIZE (uns_type))),
4592 expr_tree,
4593 convert (tree_type, integer_zero_node));
4594#endif
4595 /* Make sure SAVE_EXPRs get referenced early enough. */
4596 expr_tree
4597 = ffecom_2 (COMPOUND_EXPR, tree_type,
4598 convert (void_type_node, arg1_tree),
4599 ffecom_2 (COMPOUND_EXPR, tree_type,
4600 convert (void_type_node, arg2_tree),
4601 expr_tree));
4602 }
4603 return expr_tree;
4604
4605 case FFEINTRIN_impISHFTC:
4606 {
4607 tree arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4608 tree arg2_tree = ffecom_save_tree (convert (integer_type_node,
4609 ffecom_expr (arg2)));
4610 tree arg3_tree = (arg3 == NULL) ? TYPE_SIZE (tree_type)
4611 : ffecom_save_tree (convert (integer_type_node, ffecom_expr (arg3)));
4612 tree shift_neg;
4613 tree shift_pos;
4614 tree mask_arg1;
4615 tree masked_arg1;
4616 tree uns_type
4617 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4618
4619 mask_arg1
4620 = ffecom_2 (LSHIFT_EXPR, tree_type,
4621 ffecom_1 (BIT_NOT_EXPR, tree_type,
4622 convert (tree_type, integer_zero_node)),
4623 arg3_tree);
4624#if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4625 mask_arg1
4626 = ffecom_3 (COND_EXPR, tree_type,
4627 ffecom_truth_value
4628 (ffecom_2 (NE_EXPR, integer_type_node,
4629 arg3_tree,
4630 TYPE_SIZE (uns_type))),
4631 mask_arg1,
4632 convert (tree_type, integer_zero_node));
4633#endif
4634 mask_arg1 = ffecom_save_tree (mask_arg1);
4635 masked_arg1
4636 = ffecom_2 (BIT_AND_EXPR, tree_type,
4637 arg1_tree,
4638 ffecom_1 (BIT_NOT_EXPR, tree_type,
4639 mask_arg1));
4640 masked_arg1 = ffecom_save_tree (masked_arg1);
4641 shift_neg
4642 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4643 convert (tree_type,
4644 ffecom_2 (RSHIFT_EXPR, uns_type,
4645 convert (uns_type, masked_arg1),
4646 ffecom_1 (NEGATE_EXPR,
4647 integer_type_node,
4648 arg2_tree))),
4649 ffecom_2 (LSHIFT_EXPR, tree_type,
4650 arg1_tree,
4651 ffecom_2 (PLUS_EXPR, integer_type_node,
4652 arg2_tree,
4653 arg3_tree)));
4654 shift_pos
4655 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4656 ffecom_2 (LSHIFT_EXPR, tree_type,
4657 arg1_tree,
4658 arg2_tree),
4659 convert (tree_type,
4660 ffecom_2 (RSHIFT_EXPR, uns_type,
4661 convert (uns_type, masked_arg1),
4662 ffecom_2 (MINUS_EXPR,
4663 integer_type_node,
4664 arg3_tree,
4665 arg2_tree))));
4666 expr_tree
4667 = ffecom_3 (COND_EXPR, tree_type,
4668 ffecom_truth_value
4669 (ffecom_2 (LT_EXPR, integer_type_node,
4670 arg2_tree,
4671 integer_zero_node)),
4672 shift_neg,
4673 shift_pos);
4674 expr_tree
4675 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4676 ffecom_2 (BIT_AND_EXPR, tree_type,
4677 mask_arg1,
4678 arg1_tree),
4679 ffecom_2 (BIT_AND_EXPR, tree_type,
4680 ffecom_1 (BIT_NOT_EXPR, tree_type,
4681 mask_arg1),
4682 expr_tree));
4683 expr_tree
4684 = ffecom_3 (COND_EXPR, tree_type,
4685 ffecom_truth_value
4686 (ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
4687 ffecom_2 (EQ_EXPR, integer_type_node,
4688 ffecom_1 (ABS_EXPR,
4689 integer_type_node,
4690 arg2_tree),
4691 arg3_tree),
4692 ffecom_2 (EQ_EXPR, integer_type_node,
4693 arg2_tree,
4694 integer_zero_node))),
4695 arg1_tree,
4696 expr_tree);
4697 /* Make sure SAVE_EXPRs get referenced early enough. */
4698 expr_tree
4699 = ffecom_2 (COMPOUND_EXPR, tree_type,
4700 convert (void_type_node, arg1_tree),
4701 ffecom_2 (COMPOUND_EXPR, tree_type,
4702 convert (void_type_node, arg2_tree),
4703 ffecom_2 (COMPOUND_EXPR, tree_type,
4704 convert (void_type_node,
4705 mask_arg1),
4706 ffecom_2 (COMPOUND_EXPR, tree_type,
4707 convert (void_type_node,
4708 masked_arg1),
4709 expr_tree))));
4710 expr_tree
4711 = ffecom_2 (COMPOUND_EXPR, tree_type,
4712 convert (void_type_node,
4713 arg3_tree),
4714 expr_tree);
4715 }
4716 return expr_tree;
4717
4718 case FFEINTRIN_impLOC:
4719 {
4720 tree arg1_tree = ffecom_expr (arg1);
4721
4722 expr_tree
4723 = convert (tree_type,
4724 ffecom_1 (ADDR_EXPR,
4725 build_pointer_type (TREE_TYPE (arg1_tree)),
4726 arg1_tree));
4727 }
4728 return expr_tree;
4729
4730 case FFEINTRIN_impMVBITS:
4731 {
4732 tree arg1_tree;
4733 tree arg2_tree;
4734 tree arg3_tree;
4735 ffebld arg4 = ffebld_head (ffebld_trail (list));
4736 tree arg4_tree;
4737 tree arg4_type;
4738 ffebld arg5 = ffebld_head (ffebld_trail (ffebld_trail (list)));
4739 tree arg5_tree;
4740 tree prep_arg1;
4741 tree prep_arg4;
4742 tree arg5_plus_arg3;
4743
5ff904cd
JL
4744 arg2_tree = convert (integer_type_node,
4745 ffecom_expr (arg2));
4746 arg3_tree = ffecom_save_tree (convert (integer_type_node,
4747 ffecom_expr (arg3)));
c7e4ee3a 4748 arg4_tree = ffecom_expr_rw (NULL_TREE, arg4);
5ff904cd
JL
4749 arg4_type = TREE_TYPE (arg4_tree);
4750
4751 arg1_tree = ffecom_save_tree (convert (arg4_type,
4752 ffecom_expr (arg1)));
4753
4754 arg5_tree = ffecom_save_tree (convert (integer_type_node,
4755 ffecom_expr (arg5)));
4756
5ff904cd
JL
4757 prep_arg1
4758 = ffecom_2 (LSHIFT_EXPR, arg4_type,
4759 ffecom_2 (BIT_AND_EXPR, arg4_type,
4760 ffecom_2 (RSHIFT_EXPR, arg4_type,
4761 arg1_tree,
4762 arg2_tree),
4763 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4764 ffecom_2 (LSHIFT_EXPR, arg4_type,
4765 ffecom_1 (BIT_NOT_EXPR,
4766 arg4_type,
4767 convert
4768 (arg4_type,
4769 integer_zero_node)),
4770 arg3_tree))),
4771 arg5_tree);
4772 arg5_plus_arg3
4773 = ffecom_save_tree (ffecom_2 (PLUS_EXPR, arg4_type,
4774 arg5_tree,
4775 arg3_tree));
4776 prep_arg4
4777 = ffecom_2 (LSHIFT_EXPR, arg4_type,
4778 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4779 convert (arg4_type,
4780 integer_zero_node)),
4781 arg5_plus_arg3);
4782#if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4783 prep_arg4
4784 = ffecom_3 (COND_EXPR, arg4_type,
4785 ffecom_truth_value
4786 (ffecom_2 (NE_EXPR, integer_type_node,
4787 arg5_plus_arg3,
4788 convert (TREE_TYPE (arg5_plus_arg3),
4789 TYPE_SIZE (arg4_type)))),
4790 prep_arg4,
4791 convert (arg4_type, integer_zero_node));
4792#endif
4793 prep_arg4
4794 = ffecom_2 (BIT_AND_EXPR, arg4_type,
4795 arg4_tree,
4796 ffecom_2 (BIT_IOR_EXPR, arg4_type,
4797 prep_arg4,
4798 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4799 ffecom_2 (LSHIFT_EXPR, arg4_type,
4800 ffecom_1 (BIT_NOT_EXPR,
4801 arg4_type,
4802 convert
4803 (arg4_type,
4804 integer_zero_node)),
4805 arg5_tree))));
4806 prep_arg1
4807 = ffecom_2 (BIT_IOR_EXPR, arg4_type,
4808 prep_arg1,
4809 prep_arg4);
4810#if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4811 prep_arg1
4812 = ffecom_3 (COND_EXPR, arg4_type,
4813 ffecom_truth_value
4814 (ffecom_2 (NE_EXPR, integer_type_node,
4815 arg3_tree,
4816 convert (TREE_TYPE (arg3_tree),
4817 integer_zero_node))),
4818 prep_arg1,
4819 arg4_tree);
4820 prep_arg1
4821 = ffecom_3 (COND_EXPR, arg4_type,
4822 ffecom_truth_value
4823 (ffecom_2 (NE_EXPR, integer_type_node,
4824 arg3_tree,
4825 convert (TREE_TYPE (arg3_tree),
4826 TYPE_SIZE (arg4_type)))),
4827 prep_arg1,
4828 arg1_tree);
4829#endif
4830 expr_tree
4831 = ffecom_2s (MODIFY_EXPR, void_type_node,
4832 arg4_tree,
4833 prep_arg1);
4834 /* Make sure SAVE_EXPRs get referenced early enough. */
4835 expr_tree
4836 = ffecom_2 (COMPOUND_EXPR, void_type_node,
4837 arg1_tree,
4838 ffecom_2 (COMPOUND_EXPR, void_type_node,
4839 arg3_tree,
4840 ffecom_2 (COMPOUND_EXPR, void_type_node,
4841 arg5_tree,
4842 ffecom_2 (COMPOUND_EXPR, void_type_node,
4843 arg5_plus_arg3,
4844 expr_tree))));
4845 expr_tree
4846 = ffecom_2 (COMPOUND_EXPR, void_type_node,
4847 arg4_tree,
4848 expr_tree);
4849
4850 }
4851 return expr_tree;
4852
4853 case FFEINTRIN_impDERF:
4854 case FFEINTRIN_impERF:
4855 case FFEINTRIN_impDERFC:
4856 case FFEINTRIN_impERFC:
4857 break;
4858
4859 case FFEINTRIN_impIARGC:
4860 /* extern int xargc; i__1 = xargc - 1; */
4861 expr_tree = ffecom_2 (MINUS_EXPR, TREE_TYPE (ffecom_tree_xargc_),
4862 ffecom_tree_xargc_,
4863 convert (TREE_TYPE (ffecom_tree_xargc_),
4864 integer_one_node));
4865 return expr_tree;
4866
4867 case FFEINTRIN_impSIGNAL_func:
4868 case FFEINTRIN_impSIGNAL_subr:
4869 {
4870 tree arg1_tree;
4871 tree arg2_tree;
4872 tree arg3_tree;
4873
5ff904cd
JL
4874 arg1_tree = convert (ffecom_f2c_integer_type_node,
4875 ffecom_expr (arg1));
4876 arg1_tree = ffecom_1 (ADDR_EXPR,
4877 build_pointer_type (TREE_TYPE (arg1_tree)),
4878 arg1_tree);
4879
4880 /* Pass procedure as a pointer to it, anything else by value. */
4881 if (ffeinfo_kind (ffebld_info (arg2)) == FFEINFO_kindENTITY)
4882 arg2_tree = convert (integer_type_node, ffecom_expr (arg2));
4883 else
4884 arg2_tree = ffecom_ptr_to_expr (arg2);
4885 arg2_tree = convert (TREE_TYPE (null_pointer_node),
4886 arg2_tree);
4887
4888 if (arg3 != NULL)
c7e4ee3a 4889 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
4890 else
4891 arg3_tree = NULL_TREE;
4892
5ff904cd
JL
4893 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4894 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
4895 TREE_CHAIN (arg1_tree) = arg2_tree;
4896
4897 expr_tree
4898 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4899 ffecom_gfrt_kindtype (gfrt),
4900 FALSE,
4901 ((codegen_imp == FFEINTRIN_impSIGNAL_subr) ?
4902 NULL_TREE :
4903 tree_type),
4904 arg1_tree,
c7e4ee3a
CB
4905 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4906 ffebld_nonter_hook (expr));
5ff904cd
JL
4907
4908 if (arg3_tree != NULL_TREE)
4909 expr_tree
4910 = ffecom_modify (NULL_TREE, arg3_tree,
4911 convert (TREE_TYPE (arg3_tree),
4912 expr_tree));
4913 }
4914 return expr_tree;
4915
4916 case FFEINTRIN_impALARM:
4917 {
4918 tree arg1_tree;
4919 tree arg2_tree;
4920 tree arg3_tree;
4921
5ff904cd
JL
4922 arg1_tree = convert (ffecom_f2c_integer_type_node,
4923 ffecom_expr (arg1));
4924 arg1_tree = ffecom_1 (ADDR_EXPR,
4925 build_pointer_type (TREE_TYPE (arg1_tree)),
4926 arg1_tree);
4927
4928 /* Pass procedure as a pointer to it, anything else by value. */
4929 if (ffeinfo_kind (ffebld_info (arg2)) == FFEINFO_kindENTITY)
4930 arg2_tree = convert (integer_type_node, ffecom_expr (arg2));
4931 else
4932 arg2_tree = ffecom_ptr_to_expr (arg2);
4933 arg2_tree = convert (TREE_TYPE (null_pointer_node),
4934 arg2_tree);
4935
4936 if (arg3 != NULL)
c7e4ee3a 4937 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
4938 else
4939 arg3_tree = NULL_TREE;
4940
5ff904cd
JL
4941 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4942 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
4943 TREE_CHAIN (arg1_tree) = arg2_tree;
4944
4945 expr_tree
4946 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4947 ffecom_gfrt_kindtype (gfrt),
4948 FALSE,
4949 NULL_TREE,
4950 arg1_tree,
c7e4ee3a
CB
4951 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4952 ffebld_nonter_hook (expr));
5ff904cd
JL
4953
4954 if (arg3_tree != NULL_TREE)
4955 expr_tree
4956 = ffecom_modify (NULL_TREE, arg3_tree,
4957 convert (TREE_TYPE (arg3_tree),
4958 expr_tree));
4959 }
4960 return expr_tree;
4961
4962 case FFEINTRIN_impCHDIR_subr:
4963 case FFEINTRIN_impFDATE_subr:
4964 case FFEINTRIN_impFGET_subr:
4965 case FFEINTRIN_impFPUT_subr:
4966 case FFEINTRIN_impGETCWD_subr:
4967 case FFEINTRIN_impHOSTNM_subr:
4968 case FFEINTRIN_impSYSTEM_subr:
4969 case FFEINTRIN_impUNLINK_subr:
4970 {
4971 tree arg1_len = integer_zero_node;
4972 tree arg1_tree;
4973 tree arg2_tree;
4974
5ff904cd
JL
4975 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
4976
4977 if (arg2 != NULL)
c7e4ee3a 4978 arg2_tree = ffecom_expr_w (NULL_TREE, arg2);
5ff904cd
JL
4979 else
4980 arg2_tree = NULL_TREE;
4981
5ff904cd
JL
4982 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4983 arg1_len = build_tree_list (NULL_TREE, arg1_len);
4984 TREE_CHAIN (arg1_tree) = arg1_len;
4985
4986 expr_tree
4987 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4988 ffecom_gfrt_kindtype (gfrt),
4989 FALSE,
4990 NULL_TREE,
4991 arg1_tree,
c7e4ee3a
CB
4992 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4993 ffebld_nonter_hook (expr));
5ff904cd
JL
4994
4995 if (arg2_tree != NULL_TREE)
4996 expr_tree
4997 = ffecom_modify (NULL_TREE, arg2_tree,
4998 convert (TREE_TYPE (arg2_tree),
4999 expr_tree));
5000 }
5001 return expr_tree;
5002
5003 case FFEINTRIN_impEXIT:
5004 if (arg1 != NULL)
5005 break;
5006
5007 expr_tree = build_tree_list (NULL_TREE,
5008 ffecom_1 (ADDR_EXPR,
5009 build_pointer_type
5010 (ffecom_integer_type_node),
5011 integer_zero_node));
5012
5013 return
5014 ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5015 ffecom_gfrt_kindtype (gfrt),
5016 FALSE,
5017 void_type_node,
5018 expr_tree,
c7e4ee3a
CB
5019 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5020 ffebld_nonter_hook (expr));
5ff904cd
JL
5021
5022 case FFEINTRIN_impFLUSH:
5023 if (arg1 == NULL)
5024 gfrt = FFECOM_gfrtFLUSH;
5025 else
5026 gfrt = FFECOM_gfrtFLUSH1;
5027 break;
5028
5029 case FFEINTRIN_impCHMOD_subr:
5030 case FFEINTRIN_impLINK_subr:
5031 case FFEINTRIN_impRENAME_subr:
5032 case FFEINTRIN_impSYMLNK_subr:
5033 {
5034 tree arg1_len = integer_zero_node;
5035 tree arg1_tree;
5036 tree arg2_len = integer_zero_node;
5037 tree arg2_tree;
5038 tree arg3_tree;
5039
5ff904cd
JL
5040 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
5041 arg2_tree = ffecom_arg_ptr_to_expr (arg2, &arg2_len);
5042 if (arg3 != NULL)
c7e4ee3a 5043 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
5044 else
5045 arg3_tree = NULL_TREE;
5046
5ff904cd
JL
5047 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5048 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5049 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5050 arg2_len = build_tree_list (NULL_TREE, arg2_len);
5051 TREE_CHAIN (arg1_tree) = arg2_tree;
5052 TREE_CHAIN (arg2_tree) = arg1_len;
5053 TREE_CHAIN (arg1_len) = arg2_len;
5054 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5055 ffecom_gfrt_kindtype (gfrt),
5056 FALSE,
5057 NULL_TREE,
5058 arg1_tree,
c7e4ee3a
CB
5059 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5060 ffebld_nonter_hook (expr));
5ff904cd
JL
5061 if (arg3_tree != NULL_TREE)
5062 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5063 convert (TREE_TYPE (arg3_tree),
5064 expr_tree));
5065 }
5066 return expr_tree;
5067
5068 case FFEINTRIN_impLSTAT_subr:
5069 case FFEINTRIN_impSTAT_subr:
5070 {
5071 tree arg1_len = integer_zero_node;
5072 tree arg1_tree;
5073 tree arg2_tree;
5074 tree arg3_tree;
5075
5ff904cd
JL
5076 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
5077
5078 arg2_tree = ffecom_ptr_to_expr (arg2);
5079
5080 if (arg3 != NULL)
c7e4ee3a 5081 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
5082 else
5083 arg3_tree = NULL_TREE;
5084
5ff904cd
JL
5085 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5086 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5087 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5088 TREE_CHAIN (arg1_tree) = arg2_tree;
5089 TREE_CHAIN (arg2_tree) = arg1_len;
5090 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5091 ffecom_gfrt_kindtype (gfrt),
5092 FALSE,
5093 NULL_TREE,
5094 arg1_tree,
c7e4ee3a
CB
5095 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5096 ffebld_nonter_hook (expr));
5ff904cd
JL
5097 if (arg3_tree != NULL_TREE)
5098 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5099 convert (TREE_TYPE (arg3_tree),
5100 expr_tree));
5101 }
5102 return expr_tree;
5103
5104 case FFEINTRIN_impFGETC_subr:
5105 case FFEINTRIN_impFPUTC_subr:
5106 {
5107 tree arg1_tree;
5108 tree arg2_tree;
5109 tree arg2_len = integer_zero_node;
5110 tree arg3_tree;
5111
5ff904cd
JL
5112 arg1_tree = convert (ffecom_f2c_integer_type_node,
5113 ffecom_expr (arg1));
5114 arg1_tree = ffecom_1 (ADDR_EXPR,
5115 build_pointer_type (TREE_TYPE (arg1_tree)),
5116 arg1_tree);
5117
5118 arg2_tree = ffecom_arg_ptr_to_expr (arg2, &arg2_len);
c7e4ee3a 5119 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
5120
5121 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5122 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5123 arg2_len = build_tree_list (NULL_TREE, arg2_len);
5124 TREE_CHAIN (arg1_tree) = arg2_tree;
5125 TREE_CHAIN (arg2_tree) = arg2_len;
5126
5127 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5128 ffecom_gfrt_kindtype (gfrt),
5129 FALSE,
5130 NULL_TREE,
5131 arg1_tree,
c7e4ee3a
CB
5132 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5133 ffebld_nonter_hook (expr));
5ff904cd
JL
5134 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5135 convert (TREE_TYPE (arg3_tree),
5136 expr_tree));
5137 }
5138 return expr_tree;
5139
5140 case FFEINTRIN_impFSTAT_subr:
5141 {
5142 tree arg1_tree;
5143 tree arg2_tree;
5144 tree arg3_tree;
5145
5ff904cd
JL
5146 arg1_tree = convert (ffecom_f2c_integer_type_node,
5147 ffecom_expr (arg1));
5148 arg1_tree = ffecom_1 (ADDR_EXPR,
5149 build_pointer_type (TREE_TYPE (arg1_tree)),
5150 arg1_tree);
5151
5152 arg2_tree = convert (ffecom_f2c_ptr_to_integer_type_node,
5153 ffecom_ptr_to_expr (arg2));
5154
5155 if (arg3 == NULL)
5156 arg3_tree = NULL_TREE;
5157 else
c7e4ee3a 5158 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
5159
5160 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5161 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5162 TREE_CHAIN (arg1_tree) = arg2_tree;
5163 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5164 ffecom_gfrt_kindtype (gfrt),
5165 FALSE,
5166 NULL_TREE,
5167 arg1_tree,
c7e4ee3a
CB
5168 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5169 ffebld_nonter_hook (expr));
5ff904cd
JL
5170 if (arg3_tree != NULL_TREE) {
5171 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5172 convert (TREE_TYPE (arg3_tree),
5173 expr_tree));
5174 }
5175 }
5176 return expr_tree;
5177
5178 case FFEINTRIN_impKILL_subr:
5179 {
5180 tree arg1_tree;
5181 tree arg2_tree;
5182 tree arg3_tree;
5183
5ff904cd
JL
5184 arg1_tree = convert (ffecom_f2c_integer_type_node,
5185 ffecom_expr (arg1));
5186 arg1_tree = ffecom_1 (ADDR_EXPR,
5187 build_pointer_type (TREE_TYPE (arg1_tree)),
5188 arg1_tree);
5189
5190 arg2_tree = convert (ffecom_f2c_integer_type_node,
5191 ffecom_expr (arg2));
5192 arg2_tree = ffecom_1 (ADDR_EXPR,
5193 build_pointer_type (TREE_TYPE (arg2_tree)),
5194 arg2_tree);
5195
5196 if (arg3 == NULL)
5197 arg3_tree = NULL_TREE;
5198 else
c7e4ee3a 5199 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
5200
5201 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5202 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5203 TREE_CHAIN (arg1_tree) = arg2_tree;
5204 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5205 ffecom_gfrt_kindtype (gfrt),
5206 FALSE,
5207 NULL_TREE,
5208 arg1_tree,
c7e4ee3a
CB
5209 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5210 ffebld_nonter_hook (expr));
5ff904cd
JL
5211 if (arg3_tree != NULL_TREE) {
5212 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5213 convert (TREE_TYPE (arg3_tree),
5214 expr_tree));
5215 }
5216 }
5217 return expr_tree;
5218
5219 case FFEINTRIN_impCTIME_subr:
5220 case FFEINTRIN_impTTYNAM_subr:
5221 {
5222 tree arg1_len = integer_zero_node;
5223 tree arg1_tree;
5224 tree arg2_tree;
5225
5ff904cd
JL
5226 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
5227
5228 arg2_tree = convert (((gfrt == FFEINTRIN_impCTIME_subr) ?
5229 ffecom_f2c_longint_type_node :
5230 ffecom_f2c_integer_type_node),
5231 ffecom_expr (arg2));
5232 arg2_tree = ffecom_1 (ADDR_EXPR,
5233 build_pointer_type (TREE_TYPE (arg2_tree)),
5234 arg2_tree);
5235
5ff904cd
JL
5236 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5237 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5238 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5239 TREE_CHAIN (arg1_len) = arg2_tree;
5240 TREE_CHAIN (arg1_tree) = arg1_len;
5241
5242 expr_tree
5243 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5244 ffecom_gfrt_kindtype (gfrt),
5245 FALSE,
5246 NULL_TREE,
5247 arg1_tree,
c7e4ee3a
CB
5248 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5249 ffebld_nonter_hook (expr));
5ff904cd
JL
5250 }
5251 return expr_tree;
5252
5253 case FFEINTRIN_impIRAND:
5254 case FFEINTRIN_impRAND:
5255 /* Arg defaults to 0 (normal random case) */
5256 {
5257 tree arg1_tree;
5258
5259 if (arg1 == NULL)
5260 arg1_tree = ffecom_integer_zero_node;
5261 else
5262 arg1_tree = ffecom_expr (arg1);
5263 arg1_tree = convert (ffecom_f2c_integer_type_node,
5264 arg1_tree);
5265 arg1_tree = ffecom_1 (ADDR_EXPR,
5266 build_pointer_type (TREE_TYPE (arg1_tree)),
5267 arg1_tree);
5268 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5269
5270 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5271 ffecom_gfrt_kindtype (gfrt),
5272 FALSE,
5273 ((codegen_imp == FFEINTRIN_impIRAND) ?
5274 ffecom_f2c_integer_type_node :
de7f278a 5275 ffecom_f2c_real_type_node),
5ff904cd
JL
5276 arg1_tree,
5277 dest_tree, dest, dest_used,
c7e4ee3a
CB
5278 NULL_TREE, TRUE,
5279 ffebld_nonter_hook (expr));
5ff904cd
JL
5280 }
5281 return expr_tree;
5282
5283 case FFEINTRIN_impFTELL_subr:
5284 case FFEINTRIN_impUMASK_subr:
5285 {
5286 tree arg1_tree;
5287 tree arg2_tree;
5288
5ff904cd
JL
5289 arg1_tree = convert (ffecom_f2c_integer_type_node,
5290 ffecom_expr (arg1));
5291 arg1_tree = ffecom_1 (ADDR_EXPR,
5292 build_pointer_type (TREE_TYPE (arg1_tree)),
5293 arg1_tree);
5294
5295 if (arg2 == NULL)
5296 arg2_tree = NULL_TREE;
5297 else
c7e4ee3a 5298 arg2_tree = ffecom_expr_w (NULL_TREE, arg2);
5ff904cd
JL
5299
5300 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5301 ffecom_gfrt_kindtype (gfrt),
5302 FALSE,
5303 NULL_TREE,
5304 build_tree_list (NULL_TREE, arg1_tree),
5305 NULL_TREE, NULL, NULL, NULL_TREE,
c7e4ee3a
CB
5306 TRUE,
5307 ffebld_nonter_hook (expr));
5ff904cd
JL
5308 if (arg2_tree != NULL_TREE) {
5309 expr_tree = ffecom_modify (NULL_TREE, arg2_tree,
5310 convert (TREE_TYPE (arg2_tree),
5311 expr_tree));
5312 }
5313 }
5314 return expr_tree;
5315
5316 case FFEINTRIN_impCPU_TIME:
5317 case FFEINTRIN_impSECOND_subr:
5318 {
5319 tree arg1_tree;
5320
c7e4ee3a 5321 arg1_tree = ffecom_expr_w (NULL_TREE, arg1);
5ff904cd
JL
5322
5323 expr_tree
5324 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5325 ffecom_gfrt_kindtype (gfrt),
5326 FALSE,
5327 NULL_TREE,
5328 NULL_TREE,
c7e4ee3a
CB
5329 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5330 ffebld_nonter_hook (expr));
5ff904cd
JL
5331
5332 expr_tree
5333 = ffecom_modify (NULL_TREE, arg1_tree,
5334 convert (TREE_TYPE (arg1_tree),
5335 expr_tree));
5336 }
5337 return expr_tree;
5338
5339 case FFEINTRIN_impDTIME_subr:
5340 case FFEINTRIN_impETIME_subr:
5341 {
5342 tree arg1_tree;
5343 tree arg2_tree;
5344
c7e4ee3a 5345 arg1_tree = ffecom_expr_w (NULL_TREE, arg1);
5ff904cd
JL
5346
5347 arg2_tree = ffecom_ptr_to_expr (arg2);
5348
5ff904cd
JL
5349 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5350 ffecom_gfrt_kindtype (gfrt),
5351 FALSE,
5352 NULL_TREE,
5353 build_tree_list (NULL_TREE, arg2_tree),
5354 NULL_TREE, NULL, NULL, NULL_TREE,
c7e4ee3a
CB
5355 TRUE,
5356 ffebld_nonter_hook (expr));
5ff904cd
JL
5357 expr_tree = ffecom_modify (NULL_TREE, arg1_tree,
5358 convert (TREE_TYPE (arg1_tree),
5359 expr_tree));
5360 }
5361 return expr_tree;
5362
c7e4ee3a 5363 /* Straightforward calls of libf2c routines: */
5ff904cd
JL
5364 case FFEINTRIN_impABORT:
5365 case FFEINTRIN_impACCESS:
5366 case FFEINTRIN_impBESJ0:
5367 case FFEINTRIN_impBESJ1:
5368 case FFEINTRIN_impBESJN:
5369 case FFEINTRIN_impBESY0:
5370 case FFEINTRIN_impBESY1:
5371 case FFEINTRIN_impBESYN:
5372 case FFEINTRIN_impCHDIR_func:
5373 case FFEINTRIN_impCHMOD_func:
5374 case FFEINTRIN_impDATE:
9e8e701d 5375 case FFEINTRIN_impDATE_AND_TIME:
5ff904cd
JL
5376 case FFEINTRIN_impDBESJ0:
5377 case FFEINTRIN_impDBESJ1:
5378 case FFEINTRIN_impDBESJN:
5379 case FFEINTRIN_impDBESY0:
5380 case FFEINTRIN_impDBESY1:
5381 case FFEINTRIN_impDBESYN:
5382 case FFEINTRIN_impDTIME_func:
5383 case FFEINTRIN_impETIME_func:
5384 case FFEINTRIN_impFGETC_func:
5385 case FFEINTRIN_impFGET_func:
5386 case FFEINTRIN_impFNUM:
5387 case FFEINTRIN_impFPUTC_func:
5388 case FFEINTRIN_impFPUT_func:
5389 case FFEINTRIN_impFSEEK:
5390 case FFEINTRIN_impFSTAT_func:
5391 case FFEINTRIN_impFTELL_func:
5392 case FFEINTRIN_impGERROR:
5393 case FFEINTRIN_impGETARG:
5394 case FFEINTRIN_impGETCWD_func:
5395 case FFEINTRIN_impGETENV:
5396 case FFEINTRIN_impGETGID:
5397 case FFEINTRIN_impGETLOG:
5398 case FFEINTRIN_impGETPID:
5399 case FFEINTRIN_impGETUID:
5400 case FFEINTRIN_impGMTIME:
5401 case FFEINTRIN_impHOSTNM_func:
5402 case FFEINTRIN_impIDATE_unix:
5403 case FFEINTRIN_impIDATE_vxt:
5404 case FFEINTRIN_impIERRNO:
5405 case FFEINTRIN_impISATTY:
5406 case FFEINTRIN_impITIME:
5407 case FFEINTRIN_impKILL_func:
5408 case FFEINTRIN_impLINK_func:
5409 case FFEINTRIN_impLNBLNK:
5410 case FFEINTRIN_impLSTAT_func:
5411 case FFEINTRIN_impLTIME:
5412 case FFEINTRIN_impMCLOCK8:
5413 case FFEINTRIN_impMCLOCK:
5414 case FFEINTRIN_impPERROR:
5415 case FFEINTRIN_impRENAME_func:
5416 case FFEINTRIN_impSECNDS:
5417 case FFEINTRIN_impSECOND_func:
5418 case FFEINTRIN_impSLEEP:
5419 case FFEINTRIN_impSRAND:
5420 case FFEINTRIN_impSTAT_func:
5421 case FFEINTRIN_impSYMLNK_func:
5422 case FFEINTRIN_impSYSTEM_CLOCK:
5423 case FFEINTRIN_impSYSTEM_func:
5424 case FFEINTRIN_impTIME8:
5425 case FFEINTRIN_impTIME_unix:
5426 case FFEINTRIN_impTIME_vxt:
5427 case FFEINTRIN_impUMASK_func:
5428 case FFEINTRIN_impUNLINK_func:
5429 break;
5430
5431 case FFEINTRIN_impCTIME_func: /* CHARACTER functions not handled here. */
5432 case FFEINTRIN_impFDATE_func: /* CHARACTER functions not handled here. */
5433 case FFEINTRIN_impTTYNAM_func: /* CHARACTER functions not handled here. */
5434 case FFEINTRIN_impNONE:
5435 case FFEINTRIN_imp: /* Hush up gcc warning. */
5436 fprintf (stderr, "No %s implementation.\n",
5437 ffeintrin_name_implementation (ffebld_symter_implementation (ffebld_left (expr))));
5438 assert ("unimplemented intrinsic" == NULL);
5439 return error_mark_node;
5440 }
5441
5442 assert (gfrt != FFECOM_gfrt); /* Must have an implementation! */
5443
5ff904cd
JL
5444 expr_tree = ffecom_arglist_expr_ (ffecom_gfrt_args_ (gfrt),
5445 ffebld_right (expr));
5ff904cd
JL
5446
5447 return ffecom_call_ (ffecom_gfrt_tree_ (gfrt), ffecom_gfrt_kindtype (gfrt),
5448 (ffe_is_f2c_library () && ffecom_gfrt_complex_[gfrt]),
5449 tree_type,
5450 expr_tree, dest_tree, dest, dest_used,
c7e4ee3a
CB
5451 NULL_TREE, TRUE,
5452 ffebld_nonter_hook (expr));
5ff904cd 5453
c7e4ee3a
CB
5454 /* See bottom of this file for f2c transforms used to determine
5455 many of the above implementations. The info seems to confuse
5456 Emacs's C mode indentation, which is why it's been moved to
5457 the bottom of this source file. */
5458}
5ff904cd 5459
c7e4ee3a
CB
5460#endif
5461/* For power (exponentiation) where right-hand operand is type INTEGER,
5462 generate in-line code to do it the fast way (which, if the operand
5463 is a constant, might just mean a series of multiplies). */
5ff904cd 5464
c7e4ee3a
CB
5465#if FFECOM_targetCURRENT == FFECOM_targetGCC
5466static tree
5467ffecom_expr_power_integer_ (ffebld expr)
5468{
5469 tree l = ffecom_expr (ffebld_left (expr));
5470 tree r = ffecom_expr (ffebld_right (expr));
5471 tree ltype = TREE_TYPE (l);
5472 tree rtype = TREE_TYPE (r);
5473 tree result = NULL_TREE;
5ff904cd 5474
c7e4ee3a
CB
5475 if (l == error_mark_node
5476 || r == error_mark_node)
5477 return error_mark_node;
5ff904cd 5478
c7e4ee3a
CB
5479 if (TREE_CODE (r) == INTEGER_CST)
5480 {
5481 int sgn = tree_int_cst_sgn (r);
5ff904cd 5482
c7e4ee3a
CB
5483 if (sgn == 0)
5484 return convert (ltype, integer_one_node);
5ff904cd 5485
c7e4ee3a
CB
5486 if ((TREE_CODE (ltype) == INTEGER_TYPE)
5487 && (sgn < 0))
5488 {
5489 /* Reciprocal of integer is either 0, -1, or 1, so after
5490 calculating that (which we leave to the back end to do
5491 or not do optimally), don't bother with any multiplying. */
5ff904cd 5492
c7e4ee3a
CB
5493 result = ffecom_tree_divide_ (ltype,
5494 convert (ltype, integer_one_node),
5495 l,
5496 NULL_TREE, NULL, NULL, NULL_TREE);
5497 r = ffecom_1 (NEGATE_EXPR,
5498 rtype,
5499 r);
5500 if ((TREE_INT_CST_LOW (r) & 1) == 0)
5501 result = ffecom_1 (ABS_EXPR, rtype,
5502 result);
5503 }
5ff904cd 5504
c7e4ee3a
CB
5505 /* Generate appropriate series of multiplies, preceded
5506 by divide if the exponent is negative. */
5ff904cd 5507
c7e4ee3a 5508 l = save_expr (l);
5ff904cd 5509
c7e4ee3a
CB
5510 if (sgn < 0)
5511 {
5512 l = ffecom_tree_divide_ (ltype,
5513 convert (ltype, integer_one_node),
5514 l,
5515 NULL_TREE, NULL, NULL,
5516 ffebld_nonter_hook (expr));
5517 r = ffecom_1 (NEGATE_EXPR, rtype, r);
5518 assert (TREE_CODE (r) == INTEGER_CST);
5ff904cd 5519
c7e4ee3a
CB
5520 if (tree_int_cst_sgn (r) < 0)
5521 { /* The "most negative" number. */
5522 r = ffecom_1 (NEGATE_EXPR, rtype,
5523 ffecom_2 (RSHIFT_EXPR, rtype,
5524 r,
5525 integer_one_node));
5526 l = save_expr (l);
5527 l = ffecom_2 (MULT_EXPR, ltype,
5528 l,
5529 l);
5530 }
5531 }
5ff904cd 5532
c7e4ee3a
CB
5533 for (;;)
5534 {
5535 if (TREE_INT_CST_LOW (r) & 1)
5536 {
5537 if (result == NULL_TREE)
5538 result = l;
5539 else
5540 result = ffecom_2 (MULT_EXPR, ltype,
5541 result,
5542 l);
5543 }
5ff904cd 5544
c7e4ee3a
CB
5545 r = ffecom_2 (RSHIFT_EXPR, rtype,
5546 r,
5547 integer_one_node);
5548 if (integer_zerop (r))
5549 break;
5550 assert (TREE_CODE (r) == INTEGER_CST);
5ff904cd 5551
c7e4ee3a
CB
5552 l = save_expr (l);
5553 l = ffecom_2 (MULT_EXPR, ltype,
5554 l,
5555 l);
5556 }
5557 return result;
5558 }
5ff904cd 5559
c7e4ee3a
CB
5560 /* Though rhs isn't a constant, in-line code cannot be expanded
5561 while transforming dummies
5562 because the back end cannot be easily convinced to generate
5563 stores (MODIFY_EXPR), handle temporaries, and so on before
5564 all the appropriate rtx's have been generated for things like
5565 dummy args referenced in rhs -- which doesn't happen until
5566 store_parm_decls() is called (expand_function_start, I believe,
5567 does the actual rtx-stuffing of PARM_DECLs).
5ff904cd 5568
c7e4ee3a
CB
5569 So, in this case, let the caller generate the call to the
5570 run-time-library function to evaluate the power for us. */
5ff904cd 5571
c7e4ee3a
CB
5572 if (ffecom_transform_only_dummies_)
5573 return NULL_TREE;
5ff904cd 5574
c7e4ee3a
CB
5575 /* Right-hand operand not a constant, expand in-line code to figure
5576 out how to do the multiplies, &c.
5ff904cd 5577
c7e4ee3a
CB
5578 The returned expression is expressed this way in GNU C, where l and
5579 r are the "inputs":
5ff904cd 5580
c7e4ee3a
CB
5581 ({ typeof (r) rtmp = r;
5582 typeof (l) ltmp = l;
5583 typeof (l) result;
5ff904cd 5584
c7e4ee3a
CB
5585 if (rtmp == 0)
5586 result = 1;
5587 else
5588 {
5589 if ((basetypeof (l) == basetypeof (int))
5590 && (rtmp < 0))
5591 {
5592 result = ((typeof (l)) 1) / ltmp;
5593 if ((ltmp < 0) && (((-rtmp) & 1) == 0))
5594 result = -result;
5595 }
5596 else
5597 {
5598 result = 1;
5599 if ((basetypeof (l) != basetypeof (int))
5600 && (rtmp < 0))
5601 {
5602 ltmp = ((typeof (l)) 1) / ltmp;
5603 rtmp = -rtmp;
5604 if (rtmp < 0)
5605 {
5606 rtmp = -(rtmp >> 1);
5607 ltmp *= ltmp;
5608 }
5609 }
5610 for (;;)
5611 {
5612 if (rtmp & 1)
5613 result *= ltmp;
5614 if ((rtmp >>= 1) == 0)
5615 break;
5616 ltmp *= ltmp;
5617 }
5618 }
5619 }
5620 result;
5621 })
5ff904cd 5622
c7e4ee3a
CB
5623 Note that some of the above is compile-time collapsable, such as
5624 the first part of the if statements that checks the base type of
5625 l against int. The if statements are phrased that way to suggest
5626 an easy way to generate the if/else constructs here, knowing that
5627 the back end should (and probably does) eliminate the resulting
5628 dead code (either the int case or the non-int case), something
5629 it couldn't do without the redundant phrasing, requiring explicit
5630 dead-code elimination here, which would be kind of difficult to
5631 read. */
5ff904cd 5632
c7e4ee3a
CB
5633 {
5634 tree rtmp;
5635 tree ltmp;
5636 tree divide;
5637 tree basetypeof_l_is_int;
5638 tree se;
5639 tree t;
5ff904cd 5640
c7e4ee3a
CB
5641 basetypeof_l_is_int
5642 = build_int_2 ((TREE_CODE (ltype) == INTEGER_TYPE), 0);
5ff904cd 5643
c7e4ee3a 5644 se = expand_start_stmt_expr ();
5ff904cd 5645
c7e4ee3a
CB
5646 ffecom_start_compstmt ();
5647
5648#ifndef HAHA
5649 rtmp = ffecom_make_tempvar ("power_r", rtype,
5650 FFETARGET_charactersizeNONE, -1);
5651 ltmp = ffecom_make_tempvar ("power_l", ltype,
5652 FFETARGET_charactersizeNONE, -1);
5653 result = ffecom_make_tempvar ("power_res", ltype,
5654 FFETARGET_charactersizeNONE, -1);
5655 if (TREE_CODE (ltype) == COMPLEX_TYPE
5656 || TREE_CODE (ltype) == RECORD_TYPE)
5657 divide = ffecom_make_tempvar ("power_div", ltype,
5658 FFETARGET_charactersizeNONE, -1);
5659 else
5660 divide = NULL_TREE;
5661#else /* HAHA */
5662 {
5663 tree hook;
5664
5665 hook = ffebld_nonter_hook (expr);
5666 assert (hook);
5667 assert (TREE_CODE (hook) == TREE_VEC);
5668 assert (TREE_VEC_LENGTH (hook) == 4);
5669 rtmp = TREE_VEC_ELT (hook, 0);
5670 ltmp = TREE_VEC_ELT (hook, 1);
5671 result = TREE_VEC_ELT (hook, 2);
5672 divide = TREE_VEC_ELT (hook, 3);
5673 if (TREE_CODE (ltype) == COMPLEX_TYPE
5674 || TREE_CODE (ltype) == RECORD_TYPE)
5675 assert (divide);
5676 else
5677 assert (! divide);
5678 }
5679#endif /* HAHA */
5ff904cd 5680
c7e4ee3a
CB
5681 expand_expr_stmt (ffecom_modify (void_type_node,
5682 rtmp,
5683 r));
5684 expand_expr_stmt (ffecom_modify (void_type_node,
5685 ltmp,
5686 l));
5687 expand_start_cond (ffecom_truth_value
5688 (ffecom_2 (EQ_EXPR, integer_type_node,
5689 rtmp,
5690 convert (rtype, integer_zero_node))),
5691 0);
5692 expand_expr_stmt (ffecom_modify (void_type_node,
5693 result,
5694 convert (ltype, integer_one_node)));
5695 expand_start_else ();
5696 if (! integer_zerop (basetypeof_l_is_int))
5697 {
5698 expand_start_cond (ffecom_2 (LT_EXPR, integer_type_node,
5699 rtmp,
5700 convert (rtype,
5701 integer_zero_node)),
5702 0);
5703 expand_expr_stmt (ffecom_modify (void_type_node,
5704 result,
5705 ffecom_tree_divide_
5706 (ltype,
5707 convert (ltype, integer_one_node),
5708 ltmp,
5709 NULL_TREE, NULL, NULL,
5710 divide)));
5711 expand_start_cond (ffecom_truth_value
5712 (ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
5713 ffecom_2 (LT_EXPR, integer_type_node,
5714 ltmp,
5715 convert (ltype,
5716 integer_zero_node)),
5717 ffecom_2 (EQ_EXPR, integer_type_node,
5718 ffecom_2 (BIT_AND_EXPR,
5719 rtype,
5720 ffecom_1 (NEGATE_EXPR,
5721 rtype,
5722 rtmp),
5723 convert (rtype,
5724 integer_one_node)),
5725 convert (rtype,
5726 integer_zero_node)))),
5727 0);
5728 expand_expr_stmt (ffecom_modify (void_type_node,
5729 result,
5730 ffecom_1 (NEGATE_EXPR,
5731 ltype,
5732 result)));
5733 expand_end_cond ();
5734 expand_start_else ();
5735 }
5736 expand_expr_stmt (ffecom_modify (void_type_node,
5737 result,
5738 convert (ltype, integer_one_node)));
5739 expand_start_cond (ffecom_truth_value
5740 (ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
5741 ffecom_truth_value_invert
5742 (basetypeof_l_is_int),
5743 ffecom_2 (LT_EXPR, integer_type_node,
5744 rtmp,
5745 convert (rtype,
5746 integer_zero_node)))),
5747 0);
5748 expand_expr_stmt (ffecom_modify (void_type_node,
5749 ltmp,
5750 ffecom_tree_divide_
5751 (ltype,
5752 convert (ltype, integer_one_node),
5753 ltmp,
5754 NULL_TREE, NULL, NULL,
5755 divide)));
5756 expand_expr_stmt (ffecom_modify (void_type_node,
5757 rtmp,
5758 ffecom_1 (NEGATE_EXPR, rtype,
5759 rtmp)));
5760 expand_start_cond (ffecom_truth_value
5761 (ffecom_2 (LT_EXPR, integer_type_node,
5762 rtmp,
5763 convert (rtype, integer_zero_node))),
5764 0);
5765 expand_expr_stmt (ffecom_modify (void_type_node,
5766 rtmp,
5767 ffecom_1 (NEGATE_EXPR, rtype,
5768 ffecom_2 (RSHIFT_EXPR,
5769 rtype,
5770 rtmp,
5771 integer_one_node))));
5772 expand_expr_stmt (ffecom_modify (void_type_node,
5773 ltmp,
5774 ffecom_2 (MULT_EXPR, ltype,
5775 ltmp,
5776 ltmp)));
5777 expand_end_cond ();
5778 expand_end_cond ();
5779 expand_start_loop (1);
5780 expand_start_cond (ffecom_truth_value
5781 (ffecom_2 (BIT_AND_EXPR, rtype,
5782 rtmp,
5783 convert (rtype, integer_one_node))),
5784 0);
5785 expand_expr_stmt (ffecom_modify (void_type_node,
5786 result,
5787 ffecom_2 (MULT_EXPR, ltype,
5788 result,
5789 ltmp)));
5790 expand_end_cond ();
5791 expand_exit_loop_if_false (NULL,
5792 ffecom_truth_value
5793 (ffecom_modify (rtype,
5794 rtmp,
5795 ffecom_2 (RSHIFT_EXPR,
5796 rtype,
5797 rtmp,
5798 integer_one_node))));
5799 expand_expr_stmt (ffecom_modify (void_type_node,
5800 ltmp,
5801 ffecom_2 (MULT_EXPR, ltype,
5802 ltmp,
5803 ltmp)));
5804 expand_end_loop ();
5805 expand_end_cond ();
5806 if (!integer_zerop (basetypeof_l_is_int))
5807 expand_end_cond ();
5808 expand_expr_stmt (result);
5ff904cd 5809
c7e4ee3a 5810 t = ffecom_end_compstmt ();
5ff904cd 5811
c7e4ee3a 5812 result = expand_end_stmt_expr (se);
5ff904cd 5813
c7e4ee3a 5814 /* This code comes from c-parse.in, after its expand_end_stmt_expr. */
5ff904cd 5815
c7e4ee3a
CB
5816 if (TREE_CODE (t) == BLOCK)
5817 {
5818 /* Make a BIND_EXPR for the BLOCK already made. */
5819 result = build (BIND_EXPR, TREE_TYPE (result),
5820 NULL_TREE, result, t);
5821 /* Remove the block from the tree at this point.
5822 It gets put back at the proper place
5823 when the BIND_EXPR is expanded. */
5824 delete_block (t);
5825 }
5826 else
5827 result = t;
5828 }
5ff904cd 5829
c7e4ee3a
CB
5830 return result;
5831}
5ff904cd 5832
c7e4ee3a
CB
5833#endif
5834/* ffecom_expr_transform_ -- Transform symbols in expr
5ff904cd 5835
c7e4ee3a
CB
5836 ffebld expr; // FFE expression.
5837 ffecom_expr_transform_ (expr);
5ff904cd 5838
c7e4ee3a 5839 Recursive descent on expr while transforming any untransformed SYMTERs. */
5ff904cd 5840
c7e4ee3a
CB
5841#if FFECOM_targetCURRENT == FFECOM_targetGCC
5842static void
5843ffecom_expr_transform_ (ffebld expr)
5844{
5845 tree t;
5846 ffesymbol s;
5ff904cd 5847
c7e4ee3a 5848tail_recurse: /* :::::::::::::::::::: */
5ff904cd 5849
c7e4ee3a
CB
5850 if (expr == NULL)
5851 return;
5ff904cd 5852
c7e4ee3a
CB
5853 switch (ffebld_op (expr))
5854 {
5855 case FFEBLD_opSYMTER:
5856 s = ffebld_symter (expr);
5857 t = ffesymbol_hook (s).decl_tree;
5858 if ((t == NULL_TREE)
5859 && ((ffesymbol_kind (s) != FFEINFO_kindNONE)
5860 || ((ffesymbol_where (s) != FFEINFO_whereNONE)
5861 && (ffesymbol_where (s) != FFEINFO_whereINTRINSIC))))
5862 {
5863 s = ffecom_sym_transform_ (s);
5864 t = ffesymbol_hook (s).decl_tree; /* Sfunc expr non-dummy,
5865 DIMENSION expr? */
5866 }
5867 break; /* Ok if (t == NULL) here. */
5ff904cd 5868
c7e4ee3a
CB
5869 case FFEBLD_opITEM:
5870 ffecom_expr_transform_ (ffebld_head (expr));
5871 expr = ffebld_trail (expr);
5872 goto tail_recurse; /* :::::::::::::::::::: */
5ff904cd 5873
c7e4ee3a
CB
5874 default:
5875 break;
5876 }
5ff904cd 5877
c7e4ee3a
CB
5878 switch (ffebld_arity (expr))
5879 {
5880 case 2:
5881 ffecom_expr_transform_ (ffebld_left (expr));
5882 expr = ffebld_right (expr);
5883 goto tail_recurse; /* :::::::::::::::::::: */
5ff904cd 5884
c7e4ee3a
CB
5885 case 1:
5886 expr = ffebld_left (expr);
5887 goto tail_recurse; /* :::::::::::::::::::: */
5ff904cd 5888
c7e4ee3a
CB
5889 default:
5890 break;
5891 }
5ff904cd 5892
c7e4ee3a
CB
5893 return;
5894}
5ff904cd 5895
c7e4ee3a
CB
5896#endif
5897/* Make a type based on info in live f2c.h file. */
5ff904cd 5898
c7e4ee3a
CB
5899#if FFECOM_targetCURRENT == FFECOM_targetGCC
5900static void
5901ffecom_f2c_make_type_ (tree *type, int tcode, const char *name)
5902{
5903 switch (tcode)
5904 {
5905 case FFECOM_f2ccodeCHAR:
5906 *type = make_signed_type (CHAR_TYPE_SIZE);
5907 break;
5ff904cd 5908
c7e4ee3a
CB
5909 case FFECOM_f2ccodeSHORT:
5910 *type = make_signed_type (SHORT_TYPE_SIZE);
5911 break;
5ff904cd 5912
c7e4ee3a
CB
5913 case FFECOM_f2ccodeINT:
5914 *type = make_signed_type (INT_TYPE_SIZE);
5915 break;
5ff904cd 5916
c7e4ee3a
CB
5917 case FFECOM_f2ccodeLONG:
5918 *type = make_signed_type (LONG_TYPE_SIZE);
5919 break;
5ff904cd 5920
c7e4ee3a
CB
5921 case FFECOM_f2ccodeLONGLONG:
5922 *type = make_signed_type (LONG_LONG_TYPE_SIZE);
5923 break;
5ff904cd 5924
c7e4ee3a
CB
5925 case FFECOM_f2ccodeCHARPTR:
5926 *type = build_pointer_type (DEFAULT_SIGNED_CHAR
5927 ? signed_char_type_node
5928 : unsigned_char_type_node);
5929 break;
5ff904cd 5930
c7e4ee3a
CB
5931 case FFECOM_f2ccodeFLOAT:
5932 *type = make_node (REAL_TYPE);
5933 TYPE_PRECISION (*type) = FLOAT_TYPE_SIZE;
5934 layout_type (*type);
5935 break;
5936
5937 case FFECOM_f2ccodeDOUBLE:
5938 *type = make_node (REAL_TYPE);
5939 TYPE_PRECISION (*type) = DOUBLE_TYPE_SIZE;
5940 layout_type (*type);
5941 break;
5942
5943 case FFECOM_f2ccodeLONGDOUBLE:
5944 *type = make_node (REAL_TYPE);
5945 TYPE_PRECISION (*type) = LONG_DOUBLE_TYPE_SIZE;
5946 layout_type (*type);
5947 break;
5ff904cd 5948
c7e4ee3a
CB
5949 case FFECOM_f2ccodeTWOREALS:
5950 *type = ffecom_make_complex_type_ (ffecom_f2c_real_type_node);
5951 break;
5ff904cd 5952
c7e4ee3a
CB
5953 case FFECOM_f2ccodeTWODOUBLEREALS:
5954 *type = ffecom_make_complex_type_ (ffecom_f2c_doublereal_type_node);
5955 break;
5ff904cd 5956
c7e4ee3a
CB
5957 default:
5958 assert ("unexpected FFECOM_f2ccodeXYZZY!" == NULL);
5959 *type = error_mark_node;
5960 return;
5961 }
5ff904cd 5962
c7e4ee3a
CB
5963 pushdecl (build_decl (TYPE_DECL,
5964 ffecom_get_invented_identifier ("__g77_f2c_%s",
5965 name, -1),
5966 *type));
5967}
5ff904cd 5968
c7e4ee3a
CB
5969#endif
5970#if FFECOM_targetCURRENT == FFECOM_targetGCC
5971/* Set the f2c list-directed-I/O code for whatever (integral) type has the
5972 given size. */
5ff904cd 5973
c7e4ee3a
CB
5974static void
5975ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size,
5976 int code)
5977{
5978 int j;
5979 tree t;
5ff904cd 5980
c7e4ee3a
CB
5981 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
5982 if (((t = ffecom_tree_type[bt][j]) != NULL_TREE)
5983 && (TREE_INT_CST_LOW (TYPE_SIZE (t)) == size))
5984 {
5985 assert (code != -1);
5986 ffecom_f2c_typecode_[bt][j] = code;
5987 code = -1;
5988 }
5989}
5ff904cd 5990
c7e4ee3a
CB
5991#endif
5992/* Finish up globals after doing all program units in file
5ff904cd 5993
c7e4ee3a 5994 Need to handle only uninitialized COMMON areas. */
5ff904cd 5995
c7e4ee3a
CB
5996#if FFECOM_targetCURRENT == FFECOM_targetGCC
5997static ffeglobal
5998ffecom_finish_global_ (ffeglobal global)
5999{
6000 tree cbtype;
6001 tree cbt;
6002 tree size;
5ff904cd 6003
c7e4ee3a
CB
6004 if (ffeglobal_type (global) != FFEGLOBAL_typeCOMMON)
6005 return global;
5ff904cd 6006
c7e4ee3a
CB
6007 if (ffeglobal_common_init (global))
6008 return global;
5ff904cd 6009
c7e4ee3a
CB
6010 cbt = ffeglobal_hook (global);
6011 if ((cbt == NULL_TREE)
6012 || !ffeglobal_common_have_size (global))
6013 return global; /* No need to make common, never ref'd. */
5ff904cd 6014
c7e4ee3a 6015 suspend_momentary ();
5ff904cd 6016
c7e4ee3a 6017 DECL_EXTERNAL (cbt) = 0;
5ff904cd 6018
c7e4ee3a 6019 /* Give the array a size now. */
5ff904cd 6020
c7e4ee3a
CB
6021 size = build_int_2 ((ffeglobal_common_size (global)
6022 + ffeglobal_common_pad (global)) - 1,
6023 0);
5ff904cd 6024
c7e4ee3a
CB
6025 cbtype = TREE_TYPE (cbt);
6026 TYPE_DOMAIN (cbtype) = build_range_type (integer_type_node,
6027 integer_zero_node,
6028 size);
6029 if (!TREE_TYPE (size))
6030 TREE_TYPE (size) = TYPE_DOMAIN (cbtype);
6031 layout_type (cbtype);
5ff904cd 6032
c7e4ee3a
CB
6033 cbt = start_decl (cbt, FALSE);
6034 assert (cbt == ffeglobal_hook (global));
5ff904cd 6035
c7e4ee3a 6036 finish_decl (cbt, NULL_TREE, FALSE);
5ff904cd 6037
c7e4ee3a
CB
6038 return global;
6039}
5ff904cd 6040
c7e4ee3a
CB
6041#endif
6042/* Finish up any untransformed symbols. */
5ff904cd 6043
c7e4ee3a
CB
6044#if FFECOM_targetCURRENT == FFECOM_targetGCC
6045static ffesymbol
6046ffecom_finish_symbol_transform_ (ffesymbol s)
5ff904cd 6047{
c7e4ee3a
CB
6048 if ((s == NULL) || (TREE_CODE (current_function_decl) == ERROR_MARK))
6049 return s;
5ff904cd 6050
c7e4ee3a
CB
6051 /* It's easy to know to transform an untransformed symbol, to make sure
6052 we put out debugging info for it. But COMMON variables, unlike
6053 EQUIVALENCE ones, aren't given declarations in addition to the
6054 tree expressions that specify offsets, because COMMON variables
6055 can be referenced in the outer scope where only dummy arguments
6056 (PARM_DECLs) should really be seen. To be safe, just don't do any
6057 VAR_DECLs for COMMON variables when we transform them for real
6058 use, and therefore we do all the VAR_DECL creating here. */
5ff904cd 6059
c7e4ee3a
CB
6060 if (ffesymbol_hook (s).decl_tree == NULL_TREE)
6061 {
6062 if (ffesymbol_kind (s) != FFEINFO_kindNONE
6063 || (ffesymbol_where (s) != FFEINFO_whereNONE
6064 && ffesymbol_where (s) != FFEINFO_whereINTRINSIC
6065 && ffesymbol_where (s) != FFEINFO_whereDUMMY))
6066 /* Not transformed, and not CHARACTER*(*), and not a dummy
6067 argument, which can happen only if the entry point names
6068 it "rides in on" are all invalidated for other reasons. */
6069 s = ffecom_sym_transform_ (s);
6070 }
5ff904cd 6071
c7e4ee3a
CB
6072 if ((ffesymbol_where (s) == FFEINFO_whereCOMMON)
6073 && (ffesymbol_hook (s).decl_tree != error_mark_node))
6074 {
6075#ifdef SOMEONE_GETS_DEBUG_SUPPORT_WORKING
6076 int yes = suspend_momentary ();
5ff904cd 6077
c7e4ee3a
CB
6078 /* This isn't working, at least for dbxout. The .s file looks
6079 okay to me (burley), but in gdb 4.9 at least, the variables
6080 appear to reside somewhere outside of the common area, so
6081 it doesn't make sense to mislead anyone by generating the info
6082 on those variables until this is fixed. NOTE: Same problem
6083 with EQUIVALENCE, sadly...see similar #if later. */
6084 ffecom_member_phase2_ (ffesymbol_storage (ffesymbol_common (s)),
6085 ffesymbol_storage (s));
5ff904cd 6086
c7e4ee3a
CB
6087 resume_momentary (yes);
6088#endif
5ff904cd
JL
6089 }
6090
c7e4ee3a
CB
6091 return s;
6092}
5ff904cd 6093
c7e4ee3a
CB
6094#endif
6095/* Append underscore(s) to name before calling get_identifier. "us"
6096 is nonzero if the name already contains an underscore and thus
6097 needs two underscores appended. */
5ff904cd 6098
c7e4ee3a
CB
6099#if FFECOM_targetCURRENT == FFECOM_targetGCC
6100static tree
6101ffecom_get_appended_identifier_ (char us, const char *name)
6102{
6103 int i;
6104 char *newname;
6105 tree id;
5ff904cd 6106
c7e4ee3a
CB
6107 newname = xmalloc ((i = strlen (name)) + 1
6108 + ffe_is_underscoring ()
6109 + us);
6110 memcpy (newname, name, i);
6111 newname[i] = '_';
6112 newname[i + us] = '_';
6113 newname[i + 1 + us] = '\0';
6114 id = get_identifier (newname);
5ff904cd 6115
c7e4ee3a 6116 free (newname);
5ff904cd 6117
c7e4ee3a
CB
6118 return id;
6119}
5ff904cd 6120
c7e4ee3a
CB
6121#endif
6122/* Decide whether to append underscore to name before calling
6123 get_identifier. */
5ff904cd 6124
c7e4ee3a
CB
6125#if FFECOM_targetCURRENT == FFECOM_targetGCC
6126static tree
6127ffecom_get_external_identifier_ (ffesymbol s)
6128{
6129 char us;
6130 const char *name = ffesymbol_text (s);
5ff904cd 6131
c7e4ee3a 6132 /* If name is a built-in name, just return it as is. */
5ff904cd 6133
c7e4ee3a
CB
6134 if (!ffe_is_underscoring ()
6135 || (strcmp (name, FFETARGET_nameBLANK_COMMON) == 0)
6136#if FFETARGET_isENFORCED_MAIN_NAME
6137 || (strcmp (name, FFETARGET_nameENFORCED_NAME) == 0)
6138#else
6139 || (strcmp (name, FFETARGET_nameUNNAMED_MAIN) == 0)
6140#endif
6141 || (strcmp (name, FFETARGET_nameUNNAMED_BLOCK_DATA) == 0))
6142 return get_identifier (name);
5ff904cd 6143
c7e4ee3a
CB
6144 us = ffe_is_second_underscore ()
6145 ? (strchr (name, '_') != NULL)
6146 : 0;
5ff904cd 6147
c7e4ee3a
CB
6148 return ffecom_get_appended_identifier_ (us, name);
6149}
5ff904cd 6150
c7e4ee3a
CB
6151#endif
6152/* Decide whether to append underscore to internal name before calling
6153 get_identifier.
6154
6155 This is for non-external, top-function-context names only. Transform
6156 identifier so it doesn't conflict with the transformed result
6157 of using a _different_ external name. E.g. if "CALL FOO" is
6158 transformed into "FOO_();", then the variable in "FOO_ = 3"
6159 must be transformed into something that does not conflict, since
6160 these two things should be independent.
5ff904cd 6161
c7e4ee3a
CB
6162 The transformation is as follows. If the name does not contain
6163 an underscore, there is no possible conflict, so just return.
6164 If the name does contain an underscore, then transform it just
6165 like we transform an external identifier. */
5ff904cd 6166
c7e4ee3a
CB
6167#if FFECOM_targetCURRENT == FFECOM_targetGCC
6168static tree
6169ffecom_get_identifier_ (const char *name)
6170{
6171 /* If name does not contain an underscore, just return it as is. */
6172
6173 if (!ffe_is_underscoring ()
6174 || (strchr (name, '_') == NULL))
6175 return get_identifier (name);
6176
6177 return ffecom_get_appended_identifier_ (ffe_is_second_underscore (),
6178 name);
5ff904cd
JL
6179}
6180
6181#endif
c7e4ee3a 6182/* ffecom_gen_sfuncdef_ -- Generate definition of statement function
5ff904cd 6183
c7e4ee3a
CB
6184 tree t;
6185 ffesymbol s; // kindFUNCTION, whereIMMEDIATE.
6186 t = ffecom_gen_sfuncdef_(s,ffesymbol_basictype(s),
6187 ffesymbol_kindtype(s));
5ff904cd 6188
c7e4ee3a
CB
6189 Call after setting up containing function and getting trees for all
6190 other symbols. */
5ff904cd
JL
6191
6192#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
6193static tree
6194ffecom_gen_sfuncdef_ (ffesymbol s, ffeinfoBasictype bt, ffeinfoKindtype kt)
5ff904cd 6195{
c7e4ee3a
CB
6196 ffebld expr = ffesymbol_sfexpr (s);
6197 tree type;
6198 tree func;
6199 tree result;
6200 bool charfunc = (bt == FFEINFO_basictypeCHARACTER);
6201 static bool recurse = FALSE;
6202 int yes;
6203 int old_lineno = lineno;
6204 char *old_input_filename = input_filename;
5ff904cd 6205
c7e4ee3a 6206 ffecom_nested_entry_ = s;
5ff904cd 6207
c7e4ee3a
CB
6208 /* For now, we don't have a handy pointer to where the sfunc is actually
6209 defined, though that should be easy to add to an ffesymbol. (The
6210 token/where info available might well point to the place where the type
6211 of the sfunc is declared, especially if that precedes the place where
6212 the sfunc itself is defined, which is typically the case.) We should
6213 put out a null pointer rather than point somewhere wrong, but I want to
6214 see how it works at this point. */
5ff904cd 6215
c7e4ee3a
CB
6216 input_filename = ffesymbol_where_filename (s);
6217 lineno = ffesymbol_where_filelinenum (s);
5ff904cd 6218
c7e4ee3a
CB
6219 /* Pretransform the expression so any newly discovered things belong to the
6220 outer program unit, not to the statement function. */
5ff904cd 6221
c7e4ee3a 6222 ffecom_expr_transform_ (expr);
5ff904cd 6223
c7e4ee3a
CB
6224 /* Make sure no recursive invocation of this fn (a specific case of failing
6225 to pretransform an sfunc's expression, i.e. where its expression
6226 references another untransformed sfunc) happens. */
6227
6228 assert (!recurse);
6229 recurse = TRUE;
6230
6231 yes = suspend_momentary ();
6232
6233 push_f_function_context ();
6234
6235 if (charfunc)
6236 type = void_type_node;
6237 else
5ff904cd 6238 {
c7e4ee3a
CB
6239 type = ffecom_tree_type[bt][kt];
6240 if (type == NULL_TREE)
6241 type = integer_type_node; /* _sym_exec_transition reports
6242 error. */
6243 }
5ff904cd 6244
c7e4ee3a
CB
6245 start_function (ffecom_get_identifier_ (ffesymbol_text (s)),
6246 build_function_type (type, NULL_TREE),
6247 1, /* nested/inline */
6248 0); /* TREE_PUBLIC */
5ff904cd 6249
c7e4ee3a
CB
6250 /* We don't worry about COMPLEX return values here, because this is
6251 entirely internal to our code, and gcc has the ability to return COMPLEX
6252 directly as a value. */
6253
6254 yes = suspend_momentary ();
6255
6256 if (charfunc)
6257 { /* Prepend arg for where result goes. */
6258 tree type;
6259
6260 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
6261
6262 result = ffecom_get_invented_identifier ("__g77_%s",
6263 "result", -1);
6264
6265 ffecom_char_enhance_arg_ (&type, s); /* Ignore returned length. */
6266
6267 type = build_pointer_type (type);
6268 result = build_decl (PARM_DECL, result, type);
6269
6270 push_parm_decl (result);
5ff904cd 6271 }
c7e4ee3a
CB
6272 else
6273 result = NULL_TREE; /* Not ref'd if !charfunc. */
5ff904cd 6274
c7e4ee3a 6275 ffecom_push_dummy_decls_ (ffesymbol_dummyargs (s), TRUE);
5ff904cd 6276
c7e4ee3a 6277 resume_momentary (yes);
5ff904cd 6278
c7e4ee3a
CB
6279 store_parm_decls (0);
6280
6281 ffecom_start_compstmt ();
6282
6283 if (expr != NULL)
5ff904cd 6284 {
c7e4ee3a
CB
6285 if (charfunc)
6286 {
6287 ffetargetCharacterSize sz = ffesymbol_size (s);
6288 tree result_length;
5ff904cd 6289
c7e4ee3a
CB
6290 result_length = build_int_2 (sz, 0);
6291 TREE_TYPE (result_length) = ffecom_f2c_ftnlen_type_node;
5ff904cd 6292
c7e4ee3a 6293 ffecom_prepare_let_char_ (sz, expr);
5ff904cd 6294
c7e4ee3a 6295 ffecom_prepare_end ();
5ff904cd 6296
c7e4ee3a
CB
6297 ffecom_let_char_ (result, result_length, sz, expr);
6298 expand_null_return ();
6299 }
6300 else
6301 {
6302 ffecom_prepare_expr (expr);
5ff904cd 6303
c7e4ee3a 6304 ffecom_prepare_end ();
5ff904cd 6305
c7e4ee3a
CB
6306 expand_return (ffecom_modify (NULL_TREE,
6307 DECL_RESULT (current_function_decl),
6308 ffecom_expr (expr)));
6309 }
5ff904cd 6310
c7e4ee3a
CB
6311 clear_momentary ();
6312 }
5ff904cd 6313
c7e4ee3a 6314 ffecom_end_compstmt ();
5ff904cd 6315
c7e4ee3a
CB
6316 func = current_function_decl;
6317 finish_function (1);
5ff904cd 6318
c7e4ee3a 6319 pop_f_function_context ();
5ff904cd 6320
c7e4ee3a 6321 resume_momentary (yes);
5ff904cd 6322
c7e4ee3a
CB
6323 recurse = FALSE;
6324
6325 lineno = old_lineno;
6326 input_filename = old_input_filename;
6327
6328 ffecom_nested_entry_ = NULL;
6329
6330 return func;
5ff904cd
JL
6331}
6332
6333#endif
5ff904cd 6334
c7e4ee3a
CB
6335#if FFECOM_targetCURRENT == FFECOM_targetGCC
6336static const char *
6337ffecom_gfrt_args_ (ffecomGfrt ix)
5ff904cd 6338{
c7e4ee3a
CB
6339 return ffecom_gfrt_argstring_[ix];
6340}
5ff904cd 6341
c7e4ee3a
CB
6342#endif
6343#if FFECOM_targetCURRENT == FFECOM_targetGCC
6344static tree
6345ffecom_gfrt_tree_ (ffecomGfrt ix)
6346{
6347 if (ffecom_gfrt_[ix] == NULL_TREE)
6348 ffecom_make_gfrt_ (ix);
6349
6350 return ffecom_1 (ADDR_EXPR,
6351 build_pointer_type (TREE_TYPE (ffecom_gfrt_[ix])),
6352 ffecom_gfrt_[ix]);
5ff904cd
JL
6353}
6354
6355#endif
c7e4ee3a 6356/* Return initialize-to-zero expression for this VAR_DECL. */
5ff904cd
JL
6357
6358#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
6359static tree
6360ffecom_init_zero_ (tree decl)
5ff904cd 6361{
c7e4ee3a
CB
6362 tree init;
6363 int incremental = TREE_STATIC (decl);
6364 tree type = TREE_TYPE (decl);
5ff904cd 6365
c7e4ee3a
CB
6366 if (incremental)
6367 {
6368 int momentary = suspend_momentary ();
6369 push_obstacks_nochange ();
6370 if (TREE_PERMANENT (decl))
6371 end_temporary_allocation ();
6372 make_decl_rtl (decl, NULL, TREE_PUBLIC (decl) ? 1 : 0);
6373 assemble_variable (decl, TREE_PUBLIC (decl) ? 1 : 0, 0, 1);
6374 pop_obstacks ();
6375 resume_momentary (momentary);
6376 }
5ff904cd 6377
c7e4ee3a 6378 push_momentary ();
5ff904cd 6379
c7e4ee3a
CB
6380 if ((TREE_CODE (type) != ARRAY_TYPE)
6381 && (TREE_CODE (type) != RECORD_TYPE)
6382 && (TREE_CODE (type) != UNION_TYPE)
6383 && !incremental)
6384 init = convert (type, integer_zero_node);
6385 else if (!incremental)
6386 {
6387 int momentary = suspend_momentary ();
5ff904cd 6388
c7e4ee3a
CB
6389 init = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
6390 TREE_CONSTANT (init) = 1;
6391 TREE_STATIC (init) = 1;
5ff904cd 6392
c7e4ee3a
CB
6393 resume_momentary (momentary);
6394 }
6395 else
6396 {
6397 int momentary = suspend_momentary ();
5ff904cd 6398
c7e4ee3a
CB
6399 assemble_zeros (int_size_in_bytes (type));
6400 init = error_mark_node;
5ff904cd 6401
c7e4ee3a
CB
6402 resume_momentary (momentary);
6403 }
5ff904cd 6404
c7e4ee3a 6405 pop_momentary_nofree ();
5ff904cd 6406
c7e4ee3a 6407 return init;
5ff904cd
JL
6408}
6409
6410#endif
5ff904cd 6411#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
6412static tree
6413ffecom_intrinsic_ichar_ (tree tree_type, ffebld arg,
6414 tree *maybe_tree)
5ff904cd 6415{
c7e4ee3a
CB
6416 tree expr_tree;
6417 tree length_tree;
5ff904cd 6418
c7e4ee3a 6419 switch (ffebld_op (arg))
6829256f 6420 {
c7e4ee3a
CB
6421 case FFEBLD_opCONTER: /* For F90, check 0-length. */
6422 if (ffetarget_length_character1
6423 (ffebld_constant_character1
6424 (ffebld_conter (arg))) == 0)
6425 {
6426 *maybe_tree = integer_zero_node;
6427 return convert (tree_type, integer_zero_node);
6428 }
5ff904cd 6429
c7e4ee3a
CB
6430 *maybe_tree = integer_one_node;
6431 expr_tree = build_int_2 (*ffetarget_text_character1
6432 (ffebld_constant_character1
6433 (ffebld_conter (arg))),
6434 0);
6435 TREE_TYPE (expr_tree) = tree_type;
6436 return expr_tree;
5ff904cd 6437
c7e4ee3a
CB
6438 case FFEBLD_opSYMTER:
6439 case FFEBLD_opARRAYREF:
6440 case FFEBLD_opFUNCREF:
6441 case FFEBLD_opSUBSTR:
6442 ffecom_char_args_ (&expr_tree, &length_tree, arg);
5ff904cd 6443
c7e4ee3a
CB
6444 if ((expr_tree == error_mark_node)
6445 || (length_tree == error_mark_node))
6446 {
6447 *maybe_tree = error_mark_node;
6448 return error_mark_node;
6449 }
5ff904cd 6450
c7e4ee3a
CB
6451 if (integer_zerop (length_tree))
6452 {
6453 *maybe_tree = integer_zero_node;
6454 return convert (tree_type, integer_zero_node);
6455 }
6456
6457 expr_tree
6458 = ffecom_1 (INDIRECT_REF,
6459 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
6460 expr_tree);
6461 expr_tree
6462 = ffecom_2 (ARRAY_REF,
6463 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
6464 expr_tree,
6465 integer_one_node);
6466 expr_tree = convert (tree_type, expr_tree);
6467
6468 if (TREE_CODE (length_tree) == INTEGER_CST)
6469 *maybe_tree = integer_one_node;
6470 else /* Must check length at run time. */
6471 *maybe_tree
6472 = ffecom_truth_value
6473 (ffecom_2 (GT_EXPR, integer_type_node,
6474 length_tree,
6475 ffecom_f2c_ftnlen_zero_node));
6476 return expr_tree;
6477
6478 case FFEBLD_opPAREN:
6479 case FFEBLD_opCONVERT:
6480 if (ffeinfo_size (ffebld_info (arg)) == 0)
6481 {
6482 *maybe_tree = integer_zero_node;
6483 return convert (tree_type, integer_zero_node);
6484 }
6485 return ffecom_intrinsic_ichar_ (tree_type, ffebld_left (arg),
6486 maybe_tree);
6487
6488 case FFEBLD_opCONCATENATE:
6489 {
6490 tree maybe_left;
6491 tree maybe_right;
6492 tree expr_left;
6493 tree expr_right;
6494
6495 expr_left = ffecom_intrinsic_ichar_ (tree_type, ffebld_left (arg),
6496 &maybe_left);
6497 expr_right = ffecom_intrinsic_ichar_ (tree_type, ffebld_right (arg),
6498 &maybe_right);
6499 *maybe_tree = ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
6500 maybe_left,
6501 maybe_right);
6502 expr_tree = ffecom_3 (COND_EXPR, tree_type,
6503 maybe_left,
6504 expr_left,
6505 expr_right);
6506 return expr_tree;
6507 }
6508
6509 default:
6510 assert ("bad op in ICHAR" == NULL);
6511 return error_mark_node;
6512 }
5ff904cd
JL
6513}
6514
6515#endif
c7e4ee3a
CB
6516/* ffecom_intrinsic_len_ -- Return length info for char arg (LEN())
6517
6518 tree length_arg;
6519 ffebld expr;
6520 length_arg = ffecom_intrinsic_len_ (expr);
6521
6522 Handles CHARACTER-type CONTER, SYMTER, SUBSTR, ARRAYREF, and FUNCREF
6523 subexpressions by constructing the appropriate tree for the
6524 length-of-character-text argument in a calling sequence. */
5ff904cd
JL
6525
6526#if FFECOM_targetCURRENT == FFECOM_targetGCC
6527static tree
c7e4ee3a 6528ffecom_intrinsic_len_ (ffebld expr)
5ff904cd 6529{
c7e4ee3a
CB
6530 ffetargetCharacter1 val;
6531 tree length;
6532
6533 switch (ffebld_op (expr))
6534 {
6535 case FFEBLD_opCONTER:
6536 val = ffebld_constant_character1 (ffebld_conter (expr));
6537 length = build_int_2 (ffetarget_length_character1 (val), 0);
6538 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6539 break;
6540
6541 case FFEBLD_opSYMTER:
6542 {
6543 ffesymbol s = ffebld_symter (expr);
6544 tree item;
6545
6546 item = ffesymbol_hook (s).decl_tree;
6547 if (item == NULL_TREE)
6548 {
6549 s = ffecom_sym_transform_ (s);
6550 item = ffesymbol_hook (s).decl_tree;
6551 }
6552 if (ffesymbol_kind (s) == FFEINFO_kindENTITY)
6553 {
6554 if (ffesymbol_size (s) == FFETARGET_charactersizeNONE)
6555 length = ffesymbol_hook (s).length_tree;
6556 else
6557 {
6558 length = build_int_2 (ffesymbol_size (s), 0);
6559 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6560 }
6561 }
6562 else if (item == error_mark_node)
6563 length = error_mark_node;
6564 else /* FFEINFO_kindFUNCTION: */
6565 length = NULL_TREE;
6566 }
6567 break;
5ff904cd 6568
c7e4ee3a
CB
6569 case FFEBLD_opARRAYREF:
6570 length = ffecom_intrinsic_len_ (ffebld_left (expr));
6571 break;
5ff904cd 6572
c7e4ee3a
CB
6573 case FFEBLD_opSUBSTR:
6574 {
6575 ffebld start;
6576 ffebld end;
6577 ffebld thing = ffebld_right (expr);
6578 tree start_tree;
6579 tree end_tree;
5ff904cd 6580
c7e4ee3a
CB
6581 assert (ffebld_op (thing) == FFEBLD_opITEM);
6582 start = ffebld_head (thing);
6583 thing = ffebld_trail (thing);
6584 assert (ffebld_trail (thing) == NULL);
6585 end = ffebld_head (thing);
5ff904cd 6586
c7e4ee3a 6587 length = ffecom_intrinsic_len_ (ffebld_left (expr));
5ff904cd 6588
c7e4ee3a
CB
6589 if (length == error_mark_node)
6590 break;
5ff904cd 6591
c7e4ee3a
CB
6592 if (start == NULL)
6593 {
6594 if (end == NULL)
6595 ;
6596 else
6597 {
6598 length = convert (ffecom_f2c_ftnlen_type_node,
6599 ffecom_expr (end));
6600 }
6601 }
6602 else
6603 {
6604 start_tree = convert (ffecom_f2c_ftnlen_type_node,
6605 ffecom_expr (start));
5ff904cd 6606
c7e4ee3a
CB
6607 if (start_tree == error_mark_node)
6608 {
6609 length = error_mark_node;
6610 break;
6611 }
5ff904cd 6612
c7e4ee3a
CB
6613 if (end == NULL)
6614 {
6615 length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6616 ffecom_f2c_ftnlen_one_node,
6617 ffecom_2 (MINUS_EXPR,
6618 ffecom_f2c_ftnlen_type_node,
6619 length,
6620 start_tree));
6621 }
6622 else
6623 {
6624 end_tree = convert (ffecom_f2c_ftnlen_type_node,
6625 ffecom_expr (end));
5ff904cd 6626
c7e4ee3a
CB
6627 if (end_tree == error_mark_node)
6628 {
6629 length = error_mark_node;
6630 break;
6631 }
5ff904cd 6632
c7e4ee3a
CB
6633 length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6634 ffecom_f2c_ftnlen_one_node,
6635 ffecom_2 (MINUS_EXPR,
6636 ffecom_f2c_ftnlen_type_node,
6637 end_tree, start_tree));
6638 }
6639 }
6640 }
6641 break;
5ff904cd 6642
c7e4ee3a
CB
6643 case FFEBLD_opCONCATENATE:
6644 length
6645 = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6646 ffecom_intrinsic_len_ (ffebld_left (expr)),
6647 ffecom_intrinsic_len_ (ffebld_right (expr)));
6648 break;
5ff904cd 6649
c7e4ee3a
CB
6650 case FFEBLD_opFUNCREF:
6651 case FFEBLD_opCONVERT:
6652 length = build_int_2 (ffebld_size (expr), 0);
6653 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6654 break;
5ff904cd 6655
c7e4ee3a
CB
6656 default:
6657 assert ("bad op for single char arg expr" == NULL);
6658 length = ffecom_f2c_ftnlen_zero_node;
6659 break;
6660 }
5ff904cd 6661
c7e4ee3a 6662 assert (length != NULL_TREE);
5ff904cd 6663
c7e4ee3a 6664 return length;
5ff904cd
JL
6665}
6666
6667#endif
c7e4ee3a 6668/* Handle CHARACTER assignments.
5ff904cd 6669
c7e4ee3a
CB
6670 Generates code to do the assignment. Used by ordinary assignment
6671 statement handler ffecom_let_stmt and by statement-function
6672 handler to generate code for a statement function. */
5ff904cd
JL
6673
6674#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
6675static void
6676ffecom_let_char_ (tree dest_tree, tree dest_length,
6677 ffetargetCharacterSize dest_size, ffebld source)
5ff904cd 6678{
c7e4ee3a
CB
6679 ffecomConcatList_ catlist;
6680 tree source_length;
6681 tree source_tree;
6682 tree expr_tree;
5ff904cd 6683
c7e4ee3a
CB
6684 if ((dest_tree == error_mark_node)
6685 || (dest_length == error_mark_node))
6686 return;
5ff904cd 6687
c7e4ee3a
CB
6688 assert (dest_tree != NULL_TREE);
6689 assert (dest_length != NULL_TREE);
5ff904cd 6690
c7e4ee3a
CB
6691 /* Source might be an opCONVERT, which just means it is a different size
6692 than the destination. Since the underlying implementation here handles
6693 that (directly or via the s_copy or s_cat run-time-library functions),
6694 we don't need the "convenience" of an opCONVERT that tells us to
6695 truncate or blank-pad, particularly since the resulting implementation
6696 would probably be slower than otherwise. */
5ff904cd 6697
c7e4ee3a
CB
6698 while (ffebld_op (source) == FFEBLD_opCONVERT)
6699 source = ffebld_left (source);
5ff904cd 6700
c7e4ee3a
CB
6701 catlist = ffecom_concat_list_new_ (source, dest_size);
6702 switch (ffecom_concat_list_count_ (catlist))
6703 {
6704 case 0: /* Shouldn't happen, but in case it does... */
6705 ffecom_concat_list_kill_ (catlist);
6706 source_tree = null_pointer_node;
6707 source_length = ffecom_f2c_ftnlen_zero_node;
6708 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6709 TREE_CHAIN (expr_tree) = build_tree_list (NULL_TREE, source_tree);
6710 TREE_CHAIN (TREE_CHAIN (expr_tree))
6711 = build_tree_list (NULL_TREE, dest_length);
6712 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6713 = build_tree_list (NULL_TREE, source_length);
5ff904cd 6714
c7e4ee3a
CB
6715 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCOPY, expr_tree, NULL_TREE);
6716 TREE_SIDE_EFFECTS (expr_tree) = 1;
5ff904cd 6717
c7e4ee3a 6718 expand_expr_stmt (expr_tree);
5ff904cd 6719
c7e4ee3a 6720 return;
5ff904cd 6721
c7e4ee3a
CB
6722 case 1: /* The (fairly) easy case. */
6723 ffecom_char_args_ (&source_tree, &source_length,
6724 ffecom_concat_list_expr_ (catlist, 0));
6725 ffecom_concat_list_kill_ (catlist);
6726 assert (source_tree != NULL_TREE);
6727 assert (source_length != NULL_TREE);
6728
6729 if ((source_tree == error_mark_node)
6730 || (source_length == error_mark_node))
6731 return;
6732
6733 if (dest_size == 1)
6734 {
6735 dest_tree
6736 = ffecom_1 (INDIRECT_REF,
6737 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6738 (dest_tree))),
6739 dest_tree);
6740 dest_tree
6741 = ffecom_2 (ARRAY_REF,
6742 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6743 (dest_tree))),
6744 dest_tree,
6745 integer_one_node);
6746 source_tree
6747 = ffecom_1 (INDIRECT_REF,
6748 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6749 (source_tree))),
6750 source_tree);
6751 source_tree
6752 = ffecom_2 (ARRAY_REF,
6753 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6754 (source_tree))),
6755 source_tree,
6756 integer_one_node);
5ff904cd 6757
c7e4ee3a 6758 expr_tree = ffecom_modify (void_type_node, dest_tree, source_tree);
5ff904cd 6759
c7e4ee3a 6760 expand_expr_stmt (expr_tree);
5ff904cd 6761
c7e4ee3a
CB
6762 return;
6763 }
5ff904cd 6764
c7e4ee3a
CB
6765 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6766 TREE_CHAIN (expr_tree) = build_tree_list (NULL_TREE, source_tree);
6767 TREE_CHAIN (TREE_CHAIN (expr_tree))
6768 = build_tree_list (NULL_TREE, dest_length);
6769 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6770 = build_tree_list (NULL_TREE, source_length);
5ff904cd 6771
c7e4ee3a
CB
6772 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCOPY, expr_tree, NULL_TREE);
6773 TREE_SIDE_EFFECTS (expr_tree) = 1;
5ff904cd 6774
c7e4ee3a 6775 expand_expr_stmt (expr_tree);
5ff904cd 6776
c7e4ee3a 6777 return;
5ff904cd 6778
c7e4ee3a
CB
6779 default: /* Must actually concatenate things. */
6780 break;
6781 }
5ff904cd 6782
c7e4ee3a 6783 /* Heavy-duty concatenation. */
5ff904cd 6784
c7e4ee3a
CB
6785 {
6786 int count = ffecom_concat_list_count_ (catlist);
6787 int i;
6788 tree lengths;
6789 tree items;
6790 tree length_array;
6791 tree item_array;
6792 tree citem;
6793 tree clength;
5ff904cd 6794
c7e4ee3a
CB
6795#ifdef HOHO
6796 length_array
6797 = lengths
6798 = ffecom_push_tempvar (ffecom_f2c_ftnlen_type_node,
6799 FFETARGET_charactersizeNONE, count, TRUE);
6800 item_array = items = ffecom_push_tempvar (ffecom_f2c_address_type_node,
6801 FFETARGET_charactersizeNONE,
6802 count, TRUE);
6803#else
6804 {
6805 tree hook;
6806
6807 hook = ffebld_nonter_hook (source);
6808 assert (hook);
6809 assert (TREE_CODE (hook) == TREE_VEC);
6810 assert (TREE_VEC_LENGTH (hook) == 2);
6811 length_array = lengths = TREE_VEC_ELT (hook, 0);
6812 item_array = items = TREE_VEC_ELT (hook, 1);
5ff904cd 6813 }
c7e4ee3a 6814#endif
5ff904cd 6815
c7e4ee3a
CB
6816 for (i = 0; i < count; ++i)
6817 {
6818 ffecom_char_args_ (&citem, &clength,
6819 ffecom_concat_list_expr_ (catlist, i));
6820 if ((citem == error_mark_node)
6821 || (clength == error_mark_node))
6822 {
6823 ffecom_concat_list_kill_ (catlist);
6824 return;
6825 }
5ff904cd 6826
c7e4ee3a
CB
6827 items
6828 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (items),
6829 ffecom_modify (void_type_node,
6830 ffecom_2 (ARRAY_REF,
6831 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array))),
6832 item_array,
6833 build_int_2 (i, 0)),
6834 citem),
6835 items);
6836 lengths
6837 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (lengths),
6838 ffecom_modify (void_type_node,
6839 ffecom_2 (ARRAY_REF,
6840 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array))),
6841 length_array,
6842 build_int_2 (i, 0)),
6843 clength),
6844 lengths);
6845 }
5ff904cd 6846
c7e4ee3a
CB
6847 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6848 TREE_CHAIN (expr_tree)
6849 = build_tree_list (NULL_TREE,
6850 ffecom_1 (ADDR_EXPR,
6851 build_pointer_type (TREE_TYPE (items)),
6852 items));
6853 TREE_CHAIN (TREE_CHAIN (expr_tree))
6854 = build_tree_list (NULL_TREE,
6855 ffecom_1 (ADDR_EXPR,
6856 build_pointer_type (TREE_TYPE (lengths)),
6857 lengths));
6858 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6859 = build_tree_list
6860 (NULL_TREE,
6861 ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
6862 convert (ffecom_f2c_ftnlen_type_node,
6863 build_int_2 (count, 0))));
6864 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree))))
6865 = build_tree_list (NULL_TREE, dest_length);
5ff904cd 6866
c7e4ee3a
CB
6867 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCAT, expr_tree, NULL_TREE);
6868 TREE_SIDE_EFFECTS (expr_tree) = 1;
5ff904cd 6869
c7e4ee3a
CB
6870 expand_expr_stmt (expr_tree);
6871 }
5ff904cd 6872
c7e4ee3a
CB
6873 ffecom_concat_list_kill_ (catlist);
6874}
5ff904cd 6875
c7e4ee3a
CB
6876#endif
6877/* ffecom_make_gfrt_ -- Make initial info for run-time routine
5ff904cd 6878
c7e4ee3a
CB
6879 ffecomGfrt ix;
6880 ffecom_make_gfrt_(ix);
5ff904cd 6881
c7e4ee3a
CB
6882 Assumes gfrt_[ix] is NULL_TREE, and replaces it with the FUNCTION_DECL
6883 for the indicated run-time routine (ix). */
5ff904cd 6884
c7e4ee3a
CB
6885#if FFECOM_targetCURRENT == FFECOM_targetGCC
6886static void
6887ffecom_make_gfrt_ (ffecomGfrt ix)
6888{
6889 tree t;
6890 tree ttype;
5ff904cd 6891
c7e4ee3a
CB
6892 push_obstacks_nochange ();
6893 end_temporary_allocation ();
5ff904cd 6894
c7e4ee3a
CB
6895 switch (ffecom_gfrt_type_[ix])
6896 {
6897 case FFECOM_rttypeVOID_:
6898 ttype = void_type_node;
6899 break;
5ff904cd 6900
c7e4ee3a
CB
6901 case FFECOM_rttypeVOIDSTAR_:
6902 ttype = TREE_TYPE (null_pointer_node); /* `void *'. */
6903 break;
5ff904cd 6904
c7e4ee3a
CB
6905 case FFECOM_rttypeFTNINT_:
6906 ttype = ffecom_f2c_ftnint_type_node;
6907 break;
5ff904cd 6908
c7e4ee3a
CB
6909 case FFECOM_rttypeINTEGER_:
6910 ttype = ffecom_f2c_integer_type_node;
6911 break;
5ff904cd 6912
c7e4ee3a
CB
6913 case FFECOM_rttypeLONGINT_:
6914 ttype = ffecom_f2c_longint_type_node;
6915 break;
5ff904cd 6916
c7e4ee3a
CB
6917 case FFECOM_rttypeLOGICAL_:
6918 ttype = ffecom_f2c_logical_type_node;
6919 break;
5ff904cd 6920
c7e4ee3a
CB
6921 case FFECOM_rttypeREAL_F2C_:
6922 ttype = double_type_node;
6923 break;
5ff904cd 6924
c7e4ee3a
CB
6925 case FFECOM_rttypeREAL_GNU_:
6926 ttype = float_type_node;
6927 break;
5ff904cd 6928
c7e4ee3a
CB
6929 case FFECOM_rttypeCOMPLEX_F2C_:
6930 ttype = void_type_node;
6931 break;
5ff904cd 6932
c7e4ee3a
CB
6933 case FFECOM_rttypeCOMPLEX_GNU_:
6934 ttype = ffecom_f2c_complex_type_node;
6935 break;
5ff904cd 6936
c7e4ee3a
CB
6937 case FFECOM_rttypeDOUBLE_:
6938 ttype = double_type_node;
6939 break;
5ff904cd 6940
c7e4ee3a
CB
6941 case FFECOM_rttypeDOUBLEREAL_:
6942 ttype = ffecom_f2c_doublereal_type_node;
6943 break;
5ff904cd 6944
c7e4ee3a
CB
6945 case FFECOM_rttypeDBLCMPLX_F2C_:
6946 ttype = void_type_node;
6947 break;
5ff904cd 6948
c7e4ee3a
CB
6949 case FFECOM_rttypeDBLCMPLX_GNU_:
6950 ttype = ffecom_f2c_doublecomplex_type_node;
6951 break;
5ff904cd 6952
c7e4ee3a
CB
6953 case FFECOM_rttypeCHARACTER_:
6954 ttype = void_type_node;
6955 break;
6956
6957 default:
6958 ttype = NULL;
6959 assert ("bad rttype" == NULL);
6960 break;
5ff904cd 6961 }
5ff904cd 6962
c7e4ee3a
CB
6963 ttype = build_function_type (ttype, NULL_TREE);
6964 t = build_decl (FUNCTION_DECL,
6965 get_identifier (ffecom_gfrt_name_[ix]),
6966 ttype);
6967 DECL_EXTERNAL (t) = 1;
6968 TREE_PUBLIC (t) = 1;
6969 TREE_THIS_VOLATILE (t) = ffecom_gfrt_volatile_[ix] ? 1 : 0;
5ff904cd 6970
c7e4ee3a 6971 t = start_decl (t, TRUE);
5ff904cd 6972
c7e4ee3a 6973 finish_decl (t, NULL_TREE, TRUE);
5ff904cd 6974
c7e4ee3a
CB
6975 resume_temporary_allocation ();
6976 pop_obstacks ();
6977
6978 ffecom_gfrt_[ix] = t;
5ff904cd
JL
6979}
6980
6981#endif
c7e4ee3a
CB
6982/* Phase 1 pass over each member of a COMMON/EQUIVALENCE group. */
6983
5ff904cd 6984#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
6985static void
6986ffecom_member_phase1_ (ffestorag mst UNUSED, ffestorag st)
5ff904cd 6987{
c7e4ee3a 6988 ffesymbol s = ffestorag_symbol (st);
5ff904cd 6989
c7e4ee3a
CB
6990 if (ffesymbol_namelisted (s))
6991 ffecom_member_namelisted_ = TRUE;
6992}
5ff904cd 6993
c7e4ee3a
CB
6994#endif
6995/* Phase 2 pass over each member of a COMMON/EQUIVALENCE group. Declare
6996 the member so debugger will see it. Otherwise nobody should be
6997 referencing the member. */
5ff904cd 6998
c7e4ee3a
CB
6999#if FFECOM_targetCURRENT == FFECOM_targetGCC
7000#ifdef SOMEONE_GETS_DEBUG_SUPPORT_WORKING
7001static void
7002ffecom_member_phase2_ (ffestorag mst, ffestorag st)
7003{
7004 ffesymbol s;
7005 tree t;
7006 tree mt;
7007 tree type;
5ff904cd 7008
c7e4ee3a
CB
7009 if ((mst == NULL)
7010 || ((mt = ffestorag_hook (mst)) == NULL)
7011 || (mt == error_mark_node))
7012 return;
5ff904cd 7013
c7e4ee3a
CB
7014 if ((st == NULL)
7015 || ((s = ffestorag_symbol (st)) == NULL))
7016 return;
5ff904cd 7017
c7e4ee3a
CB
7018 type = ffecom_type_localvar_ (s,
7019 ffesymbol_basictype (s),
7020 ffesymbol_kindtype (s));
7021 if (type == error_mark_node)
7022 return;
5ff904cd 7023
c7e4ee3a
CB
7024 t = build_decl (VAR_DECL,
7025 ffecom_get_identifier_ (ffesymbol_text (s)),
7026 type);
5ff904cd 7027
c7e4ee3a
CB
7028 TREE_STATIC (t) = TREE_STATIC (mt);
7029 DECL_INITIAL (t) = NULL_TREE;
7030 TREE_ASM_WRITTEN (t) = 1;
5ff904cd 7031
c7e4ee3a
CB
7032 DECL_RTL (t)
7033 = gen_rtx (MEM, TYPE_MODE (type),
7034 plus_constant (XEXP (DECL_RTL (mt), 0),
7035 ffestorag_modulo (mst)
7036 + ffestorag_offset (st)
7037 - ffestorag_offset (mst)));
5ff904cd 7038
c7e4ee3a 7039 t = start_decl (t, FALSE);
5ff904cd 7040
c7e4ee3a 7041 finish_decl (t, NULL_TREE, FALSE);
5ff904cd
JL
7042}
7043
7044#endif
c7e4ee3a
CB
7045#endif
7046/* Prepare source expression for assignment into a destination perhaps known
7047 to be of a specific size. */
5ff904cd 7048
c7e4ee3a
CB
7049static void
7050ffecom_prepare_let_char_ (ffetargetCharacterSize dest_size, ffebld source)
5ff904cd 7051{
c7e4ee3a
CB
7052 ffecomConcatList_ catlist;
7053 int count;
7054 int i;
7055 tree ltmp;
7056 tree itmp;
7057 tree tempvar = NULL_TREE;
5ff904cd 7058
c7e4ee3a
CB
7059 while (ffebld_op (source) == FFEBLD_opCONVERT)
7060 source = ffebld_left (source);
5ff904cd 7061
c7e4ee3a
CB
7062 catlist = ffecom_concat_list_new_ (source, dest_size);
7063 count = ffecom_concat_list_count_ (catlist);
5ff904cd 7064
c7e4ee3a
CB
7065 if (count >= 2)
7066 {
7067 ltmp
7068 = ffecom_make_tempvar ("let_char_len", ffecom_f2c_ftnlen_type_node,
7069 FFETARGET_charactersizeNONE, count);
7070 itmp
7071 = ffecom_make_tempvar ("let_char_item", ffecom_f2c_address_type_node,
7072 FFETARGET_charactersizeNONE, count);
7073
7074 tempvar = make_tree_vec (2);
7075 TREE_VEC_ELT (tempvar, 0) = ltmp;
7076 TREE_VEC_ELT (tempvar, 1) = itmp;
7077 }
5ff904cd 7078
c7e4ee3a
CB
7079 for (i = 0; i < count; ++i)
7080 ffecom_prepare_arg_ptr_to_expr (ffecom_concat_list_expr_ (catlist, i));
5ff904cd 7081
c7e4ee3a 7082 ffecom_concat_list_kill_ (catlist);
5ff904cd 7083
c7e4ee3a
CB
7084 if (tempvar)
7085 {
7086 ffebld_nonter_set_hook (source, tempvar);
7087 current_binding_level->prep_state = 1;
7088 }
7089}
5ff904cd 7090
c7e4ee3a 7091/* ffecom_push_dummy_decls_ -- Transform dummy args, push parm decls in order
5ff904cd 7092
c7e4ee3a
CB
7093 Ignores STAR (alternate-return) dummies. All other get exec-transitioned
7094 (which generates their trees) and then their trees get push_parm_decl'd.
5ff904cd 7095
c7e4ee3a
CB
7096 The second arg is TRUE if the dummies are for a statement function, in
7097 which case lengths are not pushed for character arguments (since they are
7098 always known by both the caller and the callee, though the code allows
7099 for someday permitting CHAR*(*) stmtfunc dummies). */
5ff904cd 7100
c7e4ee3a
CB
7101#if FFECOM_targetCURRENT == FFECOM_targetGCC
7102static void
7103ffecom_push_dummy_decls_ (ffebld dummy_list, bool stmtfunc)
7104{
7105 ffebld dummy;
7106 ffebld dumlist;
7107 ffesymbol s;
7108 tree parm;
5ff904cd 7109
c7e4ee3a 7110 ffecom_transform_only_dummies_ = TRUE;
5ff904cd 7111
c7e4ee3a 7112 /* First push the parms corresponding to actual dummy "contents". */
5ff904cd 7113
c7e4ee3a
CB
7114 for (dumlist = dummy_list; dumlist != NULL; dumlist = ffebld_trail (dumlist))
7115 {
7116 dummy = ffebld_head (dumlist);
7117 switch (ffebld_op (dummy))
7118 {
7119 case FFEBLD_opSTAR:
7120 case FFEBLD_opANY:
7121 continue; /* Forget alternate returns. */
5ff904cd 7122
c7e4ee3a
CB
7123 default:
7124 break;
7125 }
7126 assert (ffebld_op (dummy) == FFEBLD_opSYMTER);
7127 s = ffebld_symter (dummy);
7128 parm = ffesymbol_hook (s).decl_tree;
7129 if (parm == NULL_TREE)
7130 {
7131 s = ffecom_sym_transform_ (s);
7132 parm = ffesymbol_hook (s).decl_tree;
7133 assert (parm != NULL_TREE);
7134 }
7135 if (parm != error_mark_node)
7136 push_parm_decl (parm);
5ff904cd
JL
7137 }
7138
c7e4ee3a 7139 /* Then, for CHARACTER dummies, push the parms giving their lengths. */
5ff904cd 7140
c7e4ee3a
CB
7141 for (dumlist = dummy_list; dumlist != NULL; dumlist = ffebld_trail (dumlist))
7142 {
7143 dummy = ffebld_head (dumlist);
7144 switch (ffebld_op (dummy))
7145 {
7146 case FFEBLD_opSTAR:
7147 case FFEBLD_opANY:
7148 continue; /* Forget alternate returns, they mean
7149 NOTHING! */
7150
7151 default:
7152 break;
7153 }
7154 s = ffebld_symter (dummy);
7155 if (ffesymbol_basictype (s) != FFEINFO_basictypeCHARACTER)
7156 continue; /* Only looking for CHARACTER arguments. */
7157 if (stmtfunc && (ffesymbol_size (s) != FFETARGET_charactersizeNONE))
7158 continue; /* Stmtfunc arg with known size needs no
7159 length param. */
7160 if (ffesymbol_kind (s) != FFEINFO_kindENTITY)
7161 continue; /* Only looking for variables and arrays. */
7162 parm = ffesymbol_hook (s).length_tree;
7163 assert (parm != NULL_TREE);
7164 if (parm != error_mark_node)
7165 push_parm_decl (parm);
7166 }
7167
7168 ffecom_transform_only_dummies_ = FALSE;
5ff904cd
JL
7169}
7170
7171#endif
c7e4ee3a 7172/* ffecom_start_progunit_ -- Beginning of program unit
5ff904cd 7173
c7e4ee3a
CB
7174 Does GNU back end stuff necessary to teach it about the start of its
7175 equivalent of a Fortran program unit. */
5ff904cd
JL
7176
7177#if FFECOM_targetCURRENT == FFECOM_targetGCC
7178static void
c7e4ee3a 7179ffecom_start_progunit_ ()
5ff904cd 7180{
c7e4ee3a
CB
7181 ffesymbol fn = ffecom_primary_entry_;
7182 ffebld arglist;
7183 tree id; /* Identifier (name) of function. */
7184 tree type; /* Type of function. */
7185 tree result; /* Result of function. */
7186 ffeinfoBasictype bt;
7187 ffeinfoKindtype kt;
7188 ffeglobal g;
7189 ffeglobalType gt;
7190 ffeglobalType egt = FFEGLOBAL_type;
7191 bool charfunc;
7192 bool cmplxfunc;
7193 bool altentries = (ffecom_num_entrypoints_ != 0);
7194 bool multi
7195 = altentries
7196 && (ffecom_primary_entry_kind_ == FFEINFO_kindFUNCTION)
7197 && (ffecom_master_bt_ == FFEINFO_basictypeNONE);
7198 bool main_program = FALSE;
7199 int old_lineno = lineno;
7200 char *old_input_filename = input_filename;
7201 int yes;
5ff904cd 7202
c7e4ee3a
CB
7203 assert (fn != NULL);
7204 assert (ffesymbol_hook (fn).decl_tree == NULL_TREE);
5ff904cd 7205
c7e4ee3a
CB
7206 input_filename = ffesymbol_where_filename (fn);
7207 lineno = ffesymbol_where_filelinenum (fn);
5ff904cd 7208
c7e4ee3a
CB
7209 /* c-parse.y indeed does call suspend_momentary and not only ignores the
7210 return value, but also never calls resume_momentary, when starting an
7211 outer function (see "fndef:", "setspecs:", and so on). So g77 does the
7212 same thing. It shouldn't be a problem since start_function calls
7213 temporary_allocation, but it might be necessary. If it causes a problem
7214 here, then maybe there's a bug lurking in gcc. NOTE: This identical
7215 comment appears twice in thist file. */
7216
7217 suspend_momentary ();
7218
7219 switch (ffecom_primary_entry_kind_)
7220 {
7221 case FFEINFO_kindPROGRAM:
7222 main_program = TRUE;
7223 gt = FFEGLOBAL_typeMAIN;
7224 bt = FFEINFO_basictypeNONE;
7225 kt = FFEINFO_kindtypeNONE;
7226 type = ffecom_tree_fun_type_void;
7227 charfunc = FALSE;
7228 cmplxfunc = FALSE;
7229 break;
7230
7231 case FFEINFO_kindBLOCKDATA:
7232 gt = FFEGLOBAL_typeBDATA;
7233 bt = FFEINFO_basictypeNONE;
7234 kt = FFEINFO_kindtypeNONE;
7235 type = ffecom_tree_fun_type_void;
7236 charfunc = FALSE;
7237 cmplxfunc = FALSE;
7238 break;
7239
7240 case FFEINFO_kindFUNCTION:
7241 gt = FFEGLOBAL_typeFUNC;
7242 egt = FFEGLOBAL_typeEXT;
7243 bt = ffesymbol_basictype (fn);
7244 kt = ffesymbol_kindtype (fn);
7245 if (bt == FFEINFO_basictypeNONE)
7246 {
7247 ffeimplic_establish_symbol (fn);
7248 if (ffesymbol_funcresult (fn) != NULL)
7249 ffeimplic_establish_symbol (ffesymbol_funcresult (fn));
7250 bt = ffesymbol_basictype (fn);
7251 kt = ffesymbol_kindtype (fn);
7252 }
7253
7254 if (multi)
7255 charfunc = cmplxfunc = FALSE;
7256 else if (bt == FFEINFO_basictypeCHARACTER)
7257 charfunc = TRUE, cmplxfunc = FALSE;
7258 else if ((bt == FFEINFO_basictypeCOMPLEX)
7259 && ffesymbol_is_f2c (fn)
7260 && !altentries)
7261 charfunc = FALSE, cmplxfunc = TRUE;
7262 else
7263 charfunc = cmplxfunc = FALSE;
7264
7265 if (multi || charfunc)
7266 type = ffecom_tree_fun_type_void;
7267 else if (ffesymbol_is_f2c (fn) && !altentries)
7268 type = ffecom_tree_fun_type[bt][kt];
7269 else
7270 type = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
7271
7272 if ((type == NULL_TREE)
7273 || (TREE_TYPE (type) == NULL_TREE))
7274 type = ffecom_tree_fun_type_void; /* _sym_exec_transition. */
7275 break;
7276
7277 case FFEINFO_kindSUBROUTINE:
7278 gt = FFEGLOBAL_typeSUBR;
7279 egt = FFEGLOBAL_typeEXT;
7280 bt = FFEINFO_basictypeNONE;
7281 kt = FFEINFO_kindtypeNONE;
7282 if (ffecom_is_altreturning_)
7283 type = ffecom_tree_subr_type;
7284 else
7285 type = ffecom_tree_fun_type_void;
7286 charfunc = FALSE;
7287 cmplxfunc = FALSE;
7288 break;
5ff904cd 7289
c7e4ee3a
CB
7290 default:
7291 assert ("say what??" == NULL);
7292 /* Fall through. */
7293 case FFEINFO_kindANY:
7294 gt = FFEGLOBAL_typeANY;
7295 bt = FFEINFO_basictypeNONE;
7296 kt = FFEINFO_kindtypeNONE;
7297 type = error_mark_node;
7298 charfunc = FALSE;
7299 cmplxfunc = FALSE;
7300 break;
7301 }
5ff904cd 7302
c7e4ee3a 7303 if (altentries)
5ff904cd 7304 {
c7e4ee3a
CB
7305 id = ffecom_get_invented_identifier ("__g77_masterfun_%s",
7306 ffesymbol_text (fn),
7307 -1);
7308 }
7309#if FFETARGET_isENFORCED_MAIN
7310 else if (main_program)
7311 id = get_identifier (FFETARGET_nameENFORCED_MAIN_NAME);
7312#endif
7313 else
7314 id = ffecom_get_external_identifier_ (fn);
5ff904cd 7315
c7e4ee3a
CB
7316 start_function (id,
7317 type,
7318 0, /* nested/inline */
7319 !altentries); /* TREE_PUBLIC */
5ff904cd 7320
c7e4ee3a 7321 TREE_USED (current_function_decl) = 1; /* Avoid spurious warning if altentries. */
5ff904cd 7322
c7e4ee3a
CB
7323 if (!altentries
7324 && ((g = ffesymbol_global (fn)) != NULL)
7325 && ((ffeglobal_type (g) == gt)
7326 || (ffeglobal_type (g) == egt)))
7327 {
7328 ffeglobal_set_hook (g, current_function_decl);
7329 }
5ff904cd 7330
c7e4ee3a 7331 yes = suspend_momentary ();
5ff904cd 7332
c7e4ee3a
CB
7333 /* Arg handling needs exec-transitioned ffesymbols to work with. But
7334 exec-transitioning needs current_function_decl to be filled in. So we
7335 do these things in two phases. */
5ff904cd 7336
c7e4ee3a
CB
7337 if (altentries)
7338 { /* 1st arg identifies which entrypoint. */
7339 ffecom_which_entrypoint_decl_
7340 = build_decl (PARM_DECL,
7341 ffecom_get_invented_identifier ("__g77_%s",
7342 "which_entrypoint",
7343 -1),
7344 integer_type_node);
7345 push_parm_decl (ffecom_which_entrypoint_decl_);
7346 }
5ff904cd 7347
c7e4ee3a
CB
7348 if (charfunc
7349 || cmplxfunc
7350 || multi)
7351 { /* Arg for result (return value). */
7352 tree type;
7353 tree length;
5ff904cd 7354
c7e4ee3a
CB
7355 if (charfunc)
7356 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
7357 else if (cmplxfunc)
7358 type = ffecom_tree_type[FFEINFO_basictypeCOMPLEX][kt];
7359 else
7360 type = ffecom_multi_type_node_;
5ff904cd 7361
c7e4ee3a
CB
7362 result = ffecom_get_invented_identifier ("__g77_%s",
7363 "result", -1);
5ff904cd 7364
c7e4ee3a 7365 /* Make length arg _and_ enhance type info for CHAR arg itself. */
5ff904cd 7366
c7e4ee3a
CB
7367 if (charfunc)
7368 length = ffecom_char_enhance_arg_ (&type, fn);
7369 else
7370 length = NULL_TREE; /* Not ref'd if !charfunc. */
5ff904cd 7371
c7e4ee3a
CB
7372 type = build_pointer_type (type);
7373 result = build_decl (PARM_DECL, result, type);
5ff904cd 7374
c7e4ee3a
CB
7375 push_parm_decl (result);
7376 if (multi)
7377 ffecom_multi_retval_ = result;
7378 else
7379 ffecom_func_result_ = result;
5ff904cd 7380
c7e4ee3a
CB
7381 if (charfunc)
7382 {
7383 push_parm_decl (length);
7384 ffecom_func_length_ = length;
7385 }
5ff904cd
JL
7386 }
7387
c7e4ee3a
CB
7388 if (ffecom_primary_entry_is_proc_)
7389 {
7390 if (altentries)
7391 arglist = ffecom_master_arglist_;
7392 else
7393 arglist = ffesymbol_dummyargs (fn);
7394 ffecom_push_dummy_decls_ (arglist, FALSE);
7395 }
5ff904cd 7396
c7e4ee3a 7397 resume_momentary (yes);
5ff904cd 7398
c7e4ee3a
CB
7399 if (TREE_CODE (current_function_decl) != ERROR_MARK)
7400 store_parm_decls (main_program ? 1 : 0);
5ff904cd 7401
c7e4ee3a
CB
7402 ffecom_start_compstmt ();
7403 /* Disallow temp vars at this level. */
7404 current_binding_level->prep_state = 2;
5ff904cd 7405
c7e4ee3a
CB
7406 lineno = old_lineno;
7407 input_filename = old_input_filename;
5ff904cd 7408
c7e4ee3a
CB
7409 /* This handles any symbols still untransformed, in case -g specified.
7410 This used to be done in ffecom_finish_progunit, but it turns out to
7411 be necessary to do it here so that statement functions are
7412 expanded before code. But don't bother for BLOCK DATA. */
5ff904cd 7413
c7e4ee3a
CB
7414 if (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA)
7415 ffesymbol_drive (ffecom_finish_symbol_transform_);
5ff904cd
JL
7416}
7417
7418#endif
c7e4ee3a 7419/* ffecom_sym_transform_ -- Transform FFE sym into backend sym
5ff904cd 7420
c7e4ee3a
CB
7421 ffesymbol s;
7422 ffecom_sym_transform_(s);
7423
7424 The ffesymbol_hook info for s is updated with appropriate backend info
7425 on the symbol. */
7426
7427#if FFECOM_targetCURRENT == FFECOM_targetGCC
7428static ffesymbol
7429ffecom_sym_transform_ (ffesymbol s)
7430{
7431 tree t; /* Transformed thingy. */
7432 tree tlen; /* Length if CHAR*(*). */
7433 bool addr; /* Is t the address of the thingy? */
7434 ffeinfoBasictype bt;
7435 ffeinfoKindtype kt;
7436 ffeglobal g;
7437 int yes;
7438 int old_lineno = lineno;
7439 char *old_input_filename = input_filename;
5ff904cd 7440
c7e4ee3a
CB
7441 /* Must ensure special ASSIGN variables are declared at top of outermost
7442 block, else they'll end up in the innermost block when their first
7443 ASSIGN is seen, which leaves them out of scope when they're the
7444 subject of a GOTO or I/O statement.
5ff904cd 7445
c7e4ee3a
CB
7446 We make this variable even if -fugly-assign. Just let it go unused,
7447 in case it turns out there are cases where we really want to use this
7448 variable anyway (e.g. ASSIGN to INTEGER*2 variable). */
5ff904cd 7449
c7e4ee3a
CB
7450 if (! ffecom_transform_only_dummies_
7451 && ffesymbol_assigned (s)
7452 && ! ffesymbol_hook (s).assign_tree)
7453 s = ffecom_sym_transform_assign_ (s);
5ff904cd 7454
c7e4ee3a 7455 if (ffesymbol_sfdummyparent (s) == NULL)
5ff904cd 7456 {
c7e4ee3a
CB
7457 input_filename = ffesymbol_where_filename (s);
7458 lineno = ffesymbol_where_filelinenum (s);
7459 }
7460 else
7461 {
7462 ffesymbol sf = ffesymbol_sfdummyparent (s);
5ff904cd 7463
c7e4ee3a
CB
7464 input_filename = ffesymbol_where_filename (sf);
7465 lineno = ffesymbol_where_filelinenum (sf);
7466 }
6d433196 7467
c7e4ee3a
CB
7468 bt = ffeinfo_basictype (ffebld_info (s));
7469 kt = ffeinfo_kindtype (ffebld_info (s));
5ff904cd 7470
c7e4ee3a
CB
7471 t = NULL_TREE;
7472 tlen = NULL_TREE;
7473 addr = FALSE;
5ff904cd 7474
c7e4ee3a
CB
7475 switch (ffesymbol_kind (s))
7476 {
7477 case FFEINFO_kindNONE:
7478 switch (ffesymbol_where (s))
7479 {
7480 case FFEINFO_whereDUMMY: /* Subroutine or function. */
7481 assert (ffecom_transform_only_dummies_);
5ff904cd 7482
c7e4ee3a
CB
7483 /* Before 0.4, this could be ENTITY/DUMMY, but see
7484 ffestu_sym_end_transition -- no longer true (in particular, if
7485 it could be an ENTITY, it _will_ be made one, so that
7486 possibility won't come through here). So we never make length
7487 arg for CHARACTER type. */
5ff904cd 7488
c7e4ee3a
CB
7489 t = build_decl (PARM_DECL,
7490 ffecom_get_identifier_ (ffesymbol_text (s)),
7491 ffecom_tree_ptr_to_subr_type);
7492#if BUILT_FOR_270
7493 DECL_ARTIFICIAL (t) = 1;
7494#endif
7495 addr = TRUE;
7496 break;
5ff904cd 7497
c7e4ee3a
CB
7498 case FFEINFO_whereGLOBAL: /* Subroutine or function. */
7499 assert (!ffecom_transform_only_dummies_);
5ff904cd 7500
c7e4ee3a
CB
7501 if (((g = ffesymbol_global (s)) != NULL)
7502 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
7503 || (ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
7504 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
7505 && (ffeglobal_hook (g) != NULL_TREE)
7506 && ffe_is_globals ())
7507 {
7508 t = ffeglobal_hook (g);
7509 break;
7510 }
5ff904cd 7511
c7e4ee3a
CB
7512 push_obstacks_nochange ();
7513 end_temporary_allocation ();
5ff904cd 7514
c7e4ee3a
CB
7515 t = build_decl (FUNCTION_DECL,
7516 ffecom_get_external_identifier_ (s),
7517 ffecom_tree_subr_type); /* Assume subr. */
7518 DECL_EXTERNAL (t) = 1;
7519 TREE_PUBLIC (t) = 1;
5ff904cd 7520
c7e4ee3a
CB
7521 t = start_decl (t, FALSE);
7522 finish_decl (t, NULL_TREE, FALSE);
795232f7 7523
c7e4ee3a
CB
7524 if ((g != NULL)
7525 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
7526 || (ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
7527 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
7528 ffeglobal_set_hook (g, t);
5ff904cd 7529
c7e4ee3a
CB
7530 resume_temporary_allocation ();
7531 pop_obstacks ();
5ff904cd 7532
c7e4ee3a 7533 break;
5ff904cd 7534
c7e4ee3a
CB
7535 default:
7536 assert ("NONE where unexpected" == NULL);
7537 /* Fall through. */
7538 case FFEINFO_whereANY:
7539 break;
7540 }
5ff904cd 7541 break;
5ff904cd 7542
c7e4ee3a
CB
7543 case FFEINFO_kindENTITY:
7544 switch (ffeinfo_where (ffesymbol_info (s)))
7545 {
5ff904cd 7546
c7e4ee3a
CB
7547 case FFEINFO_whereCONSTANT:
7548 /* ~~Debugging info needed? */
7549 assert (!ffecom_transform_only_dummies_);
7550 t = error_mark_node; /* Shouldn't ever see this in expr. */
7551 break;
5ff904cd 7552
c7e4ee3a
CB
7553 case FFEINFO_whereLOCAL:
7554 assert (!ffecom_transform_only_dummies_);
5ff904cd 7555
c7e4ee3a
CB
7556 {
7557 ffestorag st = ffesymbol_storage (s);
7558 tree type;
5ff904cd 7559
c7e4ee3a
CB
7560 if ((st != NULL)
7561 && (ffestorag_size (st) == 0))
7562 {
7563 t = error_mark_node;
7564 break;
7565 }
5ff904cd 7566
c7e4ee3a
CB
7567 yes = suspend_momentary ();
7568 type = ffecom_type_localvar_ (s, bt, kt);
7569 resume_momentary (yes);
5ff904cd 7570
c7e4ee3a
CB
7571 if (type == error_mark_node)
7572 {
7573 t = error_mark_node;
7574 break;
7575 }
5ff904cd 7576
c7e4ee3a
CB
7577 if ((st != NULL)
7578 && (ffestorag_parent (st) != NULL))
7579 { /* Child of EQUIVALENCE parent. */
7580 ffestorag est;
7581 tree et;
7582 int yes;
7583 ffetargetOffset offset;
5ff904cd 7584
c7e4ee3a
CB
7585 est = ffestorag_parent (st);
7586 ffecom_transform_equiv_ (est);
5ff904cd 7587
c7e4ee3a
CB
7588 et = ffestorag_hook (est);
7589 assert (et != NULL_TREE);
5ff904cd 7590
c7e4ee3a
CB
7591 if (! TREE_STATIC (et))
7592 put_var_into_stack (et);
5ff904cd 7593
c7e4ee3a 7594 yes = suspend_momentary ();
5ff904cd 7595
c7e4ee3a
CB
7596 offset = ffestorag_modulo (est)
7597 + ffestorag_offset (ffesymbol_storage (s))
7598 - ffestorag_offset (est);
5ff904cd 7599
c7e4ee3a 7600 ffecom_debug_kludge_ (et, "EQUIVALENCE", s, type, offset);
5ff904cd 7601
c7e4ee3a 7602 /* (t_type *) (((char *) &et) + offset) */
5ff904cd 7603
c7e4ee3a
CB
7604 t = convert (string_type_node, /* (char *) */
7605 ffecom_1 (ADDR_EXPR,
7606 build_pointer_type (TREE_TYPE (et)),
7607 et));
7608 t = ffecom_2 (PLUS_EXPR, TREE_TYPE (t),
7609 t,
7610 build_int_2 (offset, 0));
7611 t = convert (build_pointer_type (type),
7612 t);
d50108c7 7613 TREE_CONSTANT (t) = staticp (et);
5ff904cd 7614
c7e4ee3a 7615 addr = TRUE;
5ff904cd 7616
c7e4ee3a
CB
7617 resume_momentary (yes);
7618 }
7619 else
7620 {
7621 tree initexpr;
7622 bool init = ffesymbol_is_init (s);
5ff904cd 7623
c7e4ee3a 7624 yes = suspend_momentary ();
5ff904cd 7625
c7e4ee3a
CB
7626 t = build_decl (VAR_DECL,
7627 ffecom_get_identifier_ (ffesymbol_text (s)),
7628 type);
5ff904cd 7629
c7e4ee3a
CB
7630 if (init
7631 || ffesymbol_namelisted (s)
7632#ifdef FFECOM_sizeMAXSTACKITEM
7633 || ((st != NULL)
7634 && (ffestorag_size (st) > FFECOM_sizeMAXSTACKITEM))
7635#endif
7636 || ((ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
7637 && (ffecom_primary_entry_kind_
7638 != FFEINFO_kindBLOCKDATA)
7639 && (ffesymbol_is_save (s) || ffe_is_saveall ())))
7640 TREE_STATIC (t) = !ffesymbol_attr (s, FFESYMBOL_attrADJUSTABLE);
7641 else
7642 TREE_STATIC (t) = 0; /* No need to make static. */
5ff904cd 7643
c7e4ee3a
CB
7644 if (init || ffe_is_init_local_zero ())
7645 DECL_INITIAL (t) = error_mark_node;
5ff904cd 7646
c7e4ee3a
CB
7647 /* Keep -Wunused from complaining about var if it
7648 is used as sfunc arg or DATA implied-DO. */
7649 if (ffesymbol_attrs (s) & FFESYMBOL_attrsSFARG)
7650 DECL_IN_SYSTEM_HEADER (t) = 1;
5ff904cd 7651
c7e4ee3a 7652 t = start_decl (t, FALSE);
5ff904cd 7653
c7e4ee3a
CB
7654 if (init)
7655 {
7656 if (ffesymbol_init (s) != NULL)
7657 initexpr = ffecom_expr (ffesymbol_init (s));
7658 else
7659 initexpr = ffecom_init_zero_ (t);
7660 }
7661 else if (ffe_is_init_local_zero ())
7662 initexpr = ffecom_init_zero_ (t);
7663 else
7664 initexpr = NULL_TREE; /* Not ref'd if !init. */
5ff904cd 7665
c7e4ee3a 7666 finish_decl (t, initexpr, FALSE);
5ff904cd 7667
c7e4ee3a
CB
7668 if ((st != NULL) && (DECL_SIZE (t) != error_mark_node))
7669 {
7670 tree size_tree;
5ff904cd 7671
c7e4ee3a
CB
7672 size_tree = size_binop (CEIL_DIV_EXPR,
7673 DECL_SIZE (t),
7674 size_int (BITS_PER_UNIT));
7675 assert (TREE_INT_CST_HIGH (size_tree) == 0);
7676 assert (TREE_INT_CST_LOW (size_tree) == ffestorag_size (st));
7677 }
5ff904cd 7678
c7e4ee3a
CB
7679 resume_momentary (yes);
7680 }
7681 }
5ff904cd 7682 break;
5ff904cd 7683
c7e4ee3a
CB
7684 case FFEINFO_whereRESULT:
7685 assert (!ffecom_transform_only_dummies_);
5ff904cd 7686
c7e4ee3a
CB
7687 if (bt == FFEINFO_basictypeCHARACTER)
7688 { /* Result is already in list of dummies, use
7689 it (& length). */
7690 t = ffecom_func_result_;
7691 tlen = ffecom_func_length_;
7692 addr = TRUE;
7693 break;
7694 }
7695 if ((ffecom_num_entrypoints_ == 0)
7696 && (bt == FFEINFO_basictypeCOMPLEX)
7697 && (ffesymbol_is_f2c (ffecom_primary_entry_)))
7698 { /* Result is already in list of dummies, use
7699 it. */
7700 t = ffecom_func_result_;
7701 addr = TRUE;
7702 break;
7703 }
7704 if (ffecom_func_result_ != NULL_TREE)
7705 {
7706 t = ffecom_func_result_;
7707 break;
7708 }
7709 if ((ffecom_num_entrypoints_ != 0)
7710 && (ffecom_master_bt_ == FFEINFO_basictypeNONE))
7711 {
7712 yes = suspend_momentary ();
5ff904cd 7713
c7e4ee3a
CB
7714 assert (ffecom_multi_retval_ != NULL_TREE);
7715 t = ffecom_1 (INDIRECT_REF, ffecom_multi_type_node_,
7716 ffecom_multi_retval_);
7717 t = ffecom_2 (COMPONENT_REF, ffecom_tree_type[bt][kt],
7718 t, ffecom_multi_fields_[bt][kt]);
5ff904cd 7719
c7e4ee3a
CB
7720 resume_momentary (yes);
7721 break;
7722 }
5ff904cd 7723
c7e4ee3a 7724 yes = suspend_momentary ();
5ff904cd 7725
c7e4ee3a
CB
7726 t = build_decl (VAR_DECL,
7727 ffecom_get_identifier_ (ffesymbol_text (s)),
7728 ffecom_tree_type[bt][kt]);
7729 TREE_STATIC (t) = 0; /* Put result on stack. */
7730 t = start_decl (t, FALSE);
7731 finish_decl (t, NULL_TREE, FALSE);
5ff904cd 7732
c7e4ee3a 7733 ffecom_func_result_ = t;
5ff904cd 7734
c7e4ee3a
CB
7735 resume_momentary (yes);
7736 break;
5ff904cd 7737
c7e4ee3a
CB
7738 case FFEINFO_whereDUMMY:
7739 {
7740 tree type;
7741 ffebld dl;
7742 ffebld dim;
7743 tree low;
7744 tree high;
7745 tree old_sizes;
7746 bool adjustable = FALSE; /* Conditionally adjustable? */
5ff904cd 7747
c7e4ee3a
CB
7748 type = ffecom_tree_type[bt][kt];
7749 if (ffesymbol_sfdummyparent (s) != NULL)
7750 {
7751 if (current_function_decl == ffecom_outer_function_decl_)
7752 { /* Exec transition before sfunc
7753 context; get it later. */
7754 break;
7755 }
7756 t = ffecom_get_identifier_ (ffesymbol_text
7757 (ffesymbol_sfdummyparent (s)));
7758 }
7759 else
7760 t = ffecom_get_identifier_ (ffesymbol_text (s));
5ff904cd 7761
c7e4ee3a 7762 assert (ffecom_transform_only_dummies_);
5ff904cd 7763
c7e4ee3a
CB
7764 old_sizes = get_pending_sizes ();
7765 put_pending_sizes (old_sizes);
5ff904cd 7766
c7e4ee3a
CB
7767 if (bt == FFEINFO_basictypeCHARACTER)
7768 tlen = ffecom_char_enhance_arg_ (&type, s);
7769 type = ffecom_check_size_overflow_ (s, type, TRUE);
5ff904cd 7770
c7e4ee3a
CB
7771 for (dl = ffesymbol_dims (s); dl != NULL; dl = ffebld_trail (dl))
7772 {
7773 if (type == error_mark_node)
7774 break;
5ff904cd 7775
c7e4ee3a
CB
7776 dim = ffebld_head (dl);
7777 assert (ffebld_op (dim) == FFEBLD_opBOUNDS);
7778 if ((ffebld_left (dim) == NULL) || ffecom_doing_entry_)
7779 low = ffecom_integer_one_node;
7780 else
7781 low = ffecom_expr (ffebld_left (dim));
7782 assert (ffebld_right (dim) != NULL);
7783 if ((ffebld_op (ffebld_right (dim)) == FFEBLD_opSTAR)
7784 || ffecom_doing_entry_)
7785 {
7786 /* Used to just do high=low. But for ffecom_tree_
7787 canonize_ref_, it probably is important to correctly
7788 assess the size. E.g. given COMPLEX C(*),CFUNC and
7789 C(2)=CFUNC(C), overlap can happen, while it can't
7790 for, say, C(1)=CFUNC(C(2)). */
7791 /* Even more recently used to set to INT_MAX, but that
7792 broke when some overflow checking went into the back
7793 end. Now we just leave the upper bound unspecified. */
7794 high = NULL;
7795 }
7796 else
7797 high = ffecom_expr (ffebld_right (dim));
5ff904cd 7798
c7e4ee3a
CB
7799 /* Determine whether array is conditionally adjustable,
7800 to decide whether back-end magic is needed.
5ff904cd 7801
c7e4ee3a
CB
7802 Normally the front end uses the back-end function
7803 variable_size to wrap SAVE_EXPR's around expressions
7804 affecting the size/shape of an array so that the
7805 size/shape info doesn't change during execution
7806 of the compiled code even though variables and
7807 functions referenced in those expressions might.
5ff904cd 7808
c7e4ee3a
CB
7809 variable_size also makes sure those saved expressions
7810 get evaluated immediately upon entry to the
7811 compiled procedure -- the front end normally doesn't
7812 have to worry about that.
3cf0cea4 7813
c7e4ee3a
CB
7814 However, there is a problem with this that affects
7815 g77's implementation of entry points, and that is
7816 that it is _not_ true that each invocation of the
7817 compiled procedure is permitted to evaluate
7818 array size/shape info -- because it is possible
7819 that, for some invocations, that info is invalid (in
7820 which case it is "promised" -- i.e. a violation of
7821 the Fortran standard -- that the compiled code
7822 won't reference the array or its size/shape
7823 during that particular invocation).
5ff904cd 7824
c7e4ee3a 7825 To phrase this in C terms, consider this gcc function:
5ff904cd 7826
c7e4ee3a
CB
7827 void foo (int *n, float (*a)[*n])
7828 {
7829 // a is "pointer to array ...", fyi.
7830 }
5ff904cd 7831
c7e4ee3a
CB
7832 Suppose that, for some invocations, it is permitted
7833 for a caller of foo to do this:
5ff904cd 7834
c7e4ee3a 7835 foo (NULL, NULL);
5ff904cd 7836
c7e4ee3a
CB
7837 Now the _written_ code for foo can take such a call
7838 into account by either testing explicitly for whether
7839 (a == NULL) || (n == NULL) -- presumably it is
7840 not permitted to reference *a in various fashions
7841 if (n == NULL) I suppose -- or it can avoid it by
7842 looking at other info (other arguments, static/global
7843 data, etc.).
5ff904cd 7844
c7e4ee3a
CB
7845 However, this won't work in gcc 2.5.8 because it'll
7846 automatically emit the code to save the "*n"
7847 expression, which'll yield a NULL dereference for
7848 the "foo (NULL, NULL)" call, something the code
7849 for foo cannot prevent.
5ff904cd 7850
c7e4ee3a
CB
7851 g77 definitely needs to avoid executing such
7852 code anytime the pointer to the adjustable array
7853 is NULL, because even if its bounds expressions
7854 don't have any references to possible "absent"
7855 variables like "*n" -- say all variable references
7856 are to COMMON variables, i.e. global (though in C,
7857 local static could actually make sense) -- the
7858 expressions could yield other run-time problems
7859 for allowably "dead" values in those variables.
5ff904cd 7860
c7e4ee3a
CB
7861 For example, let's consider a more complicated
7862 version of foo:
5ff904cd 7863
c7e4ee3a
CB
7864 extern int i;
7865 extern int j;
5ff904cd 7866
c7e4ee3a
CB
7867 void foo (float (*a)[i/j])
7868 {
7869 ...
7870 }
5ff904cd 7871
c7e4ee3a
CB
7872 The above is (essentially) quite valid for Fortran
7873 but, again, for a call like "foo (NULL);", it is
7874 permitted for i and j to be undefined when the
7875 call is made. If j happened to be zero, for
7876 example, emitting the code to evaluate "i/j"
7877 could result in a run-time error.
5ff904cd 7878
c7e4ee3a
CB
7879 Offhand, though I don't have my F77 or F90
7880 standards handy, it might even be valid for a
7881 bounds expression to contain a function reference,
7882 in which case I doubt it is permitted for an
7883 implementation to invoke that function in the
7884 Fortran case involved here (invocation of an
7885 alternate ENTRY point that doesn't have the adjustable
7886 array as one of its arguments).
5ff904cd 7887
c7e4ee3a
CB
7888 So, the code that the compiler would normally emit
7889 to preevaluate the size/shape info for an
7890 adjustable array _must not_ be executed at run time
7891 in certain cases. Specifically, for Fortran,
7892 the case is when the pointer to the adjustable
7893 array == NULL. (For gnu-ish C, it might be nice
7894 for the source code itself to specify an expression
7895 that, if TRUE, inhibits execution of the code. Or
7896 reverse the sense for elegance.)
5ff904cd 7897
c7e4ee3a
CB
7898 (Note that g77 could use a different test than NULL,
7899 actually, since it happens to always pass an
7900 integer to the called function that specifies which
7901 entry point is being invoked. Hmm, this might
7902 solve the next problem.)
7903
7904 One way a user could, I suppose, write "foo" so
7905 it works is to insert COND_EXPR's for the
7906 size/shape info so the dangerous stuff isn't
7907 actually done, as in:
7908
7909 void foo (int *n, float (*a)[(a == NULL) ? 0 : *n])
7910 {
7911 ...
7912 }
5ff904cd 7913
c7e4ee3a
CB
7914 The next problem is that the front end needs to
7915 be able to tell the back end about the array's
7916 decl _before_ it tells it about the conditional
7917 expression to inhibit evaluation of size/shape info,
7918 as shown above.
5ff904cd 7919
c7e4ee3a
CB
7920 To solve this, the front end needs to be able
7921 to give the back end the expression to inhibit
7922 generation of the preevaluation code _after_
7923 it makes the decl for the adjustable array.
5ff904cd 7924
c7e4ee3a
CB
7925 Until then, the above example using the COND_EXPR
7926 doesn't pass muster with gcc because the "(a == NULL)"
7927 part has a reference to "a", which is still
7928 undefined at that point.
5ff904cd 7929
c7e4ee3a
CB
7930 g77 will therefore use a different mechanism in the
7931 meantime. */
5ff904cd 7932
c7e4ee3a
CB
7933 if (!adjustable
7934 && ((TREE_CODE (low) != INTEGER_CST)
7935 || (high && TREE_CODE (high) != INTEGER_CST)))
7936 adjustable = TRUE;
5ff904cd 7937
c7e4ee3a
CB
7938#if 0 /* Old approach -- see below. */
7939 if (TREE_CODE (low) != INTEGER_CST)
7940 low = ffecom_3 (COND_EXPR, integer_type_node,
7941 ffecom_adjarray_passed_ (s),
7942 low,
7943 ffecom_integer_zero_node);
5ff904cd 7944
c7e4ee3a
CB
7945 if (high && TREE_CODE (high) != INTEGER_CST)
7946 high = ffecom_3 (COND_EXPR, integer_type_node,
7947 ffecom_adjarray_passed_ (s),
7948 high,
7949 ffecom_integer_zero_node);
7950#endif
5ff904cd 7951
c7e4ee3a
CB
7952 /* ~~~gcc/stor-layout.c (layout_type) should do this,
7953 probably. Fixes 950302-1.f. */
5ff904cd 7954
c7e4ee3a
CB
7955 if (TREE_CODE (low) != INTEGER_CST)
7956 low = variable_size (low);
5ff904cd 7957
c7e4ee3a
CB
7958 /* ~~~Similarly, this fixes dumb0.f. The C front end
7959 does this, which is why dumb0.c would work. */
5ff904cd 7960
c7e4ee3a
CB
7961 if (high && TREE_CODE (high) != INTEGER_CST)
7962 high = variable_size (high);
5ff904cd 7963
c7e4ee3a
CB
7964 type
7965 = build_array_type
7966 (type,
7967 build_range_type (ffecom_integer_type_node,
7968 low, high));
7969 type = ffecom_check_size_overflow_ (s, type, TRUE);
7970 }
5ff904cd 7971
c7e4ee3a
CB
7972 if (type == error_mark_node)
7973 {
7974 t = error_mark_node;
7975 break;
7976 }
5ff904cd 7977
c7e4ee3a
CB
7978 if ((ffesymbol_sfdummyparent (s) == NULL)
7979 || (ffesymbol_basictype (s) == FFEINFO_basictypeCHARACTER))
7980 {
7981 type = build_pointer_type (type);
7982 addr = TRUE;
7983 }
5ff904cd 7984
c7e4ee3a 7985 t = build_decl (PARM_DECL, t, type);
5ff904cd 7986#if BUILT_FOR_270
c7e4ee3a 7987 DECL_ARTIFICIAL (t) = 1;
5ff904cd 7988#endif
5ff904cd 7989
c7e4ee3a
CB
7990 /* If this arg is present in every entry point's list of
7991 dummy args, then we're done. */
5ff904cd 7992
c7e4ee3a
CB
7993 if (ffesymbol_numentries (s)
7994 == (ffecom_num_entrypoints_ + 1))
5ff904cd 7995 break;
5ff904cd 7996
c7e4ee3a 7997#if 1
5ff904cd 7998
c7e4ee3a
CB
7999 /* If variable_size in stor-layout has been called during
8000 the above, then get_pending_sizes should have the
8001 yet-to-be-evaluated saved expressions pending.
8002 Make the whole lot of them get emitted, conditionally
8003 on whether the array decl ("t" above) is not NULL. */
5ff904cd 8004
c7e4ee3a
CB
8005 {
8006 tree sizes = get_pending_sizes ();
8007 tree tem;
5ff904cd 8008
c7e4ee3a
CB
8009 for (tem = sizes;
8010 tem != old_sizes;
8011 tem = TREE_CHAIN (tem))
8012 {
8013 tree temv = TREE_VALUE (tem);
5ff904cd 8014
c7e4ee3a
CB
8015 if (sizes == tem)
8016 sizes = temv;
8017 else
8018 sizes
8019 = ffecom_2 (COMPOUND_EXPR,
8020 TREE_TYPE (sizes),
8021 temv,
8022 sizes);
8023 }
5ff904cd 8024
c7e4ee3a
CB
8025 if (sizes != tem)
8026 {
8027 sizes
8028 = ffecom_3 (COND_EXPR,
8029 TREE_TYPE (sizes),
8030 ffecom_2 (NE_EXPR,
8031 integer_type_node,
8032 t,
8033 null_pointer_node),
8034 sizes,
8035 convert (TREE_TYPE (sizes),
8036 integer_zero_node));
8037 sizes = ffecom_save_tree (sizes);
5ff904cd 8038
c7e4ee3a
CB
8039 sizes
8040 = tree_cons (NULL_TREE, sizes, tem);
8041 }
5ff904cd 8042
c7e4ee3a
CB
8043 if (sizes)
8044 put_pending_sizes (sizes);
8045 }
5ff904cd 8046
c7e4ee3a
CB
8047#else
8048#if 0
8049 if (adjustable
8050 && (ffesymbol_numentries (s)
8051 != ffecom_num_entrypoints_ + 1))
8052 DECL_SOMETHING (t)
8053 = ffecom_2 (NE_EXPR, integer_type_node,
8054 t,
8055 null_pointer_node);
8056#else
8057#if 0
8058 if (adjustable
8059 && (ffesymbol_numentries (s)
8060 != ffecom_num_entrypoints_ + 1))
8061 {
8062 ffebad_start (FFEBAD_MISSING_ADJARRAY_UNSUPPORTED);
8063 ffebad_here (0, ffesymbol_where_line (s),
8064 ffesymbol_where_column (s));
8065 ffebad_string (ffesymbol_text (s));
8066 ffebad_finish ();
8067 }
8068#endif
8069#endif
8070#endif
8071 }
5ff904cd
JL
8072 break;
8073
c7e4ee3a 8074 case FFEINFO_whereCOMMON:
5ff904cd 8075 {
c7e4ee3a
CB
8076 ffesymbol cs;
8077 ffeglobal cg;
8078 tree ct;
5ff904cd
JL
8079 ffestorag st = ffesymbol_storage (s);
8080 tree type;
c7e4ee3a 8081 int yes;
5ff904cd 8082
c7e4ee3a
CB
8083 cs = ffesymbol_common (s); /* The COMMON area itself. */
8084 if (st != NULL) /* Else not laid out. */
5ff904cd 8085 {
c7e4ee3a
CB
8086 ffecom_transform_common_ (cs);
8087 st = ffesymbol_storage (s);
5ff904cd
JL
8088 }
8089
c7e4ee3a 8090 yes = suspend_momentary ();
5ff904cd 8091
c7e4ee3a 8092 type = ffecom_type_localvar_ (s, bt, kt);
5ff904cd 8093
c7e4ee3a
CB
8094 cg = ffesymbol_global (cs); /* The global COMMON info. */
8095 if ((cg == NULL)
8096 || (ffeglobal_type (cg) != FFEGLOBAL_typeCOMMON))
8097 ct = NULL_TREE;
8098 else
8099 ct = ffeglobal_hook (cg); /* The common area's tree. */
5ff904cd 8100
c7e4ee3a
CB
8101 if ((ct == NULL_TREE)
8102 || (st == NULL)
8103 || (type == error_mark_node))
8104 t = error_mark_node;
8105 else
8106 {
8107 ffetargetOffset offset;
8108 ffestorag cst;
5ff904cd 8109
c7e4ee3a
CB
8110 cst = ffestorag_parent (st);
8111 assert (cst == ffesymbol_storage (cs));
5ff904cd 8112
c7e4ee3a
CB
8113 offset = ffestorag_modulo (cst)
8114 + ffestorag_offset (st)
8115 - ffestorag_offset (cst);
5ff904cd 8116
c7e4ee3a 8117 ffecom_debug_kludge_ (ct, "COMMON", s, type, offset);
5ff904cd 8118
c7e4ee3a 8119 /* (t_type *) (((char *) &ct) + offset) */
5ff904cd
JL
8120
8121 t = convert (string_type_node, /* (char *) */
8122 ffecom_1 (ADDR_EXPR,
c7e4ee3a
CB
8123 build_pointer_type (TREE_TYPE (ct)),
8124 ct));
5ff904cd
JL
8125 t = ffecom_2 (PLUS_EXPR, TREE_TYPE (t),
8126 t,
8127 build_int_2 (offset, 0));
8128 t = convert (build_pointer_type (type),
8129 t);
d50108c7 8130 TREE_CONSTANT (t) = 1;
5ff904cd
JL
8131
8132 addr = TRUE;
5ff904cd 8133 }
5ff904cd 8134
c7e4ee3a
CB
8135 resume_momentary (yes);
8136 }
8137 break;
5ff904cd 8138
c7e4ee3a
CB
8139 case FFEINFO_whereIMMEDIATE:
8140 case FFEINFO_whereGLOBAL:
8141 case FFEINFO_whereFLEETING:
8142 case FFEINFO_whereFLEETING_CADDR:
8143 case FFEINFO_whereFLEETING_IADDR:
8144 case FFEINFO_whereINTRINSIC:
8145 case FFEINFO_whereCONSTANT_SUBOBJECT:
8146 default:
8147 assert ("ENTITY where unheard of" == NULL);
8148 /* Fall through. */
8149 case FFEINFO_whereANY:
8150 t = error_mark_node;
8151 break;
8152 }
8153 break;
5ff904cd 8154
c7e4ee3a
CB
8155 case FFEINFO_kindFUNCTION:
8156 switch (ffeinfo_where (ffesymbol_info (s)))
8157 {
8158 case FFEINFO_whereLOCAL: /* Me. */
8159 assert (!ffecom_transform_only_dummies_);
8160 t = current_function_decl;
5ff904cd
JL
8161 break;
8162
c7e4ee3a 8163 case FFEINFO_whereGLOBAL:
5ff904cd
JL
8164 assert (!ffecom_transform_only_dummies_);
8165
c7e4ee3a
CB
8166 if (((g = ffesymbol_global (s)) != NULL)
8167 && ((ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
8168 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
8169 && (ffeglobal_hook (g) != NULL_TREE)
8170 && ffe_is_globals ())
5ff904cd 8171 {
c7e4ee3a 8172 t = ffeglobal_hook (g);
5ff904cd
JL
8173 break;
8174 }
5ff904cd 8175
c7e4ee3a
CB
8176 push_obstacks_nochange ();
8177 end_temporary_allocation ();
5ff904cd 8178
c7e4ee3a
CB
8179 if (ffesymbol_is_f2c (s)
8180 && (ffesymbol_where (s) != FFEINFO_whereCONSTANT))
8181 t = ffecom_tree_fun_type[bt][kt];
8182 else
8183 t = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
5ff904cd 8184
c7e4ee3a
CB
8185 t = build_decl (FUNCTION_DECL,
8186 ffecom_get_external_identifier_ (s),
8187 t);
8188 DECL_EXTERNAL (t) = 1;
8189 TREE_PUBLIC (t) = 1;
5ff904cd 8190
5ff904cd
JL
8191 t = start_decl (t, FALSE);
8192 finish_decl (t, NULL_TREE, FALSE);
8193
c7e4ee3a
CB
8194 if ((g != NULL)
8195 && ((ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
8196 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
8197 ffeglobal_set_hook (g, t);
8198
8199 resume_temporary_allocation ();
8200 pop_obstacks ();
5ff904cd 8201
5ff904cd
JL
8202 break;
8203
8204 case FFEINFO_whereDUMMY:
c7e4ee3a 8205 assert (ffecom_transform_only_dummies_);
5ff904cd 8206
c7e4ee3a
CB
8207 if (ffesymbol_is_f2c (s)
8208 && (ffesymbol_where (s) != FFEINFO_whereCONSTANT))
8209 t = ffecom_tree_ptr_to_fun_type[bt][kt];
8210 else
8211 t = build_pointer_type
8212 (build_function_type (ffecom_tree_type[bt][kt], NULL_TREE));
8213
8214 t = build_decl (PARM_DECL,
8215 ffecom_get_identifier_ (ffesymbol_text (s)),
8216 t);
8217#if BUILT_FOR_270
8218 DECL_ARTIFICIAL (t) = 1;
8219#endif
8220 addr = TRUE;
8221 break;
8222
8223 case FFEINFO_whereCONSTANT: /* Statement function. */
8224 assert (!ffecom_transform_only_dummies_);
8225 t = ffecom_gen_sfuncdef_ (s, bt, kt);
8226 break;
8227
8228 case FFEINFO_whereINTRINSIC:
8229 assert (!ffecom_transform_only_dummies_);
8230 break; /* Let actual references generate their
8231 decls. */
8232
8233 default:
8234 assert ("FUNCTION where unheard of" == NULL);
8235 /* Fall through. */
8236 case FFEINFO_whereANY:
8237 t = error_mark_node;
8238 break;
8239 }
8240 break;
8241
8242 case FFEINFO_kindSUBROUTINE:
8243 switch (ffeinfo_where (ffesymbol_info (s)))
8244 {
8245 case FFEINFO_whereLOCAL: /* Me. */
8246 assert (!ffecom_transform_only_dummies_);
8247 t = current_function_decl;
8248 break;
5ff904cd 8249
c7e4ee3a
CB
8250 case FFEINFO_whereGLOBAL:
8251 assert (!ffecom_transform_only_dummies_);
5ff904cd 8252
c7e4ee3a
CB
8253 if (((g = ffesymbol_global (s)) != NULL)
8254 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
8255 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
8256 && (ffeglobal_hook (g) != NULL_TREE)
8257 && ffe_is_globals ())
8258 {
8259 t = ffeglobal_hook (g);
8260 break;
8261 }
5ff904cd 8262
c7e4ee3a
CB
8263 push_obstacks_nochange ();
8264 end_temporary_allocation ();
5ff904cd 8265
c7e4ee3a
CB
8266 t = build_decl (FUNCTION_DECL,
8267 ffecom_get_external_identifier_ (s),
8268 ffecom_tree_subr_type);
8269 DECL_EXTERNAL (t) = 1;
8270 TREE_PUBLIC (t) = 1;
5ff904cd 8271
c7e4ee3a
CB
8272 t = start_decl (t, FALSE);
8273 finish_decl (t, NULL_TREE, FALSE);
5ff904cd 8274
c7e4ee3a
CB
8275 if ((g != NULL)
8276 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
8277 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
8278 ffeglobal_set_hook (g, t);
5ff904cd 8279
c7e4ee3a
CB
8280 resume_temporary_allocation ();
8281 pop_obstacks ();
5ff904cd 8282
c7e4ee3a 8283 break;
5ff904cd 8284
c7e4ee3a
CB
8285 case FFEINFO_whereDUMMY:
8286 assert (ffecom_transform_only_dummies_);
5ff904cd 8287
c7e4ee3a
CB
8288 t = build_decl (PARM_DECL,
8289 ffecom_get_identifier_ (ffesymbol_text (s)),
8290 ffecom_tree_ptr_to_subr_type);
8291#if BUILT_FOR_270
8292 DECL_ARTIFICIAL (t) = 1;
8293#endif
8294 addr = TRUE;
8295 break;
5ff904cd 8296
c7e4ee3a
CB
8297 case FFEINFO_whereINTRINSIC:
8298 assert (!ffecom_transform_only_dummies_);
8299 break; /* Let actual references generate their
8300 decls. */
5ff904cd 8301
c7e4ee3a
CB
8302 default:
8303 assert ("SUBROUTINE where unheard of" == NULL);
8304 /* Fall through. */
8305 case FFEINFO_whereANY:
8306 t = error_mark_node;
8307 break;
8308 }
8309 break;
5ff904cd 8310
c7e4ee3a
CB
8311 case FFEINFO_kindPROGRAM:
8312 switch (ffeinfo_where (ffesymbol_info (s)))
8313 {
8314 case FFEINFO_whereLOCAL: /* Me. */
8315 assert (!ffecom_transform_only_dummies_);
8316 t = current_function_decl;
8317 break;
5ff904cd 8318
c7e4ee3a
CB
8319 case FFEINFO_whereCOMMON:
8320 case FFEINFO_whereDUMMY:
8321 case FFEINFO_whereGLOBAL:
8322 case FFEINFO_whereRESULT:
8323 case FFEINFO_whereFLEETING:
8324 case FFEINFO_whereFLEETING_CADDR:
8325 case FFEINFO_whereFLEETING_IADDR:
8326 case FFEINFO_whereIMMEDIATE:
8327 case FFEINFO_whereINTRINSIC:
8328 case FFEINFO_whereCONSTANT:
8329 case FFEINFO_whereCONSTANT_SUBOBJECT:
8330 default:
8331 assert ("PROGRAM where unheard of" == NULL);
8332 /* Fall through. */
8333 case FFEINFO_whereANY:
8334 t = error_mark_node;
8335 break;
8336 }
8337 break;
5ff904cd 8338
c7e4ee3a
CB
8339 case FFEINFO_kindBLOCKDATA:
8340 switch (ffeinfo_where (ffesymbol_info (s)))
8341 {
8342 case FFEINFO_whereLOCAL: /* Me. */
8343 assert (!ffecom_transform_only_dummies_);
8344 t = current_function_decl;
8345 break;
5ff904cd 8346
c7e4ee3a
CB
8347 case FFEINFO_whereGLOBAL:
8348 assert (!ffecom_transform_only_dummies_);
5ff904cd 8349
c7e4ee3a
CB
8350 push_obstacks_nochange ();
8351 end_temporary_allocation ();
5ff904cd 8352
c7e4ee3a
CB
8353 t = build_decl (FUNCTION_DECL,
8354 ffecom_get_external_identifier_ (s),
8355 ffecom_tree_blockdata_type);
8356 DECL_EXTERNAL (t) = 1;
8357 TREE_PUBLIC (t) = 1;
5ff904cd 8358
c7e4ee3a
CB
8359 t = start_decl (t, FALSE);
8360 finish_decl (t, NULL_TREE, FALSE);
5ff904cd 8361
c7e4ee3a
CB
8362 resume_temporary_allocation ();
8363 pop_obstacks ();
5ff904cd 8364
c7e4ee3a 8365 break;
5ff904cd 8366
c7e4ee3a
CB
8367 case FFEINFO_whereCOMMON:
8368 case FFEINFO_whereDUMMY:
8369 case FFEINFO_whereRESULT:
8370 case FFEINFO_whereFLEETING:
8371 case FFEINFO_whereFLEETING_CADDR:
8372 case FFEINFO_whereFLEETING_IADDR:
8373 case FFEINFO_whereIMMEDIATE:
8374 case FFEINFO_whereINTRINSIC:
8375 case FFEINFO_whereCONSTANT:
8376 case FFEINFO_whereCONSTANT_SUBOBJECT:
8377 default:
8378 assert ("BLOCKDATA where unheard of" == NULL);
8379 /* Fall through. */
8380 case FFEINFO_whereANY:
8381 t = error_mark_node;
8382 break;
8383 }
8384 break;
5ff904cd 8385
c7e4ee3a
CB
8386 case FFEINFO_kindCOMMON:
8387 switch (ffeinfo_where (ffesymbol_info (s)))
8388 {
8389 case FFEINFO_whereLOCAL:
8390 assert (!ffecom_transform_only_dummies_);
8391 ffecom_transform_common_ (s);
8392 break;
8393
8394 case FFEINFO_whereNONE:
8395 case FFEINFO_whereCOMMON:
8396 case FFEINFO_whereDUMMY:
8397 case FFEINFO_whereGLOBAL:
8398 case FFEINFO_whereRESULT:
8399 case FFEINFO_whereFLEETING:
8400 case FFEINFO_whereFLEETING_CADDR:
8401 case FFEINFO_whereFLEETING_IADDR:
8402 case FFEINFO_whereIMMEDIATE:
8403 case FFEINFO_whereINTRINSIC:
8404 case FFEINFO_whereCONSTANT:
8405 case FFEINFO_whereCONSTANT_SUBOBJECT:
8406 default:
8407 assert ("COMMON where unheard of" == NULL);
8408 /* Fall through. */
8409 case FFEINFO_whereANY:
8410 t = error_mark_node;
8411 break;
8412 }
8413 break;
5ff904cd 8414
c7e4ee3a
CB
8415 case FFEINFO_kindCONSTRUCT:
8416 switch (ffeinfo_where (ffesymbol_info (s)))
8417 {
8418 case FFEINFO_whereLOCAL:
8419 assert (!ffecom_transform_only_dummies_);
8420 break;
5ff904cd 8421
c7e4ee3a
CB
8422 case FFEINFO_whereNONE:
8423 case FFEINFO_whereCOMMON:
8424 case FFEINFO_whereDUMMY:
8425 case FFEINFO_whereGLOBAL:
8426 case FFEINFO_whereRESULT:
8427 case FFEINFO_whereFLEETING:
8428 case FFEINFO_whereFLEETING_CADDR:
8429 case FFEINFO_whereFLEETING_IADDR:
8430 case FFEINFO_whereIMMEDIATE:
8431 case FFEINFO_whereINTRINSIC:
8432 case FFEINFO_whereCONSTANT:
8433 case FFEINFO_whereCONSTANT_SUBOBJECT:
8434 default:
8435 assert ("CONSTRUCT where unheard of" == NULL);
8436 /* Fall through. */
8437 case FFEINFO_whereANY:
8438 t = error_mark_node;
8439 break;
8440 }
8441 break;
5ff904cd 8442
c7e4ee3a
CB
8443 case FFEINFO_kindNAMELIST:
8444 switch (ffeinfo_where (ffesymbol_info (s)))
8445 {
8446 case FFEINFO_whereLOCAL:
8447 assert (!ffecom_transform_only_dummies_);
8448 t = ffecom_transform_namelist_ (s);
8449 break;
5ff904cd 8450
c7e4ee3a
CB
8451 case FFEINFO_whereNONE:
8452 case FFEINFO_whereCOMMON:
8453 case FFEINFO_whereDUMMY:
8454 case FFEINFO_whereGLOBAL:
8455 case FFEINFO_whereRESULT:
8456 case FFEINFO_whereFLEETING:
8457 case FFEINFO_whereFLEETING_CADDR:
8458 case FFEINFO_whereFLEETING_IADDR:
8459 case FFEINFO_whereIMMEDIATE:
8460 case FFEINFO_whereINTRINSIC:
8461 case FFEINFO_whereCONSTANT:
8462 case FFEINFO_whereCONSTANT_SUBOBJECT:
8463 default:
8464 assert ("NAMELIST where unheard of" == NULL);
8465 /* Fall through. */
8466 case FFEINFO_whereANY:
8467 t = error_mark_node;
8468 break;
8469 }
8470 break;
5ff904cd 8471
c7e4ee3a
CB
8472 default:
8473 assert ("kind unheard of" == NULL);
8474 /* Fall through. */
8475 case FFEINFO_kindANY:
8476 t = error_mark_node;
8477 break;
8478 }
5ff904cd 8479
c7e4ee3a
CB
8480 ffesymbol_hook (s).decl_tree = t;
8481 ffesymbol_hook (s).length_tree = tlen;
8482 ffesymbol_hook (s).addr = addr;
5ff904cd 8483
c7e4ee3a
CB
8484 lineno = old_lineno;
8485 input_filename = old_input_filename;
5ff904cd 8486
c7e4ee3a
CB
8487 return s;
8488}
5ff904cd 8489
5ff904cd 8490#endif
c7e4ee3a 8491/* Transform into ASSIGNable symbol.
5ff904cd 8492
c7e4ee3a
CB
8493 Symbol has already been transformed, but for whatever reason, the
8494 resulting decl_tree has been deemed not usable for an ASSIGN target.
8495 (E.g. it isn't wide enough to hold a pointer.) So, here we invent
8496 another local symbol of type void * and stuff that in the assign_tree
8497 argument. The F77/F90 standards allow this implementation. */
5ff904cd 8498
c7e4ee3a
CB
8499#if FFECOM_targetCURRENT == FFECOM_targetGCC
8500static ffesymbol
8501ffecom_sym_transform_assign_ (ffesymbol s)
8502{
8503 tree t; /* Transformed thingy. */
8504 int yes;
8505 int old_lineno = lineno;
8506 char *old_input_filename = input_filename;
5ff904cd 8507
c7e4ee3a
CB
8508 if (ffesymbol_sfdummyparent (s) == NULL)
8509 {
8510 input_filename = ffesymbol_where_filename (s);
8511 lineno = ffesymbol_where_filelinenum (s);
8512 }
8513 else
8514 {
8515 ffesymbol sf = ffesymbol_sfdummyparent (s);
5ff904cd 8516
c7e4ee3a
CB
8517 input_filename = ffesymbol_where_filename (sf);
8518 lineno = ffesymbol_where_filelinenum (sf);
8519 }
5ff904cd 8520
c7e4ee3a 8521 assert (!ffecom_transform_only_dummies_);
5ff904cd 8522
c7e4ee3a 8523 yes = suspend_momentary ();
5ff904cd 8524
c7e4ee3a
CB
8525 t = build_decl (VAR_DECL,
8526 ffecom_get_invented_identifier ("__g77_ASSIGN_%s",
8527 ffesymbol_text (s),
8528 -1),
8529 TREE_TYPE (null_pointer_node));
5ff904cd 8530
c7e4ee3a
CB
8531 switch (ffesymbol_where (s))
8532 {
8533 case FFEINFO_whereLOCAL:
8534 /* Unlike for regular vars, SAVE status is easy to determine for
8535 ASSIGNed vars, since there's no initialization, there's no
8536 effective storage association (so "SAVE J" does not apply to
8537 K even given "EQUIVALENCE (J,K)"), there's no size issue
8538 to worry about, etc. */
8539 if ((ffesymbol_is_save (s) || ffe_is_saveall ())
8540 && (ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
8541 && (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA))
8542 TREE_STATIC (t) = 1; /* SAVEd in proc, make static. */
8543 else
8544 TREE_STATIC (t) = 0; /* No need to make static. */
8545 break;
5ff904cd 8546
c7e4ee3a
CB
8547 case FFEINFO_whereCOMMON:
8548 TREE_STATIC (t) = 1; /* Assume COMMONs always SAVEd. */
8549 break;
5ff904cd 8550
c7e4ee3a
CB
8551 case FFEINFO_whereDUMMY:
8552 /* Note that twinning a DUMMY means the caller won't see
8553 the ASSIGNed value. But both F77 and F90 allow implementations
8554 to do this, i.e. disallow Fortran code that would try and
8555 take advantage of actually putting a label into a variable
8556 via a dummy argument (or any other storage association, for
8557 that matter). */
8558 TREE_STATIC (t) = 0;
8559 break;
5ff904cd 8560
c7e4ee3a
CB
8561 default:
8562 TREE_STATIC (t) = 0;
8563 break;
8564 }
5ff904cd 8565
c7e4ee3a
CB
8566 t = start_decl (t, FALSE);
8567 finish_decl (t, NULL_TREE, FALSE);
5ff904cd 8568
c7e4ee3a 8569 resume_momentary (yes);
5ff904cd 8570
c7e4ee3a 8571 ffesymbol_hook (s).assign_tree = t;
5ff904cd 8572
c7e4ee3a
CB
8573 lineno = old_lineno;
8574 input_filename = old_input_filename;
5ff904cd 8575
c7e4ee3a
CB
8576 return s;
8577}
5ff904cd 8578
c7e4ee3a
CB
8579#endif
8580/* Implement COMMON area in back end.
5ff904cd 8581
c7e4ee3a
CB
8582 Because COMMON-based variables can be referenced in the dimension
8583 expressions of dummy (adjustable) arrays, and because dummies
8584 (in the gcc back end) need to be put in the outer binding level
8585 of a function (which has two binding levels, the outer holding
8586 the dummies and the inner holding the other vars), special care
8587 must be taken to handle COMMON areas.
5ff904cd 8588
c7e4ee3a
CB
8589 The current strategy is basically to always tell the back end about
8590 the COMMON area as a top-level external reference to just a block
8591 of storage of the master type of that area (e.g. integer, real,
8592 character, whatever -- not a structure). As a distinct action,
8593 if initial values are provided, tell the back end about the area
8594 as a top-level non-external (initialized) area and remember not to
8595 allow further initialization or expansion of the area. Meanwhile,
8596 if no initialization happens at all, tell the back end about
8597 the largest size we've seen declared so the space does get reserved.
8598 (This function doesn't handle all that stuff, but it does some
8599 of the important things.)
5ff904cd 8600
c7e4ee3a
CB
8601 Meanwhile, for COMMON variables themselves, just keep creating
8602 references like *((float *) (&common_area + offset)) each time
8603 we reference the variable. In other words, don't make a VAR_DECL
8604 or any kind of component reference (like we used to do before 0.4),
8605 though we might do that as well just for debugging purposes (and
8606 stuff the rtl with the appropriate offset expression). */
5ff904cd 8607
c7e4ee3a
CB
8608#if FFECOM_targetCURRENT == FFECOM_targetGCC
8609static void
8610ffecom_transform_common_ (ffesymbol s)
8611{
8612 ffestorag st = ffesymbol_storage (s);
8613 ffeglobal g = ffesymbol_global (s);
8614 tree cbt;
8615 tree cbtype;
8616 tree init;
8617 tree high;
8618 bool is_init = ffestorag_is_init (st);
5ff904cd 8619
c7e4ee3a 8620 assert (st != NULL);
5ff904cd 8621
c7e4ee3a
CB
8622 if ((g == NULL)
8623 || (ffeglobal_type (g) != FFEGLOBAL_typeCOMMON))
8624 return;
5ff904cd 8625
c7e4ee3a 8626 /* First update the size of the area in global terms. */
5ff904cd 8627
c7e4ee3a 8628 ffeglobal_size_common (s, ffestorag_size (st));
5ff904cd 8629
c7e4ee3a
CB
8630 if (!ffeglobal_common_init (g))
8631 is_init = FALSE; /* No explicit init, don't let erroneous joins init. */
5ff904cd 8632
c7e4ee3a 8633 cbt = ffeglobal_hook (g);
5ff904cd 8634
c7e4ee3a
CB
8635 /* If we already have declared this common block for a previous program
8636 unit, and either we already initialized it or we don't have new
8637 initialization for it, just return what we have without changing it. */
5ff904cd 8638
c7e4ee3a
CB
8639 if ((cbt != NULL_TREE)
8640 && (!is_init
8641 || !DECL_EXTERNAL (cbt)))
8642 return;
5ff904cd 8643
c7e4ee3a 8644 /* Process inits. */
5ff904cd 8645
c7e4ee3a
CB
8646 if (is_init)
8647 {
8648 if (ffestorag_init (st) != NULL)
5ff904cd 8649 {
c7e4ee3a 8650 ffebld sexp;
5ff904cd 8651
c7e4ee3a
CB
8652 /* Set the padding for the expression, so ffecom_expr
8653 knows to insert that many zeros. */
8654 switch (ffebld_op (sexp = ffestorag_init (st)))
5ff904cd 8655 {
c7e4ee3a
CB
8656 case FFEBLD_opCONTER:
8657 ffebld_conter_set_pad (sexp, ffestorag_modulo (st));
5ff904cd 8658 break;
5ff904cd 8659
c7e4ee3a
CB
8660 case FFEBLD_opARRTER:
8661 ffebld_arrter_set_pad (sexp, ffestorag_modulo (st));
8662 break;
5ff904cd 8663
c7e4ee3a
CB
8664 case FFEBLD_opACCTER:
8665 ffebld_accter_set_pad (sexp, ffestorag_modulo (st));
8666 break;
5ff904cd 8667
c7e4ee3a
CB
8668 default:
8669 assert ("bad op for cmn init (pad)" == NULL);
8670 break;
8671 }
5ff904cd 8672
c7e4ee3a
CB
8673 init = ffecom_expr (sexp);
8674 if (init == error_mark_node)
8675 { /* Hopefully the back end complained! */
8676 init = NULL_TREE;
8677 if (cbt != NULL_TREE)
8678 return;
8679 }
8680 }
8681 else
8682 init = error_mark_node;
8683 }
8684 else
8685 init = NULL_TREE;
5ff904cd 8686
c7e4ee3a
CB
8687 push_obstacks_nochange ();
8688 end_temporary_allocation ();
5ff904cd 8689
c7e4ee3a 8690 /* cbtype must be permanently allocated! */
5ff904cd 8691
c7e4ee3a
CB
8692 /* Allocate the MAX of the areas so far, seen filewide. */
8693 high = build_int_2 ((ffeglobal_common_size (g)
8694 + ffeglobal_common_pad (g)) - 1, 0);
8695 TREE_TYPE (high) = ffecom_integer_type_node;
5ff904cd 8696
c7e4ee3a
CB
8697 if (init)
8698 cbtype = build_array_type (char_type_node,
8699 build_range_type (integer_type_node,
8700 integer_zero_node,
8701 high));
8702 else
8703 cbtype = build_array_type (char_type_node, NULL_TREE);
5ff904cd 8704
c7e4ee3a
CB
8705 if (cbt == NULL_TREE)
8706 {
8707 cbt
8708 = build_decl (VAR_DECL,
8709 ffecom_get_external_identifier_ (s),
8710 cbtype);
8711 TREE_STATIC (cbt) = 1;
8712 TREE_PUBLIC (cbt) = 1;
8713 }
8714 else
8715 {
8716 assert (is_init);
8717 TREE_TYPE (cbt) = cbtype;
8718 }
8719 DECL_EXTERNAL (cbt) = init ? 0 : 1;
8720 DECL_INITIAL (cbt) = init ? error_mark_node : NULL_TREE;
5ff904cd 8721
c7e4ee3a
CB
8722 cbt = start_decl (cbt, TRUE);
8723 if (ffeglobal_hook (g) != NULL)
8724 assert (cbt == ffeglobal_hook (g));
5ff904cd 8725
c7e4ee3a 8726 assert (!init || !DECL_EXTERNAL (cbt));
5ff904cd 8727
c7e4ee3a
CB
8728 /* Make sure that any type can live in COMMON and be referenced
8729 without getting a bus error. We could pick the most restrictive
8730 alignment of all entities actually placed in the COMMON, but
8731 this seems easy enough. */
5ff904cd 8732
c7e4ee3a 8733 DECL_ALIGN (cbt) = BIGGEST_ALIGNMENT;
5ff904cd 8734
c7e4ee3a
CB
8735 if (is_init && (ffestorag_init (st) == NULL))
8736 init = ffecom_init_zero_ (cbt);
5ff904cd 8737
c7e4ee3a 8738 finish_decl (cbt, init, TRUE);
5ff904cd 8739
c7e4ee3a
CB
8740 if (is_init)
8741 ffestorag_set_init (st, ffebld_new_any ());
5ff904cd 8742
c7e4ee3a
CB
8743 if (init)
8744 {
8745 tree size_tree;
5ff904cd 8746
c7e4ee3a
CB
8747 assert (DECL_SIZE (cbt) != NULL_TREE);
8748 assert (TREE_CODE (DECL_SIZE (cbt)) == INTEGER_CST);
8749 size_tree = size_binop (CEIL_DIV_EXPR,
8750 DECL_SIZE (cbt),
8751 size_int (BITS_PER_UNIT));
8752 assert (TREE_INT_CST_HIGH (size_tree) == 0);
8753 assert (TREE_INT_CST_LOW (size_tree)
8754 == ffeglobal_common_size (g) + ffeglobal_common_pad (g));
8755 }
5ff904cd 8756
c7e4ee3a 8757 ffeglobal_set_hook (g, cbt);
5ff904cd 8758
c7e4ee3a 8759 ffestorag_set_hook (st, cbt);
5ff904cd 8760
c7e4ee3a
CB
8761 resume_temporary_allocation ();
8762 pop_obstacks ();
8763}
5ff904cd 8764
c7e4ee3a
CB
8765#endif
8766/* Make master area for local EQUIVALENCE. */
5ff904cd 8767
c7e4ee3a
CB
8768#if FFECOM_targetCURRENT == FFECOM_targetGCC
8769static void
8770ffecom_transform_equiv_ (ffestorag eqst)
8771{
8772 tree eqt;
8773 tree eqtype;
8774 tree init;
8775 tree high;
8776 bool is_init = ffestorag_is_init (eqst);
8777 int yes;
5ff904cd 8778
c7e4ee3a 8779 assert (eqst != NULL);
5ff904cd 8780
c7e4ee3a 8781 eqt = ffestorag_hook (eqst);
5ff904cd 8782
c7e4ee3a
CB
8783 if (eqt != NULL_TREE)
8784 return;
5ff904cd 8785
c7e4ee3a
CB
8786 /* Process inits. */
8787
8788 if (is_init)
8789 {
8790 if (ffestorag_init (eqst) != NULL)
5ff904cd 8791 {
c7e4ee3a 8792 ffebld sexp;
5ff904cd 8793
c7e4ee3a
CB
8794 /* Set the padding for the expression, so ffecom_expr
8795 knows to insert that many zeros. */
8796 switch (ffebld_op (sexp = ffestorag_init (eqst)))
8797 {
8798 case FFEBLD_opCONTER:
8799 ffebld_conter_set_pad (sexp, ffestorag_modulo (eqst));
8800 break;
5ff904cd 8801
c7e4ee3a
CB
8802 case FFEBLD_opARRTER:
8803 ffebld_arrter_set_pad (sexp, ffestorag_modulo (eqst));
8804 break;
5ff904cd 8805
c7e4ee3a
CB
8806 case FFEBLD_opACCTER:
8807 ffebld_accter_set_pad (sexp, ffestorag_modulo (eqst));
8808 break;
5ff904cd 8809
c7e4ee3a
CB
8810 default:
8811 assert ("bad op for eqv init (pad)" == NULL);
8812 break;
8813 }
5ff904cd 8814
c7e4ee3a
CB
8815 init = ffecom_expr (sexp);
8816 if (init == error_mark_node)
8817 init = NULL_TREE; /* Hopefully the back end complained! */
8818 }
8819 else
8820 init = error_mark_node;
8821 }
8822 else if (ffe_is_init_local_zero ())
8823 init = error_mark_node;
8824 else
8825 init = NULL_TREE;
5ff904cd 8826
c7e4ee3a
CB
8827 ffecom_member_namelisted_ = FALSE;
8828 ffestorag_drive (ffestorag_list_equivs (eqst),
8829 &ffecom_member_phase1_,
8830 eqst);
5ff904cd 8831
c7e4ee3a 8832 yes = suspend_momentary ();
5ff904cd 8833
c7e4ee3a
CB
8834 high = build_int_2 ((ffestorag_size (eqst)
8835 + ffestorag_modulo (eqst)) - 1, 0);
8836 TREE_TYPE (high) = ffecom_integer_type_node;
5ff904cd 8837
c7e4ee3a
CB
8838 eqtype = build_array_type (char_type_node,
8839 build_range_type (ffecom_integer_type_node,
8840 ffecom_integer_zero_node,
8841 high));
8842
8843 eqt = build_decl (VAR_DECL,
8844 ffecom_get_invented_identifier ("__g77_equiv_%s",
8845 ffesymbol_text
8846 (ffestorag_symbol
8847 (eqst)),
8848 -1),
8849 eqtype);
8850 DECL_EXTERNAL (eqt) = 0;
8851 if (is_init
8852 || ffecom_member_namelisted_
8853#ifdef FFECOM_sizeMAXSTACKITEM
8854 || (ffestorag_size (eqst) > FFECOM_sizeMAXSTACKITEM)
8855#endif
8856 || ((ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
8857 && (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA)
8858 && (ffestorag_is_save (eqst) || ffe_is_saveall ())))
8859 TREE_STATIC (eqt) = 1;
8860 else
8861 TREE_STATIC (eqt) = 0;
8862 TREE_PUBLIC (eqt) = 0;
8863 DECL_CONTEXT (eqt) = current_function_decl;
8864 if (init)
8865 DECL_INITIAL (eqt) = error_mark_node;
8866 else
8867 DECL_INITIAL (eqt) = NULL_TREE;
5ff904cd 8868
c7e4ee3a 8869 eqt = start_decl (eqt, FALSE);
5ff904cd 8870
c7e4ee3a
CB
8871 /* Make sure that any type can live in EQUIVALENCE and be referenced
8872 without getting a bus error. We could pick the most restrictive
8873 alignment of all entities actually placed in the EQUIVALENCE, but
8874 this seems easy enough. */
5ff904cd 8875
c7e4ee3a 8876 DECL_ALIGN (eqt) = BIGGEST_ALIGNMENT;
5ff904cd 8877
c7e4ee3a
CB
8878 if ((!is_init && ffe_is_init_local_zero ())
8879 || (is_init && (ffestorag_init (eqst) == NULL)))
8880 init = ffecom_init_zero_ (eqt);
5ff904cd 8881
c7e4ee3a 8882 finish_decl (eqt, init, FALSE);
5ff904cd 8883
c7e4ee3a
CB
8884 if (is_init)
8885 ffestorag_set_init (eqst, ffebld_new_any ());
5ff904cd 8886
c7e4ee3a
CB
8887 {
8888 tree size_tree;
5ff904cd 8889
c7e4ee3a
CB
8890 size_tree = size_binop (CEIL_DIV_EXPR,
8891 DECL_SIZE (eqt),
8892 size_int (BITS_PER_UNIT));
8893 assert (TREE_INT_CST_HIGH (size_tree) == 0);
8894 assert (TREE_INT_CST_LOW (size_tree)
8895 == ffestorag_size (eqst) + ffestorag_modulo (eqst));
8896 }
5ff904cd 8897
c7e4ee3a 8898 ffestorag_set_hook (eqst, eqt);
5ff904cd 8899
c7e4ee3a
CB
8900#ifdef SOMEONE_GETS_DEBUG_SUPPORT_WORKING
8901 ffestorag_drive (ffestorag_list_equivs (eqst),
8902 &ffecom_member_phase2_,
8903 eqst);
8904#endif
8905
8906 resume_momentary (yes);
5ff904cd
JL
8907}
8908
8909#endif
c7e4ee3a 8910/* Implement NAMELIST in back end. See f2c/format.c for more info. */
5ff904cd
JL
8911
8912#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
8913static tree
8914ffecom_transform_namelist_ (ffesymbol s)
5ff904cd 8915{
c7e4ee3a
CB
8916 tree nmlt;
8917 tree nmltype = ffecom_type_namelist_ ();
8918 tree nmlinits;
8919 tree nameinit;
8920 tree varsinit;
8921 tree nvarsinit;
8922 tree field;
8923 tree high;
5ff904cd 8924 int yes;
c7e4ee3a
CB
8925 int i;
8926 static int mynumber = 0;
5ff904cd 8927
c7e4ee3a 8928 yes = suspend_momentary ();
5ff904cd 8929
c7e4ee3a
CB
8930 nmlt = build_decl (VAR_DECL,
8931 ffecom_get_invented_identifier ("__g77_namelist_%d",
8932 NULL, mynumber++),
8933 nmltype);
8934 TREE_STATIC (nmlt) = 1;
8935 DECL_INITIAL (nmlt) = error_mark_node;
5ff904cd 8936
c7e4ee3a 8937 nmlt = start_decl (nmlt, FALSE);
5ff904cd 8938
c7e4ee3a 8939 /* Process inits. */
5ff904cd 8940
c7e4ee3a 8941 i = strlen (ffesymbol_text (s));
5ff904cd 8942
c7e4ee3a
CB
8943 high = build_int_2 (i, 0);
8944 TREE_TYPE (high) = ffecom_f2c_ftnlen_type_node;
8945
8946 nameinit = ffecom_build_f2c_string_ (i + 1,
8947 ffesymbol_text (s));
8948 TREE_TYPE (nameinit)
8949 = build_type_variant
8950 (build_array_type
8951 (char_type_node,
8952 build_range_type (ffecom_f2c_ftnlen_type_node,
8953 ffecom_f2c_ftnlen_one_node,
8954 high)),
8955 1, 0);
8956 TREE_CONSTANT (nameinit) = 1;
8957 TREE_STATIC (nameinit) = 1;
8958 nameinit = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (nameinit)),
8959 nameinit);
8960
8961 varsinit = ffecom_vardesc_array_ (s);
8962 varsinit = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (varsinit)),
8963 varsinit);
8964 TREE_CONSTANT (varsinit) = 1;
8965 TREE_STATIC (varsinit) = 1;
8966
8967 {
8968 ffebld b;
8969
8970 for (i = 0, b = ffesymbol_namelist (s); b != NULL; b = ffebld_trail (b))
8971 ++i;
8972 }
8973 nvarsinit = build_int_2 (i, 0);
8974 TREE_TYPE (nvarsinit) = integer_type_node;
8975 TREE_CONSTANT (nvarsinit) = 1;
8976 TREE_STATIC (nvarsinit) = 1;
8977
8978 nmlinits = build_tree_list ((field = TYPE_FIELDS (nmltype)), nameinit);
8979 TREE_CHAIN (nmlinits) = build_tree_list ((field = TREE_CHAIN (field)),
8980 varsinit);
8981 TREE_CHAIN (TREE_CHAIN (nmlinits))
8982 = build_tree_list ((field = TREE_CHAIN (field)), nvarsinit);
8983
8984 nmlinits = build (CONSTRUCTOR, nmltype, NULL_TREE, nmlinits);
8985 TREE_CONSTANT (nmlinits) = 1;
8986 TREE_STATIC (nmlinits) = 1;
8987
8988 finish_decl (nmlt, nmlinits, FALSE);
8989
8990 nmlt = ffecom_1 (ADDR_EXPR, build_pointer_type (nmltype), nmlt);
8991
8992 resume_momentary (yes);
8993
8994 return nmlt;
8995}
8996
8997#endif
8998
8999/* A subroutine of ffecom_tree_canonize_ref_. The incoming tree is
9000 analyzed on the assumption it is calculating a pointer to be
9001 indirected through. It must return the proper decl and offset,
9002 taking into account different units of measurements for offsets. */
9003
9004#if FFECOM_targetCURRENT == FFECOM_targetGCC
9005static void
9006ffecom_tree_canonize_ptr_ (tree *decl, tree *offset,
9007 tree t)
9008{
9009 switch (TREE_CODE (t))
9010 {
9011 case NOP_EXPR:
9012 case CONVERT_EXPR:
9013 case NON_LVALUE_EXPR:
9014 ffecom_tree_canonize_ptr_ (decl, offset, TREE_OPERAND (t, 0));
5ff904cd
JL
9015 break;
9016
c7e4ee3a
CB
9017 case PLUS_EXPR:
9018 ffecom_tree_canonize_ptr_ (decl, offset, TREE_OPERAND (t, 0));
9019 if ((*decl == NULL_TREE)
9020 || (*decl == error_mark_node))
9021 break;
9022
9023 if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST)
9024 {
9025 /* An offset into COMMON. */
9026 *offset = size_binop (PLUS_EXPR,
9027 *offset,
9028 TREE_OPERAND (t, 1));
9029 /* Convert offset (presumably in bytes) into canonical units
9030 (presumably bits). */
9031 *offset = size_binop (MULT_EXPR,
9032 TYPE_SIZE (TREE_TYPE (TREE_TYPE (t))),
9033 *offset);
9034 break;
9035 }
9036 /* Not a COMMON reference, so an unrecognized pattern. */
9037 *decl = error_mark_node;
5ff904cd
JL
9038 break;
9039
c7e4ee3a
CB
9040 case PARM_DECL:
9041 *decl = t;
9042 *offset = bitsize_int (0L, 0L);
5ff904cd
JL
9043 break;
9044
c7e4ee3a
CB
9045 case ADDR_EXPR:
9046 if (TREE_CODE (TREE_OPERAND (t, 0)) == VAR_DECL)
9047 {
9048 /* A reference to COMMON. */
9049 *decl = TREE_OPERAND (t, 0);
9050 *offset = bitsize_int (0L, 0L);
9051 break;
9052 }
9053 /* Fall through. */
5ff904cd 9054 default:
c7e4ee3a
CB
9055 /* Not a COMMON reference, so an unrecognized pattern. */
9056 *decl = error_mark_node;
5ff904cd
JL
9057 break;
9058 }
c7e4ee3a
CB
9059}
9060#endif
5ff904cd 9061
c7e4ee3a
CB
9062/* Given a tree that is possibly intended for use as an lvalue, return
9063 information representing a canonical view of that tree as a decl, an
9064 offset into that decl, and a size for the lvalue.
5ff904cd 9065
c7e4ee3a
CB
9066 If there's no applicable decl, NULL_TREE is returned for the decl,
9067 and the other fields are left undefined.
5ff904cd 9068
c7e4ee3a
CB
9069 If the tree doesn't fit the recognizable forms, an ERROR_MARK node
9070 is returned for the decl, and the other fields are left undefined.
5ff904cd 9071
c7e4ee3a
CB
9072 Otherwise, the decl returned currently is either a VAR_DECL or a
9073 PARM_DECL.
5ff904cd 9074
c7e4ee3a
CB
9075 The offset returned is always valid, but of course not necessarily
9076 a constant, and not necessarily converted into the appropriate
9077 type, leaving that up to the caller (so as to avoid that overhead
9078 if the decls being looked at are different anyway).
5ff904cd 9079
c7e4ee3a
CB
9080 If the size cannot be determined (e.g. an adjustable array),
9081 an ERROR_MARK node is returned for the size. Otherwise, the
9082 size returned is valid, not necessarily a constant, and not
9083 necessarily converted into the appropriate type as with the
9084 offset.
5ff904cd 9085
c7e4ee3a
CB
9086 Note that the offset and size expressions are expressed in the
9087 base storage units (usually bits) rather than in the units of
9088 the type of the decl, because two decls with different types
9089 might overlap but with apparently non-overlapping array offsets,
9090 whereas converting the array offsets to consistant offsets will
9091 reveal the overlap. */
5ff904cd
JL
9092
9093#if FFECOM_targetCURRENT == FFECOM_targetGCC
9094static void
c7e4ee3a
CB
9095ffecom_tree_canonize_ref_ (tree *decl, tree *offset,
9096 tree *size, tree t)
5ff904cd 9097{
c7e4ee3a
CB
9098 /* The default path is to report a nonexistant decl. */
9099 *decl = NULL_TREE;
5ff904cd 9100
c7e4ee3a 9101 if (t == NULL_TREE)
5ff904cd
JL
9102 return;
9103
c7e4ee3a
CB
9104 switch (TREE_CODE (t))
9105 {
9106 case ERROR_MARK:
9107 case IDENTIFIER_NODE:
9108 case INTEGER_CST:
9109 case REAL_CST:
9110 case COMPLEX_CST:
9111 case STRING_CST:
9112 case CONST_DECL:
9113 case PLUS_EXPR:
9114 case MINUS_EXPR:
9115 case MULT_EXPR:
9116 case TRUNC_DIV_EXPR:
9117 case CEIL_DIV_EXPR:
9118 case FLOOR_DIV_EXPR:
9119 case ROUND_DIV_EXPR:
9120 case TRUNC_MOD_EXPR:
9121 case CEIL_MOD_EXPR:
9122 case FLOOR_MOD_EXPR:
9123 case ROUND_MOD_EXPR:
9124 case RDIV_EXPR:
9125 case EXACT_DIV_EXPR:
9126 case FIX_TRUNC_EXPR:
9127 case FIX_CEIL_EXPR:
9128 case FIX_FLOOR_EXPR:
9129 case FIX_ROUND_EXPR:
9130 case FLOAT_EXPR:
9131 case EXPON_EXPR:
9132 case NEGATE_EXPR:
9133 case MIN_EXPR:
9134 case MAX_EXPR:
9135 case ABS_EXPR:
9136 case FFS_EXPR:
9137 case LSHIFT_EXPR:
9138 case RSHIFT_EXPR:
9139 case LROTATE_EXPR:
9140 case RROTATE_EXPR:
9141 case BIT_IOR_EXPR:
9142 case BIT_XOR_EXPR:
9143 case BIT_AND_EXPR:
9144 case BIT_ANDTC_EXPR:
9145 case BIT_NOT_EXPR:
9146 case TRUTH_ANDIF_EXPR:
9147 case TRUTH_ORIF_EXPR:
9148 case TRUTH_AND_EXPR:
9149 case TRUTH_OR_EXPR:
9150 case TRUTH_XOR_EXPR:
9151 case TRUTH_NOT_EXPR:
9152 case LT_EXPR:
9153 case LE_EXPR:
9154 case GT_EXPR:
9155 case GE_EXPR:
9156 case EQ_EXPR:
9157 case NE_EXPR:
9158 case COMPLEX_EXPR:
9159 case CONJ_EXPR:
9160 case REALPART_EXPR:
9161 case IMAGPART_EXPR:
9162 case LABEL_EXPR:
9163 case COMPONENT_REF:
9164 case COMPOUND_EXPR:
9165 case ADDR_EXPR:
9166 return;
5ff904cd 9167
c7e4ee3a
CB
9168 case VAR_DECL:
9169 case PARM_DECL:
9170 *decl = t;
9171 *offset = bitsize_int (0L, 0L);
9172 *size = TYPE_SIZE (TREE_TYPE (t));
9173 return;
5ff904cd 9174
c7e4ee3a
CB
9175 case ARRAY_REF:
9176 {
9177 tree array = TREE_OPERAND (t, 0);
9178 tree element = TREE_OPERAND (t, 1);
9179 tree init_offset;
9180
9181 if ((array == NULL_TREE)
9182 || (element == NULL_TREE))
9183 {
9184 *decl = error_mark_node;
9185 return;
9186 }
9187
9188 ffecom_tree_canonize_ref_ (decl, &init_offset, size,
9189 array);
9190 if ((*decl == NULL_TREE)
9191 || (*decl == error_mark_node))
9192 return;
9193
9194 *offset = size_binop (MULT_EXPR,
9195 TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))),
9196 size_binop (MINUS_EXPR,
9197 element,
9198 TYPE_MIN_VALUE
9199 (TYPE_DOMAIN
9200 (TREE_TYPE (array)))));
9201
9202 *offset = size_binop (PLUS_EXPR,
9203 init_offset,
9204 *offset);
9205
9206 *size = TYPE_SIZE (TREE_TYPE (t));
9207 return;
9208 }
9209
9210 case INDIRECT_REF:
9211
9212 /* Most of this code is to handle references to COMMON. And so
9213 far that is useful only for calling library functions, since
9214 external (user) functions might reference common areas. But
9215 even calling an external function, it's worthwhile to decode
9216 COMMON references because if not storing into COMMON, we don't
9217 want COMMON-based arguments to gratuitously force use of a
9218 temporary. */
9219
9220 *size = TYPE_SIZE (TREE_TYPE (t));
5ff904cd 9221
c7e4ee3a
CB
9222 ffecom_tree_canonize_ptr_ (decl, offset,
9223 TREE_OPERAND (t, 0));
5ff904cd 9224
c7e4ee3a 9225 return;
5ff904cd 9226
c7e4ee3a
CB
9227 case CONVERT_EXPR:
9228 case NOP_EXPR:
9229 case MODIFY_EXPR:
9230 case NON_LVALUE_EXPR:
9231 case RESULT_DECL:
9232 case FIELD_DECL:
9233 case COND_EXPR: /* More cases than we can handle. */
9234 case SAVE_EXPR:
9235 case REFERENCE_EXPR:
9236 case PREDECREMENT_EXPR:
9237 case PREINCREMENT_EXPR:
9238 case POSTDECREMENT_EXPR:
9239 case POSTINCREMENT_EXPR:
9240 case CALL_EXPR:
9241 default:
9242 *decl = error_mark_node;
9243 return;
9244 }
9245}
9246#endif
5ff904cd 9247
c7e4ee3a 9248/* Do divide operation appropriate to type of operands. */
5ff904cd 9249
c7e4ee3a
CB
9250#if FFECOM_targetCURRENT == FFECOM_targetGCC
9251static tree
9252ffecom_tree_divide_ (tree tree_type, tree left, tree right,
9253 tree dest_tree, ffebld dest, bool *dest_used,
9254 tree hook)
9255{
9256 if ((left == error_mark_node)
9257 || (right == error_mark_node))
9258 return error_mark_node;
a6fa6420 9259
c7e4ee3a
CB
9260 switch (TREE_CODE (tree_type))
9261 {
9262 case INTEGER_TYPE:
9263 return ffecom_2 (TRUNC_DIV_EXPR, tree_type,
9264 left,
9265 right);
a6fa6420 9266
c7e4ee3a
CB
9267 case COMPLEX_TYPE:
9268 {
9269 ffecomGfrt ix;
a6fa6420 9270
c7e4ee3a
CB
9271 if (TREE_TYPE (tree_type)
9272 == ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1])
9273 ix = FFECOM_gfrtDIV_CC; /* Overlapping result okay. */
9274 else
9275 ix = FFECOM_gfrtDIV_ZZ; /* Overlapping result okay. */
a6fa6420 9276
c7e4ee3a
CB
9277 left = ffecom_1 (ADDR_EXPR,
9278 build_pointer_type (TREE_TYPE (left)),
9279 left);
9280 left = build_tree_list (NULL_TREE, left);
9281 right = ffecom_1 (ADDR_EXPR,
9282 build_pointer_type (TREE_TYPE (right)),
9283 right);
9284 right = build_tree_list (NULL_TREE, right);
9285 TREE_CHAIN (left) = right;
a6fa6420 9286
c7e4ee3a
CB
9287 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
9288 ffecom_gfrt_kindtype (ix),
9289 ffe_is_f2c_library (),
9290 tree_type,
9291 left,
9292 dest_tree, dest, dest_used,
9293 NULL_TREE, TRUE, hook);
9294 }
9295 break;
5ff904cd 9296
c7e4ee3a
CB
9297 case RECORD_TYPE:
9298 {
9299 ffecomGfrt ix;
5ff904cd 9300
c7e4ee3a
CB
9301 if (TREE_TYPE (TYPE_FIELDS (tree_type))
9302 == ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1])
9303 ix = FFECOM_gfrtDIV_CC; /* Overlapping result okay. */
9304 else
9305 ix = FFECOM_gfrtDIV_ZZ; /* Overlapping result okay. */
5ff904cd 9306
c7e4ee3a
CB
9307 left = ffecom_1 (ADDR_EXPR,
9308 build_pointer_type (TREE_TYPE (left)),
9309 left);
9310 left = build_tree_list (NULL_TREE, left);
9311 right = ffecom_1 (ADDR_EXPR,
9312 build_pointer_type (TREE_TYPE (right)),
9313 right);
9314 right = build_tree_list (NULL_TREE, right);
9315 TREE_CHAIN (left) = right;
a6fa6420 9316
c7e4ee3a
CB
9317 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
9318 ffecom_gfrt_kindtype (ix),
9319 ffe_is_f2c_library (),
9320 tree_type,
9321 left,
9322 dest_tree, dest, dest_used,
9323 NULL_TREE, TRUE, hook);
9324 }
9325 break;
5ff904cd 9326
c7e4ee3a
CB
9327 default:
9328 return ffecom_2 (RDIV_EXPR, tree_type,
9329 left,
9330 right);
5ff904cd 9331 }
c7e4ee3a 9332}
5ff904cd 9333
c7e4ee3a
CB
9334#endif
9335/* Build type info for non-dummy variable. */
5ff904cd 9336
c7e4ee3a
CB
9337#if FFECOM_targetCURRENT == FFECOM_targetGCC
9338static tree
9339ffecom_type_localvar_ (ffesymbol s, ffeinfoBasictype bt,
9340 ffeinfoKindtype kt)
9341{
9342 tree type;
9343 ffebld dl;
9344 ffebld dim;
9345 tree lowt;
9346 tree hight;
5ff904cd 9347
c7e4ee3a
CB
9348 type = ffecom_tree_type[bt][kt];
9349 if (bt == FFEINFO_basictypeCHARACTER)
9350 {
9351 hight = build_int_2 (ffesymbol_size (s), 0);
9352 TREE_TYPE (hight) = ffecom_f2c_ftnlen_type_node;
5ff904cd 9353
c7e4ee3a
CB
9354 type
9355 = build_array_type
9356 (type,
9357 build_range_type (ffecom_f2c_ftnlen_type_node,
9358 ffecom_f2c_ftnlen_one_node,
9359 hight));
9360 type = ffecom_check_size_overflow_ (s, type, FALSE);
9361 }
5ff904cd 9362
c7e4ee3a
CB
9363 for (dl = ffesymbol_dims (s); dl != NULL; dl = ffebld_trail (dl))
9364 {
9365 if (type == error_mark_node)
9366 break;
5ff904cd 9367
c7e4ee3a
CB
9368 dim = ffebld_head (dl);
9369 assert (ffebld_op (dim) == FFEBLD_opBOUNDS);
5ff904cd 9370
c7e4ee3a
CB
9371 if (ffebld_left (dim) == NULL)
9372 lowt = integer_one_node;
9373 else
9374 lowt = ffecom_expr (ffebld_left (dim));
5ff904cd 9375
c7e4ee3a
CB
9376 if (TREE_CODE (lowt) != INTEGER_CST)
9377 lowt = variable_size (lowt);
5ff904cd 9378
c7e4ee3a
CB
9379 assert (ffebld_right (dim) != NULL);
9380 hight = ffecom_expr (ffebld_right (dim));
5ff904cd 9381
c7e4ee3a
CB
9382 if (TREE_CODE (hight) != INTEGER_CST)
9383 hight = variable_size (hight);
5ff904cd 9384
c7e4ee3a
CB
9385 type = build_array_type (type,
9386 build_range_type (ffecom_integer_type_node,
9387 lowt, hight));
9388 type = ffecom_check_size_overflow_ (s, type, FALSE);
9389 }
5ff904cd 9390
c7e4ee3a 9391 return type;
5ff904cd
JL
9392}
9393
9394#endif
c7e4ee3a 9395/* Build Namelist type. */
5ff904cd 9396
c7e4ee3a
CB
9397#if FFECOM_targetCURRENT == FFECOM_targetGCC
9398static tree
9399ffecom_type_namelist_ ()
9400{
9401 static tree type = NULL_TREE;
5ff904cd 9402
c7e4ee3a
CB
9403 if (type == NULL_TREE)
9404 {
9405 static tree namefield, varsfield, nvarsfield;
9406 tree vardesctype;
5ff904cd 9407
c7e4ee3a 9408 vardesctype = ffecom_type_vardesc_ ();
5ff904cd 9409
c7e4ee3a
CB
9410 push_obstacks_nochange ();
9411 end_temporary_allocation ();
a6fa6420 9412
c7e4ee3a 9413 type = make_node (RECORD_TYPE);
a6fa6420 9414
c7e4ee3a 9415 vardesctype = build_pointer_type (build_pointer_type (vardesctype));
a6fa6420 9416
c7e4ee3a
CB
9417 namefield = ffecom_decl_field (type, NULL_TREE, "name",
9418 string_type_node);
9419 varsfield = ffecom_decl_field (type, namefield, "vars", vardesctype);
9420 nvarsfield = ffecom_decl_field (type, varsfield, "nvars",
9421 integer_type_node);
a6fa6420 9422
c7e4ee3a
CB
9423 TYPE_FIELDS (type) = namefield;
9424 layout_type (type);
a6fa6420 9425
c7e4ee3a
CB
9426 resume_temporary_allocation ();
9427 pop_obstacks ();
5ff904cd 9428 }
5ff904cd 9429
c7e4ee3a
CB
9430 return type;
9431}
5ff904cd 9432
c7e4ee3a 9433#endif
5ff904cd 9434
c7e4ee3a
CB
9435/* Make a copy of a type, assuming caller has switched to the permanent
9436 obstacks and that the type is for an aggregate (array) initializer. */
5ff904cd 9437
c7e4ee3a
CB
9438#if FFECOM_targetCURRENT == FFECOM_targetGCC && 0 /* Not used now. */
9439static tree
9440ffecom_type_permanent_copy_ (tree t)
9441{
9442 tree domain;
9443 tree max;
5ff904cd 9444
c7e4ee3a 9445 assert (TREE_TYPE (t) != NULL_TREE);
5ff904cd 9446
c7e4ee3a 9447 domain = TYPE_DOMAIN (t);
5ff904cd 9448
c7e4ee3a
CB
9449 assert (TREE_CODE (t) == ARRAY_TYPE);
9450 assert (TREE_PERMANENT (TREE_TYPE (t)));
9451 assert (TREE_PERMANENT (TREE_TYPE (domain)));
9452 assert (TREE_PERMANENT (TYPE_MIN_VALUE (domain)));
5ff904cd 9453
c7e4ee3a
CB
9454 max = TYPE_MAX_VALUE (domain);
9455 if (!TREE_PERMANENT (max))
9456 {
9457 assert (TREE_CODE (max) == INTEGER_CST);
5ff904cd 9458
c7e4ee3a
CB
9459 max = build_int_2 (TREE_INT_CST_LOW (max), TREE_INT_CST_HIGH (max));
9460 TREE_TYPE (max) = TREE_TYPE (TYPE_MIN_VALUE (domain));
9461 }
5ff904cd 9462
c7e4ee3a
CB
9463 return build_array_type (TREE_TYPE (t),
9464 build_range_type (TREE_TYPE (domain),
9465 TYPE_MIN_VALUE (domain),
9466 max));
9467}
9468#endif
5ff904cd 9469
c7e4ee3a 9470/* Build Vardesc type. */
5ff904cd 9471
c7e4ee3a
CB
9472#if FFECOM_targetCURRENT == FFECOM_targetGCC
9473static tree
9474ffecom_type_vardesc_ ()
9475{
9476 static tree type = NULL_TREE;
9477 static tree namefield, addrfield, dimsfield, typefield;
5ff904cd 9478
c7e4ee3a
CB
9479 if (type == NULL_TREE)
9480 {
9481 push_obstacks_nochange ();
9482 end_temporary_allocation ();
5ff904cd 9483
c7e4ee3a 9484 type = make_node (RECORD_TYPE);
5ff904cd 9485
c7e4ee3a
CB
9486 namefield = ffecom_decl_field (type, NULL_TREE, "name",
9487 string_type_node);
9488 addrfield = ffecom_decl_field (type, namefield, "addr",
9489 string_type_node);
9490 dimsfield = ffecom_decl_field (type, addrfield, "dims",
9491 ffecom_f2c_ptr_to_ftnlen_type_node);
9492 typefield = ffecom_decl_field (type, dimsfield, "type",
9493 integer_type_node);
5ff904cd 9494
c7e4ee3a
CB
9495 TYPE_FIELDS (type) = namefield;
9496 layout_type (type);
9497
9498 resume_temporary_allocation ();
9499 pop_obstacks ();
9500 }
9501
9502 return type;
5ff904cd
JL
9503}
9504
9505#endif
5ff904cd
JL
9506
9507#if FFECOM_targetCURRENT == FFECOM_targetGCC
9508static tree
c7e4ee3a 9509ffecom_vardesc_ (ffebld expr)
5ff904cd 9510{
c7e4ee3a 9511 ffesymbol s;
5ff904cd 9512
c7e4ee3a
CB
9513 assert (ffebld_op (expr) == FFEBLD_opSYMTER);
9514 s = ffebld_symter (expr);
5ff904cd 9515
c7e4ee3a
CB
9516 if (ffesymbol_hook (s).vardesc_tree == NULL_TREE)
9517 {
9518 int i;
9519 tree vardesctype = ffecom_type_vardesc_ ();
9520 tree var;
9521 tree nameinit;
9522 tree dimsinit;
9523 tree addrinit;
9524 tree typeinit;
9525 tree field;
9526 tree varinits;
9527 int yes;
9528 static int mynumber = 0;
5ff904cd 9529
c7e4ee3a 9530 yes = suspend_momentary ();
5ff904cd 9531
c7e4ee3a
CB
9532 var = build_decl (VAR_DECL,
9533 ffecom_get_invented_identifier ("__g77_vardesc_%d",
9534 NULL, mynumber++),
9535 vardesctype);
9536 TREE_STATIC (var) = 1;
9537 DECL_INITIAL (var) = error_mark_node;
5ff904cd 9538
c7e4ee3a 9539 var = start_decl (var, FALSE);
5ff904cd 9540
c7e4ee3a 9541 /* Process inits. */
5ff904cd 9542
c7e4ee3a
CB
9543 nameinit = ffecom_build_f2c_string_ ((i = strlen (ffesymbol_text (s)))
9544 + 1,
9545 ffesymbol_text (s));
9546 TREE_TYPE (nameinit)
9547 = build_type_variant
9548 (build_array_type
9549 (char_type_node,
9550 build_range_type (integer_type_node,
9551 integer_one_node,
9552 build_int_2 (i, 0))),
9553 1, 0);
9554 TREE_CONSTANT (nameinit) = 1;
9555 TREE_STATIC (nameinit) = 1;
9556 nameinit = ffecom_1 (ADDR_EXPR,
9557 build_pointer_type (TREE_TYPE (nameinit)),
9558 nameinit);
5ff904cd 9559
c7e4ee3a 9560 addrinit = ffecom_arg_ptr_to_expr (expr, &typeinit);
5ff904cd 9561
c7e4ee3a 9562 dimsinit = ffecom_vardesc_dims_ (s);
5ff904cd 9563
c7e4ee3a
CB
9564 if (typeinit == NULL_TREE)
9565 {
9566 ffeinfoBasictype bt = ffesymbol_basictype (s);
9567 ffeinfoKindtype kt = ffesymbol_kindtype (s);
9568 int tc = ffecom_f2c_typecode (bt, kt);
5ff904cd 9569
c7e4ee3a
CB
9570 assert (tc != -1);
9571 typeinit = build_int_2 (tc, (tc < 0) ? -1 : 0);
9572 }
9573 else
9574 typeinit = ffecom_1 (NEGATE_EXPR, TREE_TYPE (typeinit), typeinit);
5ff904cd 9575
c7e4ee3a
CB
9576 varinits = build_tree_list ((field = TYPE_FIELDS (vardesctype)),
9577 nameinit);
9578 TREE_CHAIN (varinits) = build_tree_list ((field = TREE_CHAIN (field)),
9579 addrinit);
9580 TREE_CHAIN (TREE_CHAIN (varinits))
9581 = build_tree_list ((field = TREE_CHAIN (field)), dimsinit);
9582 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (varinits)))
9583 = build_tree_list ((field = TREE_CHAIN (field)), typeinit);
5ff904cd 9584
c7e4ee3a
CB
9585 varinits = build (CONSTRUCTOR, vardesctype, NULL_TREE, varinits);
9586 TREE_CONSTANT (varinits) = 1;
9587 TREE_STATIC (varinits) = 1;
5ff904cd 9588
c7e4ee3a 9589 finish_decl (var, varinits, FALSE);
5ff904cd 9590
c7e4ee3a 9591 var = ffecom_1 (ADDR_EXPR, build_pointer_type (vardesctype), var);
5ff904cd 9592
c7e4ee3a 9593 resume_momentary (yes);
5ff904cd 9594
c7e4ee3a
CB
9595 ffesymbol_hook (s).vardesc_tree = var;
9596 }
5ff904cd 9597
c7e4ee3a
CB
9598 return ffesymbol_hook (s).vardesc_tree;
9599}
5ff904cd 9600
c7e4ee3a 9601#endif
5ff904cd 9602#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
9603static tree
9604ffecom_vardesc_array_ (ffesymbol s)
5ff904cd 9605{
c7e4ee3a
CB
9606 ffebld b;
9607 tree list;
9608 tree item = NULL_TREE;
9609 tree var;
9610 int i;
9611 int yes;
9612 static int mynumber = 0;
5ff904cd 9613
c7e4ee3a
CB
9614 for (i = 0, list = NULL_TREE, b = ffesymbol_namelist (s);
9615 b != NULL;
9616 b = ffebld_trail (b), ++i)
9617 {
9618 tree t;
5ff904cd 9619
c7e4ee3a 9620 t = ffecom_vardesc_ (ffebld_head (b));
5ff904cd 9621
c7e4ee3a
CB
9622 if (list == NULL_TREE)
9623 list = item = build_tree_list (NULL_TREE, t);
9624 else
5ff904cd 9625 {
c7e4ee3a
CB
9626 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
9627 item = TREE_CHAIN (item);
5ff904cd 9628 }
5ff904cd 9629 }
5ff904cd 9630
c7e4ee3a 9631 yes = suspend_momentary ();
5ff904cd 9632
c7e4ee3a
CB
9633 item = build_array_type (build_pointer_type (ffecom_type_vardesc_ ()),
9634 build_range_type (integer_type_node,
9635 integer_one_node,
9636 build_int_2 (i, 0)));
9637 list = build (CONSTRUCTOR, item, NULL_TREE, list);
9638 TREE_CONSTANT (list) = 1;
9639 TREE_STATIC (list) = 1;
5ff904cd 9640
c7e4ee3a
CB
9641 var = ffecom_get_invented_identifier ("__g77_vardesc_array_%d", NULL,
9642 mynumber++);
9643 var = build_decl (VAR_DECL, var, item);
9644 TREE_STATIC (var) = 1;
9645 DECL_INITIAL (var) = error_mark_node;
9646 var = start_decl (var, FALSE);
9647 finish_decl (var, list, FALSE);
5ff904cd 9648
c7e4ee3a 9649 resume_momentary (yes);
5ff904cd 9650
c7e4ee3a
CB
9651 return var;
9652}
5ff904cd 9653
c7e4ee3a
CB
9654#endif
9655#if FFECOM_targetCURRENT == FFECOM_targetGCC
9656static tree
9657ffecom_vardesc_dims_ (ffesymbol s)
9658{
9659 if (ffesymbol_dims (s) == NULL)
9660 return convert (ffecom_f2c_ptr_to_ftnlen_type_node,
9661 integer_zero_node);
5ff904cd 9662
c7e4ee3a
CB
9663 {
9664 ffebld b;
9665 ffebld e;
9666 tree list;
9667 tree backlist;
9668 tree item = NULL_TREE;
9669 tree var;
9670 int yes;
9671 tree numdim;
9672 tree numelem;
9673 tree baseoff = NULL_TREE;
9674 static int mynumber = 0;
9675
9676 numdim = build_int_2 ((int) ffesymbol_rank (s), 0);
9677 TREE_TYPE (numdim) = ffecom_f2c_ftnlen_type_node;
9678
9679 numelem = ffecom_expr (ffesymbol_arraysize (s));
9680 TREE_TYPE (numelem) = ffecom_f2c_ftnlen_type_node;
9681
9682 list = NULL_TREE;
9683 backlist = NULL_TREE;
9684 for (b = ffesymbol_dims (s), e = ffesymbol_extents (s);
9685 b != NULL;
9686 b = ffebld_trail (b), e = ffebld_trail (e))
5ff904cd 9687 {
c7e4ee3a
CB
9688 tree t;
9689 tree low;
9690 tree back;
5ff904cd 9691
c7e4ee3a
CB
9692 if (ffebld_trail (b) == NULL)
9693 t = NULL_TREE;
9694 else
5ff904cd 9695 {
c7e4ee3a
CB
9696 t = convert (ffecom_f2c_ftnlen_type_node,
9697 ffecom_expr (ffebld_head (e)));
5ff904cd 9698
c7e4ee3a
CB
9699 if (list == NULL_TREE)
9700 list = item = build_tree_list (NULL_TREE, t);
9701 else
9702 {
9703 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
9704 item = TREE_CHAIN (item);
9705 }
9706 }
5ff904cd 9707
c7e4ee3a
CB
9708 if (ffebld_left (ffebld_head (b)) == NULL)
9709 low = ffecom_integer_one_node;
9710 else
9711 low = ffecom_expr (ffebld_left (ffebld_head (b)));
9712 low = convert (ffecom_f2c_ftnlen_type_node, low);
5ff904cd 9713
c7e4ee3a
CB
9714 back = build_tree_list (low, t);
9715 TREE_CHAIN (back) = backlist;
9716 backlist = back;
9717 }
5ff904cd 9718
c7e4ee3a
CB
9719 for (item = backlist; item != NULL_TREE; item = TREE_CHAIN (item))
9720 {
9721 if (TREE_VALUE (item) == NULL_TREE)
9722 baseoff = TREE_PURPOSE (item);
9723 else
9724 baseoff = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
9725 TREE_PURPOSE (item),
9726 ffecom_2 (MULT_EXPR,
9727 ffecom_f2c_ftnlen_type_node,
9728 TREE_VALUE (item),
9729 baseoff));
5ff904cd
JL
9730 }
9731
c7e4ee3a 9732 /* backlist now dead, along with all TREE_PURPOSEs on it. */
5ff904cd 9733
c7e4ee3a
CB
9734 baseoff = build_tree_list (NULL_TREE, baseoff);
9735 TREE_CHAIN (baseoff) = list;
5ff904cd 9736
c7e4ee3a
CB
9737 numelem = build_tree_list (NULL_TREE, numelem);
9738 TREE_CHAIN (numelem) = baseoff;
5ff904cd 9739
c7e4ee3a
CB
9740 numdim = build_tree_list (NULL_TREE, numdim);
9741 TREE_CHAIN (numdim) = numelem;
5ff904cd 9742
c7e4ee3a 9743 yes = suspend_momentary ();
5ff904cd 9744
c7e4ee3a
CB
9745 item = build_array_type (ffecom_f2c_ftnlen_type_node,
9746 build_range_type (integer_type_node,
9747 integer_zero_node,
9748 build_int_2
9749 ((int) ffesymbol_rank (s)
9750 + 2, 0)));
9751 list = build (CONSTRUCTOR, item, NULL_TREE, numdim);
9752 TREE_CONSTANT (list) = 1;
9753 TREE_STATIC (list) = 1;
9754
9755 var = ffecom_get_invented_identifier ("__g77_dims_%d", NULL,
9756 mynumber++);
9757 var = build_decl (VAR_DECL, var, item);
9758 TREE_STATIC (var) = 1;
9759 DECL_INITIAL (var) = error_mark_node;
9760 var = start_decl (var, FALSE);
9761 finish_decl (var, list, FALSE);
9762
9763 var = ffecom_1 (ADDR_EXPR, build_pointer_type (item), var);
9764
9765 resume_momentary (yes);
9766
9767 return var;
9768 }
5ff904cd 9769}
c7e4ee3a 9770
5ff904cd 9771#endif
c7e4ee3a
CB
9772/* Essentially does a "fold (build1 (code, type, node))" while checking
9773 for certain housekeeping things.
5ff904cd 9774
c7e4ee3a
CB
9775 NOTE: for building an ADDR_EXPR around a FUNCTION_DECL, use
9776 ffecom_1_fn instead. */
5ff904cd
JL
9777
9778#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
9779tree
9780ffecom_1 (enum tree_code code, tree type, tree node)
5ff904cd 9781{
c7e4ee3a
CB
9782 tree item;
9783
9784 if ((node == error_mark_node)
9785 || (type == error_mark_node))
5ff904cd
JL
9786 return error_mark_node;
9787
c7e4ee3a 9788 if (code == ADDR_EXPR)
5ff904cd 9789 {
c7e4ee3a
CB
9790 if (!mark_addressable (node))
9791 assert ("can't mark_addressable this node!" == NULL);
9792 }
5ff904cd 9793
c7e4ee3a
CB
9794 switch (ffe_is_emulate_complex () ? code : NOP_EXPR)
9795 {
9796 tree realtype;
5ff904cd 9797
c7e4ee3a
CB
9798 case REALPART_EXPR:
9799 item = build (COMPONENT_REF, type, node, TYPE_FIELDS (TREE_TYPE (node)));
5ff904cd
JL
9800 break;
9801
c7e4ee3a
CB
9802 case IMAGPART_EXPR:
9803 item = build (COMPONENT_REF, type, node, TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (node))));
9804 break;
5ff904cd 9805
5ff904cd 9806
c7e4ee3a
CB
9807 case NEGATE_EXPR:
9808 if (TREE_CODE (type) != RECORD_TYPE)
9809 {
9810 item = build1 (code, type, node);
9811 break;
9812 }
9813 node = ffecom_stabilize_aggregate_ (node);
9814 realtype = TREE_TYPE (TYPE_FIELDS (type));
9815 item =
9816 ffecom_2 (COMPLEX_EXPR, type,
9817 ffecom_1 (NEGATE_EXPR, realtype,
9818 ffecom_1 (REALPART_EXPR, realtype,
9819 node)),
9820 ffecom_1 (NEGATE_EXPR, realtype,
9821 ffecom_1 (IMAGPART_EXPR, realtype,
9822 node)));
5ff904cd
JL
9823 break;
9824
9825 default:
c7e4ee3a
CB
9826 item = build1 (code, type, node);
9827 break;
5ff904cd 9828 }
5ff904cd 9829
c7e4ee3a
CB
9830 if (TREE_SIDE_EFFECTS (node))
9831 TREE_SIDE_EFFECTS (item) = 1;
9832 if ((code == ADDR_EXPR) && staticp (node))
9833 TREE_CONSTANT (item) = 1;
9834 return fold (item);
9835}
5ff904cd 9836#endif
5ff904cd 9837
c7e4ee3a
CB
9838/* Like ffecom_1 (ADDR_EXPR, TREE_TYPE (node), node), except
9839 handles TREE_CODE (node) == FUNCTION_DECL. In particular,
9840 does not set TREE_ADDRESSABLE (because calling an inline
9841 function does not mean the function needs to be separately
9842 compiled). */
5ff904cd
JL
9843
9844#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
9845tree
9846ffecom_1_fn (tree node)
5ff904cd 9847{
c7e4ee3a 9848 tree item;
5ff904cd 9849 tree type;
5ff904cd 9850
c7e4ee3a
CB
9851 if (node == error_mark_node)
9852 return error_mark_node;
5ff904cd 9853
c7e4ee3a
CB
9854 type = build_type_variant (TREE_TYPE (node),
9855 TREE_READONLY (node),
9856 TREE_THIS_VOLATILE (node));
9857 item = build1 (ADDR_EXPR,
9858 build_pointer_type (type), node);
9859 if (TREE_SIDE_EFFECTS (node))
9860 TREE_SIDE_EFFECTS (item) = 1;
9861 if (staticp (node))
9862 TREE_CONSTANT (item) = 1;
9863 return fold (item);
5ff904cd 9864}
5ff904cd 9865#endif
c7e4ee3a
CB
9866
9867/* Essentially does a "fold (build (code, type, node1, node2))" while
9868 checking for certain housekeeping things. */
5ff904cd
JL
9869
9870#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
9871tree
9872ffecom_2 (enum tree_code code, tree type, tree node1,
9873 tree node2)
5ff904cd 9874{
c7e4ee3a 9875 tree item;
5ff904cd 9876
c7e4ee3a
CB
9877 if ((node1 == error_mark_node)
9878 || (node2 == error_mark_node)
9879 || (type == error_mark_node))
9880 return error_mark_node;
9881
9882 switch (ffe_is_emulate_complex () ? code : NOP_EXPR)
5ff904cd 9883 {
c7e4ee3a 9884 tree a, b, c, d, realtype;
5ff904cd 9885
c7e4ee3a
CB
9886 case CONJ_EXPR:
9887 assert ("no CONJ_EXPR support yet" == NULL);
9888 return error_mark_node;
5ff904cd 9889
c7e4ee3a
CB
9890 case COMPLEX_EXPR:
9891 item = build_tree_list (TYPE_FIELDS (type), node1);
9892 TREE_CHAIN (item) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), node2);
9893 item = build (CONSTRUCTOR, type, NULL_TREE, item);
9894 break;
5ff904cd 9895
c7e4ee3a
CB
9896 case PLUS_EXPR:
9897 if (TREE_CODE (type) != RECORD_TYPE)
9898 {
9899 item = build (code, type, node1, node2);
9900 break;
9901 }
9902 node1 = ffecom_stabilize_aggregate_ (node1);
9903 node2 = ffecom_stabilize_aggregate_ (node2);
9904 realtype = TREE_TYPE (TYPE_FIELDS (type));
9905 item =
9906 ffecom_2 (COMPLEX_EXPR, type,
9907 ffecom_2 (PLUS_EXPR, realtype,
9908 ffecom_1 (REALPART_EXPR, realtype,
9909 node1),
9910 ffecom_1 (REALPART_EXPR, realtype,
9911 node2)),
9912 ffecom_2 (PLUS_EXPR, realtype,
9913 ffecom_1 (IMAGPART_EXPR, realtype,
9914 node1),
9915 ffecom_1 (IMAGPART_EXPR, realtype,
9916 node2)));
9917 break;
5ff904cd 9918
c7e4ee3a
CB
9919 case MINUS_EXPR:
9920 if (TREE_CODE (type) != RECORD_TYPE)
9921 {
9922 item = build (code, type, node1, node2);
9923 break;
9924 }
9925 node1 = ffecom_stabilize_aggregate_ (node1);
9926 node2 = ffecom_stabilize_aggregate_ (node2);
9927 realtype = TREE_TYPE (TYPE_FIELDS (type));
9928 item =
9929 ffecom_2 (COMPLEX_EXPR, type,
9930 ffecom_2 (MINUS_EXPR, realtype,
9931 ffecom_1 (REALPART_EXPR, realtype,
9932 node1),
9933 ffecom_1 (REALPART_EXPR, realtype,
9934 node2)),
9935 ffecom_2 (MINUS_EXPR, realtype,
9936 ffecom_1 (IMAGPART_EXPR, realtype,
9937 node1),
9938 ffecom_1 (IMAGPART_EXPR, realtype,
9939 node2)));
9940 break;
5ff904cd 9941
c7e4ee3a
CB
9942 case MULT_EXPR:
9943 if (TREE_CODE (type) != RECORD_TYPE)
9944 {
9945 item = build (code, type, node1, node2);
9946 break;
9947 }
9948 node1 = ffecom_stabilize_aggregate_ (node1);
9949 node2 = ffecom_stabilize_aggregate_ (node2);
9950 realtype = TREE_TYPE (TYPE_FIELDS (type));
9951 a = save_expr (ffecom_1 (REALPART_EXPR, realtype,
9952 node1));
9953 b = save_expr (ffecom_1 (IMAGPART_EXPR, realtype,
9954 node1));
9955 c = save_expr (ffecom_1 (REALPART_EXPR, realtype,
9956 node2));
9957 d = save_expr (ffecom_1 (IMAGPART_EXPR, realtype,
9958 node2));
9959 item =
9960 ffecom_2 (COMPLEX_EXPR, type,
9961 ffecom_2 (MINUS_EXPR, realtype,
9962 ffecom_2 (MULT_EXPR, realtype,
9963 a,
9964 c),
9965 ffecom_2 (MULT_EXPR, realtype,
9966 b,
9967 d)),
9968 ffecom_2 (PLUS_EXPR, realtype,
9969 ffecom_2 (MULT_EXPR, realtype,
9970 a,
9971 d),
9972 ffecom_2 (MULT_EXPR, realtype,
9973 c,
9974 b)));
9975 break;
5ff904cd 9976
c7e4ee3a
CB
9977 case EQ_EXPR:
9978 if ((TREE_CODE (node1) != RECORD_TYPE)
9979 && (TREE_CODE (node2) != RECORD_TYPE))
9980 {
9981 item = build (code, type, node1, node2);
9982 break;
9983 }
9984 assert (TREE_CODE (node1) == RECORD_TYPE);
9985 assert (TREE_CODE (node2) == RECORD_TYPE);
9986 node1 = ffecom_stabilize_aggregate_ (node1);
9987 node2 = ffecom_stabilize_aggregate_ (node2);
9988 realtype = TREE_TYPE (TYPE_FIELDS (type));
9989 item =
9990 ffecom_2 (TRUTH_ANDIF_EXPR, type,
9991 ffecom_2 (code, type,
9992 ffecom_1 (REALPART_EXPR, realtype,
9993 node1),
9994 ffecom_1 (REALPART_EXPR, realtype,
9995 node2)),
9996 ffecom_2 (code, type,
9997 ffecom_1 (IMAGPART_EXPR, realtype,
9998 node1),
9999 ffecom_1 (IMAGPART_EXPR, realtype,
10000 node2)));
10001 break;
10002
10003 case NE_EXPR:
10004 if ((TREE_CODE (node1) != RECORD_TYPE)
10005 && (TREE_CODE (node2) != RECORD_TYPE))
10006 {
10007 item = build (code, type, node1, node2);
10008 break;
10009 }
10010 assert (TREE_CODE (node1) == RECORD_TYPE);
10011 assert (TREE_CODE (node2) == RECORD_TYPE);
10012 node1 = ffecom_stabilize_aggregate_ (node1);
10013 node2 = ffecom_stabilize_aggregate_ (node2);
10014 realtype = TREE_TYPE (TYPE_FIELDS (type));
10015 item =
10016 ffecom_2 (TRUTH_ORIF_EXPR, type,
10017 ffecom_2 (code, type,
10018 ffecom_1 (REALPART_EXPR, realtype,
10019 node1),
10020 ffecom_1 (REALPART_EXPR, realtype,
10021 node2)),
10022 ffecom_2 (code, type,
10023 ffecom_1 (IMAGPART_EXPR, realtype,
10024 node1),
10025 ffecom_1 (IMAGPART_EXPR, realtype,
10026 node2)));
10027 break;
5ff904cd 10028
c7e4ee3a
CB
10029 default:
10030 item = build (code, type, node1, node2);
10031 break;
5ff904cd
JL
10032 }
10033
c7e4ee3a
CB
10034 if (TREE_SIDE_EFFECTS (node1) || TREE_SIDE_EFFECTS (node2))
10035 TREE_SIDE_EFFECTS (item) = 1;
10036 return fold (item);
5ff904cd
JL
10037}
10038
10039#endif
c7e4ee3a 10040/* ffecom_2pass_advise_entrypoint -- Advise that there's this entrypoint
5ff904cd 10041
c7e4ee3a
CB
10042 ffesymbol s; // the ENTRY point itself
10043 if (ffecom_2pass_advise_entrypoint(s))
10044 // the ENTRY point has been accepted
5ff904cd 10045
c7e4ee3a
CB
10046 Does whatever compiler needs to do when it learns about the entrypoint,
10047 like determine the return type of the master function, count the
10048 number of entrypoints, etc. Returns FALSE if the return type is
10049 not compatible with the return type(s) of other entrypoint(s).
5ff904cd 10050
c7e4ee3a
CB
10051 NOTE: for every call to this fn that returns TRUE, _do_entrypoint must
10052 later (after _finish_progunit) be called with the same entrypoint(s)
10053 as passed to this fn for which TRUE was returned.
5ff904cd 10054
c7e4ee3a
CB
10055 03-Jan-92 JCB 2.0
10056 Return FALSE if the return type conflicts with previous entrypoints. */
5ff904cd
JL
10057
10058#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
10059bool
10060ffecom_2pass_advise_entrypoint (ffesymbol entry)
5ff904cd 10061{
c7e4ee3a
CB
10062 ffebld list; /* opITEM. */
10063 ffebld mlist; /* opITEM. */
10064 ffebld plist; /* opITEM. */
10065 ffebld arg; /* ffebld_head(opITEM). */
10066 ffebld item; /* opITEM. */
10067 ffesymbol s; /* ffebld_symter(arg). */
10068 ffeinfoBasictype bt = ffesymbol_basictype (entry);
10069 ffeinfoKindtype kt = ffesymbol_kindtype (entry);
10070 ffetargetCharacterSize size = ffesymbol_size (entry);
10071 bool ok;
5ff904cd 10072
c7e4ee3a
CB
10073 if (ffecom_num_entrypoints_ == 0)
10074 { /* First entrypoint, make list of main
10075 arglist's dummies. */
10076 assert (ffecom_primary_entry_ != NULL);
5ff904cd 10077
c7e4ee3a
CB
10078 ffecom_master_bt_ = ffesymbol_basictype (ffecom_primary_entry_);
10079 ffecom_master_kt_ = ffesymbol_kindtype (ffecom_primary_entry_);
10080 ffecom_master_size_ = ffesymbol_size (ffecom_primary_entry_);
5ff904cd 10081
c7e4ee3a
CB
10082 for (plist = NULL, list = ffesymbol_dummyargs (ffecom_primary_entry_);
10083 list != NULL;
10084 list = ffebld_trail (list))
10085 {
10086 arg = ffebld_head (list);
10087 if (ffebld_op (arg) != FFEBLD_opSYMTER)
10088 continue; /* Alternate return or some such thing. */
10089 item = ffebld_new_item (arg, NULL);
10090 if (plist == NULL)
10091 ffecom_master_arglist_ = item;
10092 else
10093 ffebld_set_trail (plist, item);
10094 plist = item;
10095 }
5ff904cd
JL
10096 }
10097
c7e4ee3a
CB
10098 /* If necessary, scan entry arglist for alternate returns. Do this scan
10099 apparently redundantly (it's done below to UNIONize the arglists) so
10100 that we don't complain about RETURN 1 if an offending ENTRY is the only
10101 one with an alternate return. */
5ff904cd 10102
c7e4ee3a 10103 if (!ffecom_is_altreturning_)
5ff904cd 10104 {
c7e4ee3a
CB
10105 for (list = ffesymbol_dummyargs (entry);
10106 list != NULL;
10107 list = ffebld_trail (list))
10108 {
10109 arg = ffebld_head (list);
10110 if (ffebld_op (arg) == FFEBLD_opSTAR)
10111 {
10112 ffecom_is_altreturning_ = TRUE;
10113 break;
10114 }
10115 }
10116 }
5ff904cd 10117
c7e4ee3a 10118 /* Now check type compatibility. */
5ff904cd 10119
c7e4ee3a
CB
10120 switch (ffecom_master_bt_)
10121 {
10122 case FFEINFO_basictypeNONE:
10123 ok = (bt != FFEINFO_basictypeCHARACTER);
10124 break;
5ff904cd 10125
c7e4ee3a
CB
10126 case FFEINFO_basictypeCHARACTER:
10127 ok
10128 = (bt == FFEINFO_basictypeCHARACTER)
10129 && (kt == ffecom_master_kt_)
10130 && (size == ffecom_master_size_);
10131 break;
5ff904cd 10132
c7e4ee3a
CB
10133 case FFEINFO_basictypeANY:
10134 return FALSE; /* Just don't bother. */
5ff904cd 10135
c7e4ee3a
CB
10136 default:
10137 if (bt == FFEINFO_basictypeCHARACTER)
5ff904cd 10138 {
c7e4ee3a
CB
10139 ok = FALSE;
10140 break;
5ff904cd 10141 }
c7e4ee3a
CB
10142 ok = TRUE;
10143 if ((bt != ffecom_master_bt_) || (kt != ffecom_master_kt_))
10144 {
10145 ffecom_master_bt_ = FFEINFO_basictypeNONE;
10146 ffecom_master_kt_ = FFEINFO_kindtypeNONE;
10147 }
10148 break;
10149 }
5ff904cd 10150
c7e4ee3a
CB
10151 if (!ok)
10152 {
10153 ffebad_start (FFEBAD_ENTRY_CONFLICTS);
10154 ffest_ffebad_here_current_stmt (0);
10155 ffebad_finish ();
10156 return FALSE; /* Can't handle entrypoint. */
10157 }
5ff904cd 10158
c7e4ee3a 10159 /* Entrypoint type compatible with previous types. */
5ff904cd 10160
c7e4ee3a 10161 ++ffecom_num_entrypoints_;
5ff904cd 10162
c7e4ee3a
CB
10163 /* Master-arg-list = UNION(Master-arg-list,entry-arg-list). */
10164
10165 for (list = ffesymbol_dummyargs (entry);
10166 list != NULL;
10167 list = ffebld_trail (list))
10168 {
10169 arg = ffebld_head (list);
10170 if (ffebld_op (arg) != FFEBLD_opSYMTER)
10171 continue; /* Alternate return or some such thing. */
10172 s = ffebld_symter (arg);
10173 for (plist = NULL, mlist = ffecom_master_arglist_;
10174 mlist != NULL;
10175 plist = mlist, mlist = ffebld_trail (mlist))
10176 { /* plist points to previous item for easy
10177 appending of arg. */
10178 if (ffebld_symter (ffebld_head (mlist)) == s)
10179 break; /* Already have this arg in the master list. */
10180 }
10181 if (mlist != NULL)
10182 continue; /* Already have this arg in the master list. */
5ff904cd 10183
c7e4ee3a 10184 /* Append this arg to the master list. */
5ff904cd 10185
c7e4ee3a
CB
10186 item = ffebld_new_item (arg, NULL);
10187 if (plist == NULL)
10188 ffecom_master_arglist_ = item;
10189 else
10190 ffebld_set_trail (plist, item);
5ff904cd
JL
10191 }
10192
c7e4ee3a 10193 return TRUE;
5ff904cd
JL
10194}
10195
10196#endif
c7e4ee3a
CB
10197/* ffecom_2pass_do_entrypoint -- Do compilation of entrypoint
10198
10199 ffesymbol s; // the ENTRY point itself
10200 ffecom_2pass_do_entrypoint(s);
10201
10202 Does whatever compiler needs to do to make the entrypoint actually
10203 happen. Must be called for each entrypoint after
10204 ffecom_finish_progunit is called. */
10205
5ff904cd 10206#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
10207void
10208ffecom_2pass_do_entrypoint (ffesymbol entry)
5ff904cd 10209{
c7e4ee3a
CB
10210 static int mfn_num = 0;
10211 static int ent_num;
5ff904cd 10212
c7e4ee3a
CB
10213 if (mfn_num != ffecom_num_fns_)
10214 { /* First entrypoint for this program unit. */
10215 ent_num = 1;
10216 mfn_num = ffecom_num_fns_;
10217 ffecom_do_entry_ (ffecom_primary_entry_, 0);
10218 }
10219 else
10220 ++ent_num;
5ff904cd 10221
c7e4ee3a 10222 --ffecom_num_entrypoints_;
5ff904cd 10223
c7e4ee3a
CB
10224 ffecom_do_entry_ (entry, ent_num);
10225}
5ff904cd 10226
c7e4ee3a 10227#endif
5ff904cd 10228
c7e4ee3a
CB
10229/* Essentially does a "fold (build (code, type, node1, node2))" while
10230 checking for certain housekeeping things. Always sets
10231 TREE_SIDE_EFFECTS. */
5ff904cd 10232
c7e4ee3a
CB
10233#if FFECOM_targetCURRENT == FFECOM_targetGCC
10234tree
10235ffecom_2s (enum tree_code code, tree type, tree node1,
10236 tree node2)
10237{
10238 tree item;
5ff904cd 10239
c7e4ee3a
CB
10240 if ((node1 == error_mark_node)
10241 || (node2 == error_mark_node)
10242 || (type == error_mark_node))
10243 return error_mark_node;
5ff904cd 10244
c7e4ee3a
CB
10245 item = build (code, type, node1, node2);
10246 TREE_SIDE_EFFECTS (item) = 1;
10247 return fold (item);
5ff904cd
JL
10248}
10249
10250#endif
c7e4ee3a
CB
10251/* Essentially does a "fold (build (code, type, node1, node2, node3))" while
10252 checking for certain housekeeping things. */
10253
5ff904cd 10254#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
10255tree
10256ffecom_3 (enum tree_code code, tree type, tree node1,
10257 tree node2, tree node3)
5ff904cd 10258{
c7e4ee3a 10259 tree item;
5ff904cd 10260
c7e4ee3a
CB
10261 if ((node1 == error_mark_node)
10262 || (node2 == error_mark_node)
10263 || (node3 == error_mark_node)
10264 || (type == error_mark_node))
10265 return error_mark_node;
5ff904cd 10266
c7e4ee3a
CB
10267 item = build (code, type, node1, node2, node3);
10268 if (TREE_SIDE_EFFECTS (node1) || TREE_SIDE_EFFECTS (node2)
10269 || (node3 != NULL_TREE && TREE_SIDE_EFFECTS (node3)))
10270 TREE_SIDE_EFFECTS (item) = 1;
10271 return fold (item);
10272}
5ff904cd 10273
c7e4ee3a
CB
10274#endif
10275/* Essentially does a "fold (build (code, type, node1, node2, node3))" while
10276 checking for certain housekeeping things. Always sets
10277 TREE_SIDE_EFFECTS. */
5ff904cd 10278
c7e4ee3a
CB
10279#if FFECOM_targetCURRENT == FFECOM_targetGCC
10280tree
10281ffecom_3s (enum tree_code code, tree type, tree node1,
10282 tree node2, tree node3)
10283{
10284 tree item;
5ff904cd 10285
c7e4ee3a
CB
10286 if ((node1 == error_mark_node)
10287 || (node2 == error_mark_node)
10288 || (node3 == error_mark_node)
10289 || (type == error_mark_node))
10290 return error_mark_node;
5ff904cd 10291
c7e4ee3a
CB
10292 item = build (code, type, node1, node2, node3);
10293 TREE_SIDE_EFFECTS (item) = 1;
10294 return fold (item);
10295}
5ff904cd 10296
c7e4ee3a 10297#endif
5ff904cd 10298
c7e4ee3a 10299/* ffecom_arg_expr -- Transform argument expr into gcc tree
5ff904cd 10300
c7e4ee3a 10301 See use by ffecom_list_expr.
5ff904cd 10302
c7e4ee3a
CB
10303 If expression is NULL, returns an integer zero tree. If it is not
10304 a CHARACTER expression, returns whatever ffecom_expr
10305 returns and sets the length return value to NULL_TREE. Otherwise
10306 generates code to evaluate the character expression, returns the proper
10307 pointer to the result, but does NOT set the length return value to a tree
10308 that specifies the length of the result. (In other words, the length
10309 variable is always set to NULL_TREE, because a length is never passed.)
5ff904cd 10310
c7e4ee3a
CB
10311 21-Dec-91 JCB 1.1
10312 Don't set returned length, since nobody needs it (yet; someday if
10313 we allow CHARACTER*(*) dummies to statement functions, we'll need
10314 it). */
5ff904cd 10315
c7e4ee3a
CB
10316#if FFECOM_targetCURRENT == FFECOM_targetGCC
10317tree
10318ffecom_arg_expr (ffebld expr, tree *length)
10319{
10320 tree ign;
5ff904cd 10321
c7e4ee3a 10322 *length = NULL_TREE;
5ff904cd 10323
c7e4ee3a
CB
10324 if (expr == NULL)
10325 return integer_zero_node;
5ff904cd 10326
c7e4ee3a
CB
10327 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10328 return ffecom_expr (expr);
5ff904cd 10329
c7e4ee3a
CB
10330 return ffecom_arg_ptr_to_expr (expr, &ign);
10331}
10332
10333#endif
10334/* Transform expression into constant argument-pointer-to-expression tree.
10335
10336 If the expression can be transformed into a argument-pointer-to-expression
10337 tree that is constant, that is done, and the tree returned. Else
10338 NULL_TREE is returned.
5ff904cd 10339
c7e4ee3a
CB
10340 That way, a caller can attempt to provide compile-time initialization
10341 of a variable and, if that fails, *then* choose to start a new block
10342 and resort to using temporaries, as appropriate. */
5ff904cd 10343
c7e4ee3a
CB
10344tree
10345ffecom_arg_ptr_to_const_expr (ffebld expr, tree *length)
10346{
10347 if (! expr)
10348 return integer_zero_node;
5ff904cd 10349
c7e4ee3a
CB
10350 if (ffebld_op (expr) == FFEBLD_opANY)
10351 {
10352 if (length)
10353 *length = error_mark_node;
10354 return error_mark_node;
10355 }
10356
10357 if (ffebld_arity (expr) == 0
10358 && (ffebld_op (expr) != FFEBLD_opSYMTER
10359 || ffebld_where (expr) == FFEINFO_whereCOMMON
10360 || ffebld_where (expr) == FFEINFO_whereGLOBAL
10361 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
10362 {
10363 tree t;
10364
10365 t = ffecom_arg_ptr_to_expr (expr, length);
10366 assert (TREE_CONSTANT (t));
10367 assert (! length || TREE_CONSTANT (*length));
10368 return t;
10369 }
10370
10371 if (length
10372 && ffebld_size (expr) != FFETARGET_charactersizeNONE)
10373 *length = build_int_2 (ffebld_size (expr), 0);
10374 else if (length)
10375 *length = NULL_TREE;
10376 return NULL_TREE;
5ff904cd
JL
10377}
10378
c7e4ee3a 10379/* ffecom_arg_ptr_to_expr -- Transform argument expr into gcc tree
5ff904cd 10380
c7e4ee3a
CB
10381 See use by ffecom_list_ptr_to_expr.
10382
10383 If expression is NULL, returns an integer zero tree. If it is not
10384 a CHARACTER expression, returns whatever ffecom_ptr_to_expr
10385 returns and sets the length return value to NULL_TREE. Otherwise
10386 generates code to evaluate the character expression, returns the proper
10387 pointer to the result, AND sets the length return value to a tree that
10388 specifies the length of the result.
10389
10390 If the length argument is NULL, this is a slightly special
10391 case of building a FORMAT expression, that is, an expression that
10392 will be used at run time without regard to length. For the current
10393 implementation, which uses the libf2c library, this means it is nice
10394 to append a null byte to the end of the expression, where feasible,
10395 to make sure any diagnostic about the FORMAT string terminates at
10396 some useful point.
10397
10398 For now, treat %REF(char-expr) as the same as char-expr with a NULL
10399 length argument. This might even be seen as a feature, if a null
10400 byte can always be appended. */
5ff904cd
JL
10401
10402#if FFECOM_targetCURRENT == FFECOM_targetGCC
10403tree
c7e4ee3a 10404ffecom_arg_ptr_to_expr (ffebld expr, tree *length)
5ff904cd
JL
10405{
10406 tree item;
c7e4ee3a
CB
10407 tree ign_length;
10408 ffecomConcatList_ catlist;
5ff904cd 10409
c7e4ee3a
CB
10410 if (length != NULL)
10411 *length = NULL_TREE;
5ff904cd 10412
c7e4ee3a
CB
10413 if (expr == NULL)
10414 return integer_zero_node;
5ff904cd 10415
c7e4ee3a 10416 switch (ffebld_op (expr))
5ff904cd 10417 {
c7e4ee3a
CB
10418 case FFEBLD_opPERCENT_VAL:
10419 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10420 return ffecom_expr (ffebld_left (expr));
10421 {
10422 tree temp_exp;
10423 tree temp_length;
5ff904cd 10424
c7e4ee3a
CB
10425 temp_exp = ffecom_arg_ptr_to_expr (ffebld_left (expr), &temp_length);
10426 if (temp_exp == error_mark_node)
10427 return error_mark_node;
5ff904cd 10428
c7e4ee3a
CB
10429 return ffecom_1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (temp_exp)),
10430 temp_exp);
10431 }
5ff904cd 10432
c7e4ee3a
CB
10433 case FFEBLD_opPERCENT_REF:
10434 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10435 return ffecom_ptr_to_expr (ffebld_left (expr));
10436 if (length != NULL)
10437 {
10438 ign_length = NULL_TREE;
10439 length = &ign_length;
10440 }
10441 expr = ffebld_left (expr);
10442 break;
5ff904cd 10443
c7e4ee3a
CB
10444 case FFEBLD_opPERCENT_DESCR:
10445 switch (ffeinfo_basictype (ffebld_info (expr)))
5ff904cd 10446 {
c7e4ee3a
CB
10447#ifdef PASS_HOLLERITH_BY_DESCRIPTOR
10448 case FFEINFO_basictypeHOLLERITH:
10449#endif
10450 case FFEINFO_basictypeCHARACTER:
10451 break; /* Passed by descriptor anyway. */
10452
10453 default:
10454 item = ffecom_ptr_to_expr (expr);
10455 if (item != error_mark_node)
10456 *length = TYPE_SIZE (TREE_TYPE (TREE_TYPE (item)));
5ff904cd
JL
10457 break;
10458 }
5ff904cd
JL
10459 break;
10460
10461 default:
5ff904cd
JL
10462 break;
10463 }
10464
c7e4ee3a
CB
10465#ifdef PASS_HOLLERITH_BY_DESCRIPTOR
10466 if ((ffeinfo_basictype (ffebld_info (expr)) == FFEINFO_basictypeHOLLERITH)
10467 && (length != NULL))
10468 { /* Pass Hollerith by descriptor. */
10469 ffetargetHollerith h;
10470
10471 assert (ffebld_op (expr) == FFEBLD_opCONTER);
10472 h = ffebld_cu_val_hollerith (ffebld_constant_union
10473 (ffebld_conter (expr)));
10474 *length
10475 = build_int_2 (h.length, 0);
10476 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
10477 }
10478#endif
10479
10480 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10481 return ffecom_ptr_to_expr (expr);
10482
10483 assert (ffeinfo_kindtype (ffebld_info (expr))
10484 == FFEINFO_kindtypeCHARACTER1);
10485
10486 catlist = ffecom_concat_list_new_ (expr, FFETARGET_charactersizeNONE);
10487 switch (ffecom_concat_list_count_ (catlist))
10488 {
10489 case 0: /* Shouldn't happen, but in case it does... */
10490 if (length != NULL)
10491 {
10492 *length = ffecom_f2c_ftnlen_zero_node;
10493 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
10494 }
10495 ffecom_concat_list_kill_ (catlist);
10496 return null_pointer_node;
10497
10498 case 1: /* The (fairly) easy case. */
10499 if (length == NULL)
10500 ffecom_char_args_with_null_ (&item, &ign_length,
10501 ffecom_concat_list_expr_ (catlist, 0));
10502 else
10503 ffecom_char_args_ (&item, length,
10504 ffecom_concat_list_expr_ (catlist, 0));
10505 ffecom_concat_list_kill_ (catlist);
10506 assert (item != NULL_TREE);
10507 return item;
10508
10509 default: /* Must actually concatenate things. */
10510 break;
10511 }
10512
10513 {
10514 int count = ffecom_concat_list_count_ (catlist);
10515 int i;
10516 tree lengths;
10517 tree items;
10518 tree length_array;
10519 tree item_array;
10520 tree citem;
10521 tree clength;
10522 tree temporary;
10523 tree num;
10524 tree known_length;
10525 ffetargetCharacterSize sz;
10526
10527 sz = ffecom_concat_list_maxlen_ (catlist);
10528 /* ~~Kludge! */
10529 assert (sz != FFETARGET_charactersizeNONE);
10530
10531#ifdef HOHO
10532 length_array
10533 = lengths
10534 = ffecom_push_tempvar (ffecom_f2c_ftnlen_type_node,
10535 FFETARGET_charactersizeNONE, count, TRUE);
10536 item_array
10537 = items
10538 = ffecom_push_tempvar (ffecom_f2c_address_type_node,
10539 FFETARGET_charactersizeNONE, count, TRUE);
10540 temporary = ffecom_push_tempvar (char_type_node,
10541 sz, -1, TRUE);
10542#else
10543 {
10544 tree hook;
10545
10546 hook = ffebld_nonter_hook (expr);
10547 assert (hook);
10548 assert (TREE_CODE (hook) == TREE_VEC);
10549 assert (TREE_VEC_LENGTH (hook) == 3);
10550 length_array = lengths = TREE_VEC_ELT (hook, 0);
10551 item_array = items = TREE_VEC_ELT (hook, 1);
10552 temporary = TREE_VEC_ELT (hook, 2);
10553 }
10554#endif
10555
10556 known_length = ffecom_f2c_ftnlen_zero_node;
10557
10558 for (i = 0; i < count; ++i)
10559 {
10560 if ((i == count)
10561 && (length == NULL))
10562 ffecom_char_args_with_null_ (&citem, &clength,
10563 ffecom_concat_list_expr_ (catlist, i));
10564 else
10565 ffecom_char_args_ (&citem, &clength,
10566 ffecom_concat_list_expr_ (catlist, i));
10567 if ((citem == error_mark_node)
10568 || (clength == error_mark_node))
10569 {
10570 ffecom_concat_list_kill_ (catlist);
10571 *length = error_mark_node;
10572 return error_mark_node;
10573 }
10574
10575 items
10576 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (items),
10577 ffecom_modify (void_type_node,
10578 ffecom_2 (ARRAY_REF,
10579 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array))),
10580 item_array,
10581 build_int_2 (i, 0)),
10582 citem),
10583 items);
10584 clength = ffecom_save_tree (clength);
10585 if (length != NULL)
10586 known_length
10587 = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
10588 known_length,
10589 clength);
10590 lengths
10591 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (lengths),
10592 ffecom_modify (void_type_node,
10593 ffecom_2 (ARRAY_REF,
10594 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array))),
10595 length_array,
10596 build_int_2 (i, 0)),
10597 clength),
10598 lengths);
10599 }
10600
10601 temporary = ffecom_1 (ADDR_EXPR,
10602 build_pointer_type (TREE_TYPE (temporary)),
10603 temporary);
10604
10605 item = build_tree_list (NULL_TREE, temporary);
10606 TREE_CHAIN (item)
10607 = build_tree_list (NULL_TREE,
10608 ffecom_1 (ADDR_EXPR,
10609 build_pointer_type (TREE_TYPE (items)),
10610 items));
10611 TREE_CHAIN (TREE_CHAIN (item))
10612 = build_tree_list (NULL_TREE,
10613 ffecom_1 (ADDR_EXPR,
10614 build_pointer_type (TREE_TYPE (lengths)),
10615 lengths));
10616 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item)))
10617 = build_tree_list
10618 (NULL_TREE,
10619 ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
10620 convert (ffecom_f2c_ftnlen_type_node,
10621 build_int_2 (count, 0))));
10622 num = build_int_2 (sz, 0);
10623 TREE_TYPE (num) = ffecom_f2c_ftnlen_type_node;
10624 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item))))
10625 = build_tree_list (NULL_TREE, num);
10626
10627 item = ffecom_call_gfrt (FFECOM_gfrtCAT, item, NULL_TREE);
5ff904cd 10628 TREE_SIDE_EFFECTS (item) = 1;
c7e4ee3a
CB
10629 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (temporary),
10630 item,
10631 temporary);
10632
10633 if (length != NULL)
10634 *length = known_length;
10635 }
10636
10637 ffecom_concat_list_kill_ (catlist);
10638 assert (item != NULL_TREE);
10639 return item;
5ff904cd 10640}
c7e4ee3a 10641
5ff904cd 10642#endif
c7e4ee3a 10643/* Generate call to run-time function.
5ff904cd 10644
c7e4ee3a
CB
10645 The first arg is the GNU Fortran Run-Time function index, the second
10646 arg is the list of arguments to pass to it. Returned is the expression
10647 (WITHOUT TREE_SIDE_EFFECTS set!) that makes the call and returns the
10648 result (which may be void). */
5ff904cd
JL
10649
10650#if FFECOM_targetCURRENT == FFECOM_targetGCC
10651tree
c7e4ee3a 10652ffecom_call_gfrt (ffecomGfrt ix, tree args, tree hook)
5ff904cd 10653{
c7e4ee3a
CB
10654 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
10655 ffecom_gfrt_kindtype (ix),
10656 ffe_is_f2c_library () && ffecom_gfrt_complex_[ix],
10657 NULL_TREE, args, NULL_TREE, NULL,
10658 NULL, NULL_TREE, TRUE, hook);
5ff904cd
JL
10659}
10660#endif
10661
c7e4ee3a 10662/* Transform constant-union to tree. */
5ff904cd
JL
10663
10664#if FFECOM_targetCURRENT == FFECOM_targetGCC
10665tree
c7e4ee3a
CB
10666ffecom_constantunion (ffebldConstantUnion *cu, ffeinfoBasictype bt,
10667 ffeinfoKindtype kt, tree tree_type)
5ff904cd
JL
10668{
10669 tree item;
10670
c7e4ee3a 10671 switch (bt)
5ff904cd 10672 {
c7e4ee3a
CB
10673 case FFEINFO_basictypeINTEGER:
10674 {
10675 int val;
5ff904cd 10676
c7e4ee3a
CB
10677 switch (kt)
10678 {
10679#if FFETARGET_okINTEGER1
10680 case FFEINFO_kindtypeINTEGER1:
10681 val = ffebld_cu_val_integer1 (*cu);
10682 break;
10683#endif
5ff904cd 10684
c7e4ee3a
CB
10685#if FFETARGET_okINTEGER2
10686 case FFEINFO_kindtypeINTEGER2:
10687 val = ffebld_cu_val_integer2 (*cu);
10688 break;
10689#endif
5ff904cd 10690
c7e4ee3a
CB
10691#if FFETARGET_okINTEGER3
10692 case FFEINFO_kindtypeINTEGER3:
10693 val = ffebld_cu_val_integer3 (*cu);
10694 break;
10695#endif
5ff904cd 10696
c7e4ee3a
CB
10697#if FFETARGET_okINTEGER4
10698 case FFEINFO_kindtypeINTEGER4:
10699 val = ffebld_cu_val_integer4 (*cu);
10700 break;
10701#endif
5ff904cd 10702
c7e4ee3a
CB
10703 default:
10704 assert ("bad INTEGER constant kind type" == NULL);
10705 /* Fall through. */
10706 case FFEINFO_kindtypeANY:
10707 return error_mark_node;
10708 }
10709 item = build_int_2 (val, (val < 0) ? -1 : 0);
10710 TREE_TYPE (item) = tree_type;
10711 }
5ff904cd 10712 break;
5ff904cd 10713
c7e4ee3a
CB
10714 case FFEINFO_basictypeLOGICAL:
10715 {
10716 int val;
5ff904cd 10717
c7e4ee3a
CB
10718 switch (kt)
10719 {
10720#if FFETARGET_okLOGICAL1
10721 case FFEINFO_kindtypeLOGICAL1:
10722 val = ffebld_cu_val_logical1 (*cu);
10723 break;
5ff904cd 10724#endif
5ff904cd 10725
c7e4ee3a
CB
10726#if FFETARGET_okLOGICAL2
10727 case FFEINFO_kindtypeLOGICAL2:
10728 val = ffebld_cu_val_logical2 (*cu);
10729 break;
10730#endif
5ff904cd 10731
c7e4ee3a
CB
10732#if FFETARGET_okLOGICAL3
10733 case FFEINFO_kindtypeLOGICAL3:
10734 val = ffebld_cu_val_logical3 (*cu);
10735 break;
10736#endif
5ff904cd 10737
c7e4ee3a
CB
10738#if FFETARGET_okLOGICAL4
10739 case FFEINFO_kindtypeLOGICAL4:
10740 val = ffebld_cu_val_logical4 (*cu);
10741 break;
10742#endif
5ff904cd 10743
c7e4ee3a
CB
10744 default:
10745 assert ("bad LOGICAL constant kind type" == NULL);
10746 /* Fall through. */
10747 case FFEINFO_kindtypeANY:
10748 return error_mark_node;
10749 }
10750 item = build_int_2 (val, (val < 0) ? -1 : 0);
10751 TREE_TYPE (item) = tree_type;
10752 }
10753 break;
5ff904cd 10754
c7e4ee3a
CB
10755 case FFEINFO_basictypeREAL:
10756 {
10757 REAL_VALUE_TYPE val;
5ff904cd 10758
c7e4ee3a
CB
10759 switch (kt)
10760 {
10761#if FFETARGET_okREAL1
10762 case FFEINFO_kindtypeREAL1:
10763 val = ffetarget_value_real1 (ffebld_cu_val_real1 (*cu));
10764 break;
10765#endif
5ff904cd 10766
c7e4ee3a
CB
10767#if FFETARGET_okREAL2
10768 case FFEINFO_kindtypeREAL2:
10769 val = ffetarget_value_real2 (ffebld_cu_val_real2 (*cu));
10770 break;
10771#endif
5ff904cd 10772
c7e4ee3a
CB
10773#if FFETARGET_okREAL3
10774 case FFEINFO_kindtypeREAL3:
10775 val = ffetarget_value_real3 (ffebld_cu_val_real3 (*cu));
10776 break;
10777#endif
5ff904cd 10778
c7e4ee3a
CB
10779#if FFETARGET_okREAL4
10780 case FFEINFO_kindtypeREAL4:
10781 val = ffetarget_value_real4 (ffebld_cu_val_real4 (*cu));
10782 break;
10783#endif
5ff904cd 10784
c7e4ee3a
CB
10785 default:
10786 assert ("bad REAL constant kind type" == NULL);
10787 /* Fall through. */
10788 case FFEINFO_kindtypeANY:
10789 return error_mark_node;
10790 }
10791 item = build_real (tree_type, val);
10792 }
5ff904cd
JL
10793 break;
10794
c7e4ee3a
CB
10795 case FFEINFO_basictypeCOMPLEX:
10796 {
10797 REAL_VALUE_TYPE real;
10798 REAL_VALUE_TYPE imag;
10799 tree el_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
5ff904cd 10800
c7e4ee3a
CB
10801 switch (kt)
10802 {
10803#if FFETARGET_okCOMPLEX1
10804 case FFEINFO_kindtypeREAL1:
10805 real = ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu).real);
10806 imag = ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu).imaginary);
10807 break;
10808#endif
5ff904cd 10809
c7e4ee3a
CB
10810#if FFETARGET_okCOMPLEX2
10811 case FFEINFO_kindtypeREAL2:
10812 real = ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu).real);
10813 imag = ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu).imaginary);
10814 break;
10815#endif
5ff904cd 10816
c7e4ee3a
CB
10817#if FFETARGET_okCOMPLEX3
10818 case FFEINFO_kindtypeREAL3:
10819 real = ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu).real);
10820 imag = ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu).imaginary);
10821 break;
10822#endif
5ff904cd 10823
c7e4ee3a
CB
10824#if FFETARGET_okCOMPLEX4
10825 case FFEINFO_kindtypeREAL4:
10826 real = ffetarget_value_real4 (ffebld_cu_val_complex4 (*cu).real);
10827 imag = ffetarget_value_real4 (ffebld_cu_val_complex4 (*cu).imaginary);
10828 break;
10829#endif
5ff904cd 10830
c7e4ee3a
CB
10831 default:
10832 assert ("bad REAL constant kind type" == NULL);
10833 /* Fall through. */
10834 case FFEINFO_kindtypeANY:
10835 return error_mark_node;
10836 }
10837 item = ffecom_build_complex_constant_ (tree_type,
10838 build_real (el_type, real),
10839 build_real (el_type, imag));
10840 }
10841 break;
5ff904cd 10842
c7e4ee3a
CB
10843 case FFEINFO_basictypeCHARACTER:
10844 { /* Happens only in DATA and similar contexts. */
10845 ffetargetCharacter1 val;
5ff904cd 10846
c7e4ee3a
CB
10847 switch (kt)
10848 {
10849#if FFETARGET_okCHARACTER1
10850 case FFEINFO_kindtypeLOGICAL1:
10851 val = ffebld_cu_val_character1 (*cu);
10852 break;
10853#endif
10854
10855 default:
10856 assert ("bad CHARACTER constant kind type" == NULL);
10857 /* Fall through. */
10858 case FFEINFO_kindtypeANY:
10859 return error_mark_node;
10860 }
10861 item = build_string (ffetarget_length_character1 (val),
10862 ffetarget_text_character1 (val));
10863 TREE_TYPE (item)
10864 = build_type_variant (build_array_type (char_type_node,
10865 build_range_type
10866 (integer_type_node,
10867 integer_one_node,
10868 build_int_2
10869 (ffetarget_length_character1
10870 (val), 0))),
10871 1, 0);
10872 }
10873 break;
5ff904cd 10874
c7e4ee3a
CB
10875 case FFEINFO_basictypeHOLLERITH:
10876 {
10877 ffetargetHollerith h;
5ff904cd 10878
c7e4ee3a 10879 h = ffebld_cu_val_hollerith (*cu);
5ff904cd 10880
c7e4ee3a
CB
10881 /* If not at least as wide as default INTEGER, widen it. */
10882 if (h.length >= FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE)
10883 item = build_string (h.length, h.text);
10884 else
10885 {
10886 char str[FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE];
5ff904cd 10887
c7e4ee3a
CB
10888 memcpy (str, h.text, h.length);
10889 memset (&str[h.length], ' ',
10890 FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE
10891 - h.length);
10892 item = build_string (FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE,
10893 str);
10894 }
10895 TREE_TYPE (item)
10896 = build_type_variant (build_array_type (char_type_node,
10897 build_range_type
10898 (integer_type_node,
10899 integer_one_node,
10900 build_int_2
10901 (h.length, 0))),
10902 1, 0);
10903 }
10904 break;
5ff904cd 10905
c7e4ee3a
CB
10906 case FFEINFO_basictypeTYPELESS:
10907 {
10908 ffetargetInteger1 ival;
10909 ffetargetTypeless tless;
10910 ffebad error;
5ff904cd 10911
c7e4ee3a
CB
10912 tless = ffebld_cu_val_typeless (*cu);
10913 error = ffetarget_convert_integer1_typeless (&ival, tless);
10914 assert (error == FFEBAD);
5ff904cd 10915
c7e4ee3a
CB
10916 item = build_int_2 ((int) ival, 0);
10917 }
10918 break;
5ff904cd 10919
c7e4ee3a
CB
10920 default:
10921 assert ("not yet on constant type" == NULL);
10922 /* Fall through. */
10923 case FFEINFO_basictypeANY:
10924 return error_mark_node;
5ff904cd 10925 }
5ff904cd 10926
c7e4ee3a 10927 TREE_CONSTANT (item) = 1;
5ff904cd 10928
c7e4ee3a 10929 return item;
5ff904cd
JL
10930}
10931
10932#endif
10933
c7e4ee3a
CB
10934/* Transform expression into constant tree.
10935
10936 If the expression can be transformed into a tree that is constant,
10937 that is done, and the tree returned. Else NULL_TREE is returned.
10938
10939 That way, a caller can attempt to provide compile-time initialization
10940 of a variable and, if that fails, *then* choose to start a new block
10941 and resort to using temporaries, as appropriate. */
5ff904cd 10942
5ff904cd 10943tree
c7e4ee3a 10944ffecom_const_expr (ffebld expr)
5ff904cd 10945{
c7e4ee3a
CB
10946 if (! expr)
10947 return integer_zero_node;
5ff904cd 10948
c7e4ee3a 10949 if (ffebld_op (expr) == FFEBLD_opANY)
5ff904cd
JL
10950 return error_mark_node;
10951
c7e4ee3a
CB
10952 if (ffebld_arity (expr) == 0
10953 && (ffebld_op (expr) != FFEBLD_opSYMTER
10954#if NEWCOMMON
10955 /* ~~Enable once common/equivalence is handled properly? */
10956 || ffebld_where (expr) == FFEINFO_whereCOMMON
5ff904cd 10957#endif
c7e4ee3a
CB
10958 || ffebld_where (expr) == FFEINFO_whereGLOBAL
10959 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
10960 {
10961 tree t;
5ff904cd 10962
c7e4ee3a
CB
10963 t = ffecom_expr (expr);
10964 assert (TREE_CONSTANT (t));
10965 return t;
10966 }
5ff904cd 10967
c7e4ee3a 10968 return NULL_TREE;
5ff904cd
JL
10969}
10970
c7e4ee3a 10971/* Handy way to make a field in a struct/union. */
5ff904cd
JL
10972
10973#if FFECOM_targetCURRENT == FFECOM_targetGCC
10974tree
c7e4ee3a
CB
10975ffecom_decl_field (tree context, tree prevfield,
10976 const char *name, tree type)
5ff904cd 10977{
c7e4ee3a 10978 tree field;
5ff904cd 10979
c7e4ee3a
CB
10980 field = build_decl (FIELD_DECL, get_identifier (name), type);
10981 DECL_CONTEXT (field) = context;
10982 DECL_FRAME_SIZE (field) = 0;
10983 if (prevfield != NULL_TREE)
10984 TREE_CHAIN (prevfield) = field;
5ff904cd 10985
c7e4ee3a 10986 return field;
5ff904cd
JL
10987}
10988
10989#endif
5ff904cd 10990
c7e4ee3a
CB
10991void
10992ffecom_close_include (FILE *f)
10993{
10994#if FFECOM_GCC_INCLUDE
10995 ffecom_close_include_ (f);
10996#endif
10997}
5ff904cd 10998
c7e4ee3a
CB
10999int
11000ffecom_decode_include_option (char *spec)
11001{
11002#if FFECOM_GCC_INCLUDE
11003 return ffecom_decode_include_option_ (spec);
11004#else
11005 return 1;
11006#endif
11007}
5ff904cd 11008
c7e4ee3a 11009/* End a compound statement (block). */
5ff904cd
JL
11010
11011#if FFECOM_targetCURRENT == FFECOM_targetGCC
11012tree
c7e4ee3a 11013ffecom_end_compstmt (void)
5ff904cd 11014{
c7e4ee3a
CB
11015 return bison_rule_compstmt_ ();
11016}
11017#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
5ff904cd 11018
c7e4ee3a 11019/* ffecom_end_transition -- Perform end transition on all symbols
5ff904cd 11020
c7e4ee3a 11021 ffecom_end_transition();
5ff904cd 11022
c7e4ee3a 11023 Calls ffecom_sym_end_transition for each global and local symbol. */
5ff904cd 11024
c7e4ee3a
CB
11025void
11026ffecom_end_transition ()
11027{
11028#if FFECOM_targetCURRENT == FFECOM_targetGCC
11029 ffebld item;
5ff904cd 11030#endif
5ff904cd 11031
c7e4ee3a
CB
11032 if (ffe_is_ffedebug ())
11033 fprintf (dmpout, "; end_stmt_transition\n");
86fc7a6c 11034
c7e4ee3a
CB
11035#if FFECOM_targetCURRENT == FFECOM_targetGCC
11036 ffecom_list_blockdata_ = NULL;
11037 ffecom_list_common_ = NULL;
11038#endif
86fc7a6c 11039
c7e4ee3a
CB
11040 ffesymbol_drive (ffecom_sym_end_transition);
11041 if (ffe_is_ffedebug ())
11042 {
11043 ffestorag_report ();
11044#if FFECOM_targetCURRENT == FFECOM_targetFFE
11045 ffesymbol_report_all ();
11046#endif
11047 }
5ff904cd
JL
11048
11049#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
11050 ffecom_start_progunit_ ();
11051
11052 for (item = ffecom_list_blockdata_;
11053 item != NULL;
11054 item = ffebld_trail (item))
11055 {
11056 ffebld callee;
11057 ffesymbol s;
11058 tree dt;
11059 tree t;
11060 tree var;
11061 int yes;
11062 static int number = 0;
11063
11064 callee = ffebld_head (item);
11065 s = ffebld_symter (callee);
11066 t = ffesymbol_hook (s).decl_tree;
11067 if (t == NULL_TREE)
11068 {
11069 s = ffecom_sym_transform_ (s);
11070 t = ffesymbol_hook (s).decl_tree;
11071 }
5ff904cd 11072
c7e4ee3a 11073 yes = suspend_momentary ();
5ff904cd 11074
c7e4ee3a 11075 dt = build_pointer_type (TREE_TYPE (t));
5ff904cd 11076
c7e4ee3a
CB
11077 var = build_decl (VAR_DECL,
11078 ffecom_get_invented_identifier ("__g77_forceload_%d",
11079 NULL, number++),
11080 dt);
11081 DECL_EXTERNAL (var) = 0;
11082 TREE_STATIC (var) = 1;
11083 TREE_PUBLIC (var) = 0;
11084 DECL_INITIAL (var) = error_mark_node;
11085 TREE_USED (var) = 1;
5ff904cd 11086
c7e4ee3a 11087 var = start_decl (var, FALSE);
702edf1d 11088
c7e4ee3a 11089 t = ffecom_1 (ADDR_EXPR, dt, t);
5ff904cd 11090
c7e4ee3a 11091 finish_decl (var, t, FALSE);
5ff904cd 11092
c7e4ee3a
CB
11093 resume_momentary (yes);
11094 }
11095
11096 /* This handles any COMMON areas that weren't referenced but have, for
11097 example, important initial data. */
11098
11099 for (item = ffecom_list_common_;
11100 item != NULL;
11101 item = ffebld_trail (item))
11102 ffecom_transform_common_ (ffebld_symter (ffebld_head (item)));
11103
11104 ffecom_list_common_ = NULL;
5ff904cd 11105#endif
c7e4ee3a 11106}
5ff904cd 11107
c7e4ee3a 11108/* ffecom_exec_transition -- Perform exec transition on all symbols
5ff904cd 11109
c7e4ee3a 11110 ffecom_exec_transition();
5ff904cd 11111
c7e4ee3a
CB
11112 Calls ffecom_sym_exec_transition for each global and local symbol.
11113 Make sure error updating not inhibited. */
5ff904cd 11114
c7e4ee3a
CB
11115void
11116ffecom_exec_transition ()
11117{
11118 bool inhibited;
5ff904cd 11119
c7e4ee3a
CB
11120 if (ffe_is_ffedebug ())
11121 fprintf (dmpout, "; exec_stmt_transition\n");
5ff904cd 11122
c7e4ee3a
CB
11123 inhibited = ffebad_inhibit ();
11124 ffebad_set_inhibit (FALSE);
5ff904cd 11125
c7e4ee3a
CB
11126 ffesymbol_drive (ffecom_sym_exec_transition); /* Don't retract! */
11127 ffeequiv_exec_transition (); /* Handle all pending EQUIVALENCEs. */
11128 if (ffe_is_ffedebug ())
5ff904cd 11129 {
c7e4ee3a
CB
11130 ffestorag_report ();
11131#if FFECOM_targetCURRENT == FFECOM_targetFFE
11132 ffesymbol_report_all ();
11133#endif
11134 }
5ff904cd 11135
c7e4ee3a
CB
11136 if (inhibited)
11137 ffebad_set_inhibit (TRUE);
11138}
5ff904cd 11139
c7e4ee3a 11140/* Handle assignment statement.
5ff904cd 11141
c7e4ee3a
CB
11142 Convert dest and source using ffecom_expr, then join them
11143 with an ASSIGN op and pass the whole thing to expand_expr_stmt. */
5ff904cd 11144
c7e4ee3a
CB
11145#if FFECOM_targetCURRENT == FFECOM_targetGCC
11146void
11147ffecom_expand_let_stmt (ffebld dest, ffebld source)
11148{
11149 tree dest_tree;
11150 tree dest_length;
11151 tree source_tree;
11152 tree expr_tree;
5ff904cd 11153
c7e4ee3a
CB
11154 if (ffeinfo_basictype (ffebld_info (dest)) != FFEINFO_basictypeCHARACTER)
11155 {
11156 bool dest_used;
5ff904cd 11157
c7e4ee3a
CB
11158 /* This attempts to replicate the test below, but must not be
11159 true when the test below is false. (Always err on the side
11160 of creating unused temporaries, to avoid ICEs.) */
11161 if (ffebld_op (dest) != FFEBLD_opSYMTER
11162 || ((dest_tree = ffesymbol_hook (ffebld_symter (dest)).decl_tree)
11163 && (TREE_CODE (dest_tree) != VAR_DECL
11164 || TREE_ADDRESSABLE (dest_tree))))
11165 {
11166 ffecom_prepare_expr_ (source, dest);
11167 dest_used = TRUE;
11168 }
11169 else
11170 {
11171 ffecom_prepare_expr_ (source, NULL);
11172 dest_used = FALSE;
11173 }
5ff904cd 11174
c7e4ee3a 11175 ffecom_prepare_expr_w (NULL_TREE, dest);
5ff904cd 11176
c7e4ee3a 11177 ffecom_prepare_end ();
5ff904cd 11178
c7e4ee3a
CB
11179 dest_tree = ffecom_expr_w (NULL_TREE, dest);
11180 if (dest_tree == error_mark_node)
11181 return;
5ff904cd 11182
c7e4ee3a
CB
11183 if ((TREE_CODE (dest_tree) != VAR_DECL)
11184 || TREE_ADDRESSABLE (dest_tree))
11185 source_tree = ffecom_expr_ (source, dest_tree, dest, &dest_used,
11186 FALSE, FALSE);
11187 else
11188 {
11189 assert (! dest_used);
11190 dest_used = FALSE;
11191 source_tree = ffecom_expr (source);
11192 }
11193 if (source_tree == error_mark_node)
11194 return;
5ff904cd 11195
c7e4ee3a
CB
11196 if (dest_used)
11197 expr_tree = source_tree;
11198 else
11199 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
11200 dest_tree,
11201 source_tree);
5ff904cd 11202
c7e4ee3a
CB
11203 expand_expr_stmt (expr_tree);
11204 return;
11205 }
5ff904cd 11206
c7e4ee3a
CB
11207 ffecom_prepare_let_char_ (ffebld_size_known (dest), source);
11208 ffecom_prepare_expr_w (NULL_TREE, dest);
11209
11210 ffecom_prepare_end ();
11211
11212 ffecom_char_args_ (&dest_tree, &dest_length, dest);
11213 ffecom_let_char_ (dest_tree, dest_length, ffebld_size_known (dest),
11214 source);
5ff904cd
JL
11215}
11216
11217#endif
c7e4ee3a 11218/* ffecom_expr -- Transform expr into gcc tree
5ff904cd 11219
c7e4ee3a
CB
11220 tree t;
11221 ffebld expr; // FFE expression.
11222 tree = ffecom_expr(expr);
5ff904cd 11223
c7e4ee3a
CB
11224 Recursive descent on expr while making corresponding tree nodes and
11225 attaching type info and such. */
5ff904cd
JL
11226
11227#if FFECOM_targetCURRENT == FFECOM_targetGCC
11228tree
c7e4ee3a 11229ffecom_expr (ffebld expr)
5ff904cd 11230{
c7e4ee3a 11231 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, FALSE, FALSE);
5ff904cd 11232}
c7e4ee3a 11233
5ff904cd 11234#endif
c7e4ee3a 11235/* Like ffecom_expr, but return tree usable for assigned GOTO or FORMAT. */
5ff904cd 11236
c7e4ee3a
CB
11237#if FFECOM_targetCURRENT == FFECOM_targetGCC
11238tree
11239ffecom_expr_assign (ffebld expr)
11240{
11241 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, TRUE, FALSE);
11242}
5ff904cd 11243
c7e4ee3a
CB
11244#endif
11245/* Like ffecom_expr_rw, but return tree usable for ASSIGN. */
5ff904cd
JL
11246
11247#if FFECOM_targetCURRENT == FFECOM_targetGCC
11248tree
c7e4ee3a 11249ffecom_expr_assign_w (ffebld expr)
5ff904cd 11250{
c7e4ee3a
CB
11251 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, TRUE, FALSE);
11252}
5ff904cd 11253
5ff904cd 11254#endif
c7e4ee3a
CB
11255/* Transform expr for use as into read/write tree and stabilize the
11256 reference. Not for use on CHARACTER expressions.
5ff904cd 11257
c7e4ee3a
CB
11258 Recursive descent on expr while making corresponding tree nodes and
11259 attaching type info and such. */
5ff904cd 11260
c7e4ee3a
CB
11261#if FFECOM_targetCURRENT == FFECOM_targetGCC
11262tree
11263ffecom_expr_rw (tree type, ffebld expr)
11264{
11265 assert (expr != NULL);
11266 /* Different target types not yet supported. */
11267 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
11268
11269 return stabilize_reference (ffecom_expr (expr));
11270}
5ff904cd 11271
5ff904cd 11272#endif
c7e4ee3a
CB
11273/* Transform expr for use as into write tree and stabilize the
11274 reference. Not for use on CHARACTER expressions.
5ff904cd 11275
c7e4ee3a
CB
11276 Recursive descent on expr while making corresponding tree nodes and
11277 attaching type info and such. */
5ff904cd 11278
c7e4ee3a
CB
11279#if FFECOM_targetCURRENT == FFECOM_targetGCC
11280tree
11281ffecom_expr_w (tree type, ffebld expr)
11282{
11283 assert (expr != NULL);
11284 /* Different target types not yet supported. */
11285 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
11286
11287 return stabilize_reference (ffecom_expr (expr));
11288}
5ff904cd 11289
5ff904cd 11290#endif
c7e4ee3a
CB
11291/* Do global stuff. */
11292
11293#if FFECOM_targetCURRENT == FFECOM_targetGCC
11294void
11295ffecom_finish_compile ()
11296{
11297 assert (ffecom_outer_function_decl_ == NULL_TREE);
11298 assert (current_function_decl == NULL_TREE);
11299
11300 ffeglobal_drive (ffecom_finish_global_);
11301}
5ff904cd 11302
5ff904cd 11303#endif
c7e4ee3a
CB
11304/* Public entry point for front end to access finish_decl. */
11305
11306#if FFECOM_targetCURRENT == FFECOM_targetGCC
11307void
11308ffecom_finish_decl (tree decl, tree init, bool is_top_level)
11309{
11310 assert (!is_top_level);
11311 finish_decl (decl, init, FALSE);
11312}
5ff904cd 11313
5ff904cd 11314#endif
c7e4ee3a
CB
11315/* Finish a program unit. */
11316
11317#if FFECOM_targetCURRENT == FFECOM_targetGCC
11318void
11319ffecom_finish_progunit ()
11320{
11321 ffecom_end_compstmt ();
11322
11323 ffecom_previous_function_decl_ = current_function_decl;
11324 ffecom_which_entrypoint_decl_ = NULL_TREE;
11325
11326 finish_function (0);
11327}
5ff904cd 11328
5ff904cd 11329#endif
c7e4ee3a
CB
11330/* Wrapper for get_identifier. pattern is sprintf-like, assumed to contain
11331 one %s if text is not NULL, assumed to contain one %d if number is
11332 not -1. If both are assumed, the %s is assumed to precede the %d. */
11333
11334#if FFECOM_targetCURRENT == FFECOM_targetGCC
11335tree
11336ffecom_get_invented_identifier (const char *pattern, const char *text,
11337 int number)
11338{
11339 tree decl;
11340 char *nam;
11341 mallocSize lenlen;
11342 char space[66];
11343
11344 lenlen = 0;
11345 if (text)
11346 lenlen += strlen (text);
11347 if (number != -1)
11348 lenlen += 20;
11349 if (text || number != -1)
11350 {
11351 lenlen += strlen (pattern);
11352 if (lenlen > ARRAY_SIZE (space))
11353 nam = malloc_new_ks (malloc_pool_image (), pattern, lenlen);
11354 else
11355 nam = &space[0];
11356 }
11357 else
11358 {
11359 lenlen = 0;
11360 nam = (char *) pattern;
11361 }
11362
11363 if (text == NULL)
11364 {
11365 if (number != -1)
11366 sprintf (&nam[0], pattern, number);
11367 }
11368 else
11369 {
11370 if (number == -1)
11371 sprintf (&nam[0], pattern, text);
11372 else
11373 sprintf (&nam[0], pattern, text, number);
11374 }
11375
11376 decl = get_identifier (nam);
11377
11378 if (lenlen > ARRAY_SIZE (space))
11379 malloc_kill_ks (malloc_pool_image (), nam, lenlen);
11380
11381 IDENTIFIER_INVENTED (decl) = 1;
11382
11383 return decl;
11384}
11385
11386ffeinfoBasictype
11387ffecom_gfrt_basictype (ffecomGfrt gfrt)
11388{
11389 assert (gfrt < FFECOM_gfrt);
11390
11391 switch (ffecom_gfrt_type_[gfrt])
11392 {
11393 case FFECOM_rttypeVOID_:
11394 case FFECOM_rttypeVOIDSTAR_:
11395 return FFEINFO_basictypeNONE;
11396
11397 case FFECOM_rttypeFTNINT_:
11398 return FFEINFO_basictypeINTEGER;
11399
11400 case FFECOM_rttypeINTEGER_:
11401 return FFEINFO_basictypeINTEGER;
11402
11403 case FFECOM_rttypeLONGINT_:
11404 return FFEINFO_basictypeINTEGER;
11405
11406 case FFECOM_rttypeLOGICAL_:
11407 return FFEINFO_basictypeLOGICAL;
11408
11409 case FFECOM_rttypeREAL_F2C_:
11410 case FFECOM_rttypeREAL_GNU_:
11411 return FFEINFO_basictypeREAL;
11412
11413 case FFECOM_rttypeCOMPLEX_F2C_:
11414 case FFECOM_rttypeCOMPLEX_GNU_:
11415 return FFEINFO_basictypeCOMPLEX;
11416
11417 case FFECOM_rttypeDOUBLE_:
11418 case FFECOM_rttypeDOUBLEREAL_:
11419 return FFEINFO_basictypeREAL;
11420
11421 case FFECOM_rttypeDBLCMPLX_F2C_:
11422 case FFECOM_rttypeDBLCMPLX_GNU_:
11423 return FFEINFO_basictypeCOMPLEX;
11424
11425 case FFECOM_rttypeCHARACTER_:
11426 return FFEINFO_basictypeCHARACTER;
11427
11428 default:
11429 return FFEINFO_basictypeANY;
11430 }
11431}
11432
11433ffeinfoKindtype
11434ffecom_gfrt_kindtype (ffecomGfrt gfrt)
11435{
11436 assert (gfrt < FFECOM_gfrt);
11437
11438 switch (ffecom_gfrt_type_[gfrt])
11439 {
11440 case FFECOM_rttypeVOID_:
11441 case FFECOM_rttypeVOIDSTAR_:
11442 return FFEINFO_kindtypeNONE;
5ff904cd 11443
c7e4ee3a
CB
11444 case FFECOM_rttypeFTNINT_:
11445 return FFEINFO_kindtypeINTEGER1;
5ff904cd 11446
c7e4ee3a
CB
11447 case FFECOM_rttypeINTEGER_:
11448 return FFEINFO_kindtypeINTEGER1;
5ff904cd 11449
c7e4ee3a
CB
11450 case FFECOM_rttypeLONGINT_:
11451 return FFEINFO_kindtypeINTEGER4;
5ff904cd 11452
c7e4ee3a
CB
11453 case FFECOM_rttypeLOGICAL_:
11454 return FFEINFO_kindtypeLOGICAL1;
5ff904cd 11455
c7e4ee3a
CB
11456 case FFECOM_rttypeREAL_F2C_:
11457 case FFECOM_rttypeREAL_GNU_:
11458 return FFEINFO_kindtypeREAL1;
5ff904cd 11459
c7e4ee3a
CB
11460 case FFECOM_rttypeCOMPLEX_F2C_:
11461 case FFECOM_rttypeCOMPLEX_GNU_:
11462 return FFEINFO_kindtypeREAL1;
5ff904cd 11463
c7e4ee3a
CB
11464 case FFECOM_rttypeDOUBLE_:
11465 case FFECOM_rttypeDOUBLEREAL_:
11466 return FFEINFO_kindtypeREAL2;
5ff904cd 11467
c7e4ee3a
CB
11468 case FFECOM_rttypeDBLCMPLX_F2C_:
11469 case FFECOM_rttypeDBLCMPLX_GNU_:
11470 return FFEINFO_kindtypeREAL2;
5ff904cd 11471
c7e4ee3a
CB
11472 case FFECOM_rttypeCHARACTER_:
11473 return FFEINFO_kindtypeCHARACTER1;
5ff904cd 11474
c7e4ee3a
CB
11475 default:
11476 return FFEINFO_kindtypeANY;
11477 }
11478}
5ff904cd 11479
c7e4ee3a
CB
11480void
11481ffecom_init_0 ()
11482{
11483 tree endlink;
11484 int i;
11485 int j;
11486 tree t;
11487 tree field;
11488 ffetype type;
11489 ffetype base_type;
5ff904cd 11490
c7e4ee3a
CB
11491 /* This block of code comes from the now-obsolete cktyps.c. It checks
11492 whether the compiler environment is buggy in known ways, some of which
11493 would, if not explicitly checked here, result in subtle bugs in g77. */
5ff904cd 11494
c7e4ee3a
CB
11495 if (ffe_is_do_internal_checks ())
11496 {
11497 static char names[][12]
11498 =
11499 {"bar", "bletch", "foo", "foobar"};
11500 char *name;
11501 unsigned long ul;
11502 double fl;
5ff904cd 11503
c7e4ee3a
CB
11504 name = bsearch ("foo", &names[0], ARRAY_SIZE (names), sizeof (names[0]),
11505 (int (*)()) strcmp);
11506 if (name != (char *) &names[2])
11507 {
11508 assert ("bsearch doesn't work, #define FFEPROJ_BSEARCH 0 in proj.h"
11509 == NULL);
11510 abort ();
11511 }
5ff904cd 11512
c7e4ee3a
CB
11513 ul = strtoul ("123456789", NULL, 10);
11514 if (ul != 123456789L)
11515 {
11516 assert ("strtoul doesn't have enough range, #define FFEPROJ_STRTOUL 0\
11517 in proj.h" == NULL);
11518 abort ();
11519 }
5ff904cd 11520
c7e4ee3a
CB
11521 fl = atof ("56.789");
11522 if ((fl < 56.788) || (fl > 56.79))
11523 {
11524 assert ("atof not type double, fix your #include <stdio.h>"
11525 == NULL);
11526 abort ();
11527 }
11528 }
5ff904cd 11529
c7e4ee3a
CB
11530 /* Set the sizetype before we do anything else. This _should_ be the
11531 first type we create. */
5ff904cd 11532
c7e4ee3a
CB
11533 t = make_unsigned_type (POINTER_SIZE);
11534 assert (t == sizetype);
5ff904cd 11535
c7e4ee3a
CB
11536#if FFECOM_GCC_INCLUDE
11537 ffecom_initialize_char_syntax_ ();
11538#endif
5ff904cd 11539
c7e4ee3a
CB
11540 ffecom_outer_function_decl_ = NULL_TREE;
11541 current_function_decl = NULL_TREE;
11542 named_labels = NULL_TREE;
11543 current_binding_level = NULL_BINDING_LEVEL;
11544 free_binding_level = NULL_BINDING_LEVEL;
11545 /* Make the binding_level structure for global names. */
11546 pushlevel (0);
11547 global_binding_level = current_binding_level;
11548 current_binding_level->prep_state = 2;
5ff904cd 11549
c7e4ee3a 11550 /* Define `int' and `char' first so that dbx will output them first. */
5ff904cd 11551
c7e4ee3a
CB
11552 integer_type_node = make_signed_type (INT_TYPE_SIZE);
11553 pushdecl (build_decl (TYPE_DECL, get_identifier ("int"),
11554 integer_type_node));
5ff904cd 11555
c7e4ee3a
CB
11556 char_type_node = make_unsigned_type (CHAR_TYPE_SIZE);
11557 pushdecl (build_decl (TYPE_DECL, get_identifier ("char"),
11558 char_type_node));
5ff904cd 11559
c7e4ee3a
CB
11560 long_integer_type_node = make_signed_type (LONG_TYPE_SIZE);
11561 pushdecl (build_decl (TYPE_DECL, get_identifier ("long int"),
11562 long_integer_type_node));
5ff904cd 11563
c7e4ee3a
CB
11564 unsigned_type_node = make_unsigned_type (INT_TYPE_SIZE);
11565 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned int"),
11566 unsigned_type_node));
5ff904cd 11567
c7e4ee3a
CB
11568 long_unsigned_type_node = make_unsigned_type (LONG_TYPE_SIZE);
11569 pushdecl (build_decl (TYPE_DECL, get_identifier ("long unsigned int"),
11570 long_unsigned_type_node));
5ff904cd 11571
c7e4ee3a
CB
11572 long_long_integer_type_node = make_signed_type (LONG_LONG_TYPE_SIZE);
11573 pushdecl (build_decl (TYPE_DECL, get_identifier ("long long int"),
11574 long_long_integer_type_node));
5ff904cd 11575
c7e4ee3a
CB
11576 long_long_unsigned_type_node = make_unsigned_type (LONG_LONG_TYPE_SIZE);
11577 pushdecl (build_decl (TYPE_DECL, get_identifier ("long long unsigned int"),
11578 long_long_unsigned_type_node));
5ff904cd 11579
c7e4ee3a
CB
11580 error_mark_node = make_node (ERROR_MARK);
11581 TREE_TYPE (error_mark_node) = error_mark_node;
5ff904cd 11582
c7e4ee3a
CB
11583 short_integer_type_node = make_signed_type (SHORT_TYPE_SIZE);
11584 pushdecl (build_decl (TYPE_DECL, get_identifier ("short int"),
11585 short_integer_type_node));
5ff904cd 11586
c7e4ee3a
CB
11587 short_unsigned_type_node = make_unsigned_type (SHORT_TYPE_SIZE);
11588 pushdecl (build_decl (TYPE_DECL, get_identifier ("short unsigned int"),
11589 short_unsigned_type_node));
5ff904cd 11590
c7e4ee3a
CB
11591 /* Define both `signed char' and `unsigned char'. */
11592 signed_char_type_node = make_signed_type (CHAR_TYPE_SIZE);
11593 pushdecl (build_decl (TYPE_DECL, get_identifier ("signed char"),
11594 signed_char_type_node));
5ff904cd 11595
c7e4ee3a
CB
11596 unsigned_char_type_node = make_unsigned_type (CHAR_TYPE_SIZE);
11597 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned char"),
11598 unsigned_char_type_node));
5ff904cd 11599
c7e4ee3a
CB
11600 float_type_node = make_node (REAL_TYPE);
11601 TYPE_PRECISION (float_type_node) = FLOAT_TYPE_SIZE;
11602 layout_type (float_type_node);
11603 pushdecl (build_decl (TYPE_DECL, get_identifier ("float"),
11604 float_type_node));
5ff904cd 11605
c7e4ee3a
CB
11606 double_type_node = make_node (REAL_TYPE);
11607 TYPE_PRECISION (double_type_node) = DOUBLE_TYPE_SIZE;
11608 layout_type (double_type_node);
11609 pushdecl (build_decl (TYPE_DECL, get_identifier ("double"),
11610 double_type_node));
5ff904cd 11611
c7e4ee3a
CB
11612 long_double_type_node = make_node (REAL_TYPE);
11613 TYPE_PRECISION (long_double_type_node) = LONG_DOUBLE_TYPE_SIZE;
11614 layout_type (long_double_type_node);
11615 pushdecl (build_decl (TYPE_DECL, get_identifier ("long double"),
11616 long_double_type_node));
5ff904cd 11617
c7e4ee3a
CB
11618 complex_integer_type_node = ffecom_make_complex_type_ (integer_type_node);
11619 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex int"),
11620 complex_integer_type_node));
5ff904cd 11621
c7e4ee3a
CB
11622 complex_float_type_node = ffecom_make_complex_type_ (float_type_node);
11623 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex float"),
11624 complex_float_type_node));
5ff904cd 11625
c7e4ee3a
CB
11626 complex_double_type_node = ffecom_make_complex_type_ (double_type_node);
11627 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex double"),
11628 complex_double_type_node));
5ff904cd 11629
c7e4ee3a
CB
11630 complex_long_double_type_node = ffecom_make_complex_type_ (long_double_type_node);
11631 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex long double"),
11632 complex_long_double_type_node));
5ff904cd 11633
c7e4ee3a
CB
11634 integer_zero_node = build_int_2 (0, 0);
11635 TREE_TYPE (integer_zero_node) = integer_type_node;
11636 integer_one_node = build_int_2 (1, 0);
11637 TREE_TYPE (integer_one_node) = integer_type_node;
5ff904cd 11638
c7e4ee3a
CB
11639 size_zero_node = build_int_2 (0, 0);
11640 TREE_TYPE (size_zero_node) = sizetype;
11641 size_one_node = build_int_2 (1, 0);
11642 TREE_TYPE (size_one_node) = sizetype;
5ff904cd 11643
c7e4ee3a
CB
11644 void_type_node = make_node (VOID_TYPE);
11645 pushdecl (build_decl (TYPE_DECL, get_identifier ("void"),
11646 void_type_node));
11647 layout_type (void_type_node); /* Uses integer_zero_node */
11648 /* We are not going to have real types in C with less than byte alignment,
11649 so we might as well not have any types that claim to have it. */
11650 TYPE_ALIGN (void_type_node) = BITS_PER_UNIT;
5ff904cd 11651
c7e4ee3a
CB
11652 null_pointer_node = build_int_2 (0, 0);
11653 TREE_TYPE (null_pointer_node) = build_pointer_type (void_type_node);
11654 layout_type (TREE_TYPE (null_pointer_node));
5ff904cd 11655
c7e4ee3a 11656 string_type_node = build_pointer_type (char_type_node);
5ff904cd 11657
c7e4ee3a
CB
11658 ffecom_tree_fun_type_void
11659 = build_function_type (void_type_node, NULL_TREE);
5ff904cd 11660
c7e4ee3a
CB
11661 ffecom_tree_ptr_to_fun_type_void
11662 = build_pointer_type (ffecom_tree_fun_type_void);
5ff904cd 11663
c7e4ee3a 11664 endlink = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
5ff904cd 11665
c7e4ee3a
CB
11666 float_ftype_float
11667 = build_function_type (float_type_node,
11668 tree_cons (NULL_TREE, float_type_node, endlink));
5ff904cd 11669
c7e4ee3a
CB
11670 double_ftype_double
11671 = build_function_type (double_type_node,
11672 tree_cons (NULL_TREE, double_type_node, endlink));
5ff904cd 11673
c7e4ee3a
CB
11674 ldouble_ftype_ldouble
11675 = build_function_type (long_double_type_node,
11676 tree_cons (NULL_TREE, long_double_type_node,
11677 endlink));
5ff904cd 11678
c7e4ee3a
CB
11679 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11680 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11681 {
11682 ffecom_tree_type[i][j] = NULL_TREE;
11683 ffecom_tree_fun_type[i][j] = NULL_TREE;
11684 ffecom_tree_ptr_to_fun_type[i][j] = NULL_TREE;
11685 ffecom_f2c_typecode_[i][j] = -1;
11686 }
5ff904cd 11687
c7e4ee3a
CB
11688 /* Set up standard g77 types. Note that INTEGER and LOGICAL are set
11689 to size FLOAT_TYPE_SIZE because they have to be the same size as
11690 REAL, which also is FLOAT_TYPE_SIZE, according to the standard.
11691 Compiler options and other such stuff that change the ways these
11692 types are set should not affect this particular setup. */
5ff904cd 11693
c7e4ee3a
CB
11694 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER1]
11695 = t = make_signed_type (FLOAT_TYPE_SIZE);
11696 pushdecl (build_decl (TYPE_DECL, get_identifier ("integer"),
11697 t));
11698 type = ffetype_new ();
11699 base_type = type;
11700 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER1,
11701 type);
11702 ffetype_set_ams (type,
11703 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11704 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11705 ffetype_set_star (base_type,
11706 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11707 type);
11708 ffetype_set_kind (base_type, 1, type);
11709 assert (ffetype_size (type) == sizeof (ffetargetInteger1));
5ff904cd 11710
c7e4ee3a
CB
11711 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER1]
11712 = t = make_unsigned_type (FLOAT_TYPE_SIZE); /* HOLLERITH means unsigned. */
11713 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned"),
11714 t));
5ff904cd 11715
c7e4ee3a
CB
11716 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER2]
11717 = t = make_signed_type (CHAR_TYPE_SIZE);
11718 pushdecl (build_decl (TYPE_DECL, get_identifier ("byte"),
11719 t));
11720 type = ffetype_new ();
11721 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER2,
11722 type);
11723 ffetype_set_ams (type,
11724 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11725 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11726 ffetype_set_star (base_type,
11727 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11728 type);
11729 ffetype_set_kind (base_type, 3, type);
11730 assert (ffetype_size (type) == sizeof (ffetargetInteger2));
5ff904cd 11731
c7e4ee3a
CB
11732 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER2]
11733 = t = make_unsigned_type (CHAR_TYPE_SIZE);
11734 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned byte"),
11735 t));
11736
11737 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER3]
11738 = t = make_signed_type (CHAR_TYPE_SIZE * 2);
11739 pushdecl (build_decl (TYPE_DECL, get_identifier ("word"),
11740 t));
11741 type = ffetype_new ();
11742 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER3,
11743 type);
11744 ffetype_set_ams (type,
11745 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11746 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11747 ffetype_set_star (base_type,
11748 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11749 type);
11750 ffetype_set_kind (base_type, 6, type);
11751 assert (ffetype_size (type) == sizeof (ffetargetInteger3));
5ff904cd 11752
c7e4ee3a
CB
11753 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER3]
11754 = t = make_unsigned_type (CHAR_TYPE_SIZE * 2);
11755 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned word"),
11756 t));
5ff904cd 11757
c7e4ee3a
CB
11758 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER4]
11759 = t = make_signed_type (FLOAT_TYPE_SIZE * 2);
11760 pushdecl (build_decl (TYPE_DECL, get_identifier ("integer4"),
11761 t));
11762 type = ffetype_new ();
11763 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER4,
11764 type);
11765 ffetype_set_ams (type,
11766 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11767 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11768 ffetype_set_star (base_type,
11769 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11770 type);
11771 ffetype_set_kind (base_type, 2, type);
11772 assert (ffetype_size (type) == sizeof (ffetargetInteger4));
5ff904cd 11773
c7e4ee3a
CB
11774 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER4]
11775 = t = make_unsigned_type (FLOAT_TYPE_SIZE * 2);
11776 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned4"),
11777 t));
5ff904cd 11778
c7e4ee3a
CB
11779#if 0
11780 if (ffe_is_do_internal_checks ()
11781 && LONG_TYPE_SIZE != FLOAT_TYPE_SIZE
11782 && LONG_TYPE_SIZE != CHAR_TYPE_SIZE
11783 && LONG_TYPE_SIZE != SHORT_TYPE_SIZE
11784 && LONG_TYPE_SIZE != LONG_LONG_TYPE_SIZE)
5ff904cd 11785 {
c7e4ee3a
CB
11786 fprintf (stderr, "Sorry, no g77 support for LONG_TYPE_SIZE (%d bits) yet.\n",
11787 LONG_TYPE_SIZE);
5ff904cd 11788 }
c7e4ee3a 11789#endif
5ff904cd 11790
c7e4ee3a
CB
11791 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL1]
11792 = t = make_signed_type (FLOAT_TYPE_SIZE);
11793 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical"),
11794 t));
11795 type = ffetype_new ();
11796 base_type = type;
11797 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL1,
11798 type);
11799 ffetype_set_ams (type,
11800 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11801 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11802 ffetype_set_star (base_type,
11803 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11804 type);
11805 ffetype_set_kind (base_type, 1, type);
11806 assert (ffetype_size (type) == sizeof (ffetargetLogical1));
5ff904cd 11807
c7e4ee3a
CB
11808 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL2]
11809 = t = make_signed_type (CHAR_TYPE_SIZE);
11810 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical2"),
11811 t));
11812 type = ffetype_new ();
11813 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL2,
11814 type);
11815 ffetype_set_ams (type,
11816 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11817 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11818 ffetype_set_star (base_type,
11819 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11820 type);
11821 ffetype_set_kind (base_type, 3, type);
11822 assert (ffetype_size (type) == sizeof (ffetargetLogical2));
5ff904cd 11823
c7e4ee3a
CB
11824 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL3]
11825 = t = make_signed_type (CHAR_TYPE_SIZE * 2);
11826 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical3"),
11827 t));
11828 type = ffetype_new ();
11829 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL3,
11830 type);
11831 ffetype_set_ams (type,
11832 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11833 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11834 ffetype_set_star (base_type,
11835 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11836 type);
11837 ffetype_set_kind (base_type, 6, type);
11838 assert (ffetype_size (type) == sizeof (ffetargetLogical3));
5ff904cd 11839
c7e4ee3a
CB
11840 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL4]
11841 = t = make_signed_type (FLOAT_TYPE_SIZE * 2);
11842 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical4"),
11843 t));
11844 type = ffetype_new ();
11845 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL4,
11846 type);
11847 ffetype_set_ams (type,
11848 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11849 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11850 ffetype_set_star (base_type,
11851 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11852 type);
11853 ffetype_set_kind (base_type, 2, type);
11854 assert (ffetype_size (type) == sizeof (ffetargetLogical4));
5ff904cd 11855
c7e4ee3a
CB
11856 ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]
11857 = t = make_node (REAL_TYPE);
11858 TYPE_PRECISION (t) = FLOAT_TYPE_SIZE;
11859 pushdecl (build_decl (TYPE_DECL, get_identifier ("real"),
11860 t));
11861 layout_type (t);
11862 type = ffetype_new ();
11863 base_type = type;
11864 ffeinfo_set_type (FFEINFO_basictypeREAL, FFEINFO_kindtypeREAL1,
11865 type);
11866 ffetype_set_ams (type,
11867 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11868 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11869 ffetype_set_star (base_type,
11870 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11871 type);
11872 ffetype_set_kind (base_type, 1, type);
11873 ffecom_f2c_typecode_[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]
11874 = FFETARGET_f2cTYREAL;
11875 assert (ffetype_size (type) == sizeof (ffetargetReal1));
5ff904cd 11876
c7e4ee3a
CB
11877 ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREALDOUBLE]
11878 = t = make_node (REAL_TYPE);
11879 TYPE_PRECISION (t) = FLOAT_TYPE_SIZE * 2; /* Always twice REAL. */
11880 pushdecl (build_decl (TYPE_DECL, get_identifier ("double precision"),
11881 t));
11882 layout_type (t);
11883 type = ffetype_new ();
11884 ffeinfo_set_type (FFEINFO_basictypeREAL, FFEINFO_kindtypeREALDOUBLE,
11885 type);
11886 ffetype_set_ams (type,
11887 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11888 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11889 ffetype_set_star (base_type,
11890 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11891 type);
11892 ffetype_set_kind (base_type, 2, type);
11893 ffecom_f2c_typecode_[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2]
11894 = FFETARGET_f2cTYDREAL;
11895 assert (ffetype_size (type) == sizeof (ffetargetReal2));
5ff904cd 11896
c7e4ee3a
CB
11897 ffecom_tree_type[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL1]
11898 = t = ffecom_make_complex_type_ (ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]);
11899 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex"),
11900 t));
11901 type = ffetype_new ();
11902 base_type = type;
11903 ffeinfo_set_type (FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREAL1,
11904 type);
11905 ffetype_set_ams (type,
11906 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11907 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11908 ffetype_set_star (base_type,
11909 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11910 type);
11911 ffetype_set_kind (base_type, 1, type);
11912 ffecom_f2c_typecode_[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL1]
11913 = FFETARGET_f2cTYCOMPLEX;
11914 assert (ffetype_size (type) == sizeof (ffetargetComplex1));
5ff904cd 11915
c7e4ee3a
CB
11916 ffecom_tree_type[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREALDOUBLE]
11917 = t = ffecom_make_complex_type_ (ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2]);
11918 pushdecl (build_decl (TYPE_DECL, get_identifier ("double complex"),
11919 t));
11920 type = ffetype_new ();
11921 ffeinfo_set_type (FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREALDOUBLE,
11922 type);
11923 ffetype_set_ams (type,
11924 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11925 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11926 ffetype_set_star (base_type,
11927 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11928 type);
11929 ffetype_set_kind (base_type, 2,
11930 type);
11931 ffecom_f2c_typecode_[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL2]
11932 = FFETARGET_f2cTYDCOMPLEX;
11933 assert (ffetype_size (type) == sizeof (ffetargetComplex2));
5ff904cd 11934
c7e4ee3a 11935 /* Make function and ptr-to-function types for non-CHARACTER types. */
5ff904cd 11936
c7e4ee3a
CB
11937 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11938 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11939 {
11940 if ((t = ffecom_tree_type[i][j]) != NULL_TREE)
11941 {
11942 if (i == FFEINFO_basictypeINTEGER)
11943 {
11944 /* Figure out the smallest INTEGER type that can hold
11945 a pointer on this machine. */
11946 if (GET_MODE_SIZE (TYPE_MODE (t))
11947 >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
11948 {
11949 if ((ffecom_pointer_kind_ == FFEINFO_kindtypeNONE)
11950 || (GET_MODE_SIZE (TYPE_MODE (ffecom_tree_type[i][ffecom_pointer_kind_]))
11951 > GET_MODE_SIZE (TYPE_MODE (t))))
11952 ffecom_pointer_kind_ = j;
11953 }
11954 }
11955 else if (i == FFEINFO_basictypeCOMPLEX)
11956 t = void_type_node;
11957 /* For f2c compatibility, REAL functions are really
11958 implemented as DOUBLE PRECISION. */
11959 else if ((i == FFEINFO_basictypeREAL)
11960 && (j == FFEINFO_kindtypeREAL1))
11961 t = ffecom_tree_type
11962 [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2];
5ff904cd 11963
c7e4ee3a
CB
11964 t = ffecom_tree_fun_type[i][j] = build_function_type (t,
11965 NULL_TREE);
11966 ffecom_tree_ptr_to_fun_type[i][j] = build_pointer_type (t);
11967 }
11968 }
5ff904cd 11969
c7e4ee3a 11970 /* Set up pointer types. */
5ff904cd 11971
c7e4ee3a
CB
11972 if (ffecom_pointer_kind_ == FFEINFO_basictypeNONE)
11973 fatal ("no INTEGER type can hold a pointer on this configuration");
11974 else if (0 && ffe_is_do_internal_checks ())
11975 fprintf (stderr, "Pointer type kt=%d\n", ffecom_pointer_kind_);
11976 ffetype_set_kind (ffeinfo_type (FFEINFO_basictypeINTEGER,
11977 FFEINFO_kindtypeINTEGERDEFAULT),
11978 7,
11979 ffeinfo_type (FFEINFO_basictypeINTEGER,
11980 ffecom_pointer_kind_));
5ff904cd 11981
c7e4ee3a
CB
11982 if (ffe_is_ugly_assign ())
11983 ffecom_label_kind_ = ffecom_pointer_kind_; /* Require ASSIGN etc to this. */
11984 else
11985 ffecom_label_kind_ = FFEINFO_kindtypeINTEGERDEFAULT;
11986 if (0 && ffe_is_do_internal_checks ())
11987 fprintf (stderr, "Label type kt=%d\n", ffecom_label_kind_);
5ff904cd 11988
c7e4ee3a
CB
11989 ffecom_integer_type_node
11990 = ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER1];
11991 ffecom_integer_zero_node = convert (ffecom_integer_type_node,
11992 integer_zero_node);
11993 ffecom_integer_one_node = convert (ffecom_integer_type_node,
11994 integer_one_node);
5ff904cd 11995
c7e4ee3a
CB
11996 /* Yes, the "FLOAT_TYPE_SIZE" references below are intentional.
11997 Turns out that by TYLONG, runtime/libI77/lio.h really means
11998 "whatever size an ftnint is". For consistency and sanity,
11999 com.h and runtime/f2c.h.in agree that flag, ftnint, and ftlen
12000 all are INTEGER, which we also make out of whatever back-end
12001 integer type is FLOAT_TYPE_SIZE bits wide. This change, from
12002 LONG_TYPE_SIZE, for TYLONG and TYLOGICAL, was necessary to
12003 accommodate machines like the Alpha. Note that this suggests
12004 f2c and libf2c are missing a distinction perhaps needed on
12005 some machines between "int" and "long int". -- burley 0.5.5 950215 */
5ff904cd 12006
c7e4ee3a
CB
12007 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, FLOAT_TYPE_SIZE,
12008 FFETARGET_f2cTYLONG);
12009 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, SHORT_TYPE_SIZE,
12010 FFETARGET_f2cTYSHORT);
12011 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, CHAR_TYPE_SIZE,
12012 FFETARGET_f2cTYINT1);
12013 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, LONG_LONG_TYPE_SIZE,
12014 FFETARGET_f2cTYQUAD);
12015 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, FLOAT_TYPE_SIZE,
12016 FFETARGET_f2cTYLOGICAL);
12017 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, SHORT_TYPE_SIZE,
12018 FFETARGET_f2cTYLOGICAL2);
12019 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, CHAR_TYPE_SIZE,
12020 FFETARGET_f2cTYLOGICAL1);
12021 /* ~~~Not really such a type in libf2c, e.g. I/O support? */
12022 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, LONG_LONG_TYPE_SIZE,
12023 FFETARGET_f2cTYQUAD);
5ff904cd 12024
c7e4ee3a
CB
12025 /* CHARACTER stuff is all special-cased, so it is not handled in the above
12026 loop. CHARACTER items are built as arrays of unsigned char. */
5ff904cd 12027
c7e4ee3a
CB
12028 ffecom_tree_type[FFEINFO_basictypeCHARACTER]
12029 [FFEINFO_kindtypeCHARACTER1] = t = char_type_node;
12030 type = ffetype_new ();
12031 base_type = type;
12032 ffeinfo_set_type (FFEINFO_basictypeCHARACTER,
12033 FFEINFO_kindtypeCHARACTER1,
12034 type);
12035 ffetype_set_ams (type,
12036 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
12037 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
12038 ffetype_set_kind (base_type, 1, type);
12039 assert (ffetype_size (type)
12040 == sizeof (((ffetargetCharacter1) { 0, NULL }).text[0]));
5ff904cd 12041
c7e4ee3a
CB
12042 ffecom_tree_fun_type[FFEINFO_basictypeCHARACTER]
12043 [FFEINFO_kindtypeCHARACTER1] = ffecom_tree_fun_type_void;
12044 ffecom_tree_ptr_to_fun_type[FFEINFO_basictypeCHARACTER]
12045 [FFEINFO_kindtypeCHARACTER1]
12046 = ffecom_tree_ptr_to_fun_type_void;
12047 ffecom_f2c_typecode_[FFEINFO_basictypeCHARACTER][FFEINFO_kindtypeCHARACTER1]
12048 = FFETARGET_f2cTYCHAR;
5ff904cd 12049
c7e4ee3a
CB
12050 ffecom_f2c_typecode_[FFEINFO_basictypeANY][FFEINFO_kindtypeANY]
12051 = 0;
5ff904cd 12052
c7e4ee3a 12053 /* Make multi-return-value type and fields. */
5ff904cd 12054
c7e4ee3a 12055 ffecom_multi_type_node_ = make_node (UNION_TYPE);
5ff904cd 12056
c7e4ee3a 12057 field = NULL_TREE;
5ff904cd 12058
c7e4ee3a
CB
12059 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
12060 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
12061 {
12062 char name[30];
5ff904cd 12063
c7e4ee3a
CB
12064 if (ffecom_tree_type[i][j] == NULL_TREE)
12065 continue; /* Not supported. */
12066 sprintf (&name[0], "bt_%s_kt_%s",
12067 ffeinfo_basictype_string ((ffeinfoBasictype) i),
12068 ffeinfo_kindtype_string ((ffeinfoKindtype) j));
12069 ffecom_multi_fields_[i][j] = build_decl (FIELD_DECL,
12070 get_identifier (name),
12071 ffecom_tree_type[i][j]);
12072 DECL_CONTEXT (ffecom_multi_fields_[i][j])
12073 = ffecom_multi_type_node_;
12074 DECL_FRAME_SIZE (ffecom_multi_fields_[i][j]) = 0;
12075 TREE_CHAIN (ffecom_multi_fields_[i][j]) = field;
12076 field = ffecom_multi_fields_[i][j];
12077 }
5ff904cd 12078
c7e4ee3a
CB
12079 TYPE_FIELDS (ffecom_multi_type_node_) = field;
12080 layout_type (ffecom_multi_type_node_);
5ff904cd 12081
c7e4ee3a
CB
12082 /* Subroutines usually return integer because they might have alternate
12083 returns. */
5ff904cd 12084
c7e4ee3a
CB
12085 ffecom_tree_subr_type
12086 = build_function_type (integer_type_node, NULL_TREE);
12087 ffecom_tree_ptr_to_subr_type
12088 = build_pointer_type (ffecom_tree_subr_type);
12089 ffecom_tree_blockdata_type
12090 = build_function_type (void_type_node, NULL_TREE);
5ff904cd 12091
c7e4ee3a
CB
12092 builtin_function ("__builtin_sqrtf", float_ftype_float,
12093 BUILT_IN_FSQRT, "sqrtf");
12094 builtin_function ("__builtin_fsqrt", double_ftype_double,
12095 BUILT_IN_FSQRT, "sqrt");
12096 builtin_function ("__builtin_sqrtl", ldouble_ftype_ldouble,
12097 BUILT_IN_FSQRT, "sqrtl");
12098 builtin_function ("__builtin_sinf", float_ftype_float,
12099 BUILT_IN_SIN, "sinf");
12100 builtin_function ("__builtin_sin", double_ftype_double,
12101 BUILT_IN_SIN, "sin");
12102 builtin_function ("__builtin_sinl", ldouble_ftype_ldouble,
12103 BUILT_IN_SIN, "sinl");
12104 builtin_function ("__builtin_cosf", float_ftype_float,
12105 BUILT_IN_COS, "cosf");
12106 builtin_function ("__builtin_cos", double_ftype_double,
12107 BUILT_IN_COS, "cos");
12108 builtin_function ("__builtin_cosl", ldouble_ftype_ldouble,
12109 BUILT_IN_COS, "cosl");
5ff904cd 12110
c7e4ee3a
CB
12111#if BUILT_FOR_270
12112 pedantic_lvalues = FALSE;
5ff904cd 12113#endif
5ff904cd 12114
c7e4ee3a
CB
12115 ffecom_f2c_make_type_ (&ffecom_f2c_integer_type_node,
12116 FFECOM_f2cINTEGER,
12117 "integer");
12118 ffecom_f2c_make_type_ (&ffecom_f2c_address_type_node,
12119 FFECOM_f2cADDRESS,
12120 "address");
12121 ffecom_f2c_make_type_ (&ffecom_f2c_real_type_node,
12122 FFECOM_f2cREAL,
12123 "real");
12124 ffecom_f2c_make_type_ (&ffecom_f2c_doublereal_type_node,
12125 FFECOM_f2cDOUBLEREAL,
12126 "doublereal");
12127 ffecom_f2c_make_type_ (&ffecom_f2c_complex_type_node,
12128 FFECOM_f2cCOMPLEX,
12129 "complex");
12130 ffecom_f2c_make_type_ (&ffecom_f2c_doublecomplex_type_node,
12131 FFECOM_f2cDOUBLECOMPLEX,
12132 "doublecomplex");
12133 ffecom_f2c_make_type_ (&ffecom_f2c_longint_type_node,
12134 FFECOM_f2cLONGINT,
12135 "longint");
12136 ffecom_f2c_make_type_ (&ffecom_f2c_logical_type_node,
12137 FFECOM_f2cLOGICAL,
12138 "logical");
12139 ffecom_f2c_make_type_ (&ffecom_f2c_flag_type_node,
12140 FFECOM_f2cFLAG,
12141 "flag");
12142 ffecom_f2c_make_type_ (&ffecom_f2c_ftnlen_type_node,
12143 FFECOM_f2cFTNLEN,
12144 "ftnlen");
12145 ffecom_f2c_make_type_ (&ffecom_f2c_ftnint_type_node,
12146 FFECOM_f2cFTNINT,
12147 "ftnint");
5ff904cd 12148
c7e4ee3a
CB
12149 ffecom_f2c_ftnlen_zero_node
12150 = convert (ffecom_f2c_ftnlen_type_node, integer_zero_node);
5ff904cd 12151
c7e4ee3a
CB
12152 ffecom_f2c_ftnlen_one_node
12153 = convert (ffecom_f2c_ftnlen_type_node, integer_one_node);
5ff904cd 12154
c7e4ee3a
CB
12155 ffecom_f2c_ftnlen_two_node = build_int_2 (2, 0);
12156 TREE_TYPE (ffecom_f2c_ftnlen_two_node) = ffecom_integer_type_node;
5ff904cd 12157
c7e4ee3a
CB
12158 ffecom_f2c_ptr_to_ftnlen_type_node
12159 = build_pointer_type (ffecom_f2c_ftnlen_type_node);
5ff904cd 12160
c7e4ee3a
CB
12161 ffecom_f2c_ptr_to_ftnint_type_node
12162 = build_pointer_type (ffecom_f2c_ftnint_type_node);
5ff904cd 12163
c7e4ee3a
CB
12164 ffecom_f2c_ptr_to_integer_type_node
12165 = build_pointer_type (ffecom_f2c_integer_type_node);
5ff904cd 12166
c7e4ee3a
CB
12167 ffecom_f2c_ptr_to_real_type_node
12168 = build_pointer_type (ffecom_f2c_real_type_node);
5ff904cd 12169
c7e4ee3a
CB
12170 ffecom_float_zero_ = build_real (float_type_node, dconst0);
12171 ffecom_double_zero_ = build_real (double_type_node, dconst0);
12172 {
12173 REAL_VALUE_TYPE point_5;
5ff904cd 12174
c7e4ee3a
CB
12175#ifdef REAL_ARITHMETIC
12176 REAL_ARITHMETIC (point_5, RDIV_EXPR, dconst1, dconst2);
12177#else
12178 point_5 = .5;
12179#endif
12180 ffecom_float_half_ = build_real (float_type_node, point_5);
12181 ffecom_double_half_ = build_real (double_type_node, point_5);
12182 }
5ff904cd 12183
c7e4ee3a 12184 /* Do "extern int xargc;". */
5ff904cd 12185
c7e4ee3a
CB
12186 ffecom_tree_xargc_ = build_decl (VAR_DECL,
12187 get_identifier ("f__xargc"),
12188 integer_type_node);
12189 DECL_EXTERNAL (ffecom_tree_xargc_) = 1;
12190 TREE_STATIC (ffecom_tree_xargc_) = 1;
12191 TREE_PUBLIC (ffecom_tree_xargc_) = 1;
12192 ffecom_tree_xargc_ = start_decl (ffecom_tree_xargc_, FALSE);
12193 finish_decl (ffecom_tree_xargc_, NULL_TREE, FALSE);
5ff904cd 12194
c7e4ee3a
CB
12195#if 0 /* This is being fixed, and seems to be working now. */
12196 if ((FLOAT_TYPE_SIZE != 32)
12197 || (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node))) != 32))
5ff904cd 12198 {
c7e4ee3a
CB
12199 warning ("configuration: REAL, INTEGER, and LOGICAL are %d bits wide,",
12200 (int) FLOAT_TYPE_SIZE);
12201 warning ("and pointers are %d bits wide, but g77 doesn't yet work",
12202 (int) TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node))));
12203 warning ("properly unless they all are 32 bits wide.");
12204 warning ("Please keep this in mind before you report bugs. g77 should");
12205 warning ("support non-32-bit machines better as of version 0.6.");
12206 }
12207#endif
5ff904cd 12208
c7e4ee3a
CB
12209#if 0 /* Code in ste.c that would crash has been commented out. */
12210 if (TYPE_PRECISION (ffecom_f2c_ftnlen_type_node)
12211 < TYPE_PRECISION (string_type_node))
12212 /* I/O will probably crash. */
12213 warning ("configuration: char * holds %d bits, but ftnlen only %d",
12214 TYPE_PRECISION (string_type_node),
12215 TYPE_PRECISION (ffecom_f2c_ftnlen_type_node));
12216#endif
5ff904cd 12217
c7e4ee3a
CB
12218#if 0 /* ASSIGN-related stuff has been changed to accommodate this. */
12219 if (TYPE_PRECISION (ffecom_integer_type_node)
12220 < TYPE_PRECISION (string_type_node))
12221 /* ASSIGN 10 TO I will crash. */
12222 warning ("configuration: char * holds %d bits, but INTEGER only %d --\n\
12223 ASSIGN statement might fail",
12224 TYPE_PRECISION (string_type_node),
12225 TYPE_PRECISION (ffecom_integer_type_node));
12226#endif
12227}
5ff904cd 12228
c7e4ee3a
CB
12229#endif
12230/* ffecom_init_2 -- Initialize
5ff904cd 12231
c7e4ee3a 12232 ffecom_init_2(); */
5ff904cd 12233
c7e4ee3a
CB
12234#if FFECOM_targetCURRENT == FFECOM_targetGCC
12235void
12236ffecom_init_2 ()
12237{
12238 assert (ffecom_outer_function_decl_ == NULL_TREE);
12239 assert (current_function_decl == NULL_TREE);
12240 assert (ffecom_which_entrypoint_decl_ == NULL_TREE);
5ff904cd 12241
c7e4ee3a
CB
12242 ffecom_master_arglist_ = NULL;
12243 ++ffecom_num_fns_;
12244 ffecom_primary_entry_ = NULL;
12245 ffecom_is_altreturning_ = FALSE;
12246 ffecom_func_result_ = NULL_TREE;
12247 ffecom_multi_retval_ = NULL_TREE;
12248}
5ff904cd 12249
c7e4ee3a
CB
12250#endif
12251/* ffecom_list_expr -- Transform list of exprs into gcc tree
5ff904cd 12252
c7e4ee3a
CB
12253 tree t;
12254 ffebld expr; // FFE opITEM list.
12255 tree = ffecom_list_expr(expr);
5ff904cd 12256
c7e4ee3a 12257 List of actual args is transformed into corresponding gcc backend list. */
5ff904cd 12258
c7e4ee3a
CB
12259#if FFECOM_targetCURRENT == FFECOM_targetGCC
12260tree
12261ffecom_list_expr (ffebld expr)
5ff904cd 12262{
c7e4ee3a
CB
12263 tree list;
12264 tree *plist = &list;
12265 tree trail = NULL_TREE; /* Append char length args here. */
12266 tree *ptrail = &trail;
12267 tree length;
5ff904cd 12268
c7e4ee3a 12269 while (expr != NULL)
5ff904cd 12270 {
c7e4ee3a 12271 tree texpr = ffecom_arg_expr (ffebld_head (expr), &length);
5ff904cd 12272
c7e4ee3a
CB
12273 if (texpr == error_mark_node)
12274 return error_mark_node;
5ff904cd 12275
c7e4ee3a
CB
12276 *plist = build_tree_list (NULL_TREE, texpr);
12277 plist = &TREE_CHAIN (*plist);
12278 expr = ffebld_trail (expr);
12279 if (length != NULL_TREE)
5ff904cd 12280 {
c7e4ee3a
CB
12281 *ptrail = build_tree_list (NULL_TREE, length);
12282 ptrail = &TREE_CHAIN (*ptrail);
5ff904cd
JL
12283 }
12284 }
12285
c7e4ee3a 12286 *plist = trail;
5ff904cd 12287
c7e4ee3a
CB
12288 return list;
12289}
5ff904cd 12290
c7e4ee3a
CB
12291#endif
12292/* ffecom_list_ptr_to_expr -- Transform list of exprs into gcc tree
5ff904cd 12293
c7e4ee3a
CB
12294 tree t;
12295 ffebld expr; // FFE opITEM list.
12296 tree = ffecom_list_ptr_to_expr(expr);
5ff904cd 12297
c7e4ee3a
CB
12298 List of actual args is transformed into corresponding gcc backend list for
12299 use in calling an external procedure (vs. a statement function). */
5ff904cd 12300
c7e4ee3a
CB
12301#if FFECOM_targetCURRENT == FFECOM_targetGCC
12302tree
12303ffecom_list_ptr_to_expr (ffebld expr)
12304{
12305 tree list;
12306 tree *plist = &list;
12307 tree trail = NULL_TREE; /* Append char length args here. */
12308 tree *ptrail = &trail;
12309 tree length;
5ff904cd 12310
c7e4ee3a
CB
12311 while (expr != NULL)
12312 {
12313 tree texpr = ffecom_arg_ptr_to_expr (ffebld_head (expr), &length);
5ff904cd 12314
c7e4ee3a
CB
12315 if (texpr == error_mark_node)
12316 return error_mark_node;
5ff904cd 12317
c7e4ee3a
CB
12318 *plist = build_tree_list (NULL_TREE, texpr);
12319 plist = &TREE_CHAIN (*plist);
12320 expr = ffebld_trail (expr);
12321 if (length != NULL_TREE)
12322 {
12323 *ptrail = build_tree_list (NULL_TREE, length);
12324 ptrail = &TREE_CHAIN (*ptrail);
12325 }
12326 }
5ff904cd 12327
c7e4ee3a 12328 *plist = trail;
5ff904cd 12329
c7e4ee3a
CB
12330 return list;
12331}
5ff904cd 12332
c7e4ee3a
CB
12333#endif
12334/* Obtain gcc's LABEL_DECL tree for label. */
5ff904cd 12335
c7e4ee3a
CB
12336#if FFECOM_targetCURRENT == FFECOM_targetGCC
12337tree
12338ffecom_lookup_label (ffelab label)
12339{
12340 tree glabel;
5ff904cd 12341
c7e4ee3a
CB
12342 if (ffelab_hook (label) == NULL_TREE)
12343 {
12344 char labelname[16];
5ff904cd 12345
c7e4ee3a
CB
12346 switch (ffelab_type (label))
12347 {
12348 case FFELAB_typeLOOPEND:
12349 case FFELAB_typeNOTLOOP:
12350 case FFELAB_typeENDIF:
12351 sprintf (labelname, "%" ffelabValue_f "u", ffelab_value (label));
12352 glabel = build_decl (LABEL_DECL, get_identifier (labelname),
12353 void_type_node);
12354 DECL_CONTEXT (glabel) = current_function_decl;
12355 DECL_MODE (glabel) = VOIDmode;
12356 break;
5ff904cd 12357
c7e4ee3a
CB
12358 case FFELAB_typeFORMAT:
12359 push_obstacks_nochange ();
12360 end_temporary_allocation ();
5ff904cd 12361
c7e4ee3a
CB
12362 glabel = build_decl (VAR_DECL,
12363 ffecom_get_invented_identifier
12364 ("__g77_format_%d", NULL,
12365 (int) ffelab_value (label)),
12366 build_type_variant (build_array_type
12367 (char_type_node,
12368 NULL_TREE),
12369 1, 0));
12370 TREE_CONSTANT (glabel) = 1;
12371 TREE_STATIC (glabel) = 1;
12372 DECL_CONTEXT (glabel) = 0;
12373 DECL_INITIAL (glabel) = NULL;
12374 make_decl_rtl (glabel, NULL, 0);
12375 expand_decl (glabel);
5ff904cd 12376
c7e4ee3a
CB
12377 resume_temporary_allocation ();
12378 pop_obstacks ();
5ff904cd 12379
c7e4ee3a 12380 break;
5ff904cd 12381
c7e4ee3a
CB
12382 case FFELAB_typeANY:
12383 glabel = error_mark_node;
12384 break;
5ff904cd 12385
c7e4ee3a
CB
12386 default:
12387 assert ("bad label type" == NULL);
12388 glabel = NULL;
12389 break;
12390 }
12391 ffelab_set_hook (label, glabel);
12392 }
12393 else
12394 {
12395 glabel = ffelab_hook (label);
12396 }
5ff904cd 12397
c7e4ee3a
CB
12398 return glabel;
12399}
5ff904cd 12400
c7e4ee3a
CB
12401#endif
12402/* Stabilizes the arguments. Don't use this if the lhs and rhs come from
12403 a single source specification (as in the fourth argument of MVBITS).
12404 If the type is NULL_TREE, the type of lhs is used to make the type of
12405 the MODIFY_EXPR. */
5ff904cd 12406
c7e4ee3a
CB
12407#if FFECOM_targetCURRENT == FFECOM_targetGCC
12408tree
12409ffecom_modify (tree newtype, tree lhs,
12410 tree rhs)
12411{
12412 if (lhs == error_mark_node || rhs == error_mark_node)
12413 return error_mark_node;
5ff904cd 12414
c7e4ee3a
CB
12415 if (newtype == NULL_TREE)
12416 newtype = TREE_TYPE (lhs);
5ff904cd 12417
c7e4ee3a
CB
12418 if (TREE_SIDE_EFFECTS (lhs))
12419 lhs = stabilize_reference (lhs);
5ff904cd 12420
c7e4ee3a
CB
12421 return ffecom_2s (MODIFY_EXPR, newtype, lhs, rhs);
12422}
5ff904cd 12423
c7e4ee3a 12424#endif
5ff904cd 12425
c7e4ee3a 12426/* Register source file name. */
5ff904cd 12427
c7e4ee3a
CB
12428void
12429ffecom_file (char *name)
12430{
12431#if FFECOM_GCC_INCLUDE
12432 ffecom_file_ (name);
12433#endif
12434}
5ff904cd 12435
c7e4ee3a 12436/* ffecom_notify_init_storage -- An aggregate storage is now fully init'ed
5ff904cd 12437
c7e4ee3a
CB
12438 ffestorag st;
12439 ffecom_notify_init_storage(st);
5ff904cd 12440
c7e4ee3a
CB
12441 Gets called when all possible units in an aggregate storage area (a LOCAL
12442 with equivalences or a COMMON) have been initialized. The initialization
12443 info either is in ffestorag_init or, if that is NULL,
12444 ffestorag_accretion:
5ff904cd 12445
c7e4ee3a
CB
12446 ffestorag_init may contain an opCONTER or opARRTER. opCONTER may occur
12447 even for an array if the array is one element in length!
5ff904cd 12448
c7e4ee3a
CB
12449 ffestorag_accretion will contain an opACCTER. It is much like an
12450 opARRTER except it has an ffebit object in it instead of just a size.
12451 The back end can use the info in the ffebit object, if it wants, to
12452 reduce the amount of actual initialization, but in any case it should
12453 kill the ffebit object when done. Also, set accretion to NULL but
12454 init to a non-NULL value.
5ff904cd 12455
c7e4ee3a
CB
12456 After performing initialization, DO NOT set init to NULL, because that'll
12457 tell the front end it is ok for more initialization to happen. Instead,
12458 set init to an opANY expression or some such thing that you can use to
12459 tell that you've already initialized the object.
5ff904cd 12460
c7e4ee3a
CB
12461 27-Oct-91 JCB 1.1
12462 Support two-pass FFE. */
5ff904cd 12463
c7e4ee3a
CB
12464void
12465ffecom_notify_init_storage (ffestorag st)
12466{
12467 ffebld init; /* The initialization expression. */
12468#if 0 && FFECOM_targetCURRENT == FFECOM_targetGCC
12469 ffetargetOffset size; /* The size of the entity. */
12470 ffetargetAlign pad; /* Its initial padding. */
12471#endif
12472
12473 if (ffestorag_init (st) == NULL)
5ff904cd 12474 {
c7e4ee3a
CB
12475 init = ffestorag_accretion (st);
12476 assert (init != NULL);
12477 ffestorag_set_accretion (st, NULL);
12478 ffestorag_set_accretes (st, 0);
12479
12480#if 0 && FFECOM_targetCURRENT == FFECOM_targetGCC
12481 /* For GNU backend, just turn ACCTER into ARRTER and proceed. */
12482 size = ffebld_accter_size (init);
12483 pad = ffebld_accter_pad (init);
12484 ffebit_kill (ffebld_accter_bits (init));
12485 ffebld_set_op (init, FFEBLD_opARRTER);
12486 ffebld_set_arrter (init, ffebld_accter (init));
12487 ffebld_arrter_set_size (init, size);
12488 ffebld_arrter_set_pad (init, size);
12489#endif
12490
12491#if FFECOM_TWOPASS
12492 ffestorag_set_init (st, init);
12493#endif
5ff904cd 12494 }
c7e4ee3a
CB
12495#if FFECOM_ONEPASS
12496 else
12497 init = ffestorag_init (st);
5ff904cd
JL
12498#endif
12499
c7e4ee3a
CB
12500#if FFECOM_ONEPASS /* Process the inits, wipe 'em out. */
12501 ffestorag_set_init (st, ffebld_new_any ());
5ff904cd 12502
c7e4ee3a
CB
12503 if (ffebld_op (init) == FFEBLD_opANY)
12504 return; /* Oh, we already did this! */
5ff904cd 12505
c7e4ee3a
CB
12506#if FFECOM_targetCURRENT == FFECOM_targetFFE
12507 {
12508 ffesymbol s;
5ff904cd 12509
c7e4ee3a
CB
12510 if (ffestorag_symbol (st) != NULL)
12511 s = ffestorag_symbol (st);
12512 else
12513 s = ffestorag_typesymbol (st);
5ff904cd 12514
c7e4ee3a
CB
12515 fprintf (dmpout, "= initialize_storage \"%s\" ",
12516 (s != NULL) ? ffesymbol_text (s) : "(unnamed)");
12517 ffebld_dump (init);
12518 fputc ('\n', dmpout);
12519 }
12520#endif
5ff904cd 12521
c7e4ee3a
CB
12522#endif /* if FFECOM_ONEPASS */
12523}
5ff904cd 12524
c7e4ee3a 12525/* ffecom_notify_init_symbol -- A symbol is now fully init'ed
5ff904cd 12526
c7e4ee3a
CB
12527 ffesymbol s;
12528 ffecom_notify_init_symbol(s);
5ff904cd 12529
c7e4ee3a
CB
12530 Gets called when all possible units in a symbol (not placed in COMMON
12531 or involved in EQUIVALENCE, unless it as yet has no ffestorag object)
12532 have been initialized. The initialization info either is in
12533 ffesymbol_init or, if that is NULL, ffesymbol_accretion:
5ff904cd 12534
c7e4ee3a
CB
12535 ffesymbol_init may contain an opCONTER or opARRTER. opCONTER may occur
12536 even for an array if the array is one element in length!
5ff904cd 12537
c7e4ee3a
CB
12538 ffesymbol_accretion will contain an opACCTER. It is much like an
12539 opARRTER except it has an ffebit object in it instead of just a size.
12540 The back end can use the info in the ffebit object, if it wants, to
12541 reduce the amount of actual initialization, but in any case it should
12542 kill the ffebit object when done. Also, set accretion to NULL but
12543 init to a non-NULL value.
5ff904cd 12544
c7e4ee3a
CB
12545 After performing initialization, DO NOT set init to NULL, because that'll
12546 tell the front end it is ok for more initialization to happen. Instead,
12547 set init to an opANY expression or some such thing that you can use to
12548 tell that you've already initialized the object.
5ff904cd 12549
c7e4ee3a
CB
12550 27-Oct-91 JCB 1.1
12551 Support two-pass FFE. */
5ff904cd 12552
c7e4ee3a
CB
12553void
12554ffecom_notify_init_symbol (ffesymbol s)
12555{
12556 ffebld init; /* The initialization expression. */
12557#if 0 && FFECOM_targetCURRENT == FFECOM_targetGCC
12558 ffetargetOffset size; /* The size of the entity. */
12559 ffetargetAlign pad; /* Its initial padding. */
12560#endif
5ff904cd 12561
c7e4ee3a
CB
12562 if (ffesymbol_storage (s) == NULL)
12563 return; /* Do nothing until COMMON/EQUIVALENCE
12564 possibilities checked. */
5ff904cd 12565
c7e4ee3a
CB
12566 if ((ffesymbol_init (s) == NULL)
12567 && ((init = ffesymbol_accretion (s)) != NULL))
12568 {
12569 ffesymbol_set_accretion (s, NULL);
12570 ffesymbol_set_accretes (s, 0);
5ff904cd 12571
c7e4ee3a
CB
12572#if 0 && FFECOM_targetCURRENT == FFECOM_targetGCC
12573 /* For GNU backend, just turn ACCTER into ARRTER and proceed. */
12574 size = ffebld_accter_size (init);
12575 pad = ffebld_accter_pad (init);
12576 ffebit_kill (ffebld_accter_bits (init));
12577 ffebld_set_op (init, FFEBLD_opARRTER);
12578 ffebld_set_arrter (init, ffebld_accter (init));
12579 ffebld_arrter_set_size (init, size);
12580 ffebld_arrter_set_pad (init, size);
12581#endif
5ff904cd 12582
c7e4ee3a
CB
12583#if FFECOM_TWOPASS
12584 ffesymbol_set_init (s, init);
12585#endif
12586 }
12587#if FFECOM_ONEPASS
12588 else
12589 init = ffesymbol_init (s);
12590#endif
5ff904cd 12591
c7e4ee3a
CB
12592#if FFECOM_ONEPASS
12593 ffesymbol_set_init (s, ffebld_new_any ());
5ff904cd 12594
c7e4ee3a
CB
12595 if (ffebld_op (init) == FFEBLD_opANY)
12596 return; /* Oh, we already did this! */
5ff904cd 12597
c7e4ee3a
CB
12598#if FFECOM_targetCURRENT == FFECOM_targetFFE
12599 fprintf (dmpout, "= initialize_symbol \"%s\" ", ffesymbol_text (s));
12600 ffebld_dump (init);
12601 fputc ('\n', dmpout);
12602#endif
5ff904cd 12603
c7e4ee3a
CB
12604#endif /* if FFECOM_ONEPASS */
12605}
5ff904cd 12606
c7e4ee3a 12607/* ffecom_notify_primary_entry -- Learn which is the primary entry point
5ff904cd 12608
c7e4ee3a
CB
12609 ffesymbol s;
12610 ffecom_notify_primary_entry(s);
5ff904cd 12611
c7e4ee3a
CB
12612 Gets called when implicit or explicit PROGRAM statement seen or when
12613 FUNCTION, SUBROUTINE, or BLOCK DATA statement seen, with the primary
12614 global symbol that serves as the entry point. */
5ff904cd 12615
c7e4ee3a
CB
12616void
12617ffecom_notify_primary_entry (ffesymbol s)
12618{
12619 ffecom_primary_entry_ = s;
12620 ffecom_primary_entry_kind_ = ffesymbol_kind (s);
5ff904cd 12621
c7e4ee3a
CB
12622 if ((ffecom_primary_entry_kind_ == FFEINFO_kindFUNCTION)
12623 || (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE))
12624 ffecom_primary_entry_is_proc_ = TRUE;
12625 else
12626 ffecom_primary_entry_is_proc_ = FALSE;
5ff904cd 12627
c7e4ee3a
CB
12628 if (!ffe_is_silent ())
12629 {
12630 if (ffecom_primary_entry_kind_ == FFEINFO_kindPROGRAM)
12631 fprintf (stderr, "%s:\n", ffesymbol_text (s));
12632 else
12633 fprintf (stderr, " %s:\n", ffesymbol_text (s));
12634 }
5ff904cd 12635
c7e4ee3a
CB
12636#if FFECOM_targetCURRENT == FFECOM_targetGCC
12637 if (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE)
12638 {
12639 ffebld list;
12640 ffebld arg;
5ff904cd 12641
c7e4ee3a
CB
12642 for (list = ffesymbol_dummyargs (s);
12643 list != NULL;
12644 list = ffebld_trail (list))
12645 {
12646 arg = ffebld_head (list);
12647 if (ffebld_op (arg) == FFEBLD_opSTAR)
12648 {
12649 ffecom_is_altreturning_ = TRUE;
12650 break;
12651 }
12652 }
12653 }
12654#endif
12655}
5ff904cd 12656
c7e4ee3a
CB
12657FILE *
12658ffecom_open_include (char *name, ffewhereLine l, ffewhereColumn c)
12659{
12660#if FFECOM_GCC_INCLUDE
12661 return ffecom_open_include_ (name, l, c);
12662#else
12663 return fopen (name, "r");
5ff904cd 12664#endif
c7e4ee3a 12665}
5ff904cd 12666
c7e4ee3a 12667/* ffecom_ptr_to_expr -- Transform expr into gcc tree with & in front
5ff904cd 12668
c7e4ee3a
CB
12669 tree t;
12670 ffebld expr; // FFE expression.
12671 tree = ffecom_ptr_to_expr(expr);
5ff904cd 12672
c7e4ee3a 12673 Like ffecom_expr, but sticks address-of in front of most things. */
5ff904cd 12674
c7e4ee3a
CB
12675#if FFECOM_targetCURRENT == FFECOM_targetGCC
12676tree
12677ffecom_ptr_to_expr (ffebld expr)
12678{
12679 tree item;
12680 ffeinfoBasictype bt;
12681 ffeinfoKindtype kt;
12682 ffesymbol s;
5ff904cd 12683
c7e4ee3a 12684 assert (expr != NULL);
5ff904cd 12685
c7e4ee3a
CB
12686 switch (ffebld_op (expr))
12687 {
12688 case FFEBLD_opSYMTER:
12689 s = ffebld_symter (expr);
12690 if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC)
12691 {
12692 ffecomGfrt ix;
5ff904cd 12693
c7e4ee3a
CB
12694 ix = ffeintrin_gfrt_indirect (ffebld_symter_implementation (expr));
12695 assert (ix != FFECOM_gfrt);
12696 if ((item = ffecom_gfrt_[ix]) == NULL_TREE)
12697 {
12698 ffecom_make_gfrt_ (ix);
12699 item = ffecom_gfrt_[ix];
12700 }
12701 }
12702 else
12703 {
12704 item = ffesymbol_hook (s).decl_tree;
12705 if (item == NULL_TREE)
12706 {
12707 s = ffecom_sym_transform_ (s);
12708 item = ffesymbol_hook (s).decl_tree;
12709 }
12710 }
12711 assert (item != NULL);
12712 if (item == error_mark_node)
12713 return item;
12714 if (!ffesymbol_hook (s).addr)
12715 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12716 item);
12717 return item;
5ff904cd 12718
c7e4ee3a
CB
12719 case FFEBLD_opARRAYREF:
12720 {
c7e4ee3a 12721 item = ffecom_ptr_to_expr (ffebld_left (expr));
5ff904cd 12722
c7e4ee3a
CB
12723 if (item == error_mark_node)
12724 return item;
5ff904cd 12725
c7e4ee3a
CB
12726 if ((ffebld_where (expr) == FFEINFO_whereFLEETING)
12727 && !mark_addressable (item))
12728 return error_mark_node; /* Make sure non-const ref is to
12729 non-reg. */
5ff904cd 12730
6b55276e 12731 item = ffecom_arrayref_ (item, expr, 1);
c7e4ee3a
CB
12732 }
12733 return item;
5ff904cd 12734
c7e4ee3a 12735 case FFEBLD_opCONTER:
5ff904cd 12736
c7e4ee3a
CB
12737 bt = ffeinfo_basictype (ffebld_info (expr));
12738 kt = ffeinfo_kindtype (ffebld_info (expr));
5ff904cd 12739
c7e4ee3a
CB
12740 item = ffecom_constantunion (&ffebld_constant_union
12741 (ffebld_conter (expr)), bt, kt,
12742 ffecom_tree_type[bt][kt]);
12743 if (item == error_mark_node)
12744 return error_mark_node;
12745 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12746 item);
12747 return item;
5ff904cd 12748
c7e4ee3a
CB
12749 case FFEBLD_opANY:
12750 return error_mark_node;
5ff904cd 12751
c7e4ee3a
CB
12752 default:
12753 bt = ffeinfo_basictype (ffebld_info (expr));
12754 kt = ffeinfo_kindtype (ffebld_info (expr));
12755
12756 item = ffecom_expr (expr);
12757 if (item == error_mark_node)
12758 return error_mark_node;
12759
12760 /* The back end currently optimizes a bit too zealously for us, in that
12761 we fail JCB001 if the following block of code is omitted. It checks
12762 to see if the transformed expression is a symbol or array reference,
12763 and encloses it in a SAVE_EXPR if that is the case. */
12764
12765 STRIP_NOPS (item);
12766 if ((TREE_CODE (item) == VAR_DECL)
12767 || (TREE_CODE (item) == PARM_DECL)
12768 || (TREE_CODE (item) == RESULT_DECL)
12769 || (TREE_CODE (item) == INDIRECT_REF)
12770 || (TREE_CODE (item) == ARRAY_REF)
12771 || (TREE_CODE (item) == COMPONENT_REF)
12772#ifdef OFFSET_REF
12773 || (TREE_CODE (item) == OFFSET_REF)
12774#endif
12775 || (TREE_CODE (item) == BUFFER_REF)
12776 || (TREE_CODE (item) == REALPART_EXPR)
12777 || (TREE_CODE (item) == IMAGPART_EXPR))
12778 {
12779 item = ffecom_save_tree (item);
12780 }
12781
12782 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12783 item);
12784 return item;
12785 }
12786
12787 assert ("fall-through error" == NULL);
12788 return error_mark_node;
5ff904cd
JL
12789}
12790
12791#endif
c7e4ee3a 12792/* Obtain a temp var with given data type.
5ff904cd 12793
c7e4ee3a
CB
12794 size is FFETARGET_charactersizeNONE for a non-CHARACTER type
12795 or >= 0 for a CHARACTER type.
5ff904cd 12796
c7e4ee3a 12797 elements is -1 for a scalar or > 0 for an array of type. */
5ff904cd
JL
12798
12799#if FFECOM_targetCURRENT == FFECOM_targetGCC
12800tree
c7e4ee3a
CB
12801ffecom_make_tempvar (const char *commentary, tree type,
12802 ffetargetCharacterSize size, int elements)
5ff904cd 12803{
c7e4ee3a
CB
12804 int yes;
12805 tree t;
12806 static int mynumber;
5ff904cd 12807
c7e4ee3a 12808 assert (current_binding_level->prep_state < 2);
702edf1d 12809
c7e4ee3a
CB
12810 if (type == error_mark_node)
12811 return error_mark_node;
702edf1d 12812
c7e4ee3a 12813 yes = suspend_momentary ();
5ff904cd 12814
c7e4ee3a
CB
12815 if (size != FFETARGET_charactersizeNONE)
12816 type = build_array_type (type,
12817 build_range_type (ffecom_f2c_ftnlen_type_node,
12818 ffecom_f2c_ftnlen_one_node,
12819 build_int_2 (size, 0)));
12820 if (elements != -1)
12821 type = build_array_type (type,
12822 build_range_type (integer_type_node,
12823 integer_zero_node,
12824 build_int_2 (elements - 1,
12825 0)));
12826 t = build_decl (VAR_DECL,
12827 ffecom_get_invented_identifier ("__g77_%s_%d",
12828 commentary,
12829 mynumber++),
12830 type);
5ff904cd 12831
c7e4ee3a
CB
12832 t = start_decl (t, FALSE);
12833 finish_decl (t, NULL_TREE, FALSE);
12834
12835 resume_momentary (yes);
5ff904cd 12836
c7e4ee3a
CB
12837 return t;
12838}
5ff904cd 12839#endif
5ff904cd 12840
c7e4ee3a 12841/* Prepare argument pointer to expression.
5ff904cd 12842
c7e4ee3a
CB
12843 Like ffecom_prepare_expr, except for expressions to be evaluated
12844 via ffecom_arg_ptr_to_expr. */
5ff904cd 12845
c7e4ee3a
CB
12846void
12847ffecom_prepare_arg_ptr_to_expr (ffebld expr)
5ff904cd 12848{
c7e4ee3a
CB
12849 /* ~~For now, it seems to be the same thing. */
12850 ffecom_prepare_expr (expr);
12851 return;
12852}
702edf1d 12853
c7e4ee3a 12854/* End of preparations. */
702edf1d 12855
c7e4ee3a
CB
12856bool
12857ffecom_prepare_end (void)
12858{
12859 int prep_state = current_binding_level->prep_state;
5ff904cd 12860
c7e4ee3a
CB
12861 assert (prep_state < 2);
12862 current_binding_level->prep_state = 2;
5ff904cd 12863
c7e4ee3a 12864 return (prep_state == 1) ? TRUE : FALSE;
5ff904cd
JL
12865}
12866
c7e4ee3a 12867/* Prepare expression.
5ff904cd 12868
c7e4ee3a
CB
12869 This is called before any code is generated for the current block.
12870 It scans the expression, declares any temporaries that might be needed
12871 during evaluation of the expression, and stores those temporaries in
12872 the appropriate "hook" fields of the expression. `dest', if not NULL,
12873 specifies the destination that ffecom_expr_ will see, in case that
12874 helps avoid generating unused temporaries.
12875
12876 ~~Improve to avoid allocating unused temporaries by taking `dest'
12877 into account vis-a-vis aliasing requirements of complex/character
12878 functions. */
12879
12880void
12881ffecom_prepare_expr_ (ffebld expr, ffebld dest UNUSED)
5ff904cd 12882{
c7e4ee3a
CB
12883 ffeinfoBasictype bt;
12884 ffeinfoKindtype kt;
12885 ffetargetCharacterSize sz;
12886 tree tempvar = NULL_TREE;
5ff904cd 12887
c7e4ee3a
CB
12888 assert (current_binding_level->prep_state < 2);
12889
12890 if (! expr)
12891 return;
12892
12893 bt = ffeinfo_basictype (ffebld_info (expr));
12894 kt = ffeinfo_kindtype (ffebld_info (expr));
12895 sz = ffeinfo_size (ffebld_info (expr));
12896
12897 /* Generate whatever temporaries are needed to represent the result
12898 of the expression. */
12899
12900 switch (ffebld_op (expr))
5ff904cd 12901 {
c7e4ee3a
CB
12902 default:
12903 /* Don't make temps for SYMTER, CONTER, etc. */
12904 if (ffebld_arity (expr) == 0)
12905 break;
5ff904cd 12906
c7e4ee3a 12907 switch (bt)
5ff904cd 12908 {
c7e4ee3a
CB
12909 case FFEINFO_basictypeCOMPLEX:
12910 if (ffebld_op (expr) == FFEBLD_opFUNCREF)
12911 {
12912 ffesymbol s;
5ff904cd 12913
c7e4ee3a
CB
12914 if (ffebld_op (ffebld_left (expr)) != FFEBLD_opSYMTER)
12915 break;
5ff904cd 12916
c7e4ee3a
CB
12917 s = ffebld_symter (ffebld_left (expr));
12918 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT
12919 || ! ffesymbol_is_f2c (s))
12920 break;
12921 }
12922 else if (ffebld_op (expr) == FFEBLD_opPOWER)
12923 {
12924 /* Requires special treatment. There's no POW_CC function
12925 in libg2c, so POW_ZZ is used, which means we always
12926 need a double-complex temp, not a single-complex. */
12927 kt = FFEINFO_kindtypeREAL2;
12928 }
12929 else if (ffebld_op (expr) != FFEBLD_opDIVIDE)
12930 /* The other ops don't need temps for complex operands. */
12931 break;
5ff904cd 12932
c7e4ee3a
CB
12933 /* ~~~Avoid making temps for some intrinsics, such as AIMAG(C),
12934 REAL(C). See 19990325-0.f, routine `check', for cases. */
12935 tempvar = ffecom_make_tempvar ("complex",
12936 ffecom_tree_type
12937 [FFEINFO_basictypeCOMPLEX][kt],
12938 FFETARGET_charactersizeNONE,
12939 -1);
5ff904cd
JL
12940 break;
12941
c7e4ee3a
CB
12942 case FFEINFO_basictypeCHARACTER:
12943 if (ffebld_op (expr) != FFEBLD_opFUNCREF)
12944 break;
12945
12946 if (sz == FFETARGET_charactersizeNONE)
12947 /* ~~Kludge alert! This should someday be fixed. */
12948 sz = 24;
12949
12950 tempvar = ffecom_make_tempvar ("char", char_type_node, sz, -1);
5ff904cd
JL
12951 break;
12952
12953 default:
5ff904cd
JL
12954 break;
12955 }
c7e4ee3a 12956 break;
5ff904cd 12957
c7e4ee3a
CB
12958#ifdef HAHA
12959 case FFEBLD_opPOWER:
12960 {
12961 tree rtype, ltype;
12962 tree rtmp, ltmp, result;
5ff904cd 12963
c7e4ee3a
CB
12964 ltype = ffecom_type_expr (ffebld_left (expr));
12965 rtype = ffecom_type_expr (ffebld_right (expr));
5ff904cd 12966
c7e4ee3a
CB
12967 rtmp = ffecom_make_tempvar (rtype, FFETARGET_charactersizeNONE, -1);
12968 ltmp = ffecom_make_tempvar (ltype, FFETARGET_charactersizeNONE, -1);
12969 result = ffecom_make_tempvar (ltype, FFETARGET_charactersizeNONE, -1);
5ff904cd 12970
c7e4ee3a
CB
12971 tempvar = make_tree_vec (3);
12972 TREE_VEC_ELT (tempvar, 0) = rtmp;
12973 TREE_VEC_ELT (tempvar, 1) = ltmp;
12974 TREE_VEC_ELT (tempvar, 2) = result;
12975 }
12976 break;
12977#endif /* HAHA */
5ff904cd 12978
c7e4ee3a
CB
12979 case FFEBLD_opCONCATENATE:
12980 {
12981 /* This gets special handling, because only one set of temps
12982 is needed for a tree of these -- the tree is treated as
12983 a flattened list of concatenations when generating code. */
5ff904cd 12984
c7e4ee3a
CB
12985 ffecomConcatList_ catlist;
12986 tree ltmp, itmp, result;
12987 int count;
12988 int i;
5ff904cd 12989
c7e4ee3a
CB
12990 catlist = ffecom_concat_list_new_ (expr, FFETARGET_charactersizeNONE);
12991 count = ffecom_concat_list_count_ (catlist);
5ff904cd 12992
c7e4ee3a
CB
12993 if (count >= 2)
12994 {
12995 ltmp
12996 = ffecom_make_tempvar ("concat_len",
12997 ffecom_f2c_ftnlen_type_node,
12998 FFETARGET_charactersizeNONE, count);
12999 itmp
13000 = ffecom_make_tempvar ("concat_item",
13001 ffecom_f2c_address_type_node,
13002 FFETARGET_charactersizeNONE, count);
13003 result
13004 = ffecom_make_tempvar ("concat_res",
13005 char_type_node,
13006 ffecom_concat_list_maxlen_ (catlist),
13007 -1);
13008
13009 tempvar = make_tree_vec (3);
13010 TREE_VEC_ELT (tempvar, 0) = ltmp;
13011 TREE_VEC_ELT (tempvar, 1) = itmp;
13012 TREE_VEC_ELT (tempvar, 2) = result;
13013 }
5ff904cd 13014
c7e4ee3a
CB
13015 for (i = 0; i < count; ++i)
13016 ffecom_prepare_arg_ptr_to_expr (ffecom_concat_list_expr_ (catlist,
13017 i));
5ff904cd 13018
c7e4ee3a 13019 ffecom_concat_list_kill_ (catlist);
5ff904cd 13020
c7e4ee3a
CB
13021 if (tempvar)
13022 {
13023 ffebld_nonter_set_hook (expr, tempvar);
13024 current_binding_level->prep_state = 1;
13025 }
13026 }
13027 return;
5ff904cd 13028
c7e4ee3a
CB
13029 case FFEBLD_opCONVERT:
13030 if (bt == FFEINFO_basictypeCHARACTER
13031 && ((ffebld_size_known (ffebld_left (expr))
13032 == FFETARGET_charactersizeNONE)
13033 || (ffebld_size_known (ffebld_left (expr)) >= sz)))
13034 tempvar = ffecom_make_tempvar ("convert", char_type_node, sz, -1);
13035 break;
13036 }
5ff904cd 13037
c7e4ee3a
CB
13038 if (tempvar)
13039 {
13040 ffebld_nonter_set_hook (expr, tempvar);
13041 current_binding_level->prep_state = 1;
13042 }
5ff904cd 13043
c7e4ee3a 13044 /* Prepare subexpressions for this expr. */
5ff904cd 13045
c7e4ee3a 13046 switch (ffebld_op (expr))
5ff904cd 13047 {
c7e4ee3a
CB
13048 case FFEBLD_opPERCENT_LOC:
13049 ffecom_prepare_ptr_to_expr (ffebld_left (expr));
13050 break;
5ff904cd 13051
c7e4ee3a
CB
13052 case FFEBLD_opPERCENT_VAL:
13053 case FFEBLD_opPERCENT_REF:
13054 ffecom_prepare_expr (ffebld_left (expr));
13055 break;
5ff904cd 13056
c7e4ee3a
CB
13057 case FFEBLD_opPERCENT_DESCR:
13058 ffecom_prepare_arg_ptr_to_expr (ffebld_left (expr));
13059 break;
5ff904cd 13060
c7e4ee3a
CB
13061 case FFEBLD_opITEM:
13062 {
13063 ffebld item;
5ff904cd 13064
c7e4ee3a
CB
13065 for (item = expr;
13066 item != NULL;
13067 item = ffebld_trail (item))
13068 if (ffebld_head (item) != NULL)
13069 ffecom_prepare_expr (ffebld_head (item));
13070 }
13071 break;
5ff904cd 13072
c7e4ee3a
CB
13073 default:
13074 /* Need to handle character conversion specially. */
13075 switch (ffebld_arity (expr))
13076 {
13077 case 2:
13078 ffecom_prepare_expr (ffebld_left (expr));
13079 ffecom_prepare_expr (ffebld_right (expr));
13080 break;
5ff904cd 13081
c7e4ee3a
CB
13082 case 1:
13083 ffecom_prepare_expr (ffebld_left (expr));
13084 break;
5ff904cd 13085
c7e4ee3a
CB
13086 default:
13087 break;
13088 }
13089 }
5ff904cd 13090
c7e4ee3a 13091 return;
5ff904cd
JL
13092}
13093
c7e4ee3a 13094/* Prepare expression for reading and writing.
5ff904cd 13095
c7e4ee3a
CB
13096 Like ffecom_prepare_expr, except for expressions to be evaluated
13097 via ffecom_expr_rw. */
5ff904cd 13098
c7e4ee3a
CB
13099void
13100ffecom_prepare_expr_rw (tree type, ffebld expr)
13101{
13102 /* This is all we support for now. */
13103 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
5ff904cd 13104
c7e4ee3a
CB
13105 /* ~~For now, it seems to be the same thing. */
13106 ffecom_prepare_expr (expr);
13107 return;
13108}
5ff904cd 13109
c7e4ee3a 13110/* Prepare expression for writing.
5ff904cd 13111
c7e4ee3a
CB
13112 Like ffecom_prepare_expr, except for expressions to be evaluated
13113 via ffecom_expr_w. */
5ff904cd
JL
13114
13115void
c7e4ee3a 13116ffecom_prepare_expr_w (tree type, ffebld expr)
5ff904cd 13117{
c7e4ee3a
CB
13118 /* This is all we support for now. */
13119 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
5ff904cd 13120
c7e4ee3a
CB
13121 /* ~~For now, it seems to be the same thing. */
13122 ffecom_prepare_expr (expr);
13123 return;
13124}
5ff904cd 13125
c7e4ee3a 13126/* Prepare expression for returning.
5ff904cd 13127
c7e4ee3a
CB
13128 Like ffecom_prepare_expr, except for expressions to be evaluated
13129 via ffecom_return_expr. */
5ff904cd 13130
c7e4ee3a
CB
13131void
13132ffecom_prepare_return_expr (ffebld expr)
13133{
13134 assert (current_binding_level->prep_state < 2);
5ff904cd 13135
c7e4ee3a
CB
13136 if (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE
13137 && ffecom_is_altreturning_
13138 && expr != NULL)
13139 ffecom_prepare_expr (expr);
13140}
5ff904cd 13141
c7e4ee3a 13142/* Prepare pointer to expression.
5ff904cd 13143
c7e4ee3a
CB
13144 Like ffecom_prepare_expr, except for expressions to be evaluated
13145 via ffecom_ptr_to_expr. */
5ff904cd 13146
c7e4ee3a
CB
13147void
13148ffecom_prepare_ptr_to_expr (ffebld expr)
13149{
13150 /* ~~For now, it seems to be the same thing. */
13151 ffecom_prepare_expr (expr);
13152 return;
5ff904cd
JL
13153}
13154
c7e4ee3a 13155/* Transform expression into constant pointer-to-expression tree.
5ff904cd 13156
c7e4ee3a
CB
13157 If the expression can be transformed into a pointer-to-expression tree
13158 that is constant, that is done, and the tree returned. Else NULL_TREE
13159 is returned.
5ff904cd 13160
c7e4ee3a
CB
13161 That way, a caller can attempt to provide compile-time initialization
13162 of a variable and, if that fails, *then* choose to start a new block
13163 and resort to using temporaries, as appropriate. */
5ff904cd 13164
c7e4ee3a
CB
13165tree
13166ffecom_ptr_to_const_expr (ffebld expr)
5ff904cd 13167{
c7e4ee3a
CB
13168 if (! expr)
13169 return integer_zero_node;
5ff904cd 13170
c7e4ee3a
CB
13171 if (ffebld_op (expr) == FFEBLD_opANY)
13172 return error_mark_node;
5ff904cd 13173
c7e4ee3a
CB
13174 if (ffebld_arity (expr) == 0
13175 && (ffebld_op (expr) != FFEBLD_opSYMTER
13176 || ffebld_where (expr) == FFEINFO_whereCOMMON
13177 || ffebld_where (expr) == FFEINFO_whereGLOBAL
13178 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
5ff904cd 13179 {
c7e4ee3a
CB
13180 tree t;
13181
13182 t = ffecom_ptr_to_expr (expr);
13183 assert (TREE_CONSTANT (t));
13184 return t;
5ff904cd
JL
13185 }
13186
c7e4ee3a
CB
13187 return NULL_TREE;
13188}
13189
13190/* ffecom_return_expr -- Returns return-value expr given alt return expr
13191
13192 tree rtn; // NULL_TREE means use expand_null_return()
13193 ffebld expr; // NULL if no alt return expr to RETURN stmt
13194 rtn = ffecom_return_expr(expr);
13195
13196 Based on the program unit type and other info (like return function
13197 type, return master function type when alternate ENTRY points,
13198 whether subroutine has any alternate RETURN points, etc), returns the
13199 appropriate expression to be returned to the caller, or NULL_TREE
13200 meaning no return value or the caller expects it to be returned somewhere
13201 else (which is handled by other parts of this module). */
13202
5ff904cd 13203#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
13204tree
13205ffecom_return_expr (ffebld expr)
13206{
13207 tree rtn;
13208
13209 switch (ffecom_primary_entry_kind_)
5ff904cd 13210 {
c7e4ee3a
CB
13211 case FFEINFO_kindPROGRAM:
13212 case FFEINFO_kindBLOCKDATA:
13213 rtn = NULL_TREE;
13214 break;
5ff904cd 13215
c7e4ee3a
CB
13216 case FFEINFO_kindSUBROUTINE:
13217 if (!ffecom_is_altreturning_)
13218 rtn = NULL_TREE; /* No alt returns, never an expr. */
13219 else if (expr == NULL)
13220 rtn = integer_zero_node;
13221 else
13222 rtn = ffecom_expr (expr);
13223 break;
13224
13225 case FFEINFO_kindFUNCTION:
13226 if ((ffecom_multi_retval_ != NULL_TREE)
13227 || (ffesymbol_basictype (ffecom_primary_entry_)
13228 == FFEINFO_basictypeCHARACTER)
13229 || ((ffesymbol_basictype (ffecom_primary_entry_)
13230 == FFEINFO_basictypeCOMPLEX)
13231 && (ffecom_num_entrypoints_ == 0)
13232 && ffesymbol_is_f2c (ffecom_primary_entry_)))
13233 { /* Value is returned by direct assignment
13234 into (implicit) dummy. */
13235 rtn = NULL_TREE;
13236 break;
5ff904cd 13237 }
c7e4ee3a
CB
13238 rtn = ffecom_func_result_;
13239#if 0
13240 /* Spurious error if RETURN happens before first reference! So elide
13241 this code. In particular, for debugging registry, rtn should always
13242 be non-null after all, but TREE_USED won't be set until we encounter
13243 a reference in the code. Perfectly okay (but weird) code that,
13244 e.g., has "GOTO 20;10 RETURN;20 RTN=0;GOTO 10", would result in
13245 this diagnostic for no reason. Have people use -O -Wuninitialized
13246 and leave it to the back end to find obviously weird cases. */
5ff904cd 13247
c7e4ee3a
CB
13248 /* Used to "assert(rtn != NULL_TREE);" here, but it's kind of a valid
13249 situation; if the return value has never been referenced, it won't
13250 have a tree under 2pass mode. */
13251 if ((rtn == NULL_TREE)
13252 || !TREE_USED (rtn))
13253 {
13254 ffebad_start (FFEBAD_RETURN_VALUE_UNSET);
13255 ffebad_here (0, ffesymbol_where_line (ffecom_primary_entry_),
13256 ffesymbol_where_column (ffecom_primary_entry_));
13257 ffebad_string (ffesymbol_text (ffesymbol_funcresult
13258 (ffecom_primary_entry_)));
13259 ffebad_finish ();
13260 }
5ff904cd 13261#endif
c7e4ee3a 13262 break;
5ff904cd 13263
c7e4ee3a
CB
13264 default:
13265 assert ("bad unit kind" == NULL);
13266 case FFEINFO_kindANY:
13267 rtn = error_mark_node;
13268 break;
13269 }
5ff904cd 13270
c7e4ee3a
CB
13271 return rtn;
13272}
5ff904cd 13273
c7e4ee3a
CB
13274#endif
13275/* Do save_expr only if tree is not error_mark_node. */
5ff904cd
JL
13276
13277#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
13278tree
13279ffecom_save_tree (tree t)
5ff904cd 13280{
c7e4ee3a 13281 return save_expr (t);
5ff904cd 13282}
5ff904cd 13283#endif
c7e4ee3a
CB
13284
13285/* Start a compound statement (block). */
5ff904cd
JL
13286
13287#if FFECOM_targetCURRENT == FFECOM_targetGCC
13288void
c7e4ee3a 13289ffecom_start_compstmt (void)
5ff904cd 13290{
c7e4ee3a 13291 bison_rule_pushlevel_ ();
5ff904cd 13292}
c7e4ee3a 13293#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
5ff904cd 13294
c7e4ee3a 13295/* Public entry point for front end to access start_decl. */
5ff904cd
JL
13296
13297#if FFECOM_targetCURRENT == FFECOM_targetGCC
13298tree
c7e4ee3a 13299ffecom_start_decl (tree decl, bool is_initialized)
5ff904cd 13300{
c7e4ee3a
CB
13301 DECL_INITIAL (decl) = is_initialized ? error_mark_node : NULL_TREE;
13302 return start_decl (decl, FALSE);
13303}
5ff904cd 13304
c7e4ee3a
CB
13305#endif
13306/* ffecom_sym_commit -- Symbol's state being committed to reality
5ff904cd 13307
c7e4ee3a
CB
13308 ffesymbol s;
13309 ffecom_sym_commit(s);
5ff904cd 13310
c7e4ee3a
CB
13311 Does whatever the backend needs when a symbol is committed after having
13312 been backtrackable for a period of time. */
5ff904cd 13313
c7e4ee3a
CB
13314#if FFECOM_targetCURRENT == FFECOM_targetGCC
13315void
13316ffecom_sym_commit (ffesymbol s UNUSED)
13317{
13318 assert (!ffesymbol_retractable ());
13319}
5ff904cd 13320
c7e4ee3a
CB
13321#endif
13322/* ffecom_sym_end_transition -- Perform end transition on all symbols
5ff904cd 13323
c7e4ee3a 13324 ffecom_sym_end_transition();
5ff904cd 13325
c7e4ee3a
CB
13326 Does backend-specific stuff and also calls ffest_sym_end_transition
13327 to do the necessary FFE stuff.
5ff904cd 13328
c7e4ee3a
CB
13329 Backtracking is never enabled when this fn is called, so don't worry
13330 about it. */
5ff904cd 13331
c7e4ee3a
CB
13332ffesymbol
13333ffecom_sym_end_transition (ffesymbol s)
13334{
13335 ffestorag st;
5ff904cd 13336
c7e4ee3a 13337 assert (!ffesymbol_retractable ());
5ff904cd 13338
c7e4ee3a 13339 s = ffest_sym_end_transition (s);
5ff904cd 13340
c7e4ee3a
CB
13341#if FFECOM_targetCURRENT == FFECOM_targetGCC
13342 if ((ffesymbol_kind (s) == FFEINFO_kindBLOCKDATA)
13343 && (ffesymbol_where (s) == FFEINFO_whereGLOBAL))
13344 {
13345 ffecom_list_blockdata_
13346 = ffebld_new_item (ffebld_new_symter (s, FFEINTRIN_genNONE,
13347 FFEINTRIN_specNONE,
13348 FFEINTRIN_impNONE),
13349 ffecom_list_blockdata_);
5ff904cd 13350 }
5ff904cd 13351#endif
5ff904cd 13352
c7e4ee3a
CB
13353 /* This is where we finally notice that a symbol has partial initialization
13354 and finalize it. */
5ff904cd 13355
c7e4ee3a
CB
13356 if (ffesymbol_accretion (s) != NULL)
13357 {
13358 assert (ffesymbol_init (s) == NULL);
13359 ffecom_notify_init_symbol (s);
13360 }
13361 else if (((st = ffesymbol_storage (s)) != NULL)
13362 && ((st = ffestorag_parent (st)) != NULL)
13363 && (ffestorag_accretion (st) != NULL))
13364 {
13365 assert (ffestorag_init (st) == NULL);
13366 ffecom_notify_init_storage (st);
13367 }
5ff904cd
JL
13368
13369#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
13370 if ((ffesymbol_kind (s) == FFEINFO_kindCOMMON)
13371 && (ffesymbol_where (s) == FFEINFO_whereLOCAL)
13372 && (ffesymbol_storage (s) != NULL))
13373 {
13374 ffecom_list_common_
13375 = ffebld_new_item (ffebld_new_symter (s, FFEINTRIN_genNONE,
13376 FFEINTRIN_specNONE,
13377 FFEINTRIN_impNONE),
13378 ffecom_list_common_);
13379 }
13380#endif
5ff904cd 13381
c7e4ee3a
CB
13382 return s;
13383}
5ff904cd 13384
c7e4ee3a 13385/* ffecom_sym_exec_transition -- Perform exec transition on all symbols
5ff904cd 13386
c7e4ee3a 13387 ffecom_sym_exec_transition();
5ff904cd 13388
c7e4ee3a
CB
13389 Does backend-specific stuff and also calls ffest_sym_exec_transition
13390 to do the necessary FFE stuff.
5ff904cd 13391
c7e4ee3a
CB
13392 See the long-winded description in ffecom_sym_learned for info
13393 on handling the situation where backtracking is inhibited. */
5ff904cd 13394
c7e4ee3a
CB
13395ffesymbol
13396ffecom_sym_exec_transition (ffesymbol s)
13397{
13398 s = ffest_sym_exec_transition (s);
5ff904cd 13399
c7e4ee3a
CB
13400 return s;
13401}
5ff904cd 13402
c7e4ee3a 13403/* ffecom_sym_learned -- Initial or more info gained on symbol after exec
5ff904cd 13404
c7e4ee3a
CB
13405 ffesymbol s;
13406 s = ffecom_sym_learned(s);
5ff904cd 13407
c7e4ee3a
CB
13408 Called when a new symbol is seen after the exec transition or when more
13409 info (perhaps) is gained for an UNCERTAIN symbol. The symbol state when
13410 it arrives here is that all its latest info is updated already, so its
13411 state may be UNCERTAIN or UNDERSTOOD, it might already have the hook
13412 field filled in if its gone through here or exec_transition first, and
13413 so on.
5ff904cd 13414
c7e4ee3a
CB
13415 The backend probably wants to check ffesymbol_retractable() to see if
13416 backtracking is in effect. If so, the FFE's changes to the symbol may
13417 be retracted (undone) or committed (ratified), at which time the
13418 appropriate ffecom_sym_retract or _commit function will be called
13419 for that function.
5ff904cd 13420
c7e4ee3a
CB
13421 If the backend has its own backtracking mechanism, great, use it so that
13422 committal is a simple operation. Though it doesn't make much difference,
13423 I suppose: the reason for tentative symbol evolution in the FFE is to
13424 enable error detection in weird incorrect statements early and to disable
13425 incorrect error detection on a correct statement. The backend is not
13426 likely to introduce any information that'll get involved in these
13427 considerations, so it is probably just fine that the implementation
13428 model for this fn and for _exec_transition is to not do anything
13429 (besides the required FFE stuff) if ffesymbol_retractable() returns TRUE
13430 and instead wait until ffecom_sym_commit is called (which it never
13431 will be as long as we're using ambiguity-detecting statement analysis in
13432 the FFE, which we are initially to shake out the code, but don't depend
13433 on this), otherwise go ahead and do whatever is needed.
5ff904cd 13434
c7e4ee3a
CB
13435 In essence, then, when this fn and _exec_transition get called while
13436 backtracking is enabled, a general mechanism would be to flag which (or
13437 both) of these were called (and in what order? neat question as to what
13438 might happen that I'm too lame to think through right now) and then when
13439 _commit is called reproduce the original calling sequence, if any, for
13440 the two fns (at which point backtracking will, of course, be disabled). */
5ff904cd 13441
c7e4ee3a
CB
13442ffesymbol
13443ffecom_sym_learned (ffesymbol s)
13444{
13445 ffestorag_exec_layout (s);
5ff904cd 13446
c7e4ee3a 13447 return s;
5ff904cd
JL
13448}
13449
c7e4ee3a 13450/* ffecom_sym_retract -- Symbol's state being retracted from reality
5ff904cd 13451
c7e4ee3a
CB
13452 ffesymbol s;
13453 ffecom_sym_retract(s);
5ff904cd 13454
c7e4ee3a
CB
13455 Does whatever the backend needs when a symbol is retracted after having
13456 been backtrackable for a period of time. */
5ff904cd
JL
13457
13458#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
13459void
13460ffecom_sym_retract (ffesymbol s UNUSED)
5ff904cd 13461{
c7e4ee3a 13462 assert (!ffesymbol_retractable ());
5ff904cd 13463
c7e4ee3a
CB
13464#if 0 /* GCC doesn't commit any backtrackable sins,
13465 so nothing needed here. */
13466 switch (ffesymbol_hook (s).state)
5ff904cd 13467 {
c7e4ee3a 13468 case 0: /* nothing happened yet. */
5ff904cd
JL
13469 break;
13470
c7e4ee3a 13471 case 1: /* exec transition happened. */
5ff904cd
JL
13472 break;
13473
c7e4ee3a
CB
13474 case 2: /* learned happened. */
13475 break;
5ff904cd 13476
c7e4ee3a
CB
13477 case 3: /* learned then exec. */
13478 break;
13479
13480 case 4: /* exec then learned. */
5ff904cd
JL
13481 break;
13482
13483 default:
c7e4ee3a 13484 assert ("bad hook state" == NULL);
5ff904cd
JL
13485 break;
13486 }
c7e4ee3a
CB
13487#endif
13488}
5ff904cd 13489
c7e4ee3a
CB
13490#endif
13491/* Create temporary gcc label. */
13492
13493#if FFECOM_targetCURRENT == FFECOM_targetGCC
13494tree
13495ffecom_temp_label ()
13496{
13497 tree glabel;
13498 static int mynumber = 0;
13499
13500 glabel = build_decl (LABEL_DECL,
13501 ffecom_get_invented_identifier ("__g77_label_%d",
13502 NULL,
13503 mynumber++),
13504 void_type_node);
13505 DECL_CONTEXT (glabel) = current_function_decl;
13506 DECL_MODE (glabel) = VOIDmode;
13507
13508 return glabel;
5ff904cd
JL
13509}
13510
13511#endif
c7e4ee3a
CB
13512/* Return an expression that is usable as an arg in a conditional context
13513 (IF, DO WHILE, .NOT., and so on).
13514
13515 Use the one provided for the back end as of >2.6.0. */
5ff904cd
JL
13516
13517#if FFECOM_targetCURRENT == FFECOM_targetGCC
a2977d2d 13518tree
c7e4ee3a 13519ffecom_truth_value (tree expr)
5ff904cd 13520{
c7e4ee3a 13521 return truthvalue_conversion (expr);
5ff904cd 13522}
c7e4ee3a 13523
5ff904cd 13524#endif
c7e4ee3a
CB
13525/* Return the inversion of a truth value (the inversion of what
13526 ffecom_truth_value builds).
5ff904cd 13527
c7e4ee3a
CB
13528 Apparently invert_truthvalue, which is properly in the back end, is
13529 enough for now, so just use it. */
5ff904cd
JL
13530
13531#if FFECOM_targetCURRENT == FFECOM_targetGCC
13532tree
c7e4ee3a 13533ffecom_truth_value_invert (tree expr)
5ff904cd 13534{
c7e4ee3a 13535 return invert_truthvalue (ffecom_truth_value (expr));
5ff904cd
JL
13536}
13537
13538#endif
5ff904cd 13539
c7e4ee3a
CB
13540/* Return the tree that is the type of the expression, as would be
13541 returned in TREE_TYPE(ffecom_expr(expr)), without otherwise
13542 transforming the expression, generating temporaries, etc. */
5ff904cd 13543
c7e4ee3a
CB
13544tree
13545ffecom_type_expr (ffebld expr)
13546{
13547 ffeinfoBasictype bt;
13548 ffeinfoKindtype kt;
13549 tree tree_type;
13550
13551 assert (expr != NULL);
13552
13553 bt = ffeinfo_basictype (ffebld_info (expr));
13554 kt = ffeinfo_kindtype (ffebld_info (expr));
13555 tree_type = ffecom_tree_type[bt][kt];
13556
13557 switch (ffebld_op (expr))
13558 {
13559 case FFEBLD_opCONTER:
13560 case FFEBLD_opSYMTER:
13561 case FFEBLD_opARRAYREF:
13562 case FFEBLD_opUPLUS:
13563 case FFEBLD_opPAREN:
13564 case FFEBLD_opUMINUS:
13565 case FFEBLD_opADD:
13566 case FFEBLD_opSUBTRACT:
13567 case FFEBLD_opMULTIPLY:
13568 case FFEBLD_opDIVIDE:
13569 case FFEBLD_opPOWER:
13570 case FFEBLD_opNOT:
13571 case FFEBLD_opFUNCREF:
13572 case FFEBLD_opSUBRREF:
13573 case FFEBLD_opAND:
13574 case FFEBLD_opOR:
13575 case FFEBLD_opXOR:
13576 case FFEBLD_opNEQV:
13577 case FFEBLD_opEQV:
13578 case FFEBLD_opCONVERT:
13579 case FFEBLD_opLT:
13580 case FFEBLD_opLE:
13581 case FFEBLD_opEQ:
13582 case FFEBLD_opNE:
13583 case FFEBLD_opGT:
13584 case FFEBLD_opGE:
13585 case FFEBLD_opPERCENT_LOC:
13586 return tree_type;
13587
13588 case FFEBLD_opACCTER:
13589 case FFEBLD_opARRTER:
13590 case FFEBLD_opITEM:
13591 case FFEBLD_opSTAR:
13592 case FFEBLD_opBOUNDS:
13593 case FFEBLD_opREPEAT:
13594 case FFEBLD_opLABTER:
13595 case FFEBLD_opLABTOK:
13596 case FFEBLD_opIMPDO:
13597 case FFEBLD_opCONCATENATE:
13598 case FFEBLD_opSUBSTR:
13599 default:
13600 assert ("bad op for ffecom_type_expr" == NULL);
13601 /* Fall through. */
13602 case FFEBLD_opANY:
13603 return error_mark_node;
13604 }
13605}
13606
13607/* Return PARM_DECL for arg#1 of master fn containing alternate ENTRY points
13608
13609 If the PARM_DECL already exists, return it, else create it. It's an
13610 integer_type_node argument for the master function that implements a
13611 subroutine or function with more than one entrypoint and is bound at
13612 run time with the entrypoint number (0 for SUBROUTINE/FUNCTION, 1 for
13613 first ENTRY statement, and so on). */
5ff904cd
JL
13614
13615#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
13616tree
13617ffecom_which_entrypoint_decl ()
5ff904cd 13618{
c7e4ee3a
CB
13619 assert (ffecom_which_entrypoint_decl_ != NULL_TREE);
13620
13621 return ffecom_which_entrypoint_decl_;
5ff904cd
JL
13622}
13623
13624#endif
c7e4ee3a
CB
13625\f
13626/* The following sections consists of private and public functions
13627 that have the same names and perform roughly the same functions
13628 as counterparts in the C front end. Changes in the C front end
13629 might affect how things should be done here. Only functions
13630 needed by the back end should be public here; the rest should
13631 be private (static in the C sense). Functions needed by other
13632 g77 front-end modules should be accessed by them via public
13633 ffecom_* names, which should themselves call private versions
13634 in this section so the private versions are easy to recognize
13635 when upgrading to a new gcc and finding interesting changes
13636 in the front end.
5ff904cd 13637
c7e4ee3a
CB
13638 Functions named after rule "foo:" in c-parse.y are named
13639 "bison_rule_foo_" so they are easy to find. */
5ff904cd 13640
c7e4ee3a 13641#if FFECOM_targetCURRENT == FFECOM_targetGCC
5ff904cd 13642
c7e4ee3a
CB
13643static void
13644bison_rule_pushlevel_ ()
13645{
13646 emit_line_note (input_filename, lineno);
13647 pushlevel (0);
13648 clear_last_expr ();
13649 push_momentary ();
13650 expand_start_bindings (0);
13651}
5ff904cd 13652
c7e4ee3a
CB
13653static tree
13654bison_rule_compstmt_ ()
5ff904cd 13655{
c7e4ee3a
CB
13656 tree t;
13657 int keep = kept_level_p ();
5ff904cd 13658
c7e4ee3a
CB
13659 /* Make the temps go away. */
13660 if (! keep)
13661 current_binding_level->names = NULL_TREE;
5ff904cd 13662
c7e4ee3a
CB
13663 emit_line_note (input_filename, lineno);
13664 expand_end_bindings (getdecls (), keep, 0);
13665 t = poplevel (keep, 1, 0);
13666 pop_momentary ();
5ff904cd 13667
c7e4ee3a
CB
13668 return t;
13669}
5ff904cd 13670
c7e4ee3a
CB
13671/* Return a definition for a builtin function named NAME and whose data type
13672 is TYPE. TYPE should be a function type with argument types.
13673 FUNCTION_CODE tells later passes how to compile calls to this function.
13674 See tree.h for its possible values.
5ff904cd 13675
c7e4ee3a
CB
13676 If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME,
13677 the name to be called if we can't opencode the function. */
5ff904cd 13678
c7e4ee3a
CB
13679static tree
13680builtin_function (const char *name, tree type,
13681 enum built_in_function function_code,
13682 const char *library_name)
13683{
13684 tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
13685 DECL_EXTERNAL (decl) = 1;
13686 TREE_PUBLIC (decl) = 1;
13687 if (library_name)
13688 DECL_ASSEMBLER_NAME (decl) = get_identifier (library_name);
13689 make_decl_rtl (decl, NULL_PTR, 1);
13690 pushdecl (decl);
13691 if (function_code != NOT_BUILT_IN)
5ff904cd 13692 {
c7e4ee3a
CB
13693 DECL_BUILT_IN (decl) = 1;
13694 DECL_FUNCTION_CODE (decl) = function_code;
5ff904cd 13695 }
5ff904cd 13696
c7e4ee3a 13697 return decl;
5ff904cd
JL
13698}
13699
c7e4ee3a
CB
13700/* Handle when a new declaration NEWDECL
13701 has the same name as an old one OLDDECL
13702 in the same binding contour.
13703 Prints an error message if appropriate.
5ff904cd 13704
c7e4ee3a
CB
13705 If safely possible, alter OLDDECL to look like NEWDECL, and return 1.
13706 Otherwise, return 0. */
5ff904cd 13707
c7e4ee3a
CB
13708static int
13709duplicate_decls (tree newdecl, tree olddecl)
5ff904cd 13710{
c7e4ee3a
CB
13711 int types_match = 1;
13712 int new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL
13713 && DECL_INITIAL (newdecl) != 0);
13714 tree oldtype = TREE_TYPE (olddecl);
13715 tree newtype = TREE_TYPE (newdecl);
5ff904cd 13716
c7e4ee3a
CB
13717 if (olddecl == newdecl)
13718 return 1;
5ff904cd 13719
c7e4ee3a
CB
13720 if (TREE_CODE (newtype) == ERROR_MARK
13721 || TREE_CODE (oldtype) == ERROR_MARK)
13722 types_match = 0;
5ff904cd 13723
c7e4ee3a
CB
13724 /* New decl is completely inconsistent with the old one =>
13725 tell caller to replace the old one.
13726 This is always an error except in the case of shadowing a builtin. */
13727 if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
13728 return 0;
5ff904cd 13729
c7e4ee3a
CB
13730 /* For real parm decl following a forward decl,
13731 return 1 so old decl will be reused. */
13732 if (types_match && TREE_CODE (newdecl) == PARM_DECL
13733 && TREE_ASM_WRITTEN (olddecl) && ! TREE_ASM_WRITTEN (newdecl))
13734 return 1;
5ff904cd 13735
c7e4ee3a
CB
13736 /* The new declaration is the same kind of object as the old one.
13737 The declarations may partially match. Print warnings if they don't
13738 match enough. Ultimately, copy most of the information from the new
13739 decl to the old one, and keep using the old one. */
5ff904cd 13740
c7e4ee3a
CB
13741 if (TREE_CODE (olddecl) == FUNCTION_DECL
13742 && DECL_BUILT_IN (olddecl))
13743 {
13744 /* A function declaration for a built-in function. */
13745 if (!TREE_PUBLIC (newdecl))
13746 return 0;
13747 else if (!types_match)
13748 {
13749 /* Accept the return type of the new declaration if same modes. */
13750 tree oldreturntype = TREE_TYPE (TREE_TYPE (olddecl));
13751 tree newreturntype = TREE_TYPE (TREE_TYPE (newdecl));
5ff904cd 13752
c7e4ee3a
CB
13753 /* Make sure we put the new type in the same obstack as the old ones.
13754 If the old types are not both in the same obstack, use the
13755 permanent one. */
13756 if (TYPE_OBSTACK (oldtype) == TYPE_OBSTACK (newtype))
13757 push_obstacks (TYPE_OBSTACK (oldtype), TYPE_OBSTACK (oldtype));
13758 else
13759 {
13760 push_obstacks_nochange ();
13761 end_temporary_allocation ();
13762 }
5ff904cd 13763
c7e4ee3a
CB
13764 if (TYPE_MODE (oldreturntype) == TYPE_MODE (newreturntype))
13765 {
13766 /* Function types may be shared, so we can't just modify
13767 the return type of olddecl's function type. */
13768 tree newtype
13769 = build_function_type (newreturntype,
13770 TYPE_ARG_TYPES (TREE_TYPE (olddecl)));
5ff904cd 13771
c7e4ee3a
CB
13772 types_match = 1;
13773 if (types_match)
13774 TREE_TYPE (olddecl) = newtype;
13775 }
5ff904cd 13776
c7e4ee3a
CB
13777 pop_obstacks ();
13778 }
13779 if (!types_match)
13780 return 0;
13781 }
13782 else if (TREE_CODE (olddecl) == FUNCTION_DECL
13783 && DECL_SOURCE_LINE (olddecl) == 0)
5ff904cd 13784 {
c7e4ee3a
CB
13785 /* A function declaration for a predeclared function
13786 that isn't actually built in. */
13787 if (!TREE_PUBLIC (newdecl))
13788 return 0;
13789 else if (!types_match)
13790 {
13791 /* If the types don't match, preserve volatility indication.
13792 Later on, we will discard everything else about the
13793 default declaration. */
13794 TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
13795 }
13796 }
5ff904cd 13797
c7e4ee3a
CB
13798 /* Copy all the DECL_... slots specified in the new decl
13799 except for any that we copy here from the old type.
5ff904cd 13800
c7e4ee3a
CB
13801 Past this point, we don't change OLDTYPE and NEWTYPE
13802 even if we change the types of NEWDECL and OLDDECL. */
5ff904cd 13803
c7e4ee3a
CB
13804 if (types_match)
13805 {
13806 /* Make sure we put the new type in the same obstack as the old ones.
13807 If the old types are not both in the same obstack, use the permanent
13808 one. */
13809 if (TYPE_OBSTACK (oldtype) == TYPE_OBSTACK (newtype))
13810 push_obstacks (TYPE_OBSTACK (oldtype), TYPE_OBSTACK (oldtype));
13811 else
13812 {
13813 push_obstacks_nochange ();
13814 end_temporary_allocation ();
13815 }
5ff904cd 13816
c7e4ee3a
CB
13817 /* Merge the data types specified in the two decls. */
13818 if (TREE_CODE (newdecl) != FUNCTION_DECL || !DECL_BUILT_IN (olddecl))
13819 TREE_TYPE (newdecl)
13820 = TREE_TYPE (olddecl)
13821 = TREE_TYPE (newdecl);
5ff904cd 13822
c7e4ee3a
CB
13823 /* Lay the type out, unless already done. */
13824 if (oldtype != TREE_TYPE (newdecl))
13825 {
13826 if (TREE_TYPE (newdecl) != error_mark_node)
13827 layout_type (TREE_TYPE (newdecl));
13828 if (TREE_CODE (newdecl) != FUNCTION_DECL
13829 && TREE_CODE (newdecl) != TYPE_DECL
13830 && TREE_CODE (newdecl) != CONST_DECL)
13831 layout_decl (newdecl, 0);
13832 }
13833 else
13834 {
13835 /* Since the type is OLDDECL's, make OLDDECL's size go with. */
13836 DECL_SIZE (newdecl) = DECL_SIZE (olddecl);
13837 if (TREE_CODE (olddecl) != FUNCTION_DECL)
13838 if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl))
13839 DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl);
13840 }
5ff904cd 13841
c7e4ee3a
CB
13842 /* Keep the old rtl since we can safely use it. */
13843 DECL_RTL (newdecl) = DECL_RTL (olddecl);
5ff904cd 13844
c7e4ee3a
CB
13845 /* Merge the type qualifiers. */
13846 if (DECL_BUILT_IN_NONANSI (olddecl) && TREE_THIS_VOLATILE (olddecl)
13847 && !TREE_THIS_VOLATILE (newdecl))
13848 TREE_THIS_VOLATILE (olddecl) = 0;
13849 if (TREE_READONLY (newdecl))
13850 TREE_READONLY (olddecl) = 1;
13851 if (TREE_THIS_VOLATILE (newdecl))
13852 {
13853 TREE_THIS_VOLATILE (olddecl) = 1;
13854 if (TREE_CODE (newdecl) == VAR_DECL)
13855 make_var_volatile (newdecl);
13856 }
5ff904cd 13857
c7e4ee3a
CB
13858 /* Keep source location of definition rather than declaration.
13859 Likewise, keep decl at outer scope. */
13860 if ((DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0)
13861 || (DECL_CONTEXT (newdecl) != 0 && DECL_CONTEXT (olddecl) == 0))
13862 {
13863 DECL_SOURCE_LINE (newdecl) = DECL_SOURCE_LINE (olddecl);
13864 DECL_SOURCE_FILE (newdecl) = DECL_SOURCE_FILE (olddecl);
5ff904cd 13865
c7e4ee3a
CB
13866 if (DECL_CONTEXT (olddecl) == 0
13867 && TREE_CODE (newdecl) != FUNCTION_DECL)
13868 DECL_CONTEXT (newdecl) = 0;
13869 }
5ff904cd 13870
c7e4ee3a
CB
13871 /* Merge the unused-warning information. */
13872 if (DECL_IN_SYSTEM_HEADER (olddecl))
13873 DECL_IN_SYSTEM_HEADER (newdecl) = 1;
13874 else if (DECL_IN_SYSTEM_HEADER (newdecl))
13875 DECL_IN_SYSTEM_HEADER (olddecl) = 1;
5ff904cd 13876
c7e4ee3a
CB
13877 /* Merge the initialization information. */
13878 if (DECL_INITIAL (newdecl) == 0)
13879 DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
5ff904cd 13880
c7e4ee3a
CB
13881 /* Merge the section attribute.
13882 We want to issue an error if the sections conflict but that must be
13883 done later in decl_attributes since we are called before attributes
13884 are assigned. */
13885 if (DECL_SECTION_NAME (newdecl) == NULL_TREE)
13886 DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl);
5ff904cd 13887
c7e4ee3a
CB
13888#if BUILT_FOR_270
13889 if (TREE_CODE (newdecl) == FUNCTION_DECL)
13890 {
13891 DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl);
13892 DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
13893 }
5ff904cd 13894#endif
5ff904cd 13895
c7e4ee3a
CB
13896 pop_obstacks ();
13897 }
13898 /* If cannot merge, then use the new type and qualifiers,
13899 and don't preserve the old rtl. */
13900 else
13901 {
13902 TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
13903 TREE_READONLY (olddecl) = TREE_READONLY (newdecl);
13904 TREE_THIS_VOLATILE (olddecl) = TREE_THIS_VOLATILE (newdecl);
13905 TREE_SIDE_EFFECTS (olddecl) = TREE_SIDE_EFFECTS (newdecl);
13906 }
5ff904cd 13907
c7e4ee3a
CB
13908 /* Merge the storage class information. */
13909 /* For functions, static overrides non-static. */
13910 if (TREE_CODE (newdecl) == FUNCTION_DECL)
13911 {
13912 TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl);
13913 /* This is since we don't automatically
13914 copy the attributes of NEWDECL into OLDDECL. */
13915 TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
13916 /* If this clears `static', clear it in the identifier too. */
13917 if (! TREE_PUBLIC (olddecl))
13918 TREE_PUBLIC (DECL_NAME (olddecl)) = 0;
13919 }
13920 if (DECL_EXTERNAL (newdecl))
13921 {
13922 TREE_STATIC (newdecl) = TREE_STATIC (olddecl);
13923 DECL_EXTERNAL (newdecl) = DECL_EXTERNAL (olddecl);
13924 /* An extern decl does not override previous storage class. */
13925 TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
13926 }
13927 else
13928 {
13929 TREE_STATIC (olddecl) = TREE_STATIC (newdecl);
13930 TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
13931 }
5ff904cd 13932
c7e4ee3a
CB
13933 /* If either decl says `inline', this fn is inline,
13934 unless its definition was passed already. */
13935 if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == 0)
13936 DECL_INLINE (olddecl) = 1;
13937 DECL_INLINE (newdecl) = DECL_INLINE (olddecl);
5ff904cd 13938
c7e4ee3a
CB
13939 /* Get rid of any built-in function if new arg types don't match it
13940 or if we have a function definition. */
13941 if (TREE_CODE (newdecl) == FUNCTION_DECL
13942 && DECL_BUILT_IN (olddecl)
13943 && (!types_match || new_is_definition))
13944 {
13945 TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
13946 DECL_BUILT_IN (olddecl) = 0;
13947 }
5ff904cd 13948
c7e4ee3a
CB
13949 /* If redeclaring a builtin function, and not a definition,
13950 it stays built in.
13951 Also preserve various other info from the definition. */
13952 if (TREE_CODE (newdecl) == FUNCTION_DECL && !new_is_definition)
13953 {
13954 if (DECL_BUILT_IN (olddecl))
13955 {
13956 DECL_BUILT_IN (newdecl) = 1;
13957 DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
13958 }
13959 else
13960 DECL_FRAME_SIZE (newdecl) = DECL_FRAME_SIZE (olddecl);
5ff904cd 13961
c7e4ee3a
CB
13962 DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
13963 DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
13964 DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl);
13965 DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
13966 }
5ff904cd 13967
c7e4ee3a
CB
13968 /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
13969 But preserve olddecl's DECL_UID. */
13970 {
13971 register unsigned olddecl_uid = DECL_UID (olddecl);
5ff904cd 13972
c7e4ee3a
CB
13973 memcpy ((char *) olddecl + sizeof (struct tree_common),
13974 (char *) newdecl + sizeof (struct tree_common),
13975 sizeof (struct tree_decl) - sizeof (struct tree_common));
13976 DECL_UID (olddecl) = olddecl_uid;
13977 }
5ff904cd 13978
c7e4ee3a 13979 return 1;
5ff904cd
JL
13980}
13981
c7e4ee3a
CB
13982/* Finish processing of a declaration;
13983 install its initial value.
13984 If the length of an array type is not known before,
13985 it must be determined now, from the initial value, or it is an error. */
13986
5ff904cd 13987static void
c7e4ee3a 13988finish_decl (tree decl, tree init, bool is_top_level)
5ff904cd 13989{
c7e4ee3a
CB
13990 register tree type = TREE_TYPE (decl);
13991 int was_incomplete = (DECL_SIZE (decl) == 0);
13992 int temporary = allocation_temporary_p ();
13993 bool at_top_level = (current_binding_level == global_binding_level);
13994 bool top_level = is_top_level || at_top_level;
5ff904cd 13995
c7e4ee3a
CB
13996 /* Caller should pass TRUE for is_top_level only if we wouldn't be at top
13997 level anyway. */
13998 assert (!is_top_level || !at_top_level);
5ff904cd 13999
c7e4ee3a
CB
14000 if (TREE_CODE (decl) == PARM_DECL)
14001 assert (init == NULL_TREE);
14002 /* Remember that PARM_DECL doesn't have a DECL_INITIAL field per se -- it
14003 overlaps DECL_ARG_TYPE. */
14004 else if (init == NULL_TREE)
14005 assert (DECL_INITIAL (decl) == NULL_TREE);
14006 else
14007 assert (DECL_INITIAL (decl) == error_mark_node);
5ff904cd 14008
c7e4ee3a 14009 if (init != NULL_TREE)
5ff904cd 14010 {
c7e4ee3a
CB
14011 if (TREE_CODE (decl) != TYPE_DECL)
14012 DECL_INITIAL (decl) = init;
14013 else
14014 {
14015 /* typedef foo = bar; store the type of bar as the type of foo. */
14016 TREE_TYPE (decl) = TREE_TYPE (init);
14017 DECL_INITIAL (decl) = init = 0;
14018 }
5ff904cd
JL
14019 }
14020
c7e4ee3a
CB
14021 /* Pop back to the obstack that is current for this binding level. This is
14022 because MAXINDEX, rtl, etc. to be made below must go in the permanent
14023 obstack. But don't discard the temporary data yet. */
14024 pop_obstacks ();
5ff904cd 14025
c7e4ee3a 14026 /* Deduce size of array from initialization, if not already known */
5ff904cd 14027
c7e4ee3a
CB
14028 if (TREE_CODE (type) == ARRAY_TYPE
14029 && TYPE_DOMAIN (type) == 0
14030 && TREE_CODE (decl) != TYPE_DECL)
14031 {
14032 assert (top_level);
14033 assert (was_incomplete);
5ff904cd 14034
c7e4ee3a
CB
14035 layout_decl (decl, 0);
14036 }
5ff904cd 14037
c7e4ee3a
CB
14038 if (TREE_CODE (decl) == VAR_DECL)
14039 {
14040 if (DECL_SIZE (decl) == NULL_TREE
14041 && TYPE_SIZE (TREE_TYPE (decl)) != NULL_TREE)
14042 layout_decl (decl, 0);
5ff904cd 14043
c7e4ee3a
CB
14044 if (DECL_SIZE (decl) == NULL_TREE
14045 && (TREE_STATIC (decl)
14046 ?
14047 /* A static variable with an incomplete type is an error if it is
14048 initialized. Also if it is not file scope. Otherwise, let it
14049 through, but if it is not `extern' then it may cause an error
14050 message later. */
14051 (DECL_INITIAL (decl) != 0 || DECL_CONTEXT (decl) != 0)
14052 :
14053 /* An automatic variable with an incomplete type is an error. */
14054 !DECL_EXTERNAL (decl)))
14055 {
14056 assert ("storage size not known" == NULL);
14057 abort ();
14058 }
5ff904cd 14059
c7e4ee3a
CB
14060 if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl))
14061 && (DECL_SIZE (decl) != 0)
14062 && (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST))
14063 {
14064 assert ("storage size not constant" == NULL);
14065 abort ();
14066 }
14067 }
5ff904cd 14068
c7e4ee3a
CB
14069 /* Output the assembler code and/or RTL code for variables and functions,
14070 unless the type is an undefined structure or union. If not, it will get
14071 done when the type is completed. */
5ff904cd 14072
c7e4ee3a 14073 if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)
5ff904cd 14074 {
c7e4ee3a
CB
14075 rest_of_decl_compilation (decl, NULL,
14076 DECL_CONTEXT (decl) == 0,
14077 0);
5ff904cd 14078
c7e4ee3a
CB
14079 if (DECL_CONTEXT (decl) != 0)
14080 {
14081 /* Recompute the RTL of a local array now if it used to be an
14082 incomplete type. */
14083 if (was_incomplete
14084 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
5ff904cd 14085 {
c7e4ee3a
CB
14086 /* If we used it already as memory, it must stay in memory. */
14087 TREE_ADDRESSABLE (decl) = TREE_USED (decl);
14088 /* If it's still incomplete now, no init will save it. */
14089 if (DECL_SIZE (decl) == 0)
14090 DECL_INITIAL (decl) = 0;
14091 expand_decl (decl);
5ff904cd 14092 }
c7e4ee3a
CB
14093 /* Compute and store the initial value. */
14094 if (TREE_CODE (decl) != FUNCTION_DECL)
14095 expand_decl_init (decl);
14096 }
14097 }
14098 else if (TREE_CODE (decl) == TYPE_DECL)
14099 {
14100 rest_of_decl_compilation (decl, NULL_PTR,
14101 DECL_CONTEXT (decl) == 0,
14102 0);
14103 }
5ff904cd 14104
c7e4ee3a
CB
14105 /* This test used to include TREE_PERMANENT, however, we have the same
14106 problem with initializers at the function level. Such initializers get
14107 saved until the end of the function on the momentary_obstack. */
14108 if (!(TREE_CODE (decl) == FUNCTION_DECL && DECL_INLINE (decl))
14109 && temporary
14110 /* DECL_INITIAL is not defined in PARM_DECLs, since it shares space with
14111 DECL_ARG_TYPE. */
14112 && TREE_CODE (decl) != PARM_DECL)
14113 {
14114 /* We need to remember that this array HAD an initialization, but
14115 discard the actual temporary nodes, since we can't have a permanent
14116 node keep pointing to them. */
14117 /* We make an exception for inline functions, since it's normal for a
14118 local extern redeclaration of an inline function to have a copy of
14119 the top-level decl's DECL_INLINE. */
14120 if ((DECL_INITIAL (decl) != 0)
14121 && (DECL_INITIAL (decl) != error_mark_node))
14122 {
14123 /* If this is a const variable, then preserve the
14124 initializer instead of discarding it so that we can optimize
14125 references to it. */
14126 /* This test used to include TREE_STATIC, but this won't be set
14127 for function level initializers. */
14128 if (TREE_READONLY (decl))
5ff904cd 14129 {
c7e4ee3a
CB
14130 preserve_initializer ();
14131 /* Hack? Set the permanent bit for something that is
14132 permanent, but not on the permenent obstack, so as to
14133 convince output_constant_def to make its rtl on the
14134 permanent obstack. */
14135 TREE_PERMANENT (DECL_INITIAL (decl)) = 1;
5ff904cd 14136
c7e4ee3a
CB
14137 /* The initializer and DECL must have the same (or equivalent
14138 types), but if the initializer is a STRING_CST, its type
14139 might not be on the right obstack, so copy the type
14140 of DECL. */
14141 TREE_TYPE (DECL_INITIAL (decl)) = type;
5ff904cd 14142 }
c7e4ee3a
CB
14143 else
14144 DECL_INITIAL (decl) = error_mark_node;
5ff904cd 14145 }
5ff904cd 14146 }
c7e4ee3a
CB
14147
14148 /* If requested, warn about definitions of large data objects. */
14149
14150 if (warn_larger_than
14151 && (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL)
14152 && !DECL_EXTERNAL (decl))
5ff904cd 14153 {
c7e4ee3a
CB
14154 register tree decl_size = DECL_SIZE (decl);
14155
14156 if (decl_size && TREE_CODE (decl_size) == INTEGER_CST)
5ff904cd 14157 {
c7e4ee3a
CB
14158 unsigned units = TREE_INT_CST_LOW (decl_size) / BITS_PER_UNIT;
14159
14160 if (units > larger_than_size)
14161 warning_with_decl (decl, "size of `%s' is %u bytes", units);
5ff904cd
JL
14162 }
14163 }
14164
c7e4ee3a
CB
14165 /* If we have gone back from temporary to permanent allocation, actually
14166 free the temporary space that we no longer need. */
14167 if (temporary && !allocation_temporary_p ())
14168 permanent_allocation (0);
5ff904cd 14169
c7e4ee3a
CB
14170 /* At the end of a declaration, throw away any variable type sizes of types
14171 defined inside that declaration. There is no use computing them in the
14172 following function definition. */
14173 if (current_binding_level == global_binding_level)
14174 get_pending_sizes ();
14175}
5ff904cd 14176
c7e4ee3a
CB
14177/* Finish up a function declaration and compile that function
14178 all the way to assembler language output. The free the storage
14179 for the function definition.
5ff904cd 14180
c7e4ee3a 14181 This is called after parsing the body of the function definition.
5ff904cd 14182
c7e4ee3a
CB
14183 NESTED is nonzero if the function being finished is nested in another. */
14184
14185static void
14186finish_function (int nested)
14187{
14188 register tree fndecl = current_function_decl;
14189
14190 assert (fndecl != NULL_TREE);
14191 if (TREE_CODE (fndecl) != ERROR_MARK)
14192 {
14193 if (nested)
14194 assert (DECL_CONTEXT (fndecl) != NULL_TREE);
5ff904cd 14195 else
c7e4ee3a
CB
14196 assert (DECL_CONTEXT (fndecl) == NULL_TREE);
14197 }
5ff904cd 14198
c7e4ee3a
CB
14199/* TREE_READONLY (fndecl) = 1;
14200 This caused &foo to be of type ptr-to-const-function
14201 which then got a warning when stored in a ptr-to-function variable. */
5ff904cd 14202
c7e4ee3a 14203 poplevel (1, 0, 1);
5ff904cd 14204
c7e4ee3a
CB
14205 if (TREE_CODE (fndecl) != ERROR_MARK)
14206 {
14207 BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
5ff904cd 14208
c7e4ee3a 14209 /* Must mark the RESULT_DECL as being in this function. */
5ff904cd 14210
c7e4ee3a 14211 DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;
5ff904cd 14212
c7e4ee3a
CB
14213 /* Obey `register' declarations if `setjmp' is called in this fn. */
14214 /* Generate rtl for function exit. */
14215 expand_function_end (input_filename, lineno, 0);
5ff904cd 14216
c7e4ee3a
CB
14217 /* So we can tell if jump_optimize sets it to 1. */
14218 can_reach_end = 0;
5ff904cd 14219
c7e4ee3a
CB
14220 /* Run the optimizers and output the assembler code for this function. */
14221 rest_of_compilation (fndecl);
14222 }
5ff904cd 14223
c7e4ee3a
CB
14224 /* Free all the tree nodes making up this function. */
14225 /* Switch back to allocating nodes permanently until we start another
14226 function. */
14227 if (!nested)
14228 permanent_allocation (1);
14229
14230 if (TREE_CODE (fndecl) != ERROR_MARK
14231 && !nested
14232 && DECL_SAVED_INSNS (fndecl) == 0)
14233 {
14234 /* Stop pointing to the local nodes about to be freed. */
14235 /* But DECL_INITIAL must remain nonzero so we know this was an actual
14236 function definition. */
14237 /* For a nested function, this is done in pop_f_function_context. */
14238 /* If rest_of_compilation set this to 0, leave it 0. */
14239 if (DECL_INITIAL (fndecl) != 0)
14240 DECL_INITIAL (fndecl) = error_mark_node;
14241 DECL_ARGUMENTS (fndecl) = 0;
5ff904cd 14242 }
c7e4ee3a
CB
14243
14244 if (!nested)
5ff904cd 14245 {
c7e4ee3a
CB
14246 /* Let the error reporting routines know that we're outside a function.
14247 For a nested function, this value is used in pop_c_function_context
14248 and then reset via pop_function_context. */
14249 ffecom_outer_function_decl_ = current_function_decl = NULL;
5ff904cd 14250 }
c7e4ee3a 14251}
5ff904cd 14252
c7e4ee3a
CB
14253/* Plug-in replacement for identifying the name of a decl and, for a
14254 function, what we call it in diagnostics. For now, "program unit"
14255 should suffice, since it's a bit of a hassle to figure out which
14256 of several kinds of things it is. Note that it could conceivably
14257 be a statement function, which probably isn't really a program unit
14258 per se, but if that comes up, it should be easy to check (being a
14259 nested function and all). */
14260
14261static char *
14262lang_printable_name (tree decl, int v)
14263{
14264 /* Just to keep GCC quiet about the unused variable.
14265 In theory, differing values of V should produce different
14266 output. */
14267 switch (v)
5ff904cd 14268 {
c7e4ee3a
CB
14269 default:
14270 if (TREE_CODE (decl) == ERROR_MARK)
14271 return "erroneous code";
14272 return IDENTIFIER_POINTER (DECL_NAME (decl));
5ff904cd 14273 }
c7e4ee3a
CB
14274}
14275
14276/* g77's function to print out name of current function that caused
14277 an error. */
14278
14279#if BUILT_FOR_270
14280void
14281lang_print_error_function (file)
14282 char *file;
14283{
14284 static ffeglobal last_g = NULL;
14285 static ffesymbol last_s = NULL;
14286 ffeglobal g;
14287 ffesymbol s;
14288 const char *kind;
14289
14290 if ((ffecom_primary_entry_ == NULL)
14291 || (ffesymbol_global (ffecom_primary_entry_) == NULL))
5ff904cd 14292 {
c7e4ee3a
CB
14293 g = NULL;
14294 s = NULL;
14295 kind = NULL;
5ff904cd
JL
14296 }
14297 else
14298 {
c7e4ee3a
CB
14299 g = ffesymbol_global (ffecom_primary_entry_);
14300 if (ffecom_nested_entry_ == NULL)
14301 {
14302 s = ffecom_primary_entry_;
14303 switch (ffesymbol_kind (s))
14304 {
14305 case FFEINFO_kindFUNCTION:
14306 kind = "function";
14307 break;
5ff904cd 14308
c7e4ee3a
CB
14309 case FFEINFO_kindSUBROUTINE:
14310 kind = "subroutine";
14311 break;
5ff904cd 14312
c7e4ee3a
CB
14313 case FFEINFO_kindPROGRAM:
14314 kind = "program";
14315 break;
14316
14317 case FFEINFO_kindBLOCKDATA:
14318 kind = "block-data";
14319 break;
14320
14321 default:
14322 kind = ffeinfo_kind_message (ffesymbol_kind (s));
14323 break;
14324 }
14325 }
14326 else
14327 {
14328 s = ffecom_nested_entry_;
14329 kind = "statement function";
14330 }
5ff904cd
JL
14331 }
14332
c7e4ee3a 14333 if ((last_g != g) || (last_s != s))
5ff904cd 14334 {
c7e4ee3a
CB
14335 if (file)
14336 fprintf (stderr, "%s: ", file);
14337
14338 if (s == NULL)
14339 fprintf (stderr, "Outside of any program unit:\n");
14340 else
5ff904cd 14341 {
c7e4ee3a
CB
14342 const char *name = ffesymbol_text (s);
14343
14344 fprintf (stderr, "In %s `%s':\n", kind, name);
5ff904cd 14345 }
5ff904cd 14346
c7e4ee3a
CB
14347 last_g = g;
14348 last_s = s;
5ff904cd 14349 }
c7e4ee3a
CB
14350}
14351#endif
5ff904cd 14352
c7e4ee3a 14353/* Similar to `lookup_name' but look only at current binding level. */
5ff904cd 14354
c7e4ee3a
CB
14355static tree
14356lookup_name_current_level (tree name)
14357{
14358 register tree t;
5ff904cd 14359
c7e4ee3a
CB
14360 if (current_binding_level == global_binding_level)
14361 return IDENTIFIER_GLOBAL_VALUE (name);
14362
14363 if (IDENTIFIER_LOCAL_VALUE (name) == 0)
14364 return 0;
14365
14366 for (t = current_binding_level->names; t; t = TREE_CHAIN (t))
14367 if (DECL_NAME (t) == name)
14368 break;
14369
14370 return t;
5ff904cd
JL
14371}
14372
c7e4ee3a 14373/* Create a new `struct binding_level'. */
5ff904cd 14374
c7e4ee3a
CB
14375static struct binding_level *
14376make_binding_level ()
5ff904cd 14377{
c7e4ee3a
CB
14378 /* NOSTRICT */
14379 return (struct binding_level *) xmalloc (sizeof (struct binding_level));
14380}
5ff904cd 14381
c7e4ee3a
CB
14382/* Save and restore the variables in this file and elsewhere
14383 that keep track of the progress of compilation of the current function.
14384 Used for nested functions. */
5ff904cd 14385
c7e4ee3a
CB
14386struct f_function
14387{
14388 struct f_function *next;
14389 tree named_labels;
14390 tree shadowed_labels;
14391 struct binding_level *binding_level;
14392};
5ff904cd 14393
c7e4ee3a 14394struct f_function *f_function_chain;
5ff904cd 14395
c7e4ee3a 14396/* Restore the variables used during compilation of a C function. */
5ff904cd 14397
c7e4ee3a
CB
14398static void
14399pop_f_function_context ()
14400{
14401 struct f_function *p = f_function_chain;
14402 tree link;
5ff904cd 14403
c7e4ee3a
CB
14404 /* Bring back all the labels that were shadowed. */
14405 for (link = shadowed_labels; link; link = TREE_CHAIN (link))
14406 if (DECL_NAME (TREE_VALUE (link)) != 0)
14407 IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link)))
14408 = TREE_VALUE (link);
5ff904cd 14409
c7e4ee3a
CB
14410 if (current_function_decl != error_mark_node
14411 && DECL_SAVED_INSNS (current_function_decl) == 0)
14412 {
14413 /* Stop pointing to the local nodes about to be freed. */
14414 /* But DECL_INITIAL must remain nonzero so we know this was an actual
14415 function definition. */
14416 DECL_INITIAL (current_function_decl) = error_mark_node;
14417 DECL_ARGUMENTS (current_function_decl) = 0;
5ff904cd
JL
14418 }
14419
c7e4ee3a 14420 pop_function_context ();
5ff904cd 14421
c7e4ee3a 14422 f_function_chain = p->next;
5ff904cd 14423
c7e4ee3a
CB
14424 named_labels = p->named_labels;
14425 shadowed_labels = p->shadowed_labels;
14426 current_binding_level = p->binding_level;
5ff904cd 14427
c7e4ee3a
CB
14428 free (p);
14429}
5ff904cd 14430
c7e4ee3a
CB
14431/* Save and reinitialize the variables
14432 used during compilation of a C function. */
5ff904cd 14433
c7e4ee3a
CB
14434static void
14435push_f_function_context ()
14436{
14437 struct f_function *p
14438 = (struct f_function *) xmalloc (sizeof (struct f_function));
5ff904cd 14439
c7e4ee3a
CB
14440 push_function_context ();
14441
14442 p->next = f_function_chain;
14443 f_function_chain = p;
14444
14445 p->named_labels = named_labels;
14446 p->shadowed_labels = shadowed_labels;
14447 p->binding_level = current_binding_level;
14448}
5ff904cd 14449
c7e4ee3a
CB
14450static void
14451push_parm_decl (tree parm)
14452{
14453 int old_immediate_size_expand = immediate_size_expand;
5ff904cd 14454
c7e4ee3a 14455 /* Don't try computing parm sizes now -- wait till fn is called. */
5ff904cd 14456
c7e4ee3a 14457 immediate_size_expand = 0;
5ff904cd 14458
c7e4ee3a 14459 push_obstacks_nochange ();
5ff904cd 14460
c7e4ee3a 14461 /* Fill in arg stuff. */
5ff904cd 14462
c7e4ee3a
CB
14463 DECL_ARG_TYPE (parm) = TREE_TYPE (parm);
14464 DECL_ARG_TYPE_AS_WRITTEN (parm) = TREE_TYPE (parm);
14465 TREE_READONLY (parm) = 1; /* All implementation args are read-only. */
5ff904cd 14466
c7e4ee3a
CB
14467 parm = pushdecl (parm);
14468
14469 immediate_size_expand = old_immediate_size_expand;
14470
14471 finish_decl (parm, NULL_TREE, FALSE);
5ff904cd
JL
14472}
14473
c7e4ee3a 14474/* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL, if appropriate. */
5ff904cd 14475
c7e4ee3a
CB
14476static tree
14477pushdecl_top_level (x)
14478 tree x;
14479{
14480 register tree t;
14481 register struct binding_level *b = current_binding_level;
14482 register tree f = current_function_decl;
5ff904cd 14483
c7e4ee3a
CB
14484 current_binding_level = global_binding_level;
14485 current_function_decl = NULL_TREE;
14486 t = pushdecl (x);
14487 current_binding_level = b;
14488 current_function_decl = f;
14489 return t;
14490}
14491
14492/* Store the list of declarations of the current level.
14493 This is done for the parameter declarations of a function being defined,
14494 after they are modified in the light of any missing parameters. */
14495
14496static tree
14497storedecls (decls)
14498 tree decls;
14499{
14500 return current_binding_level->names = decls;
14501}
14502
14503/* Store the parameter declarations into the current function declaration.
14504 This is called after parsing the parameter declarations, before
14505 digesting the body of the function.
14506
14507 For an old-style definition, modify the function's type
14508 to specify at least the number of arguments. */
5ff904cd
JL
14509
14510static void
c7e4ee3a 14511store_parm_decls (int is_main_program UNUSED)
5ff904cd
JL
14512{
14513 register tree fndecl = current_function_decl;
14514
c7e4ee3a
CB
14515 if (fndecl == error_mark_node)
14516 return;
5ff904cd 14517
c7e4ee3a
CB
14518 /* This is a chain of PARM_DECLs from old-style parm declarations. */
14519 DECL_ARGUMENTS (fndecl) = storedecls (nreverse (getdecls ()));
5ff904cd 14520
c7e4ee3a 14521 /* Initialize the RTL code for the function. */
5ff904cd 14522
c7e4ee3a 14523 init_function_start (fndecl, input_filename, lineno);
56a0044b 14524
c7e4ee3a 14525 /* Set up parameters and prepare for return, for the function. */
5ff904cd 14526
c7e4ee3a
CB
14527 expand_function_start (fndecl, 0);
14528}
5ff904cd 14529
c7e4ee3a
CB
14530static tree
14531start_decl (tree decl, bool is_top_level)
14532{
14533 register tree tem;
14534 bool at_top_level = (current_binding_level == global_binding_level);
14535 bool top_level = is_top_level || at_top_level;
5ff904cd 14536
c7e4ee3a
CB
14537 /* Caller should pass TRUE for is_top_level only if we wouldn't be at top
14538 level anyway. */
14539 assert (!is_top_level || !at_top_level);
5ff904cd 14540
c7e4ee3a
CB
14541 /* The corresponding pop_obstacks is in finish_decl. */
14542 push_obstacks_nochange ();
14543
14544 if (DECL_INITIAL (decl) != NULL_TREE)
14545 {
14546 assert (DECL_INITIAL (decl) == error_mark_node);
14547 assert (!DECL_EXTERNAL (decl));
56a0044b 14548 }
c7e4ee3a
CB
14549 else if (top_level)
14550 assert ((TREE_STATIC (decl) == 1) || DECL_EXTERNAL (decl) == 1);
5ff904cd 14551
c7e4ee3a
CB
14552 /* For Fortran, we by default put things in .common when possible. */
14553 DECL_COMMON (decl) = 1;
5ff904cd 14554
c7e4ee3a
CB
14555 /* Add this decl to the current binding level. TEM may equal DECL or it may
14556 be a previous decl of the same name. */
14557 if (is_top_level)
14558 tem = pushdecl_top_level (decl);
14559 else
14560 tem = pushdecl (decl);
14561
14562 /* For a local variable, define the RTL now. */
14563 if (!top_level
14564 /* But not if this is a duplicate decl and we preserved the rtl from the
14565 previous one (which may or may not happen). */
14566 && DECL_RTL (tem) == 0)
5ff904cd 14567 {
c7e4ee3a
CB
14568 if (TYPE_SIZE (TREE_TYPE (tem)) != 0)
14569 expand_decl (tem);
14570 else if (TREE_CODE (TREE_TYPE (tem)) == ARRAY_TYPE
14571 && DECL_INITIAL (tem) != 0)
14572 expand_decl (tem);
5ff904cd
JL
14573 }
14574
c7e4ee3a 14575 if (DECL_INITIAL (tem) != NULL_TREE)
5ff904cd 14576 {
c7e4ee3a
CB
14577 /* When parsing and digesting the initializer, use temporary storage.
14578 Do this even if we will ignore the value. */
14579 if (at_top_level)
14580 temporary_allocation ();
5ff904cd 14581 }
c7e4ee3a
CB
14582
14583 return tem;
5ff904cd
JL
14584}
14585
c7e4ee3a
CB
14586/* Create the FUNCTION_DECL for a function definition.
14587 DECLSPECS and DECLARATOR are the parts of the declaration;
14588 they describe the function's name and the type it returns,
14589 but twisted together in a fashion that parallels the syntax of C.
5ff904cd 14590
c7e4ee3a
CB
14591 This function creates a binding context for the function body
14592 as well as setting up the FUNCTION_DECL in current_function_decl.
5ff904cd 14593
c7e4ee3a
CB
14594 Returns 1 on success. If the DECLARATOR is not suitable for a function
14595 (it defines a datum instead), we return 0, which tells
14596 yyparse to report a parse error.
5ff904cd 14597
c7e4ee3a
CB
14598 NESTED is nonzero for a function nested within another function. */
14599
14600static void
14601start_function (tree name, tree type, int nested, int public)
5ff904cd 14602{
c7e4ee3a
CB
14603 tree decl1;
14604 tree restype;
14605 int old_immediate_size_expand = immediate_size_expand;
5ff904cd 14606
c7e4ee3a
CB
14607 named_labels = 0;
14608 shadowed_labels = 0;
14609
14610 /* Don't expand any sizes in the return type of the function. */
14611 immediate_size_expand = 0;
14612
14613 if (nested)
5ff904cd 14614 {
c7e4ee3a
CB
14615 assert (!public);
14616 assert (current_function_decl != NULL_TREE);
14617 assert (DECL_CONTEXT (current_function_decl) == NULL_TREE);
14618 }
14619 else
14620 {
14621 assert (current_function_decl == NULL_TREE);
5ff904cd 14622 }
c7e4ee3a
CB
14623
14624 if (TREE_CODE (type) == ERROR_MARK)
14625 decl1 = current_function_decl = error_mark_node;
56a0044b 14626 else
5ff904cd 14627 {
c7e4ee3a
CB
14628 decl1 = build_decl (FUNCTION_DECL,
14629 name,
14630 type);
14631 TREE_PUBLIC (decl1) = public ? 1 : 0;
14632 if (nested)
14633 DECL_INLINE (decl1) = 1;
14634 TREE_STATIC (decl1) = 1;
14635 DECL_EXTERNAL (decl1) = 0;
5ff904cd 14636
c7e4ee3a 14637 announce_function (decl1);
5ff904cd 14638
c7e4ee3a
CB
14639 /* Make the init_value nonzero so pushdecl knows this is not tentative.
14640 error_mark_node is replaced below (in poplevel) with the BLOCK. */
14641 DECL_INITIAL (decl1) = error_mark_node;
5ff904cd 14642
c7e4ee3a
CB
14643 /* Record the decl so that the function name is defined. If we already have
14644 a decl for this name, and it is a FUNCTION_DECL, use the old decl. */
5ff904cd 14645
c7e4ee3a 14646 current_function_decl = pushdecl (decl1);
5ff904cd
JL
14647 }
14648
c7e4ee3a
CB
14649 if (!nested)
14650 ffecom_outer_function_decl_ = current_function_decl;
5ff904cd 14651
c7e4ee3a
CB
14652 pushlevel (0);
14653 current_binding_level->prep_state = 2;
5ff904cd 14654
c7e4ee3a
CB
14655 if (TREE_CODE (current_function_decl) != ERROR_MARK)
14656 {
14657 make_function_rtl (current_function_decl);
5ff904cd 14658
c7e4ee3a
CB
14659 restype = TREE_TYPE (TREE_TYPE (current_function_decl));
14660 DECL_RESULT (current_function_decl)
14661 = build_decl (RESULT_DECL, NULL_TREE, restype);
5ff904cd 14662 }
5ff904cd 14663
c7e4ee3a
CB
14664 if (!nested)
14665 /* Allocate further tree nodes temporarily during compilation of this
14666 function only. */
14667 temporary_allocation ();
5ff904cd 14668
c7e4ee3a
CB
14669 if (!nested && (TREE_CODE (current_function_decl) != ERROR_MARK))
14670 TREE_ADDRESSABLE (current_function_decl) = 1;
14671
14672 immediate_size_expand = old_immediate_size_expand;
14673}
14674\f
14675/* Here are the public functions the GNU back end needs. */
14676
14677tree
14678convert (type, expr)
14679 tree type, expr;
5ff904cd 14680{
c7e4ee3a
CB
14681 register tree e = expr;
14682 register enum tree_code code = TREE_CODE (type);
5ff904cd 14683
c7e4ee3a
CB
14684 if (type == TREE_TYPE (e)
14685 || TREE_CODE (e) == ERROR_MARK)
14686 return e;
14687 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
14688 return fold (build1 (NOP_EXPR, type, e));
14689 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
14690 || code == ERROR_MARK)
14691 return error_mark_node;
14692 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
14693 {
14694 assert ("void value not ignored as it ought to be" == NULL);
14695 return error_mark_node;
14696 }
14697 if (code == VOID_TYPE)
14698 return build1 (CONVERT_EXPR, type, e);
14699 if ((code != RECORD_TYPE)
14700 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
14701 e = ffecom_1 (REALPART_EXPR, TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e))),
14702 e);
14703 if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)
14704 return fold (convert_to_integer (type, e));
14705 if (code == POINTER_TYPE)
14706 return fold (convert_to_pointer (type, e));
14707 if (code == REAL_TYPE)
14708 return fold (convert_to_real (type, e));
14709 if (code == COMPLEX_TYPE)
14710 return fold (convert_to_complex (type, e));
14711 if (code == RECORD_TYPE)
14712 return fold (ffecom_convert_to_complex_ (type, e));
5ff904cd 14713
c7e4ee3a
CB
14714 assert ("conversion to non-scalar type requested" == NULL);
14715 return error_mark_node;
14716}
5ff904cd 14717
c7e4ee3a
CB
14718/* integrate_decl_tree calls this function, but since we don't use the
14719 DECL_LANG_SPECIFIC field, this is a no-op. */
5ff904cd 14720
c7e4ee3a
CB
14721void
14722copy_lang_decl (node)
14723 tree node UNUSED;
14724{
5ff904cd
JL
14725}
14726
c7e4ee3a
CB
14727/* Return the list of declarations of the current level.
14728 Note that this list is in reverse order unless/until
14729 you nreverse it; and when you do nreverse it, you must
14730 store the result back using `storedecls' or you will lose. */
5ff904cd 14731
c7e4ee3a
CB
14732tree
14733getdecls ()
5ff904cd 14734{
c7e4ee3a 14735 return current_binding_level->names;
5ff904cd
JL
14736}
14737
c7e4ee3a 14738/* Nonzero if we are currently in the global binding level. */
5ff904cd 14739
c7e4ee3a
CB
14740int
14741global_bindings_p ()
5ff904cd 14742{
c7e4ee3a
CB
14743 return current_binding_level == global_binding_level;
14744}
5ff904cd 14745
c7e4ee3a
CB
14746/* Print an error message for invalid use of an incomplete type.
14747 VALUE is the expression that was used (or 0 if that isn't known)
14748 and TYPE is the type that was invalid. */
5ff904cd 14749
c7e4ee3a
CB
14750void
14751incomplete_type_error (value, type)
14752 tree value UNUSED;
14753 tree type;
14754{
14755 if (TREE_CODE (type) == ERROR_MARK)
14756 return;
5ff904cd 14757
c7e4ee3a
CB
14758 assert ("incomplete type?!?" == NULL);
14759}
14760
14761void
14762init_decl_processing ()
5ff904cd 14763{
c7e4ee3a
CB
14764 malloc_init ();
14765 ffe_init_0 ();
14766}
5ff904cd 14767
c7e4ee3a
CB
14768char *
14769init_parse (filename)
14770 char *filename;
14771{
14772#if BUILT_FOR_270
14773 extern void (*print_error_function) (char *);
14774#endif
5ff904cd 14775
c7e4ee3a
CB
14776 /* Open input file. */
14777 if (filename == 0 || !strcmp (filename, "-"))
5ff904cd 14778 {
c7e4ee3a
CB
14779 finput = stdin;
14780 filename = "stdin";
5ff904cd 14781 }
c7e4ee3a
CB
14782 else
14783 finput = fopen (filename, "r");
14784 if (finput == 0)
14785 pfatal_with_name (filename);
5ff904cd 14786
c7e4ee3a
CB
14787#ifdef IO_BUFFER_SIZE
14788 setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
14789#endif
5ff904cd 14790
c7e4ee3a
CB
14791 /* Make identifier nodes long enough for the language-specific slots. */
14792 set_identifier_size (sizeof (struct lang_identifier));
14793 decl_printable_name = lang_printable_name;
14794#if BUILT_FOR_270
14795 print_error_function = lang_print_error_function;
14796#endif
5ff904cd 14797
c7e4ee3a
CB
14798 return filename;
14799}
5ff904cd 14800
c7e4ee3a
CB
14801void
14802finish_parse ()
14803{
14804 fclose (finput);
14805}
14806
14807/* Delete the node BLOCK from the current binding level.
14808 This is used for the block inside a stmt expr ({...})
14809 so that the block can be reinserted where appropriate. */
14810
14811static void
14812delete_block (block)
14813 tree block;
14814{
14815 tree t;
14816 if (current_binding_level->blocks == block)
14817 current_binding_level->blocks = TREE_CHAIN (block);
14818 for (t = current_binding_level->blocks; t;)
14819 {
14820 if (TREE_CHAIN (t) == block)
14821 TREE_CHAIN (t) = TREE_CHAIN (block);
14822 else
14823 t = TREE_CHAIN (t);
14824 }
14825 TREE_CHAIN (block) = NULL;
14826 /* Clear TREE_USED which is always set by poplevel.
14827 The flag is set again if insert_block is called. */
14828 TREE_USED (block) = 0;
14829}
14830
14831void
14832insert_block (block)
14833 tree block;
14834{
14835 TREE_USED (block) = 1;
14836 current_binding_level->blocks
14837 = chainon (current_binding_level->blocks, block);
14838}
14839
14840int
14841lang_decode_option (argc, argv)
14842 int argc;
14843 char **argv;
14844{
14845 return ffe_decode_option (argc, argv);
5ff904cd
JL
14846}
14847
c7e4ee3a 14848/* used by print-tree.c */
5ff904cd 14849
c7e4ee3a
CB
14850void
14851lang_print_xnode (file, node, indent)
14852 FILE *file UNUSED;
14853 tree node UNUSED;
14854 int indent UNUSED;
5ff904cd 14855{
c7e4ee3a 14856}
5ff904cd 14857
c7e4ee3a
CB
14858void
14859lang_finish ()
14860{
14861 ffe_terminate_0 ();
5ff904cd 14862
c7e4ee3a
CB
14863 if (ffe_is_ffedebug ())
14864 malloc_pool_display (malloc_pool_image ());
5ff904cd
JL
14865}
14866
c7e4ee3a
CB
14867char *
14868lang_identify ()
5ff904cd 14869{
c7e4ee3a
CB
14870 return "f77";
14871}
5ff904cd 14872
c7e4ee3a
CB
14873void
14874lang_init_options ()
14875{
14876 /* Set default options for Fortran. */
14877 flag_move_all_movables = 1;
14878 flag_reduce_all_givs = 1;
14879 flag_argument_noalias = 2;
14880}
5ff904cd 14881
c7e4ee3a
CB
14882void
14883lang_init ()
14884{
14885 /* If the file is output from cpp, it should contain a first line
14886 `# 1 "real-filename"', and the current design of gcc (toplev.c
14887 in particular and the way it sets up information relied on by
14888 INCLUDE) requires that we read this now, and store the
14889 "real-filename" info in master_input_filename. Ask the lexer
14890 to try doing this. */
14891 ffelex_hash_kludge (finput);
14892}
5ff904cd 14893
c7e4ee3a
CB
14894int
14895mark_addressable (exp)
14896 tree exp;
14897{
14898 register tree x = exp;
14899 while (1)
14900 switch (TREE_CODE (x))
14901 {
14902 case ADDR_EXPR:
14903 case COMPONENT_REF:
14904 case ARRAY_REF:
14905 x = TREE_OPERAND (x, 0);
14906 break;
5ff904cd 14907
c7e4ee3a
CB
14908 case CONSTRUCTOR:
14909 TREE_ADDRESSABLE (x) = 1;
14910 return 1;
5ff904cd 14911
c7e4ee3a
CB
14912 case VAR_DECL:
14913 case CONST_DECL:
14914 case PARM_DECL:
14915 case RESULT_DECL:
14916 if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
14917 && DECL_NONLOCAL (x))
14918 {
14919 if (TREE_PUBLIC (x))
14920 {
14921 assert ("address of global register var requested" == NULL);
14922 return 0;
14923 }
14924 assert ("address of register variable requested" == NULL);
14925 }
14926 else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x))
14927 {
14928 if (TREE_PUBLIC (x))
14929 {
14930 assert ("address of global register var requested" == NULL);
14931 return 0;
14932 }
14933 assert ("address of register var requested" == NULL);
14934 }
14935 put_var_into_stack (x);
5ff904cd 14936
c7e4ee3a
CB
14937 /* drops in */
14938 case FUNCTION_DECL:
14939 TREE_ADDRESSABLE (x) = 1;
14940#if 0 /* poplevel deals with this now. */
14941 if (DECL_CONTEXT (x) == 0)
14942 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (x)) = 1;
14943#endif
5ff904cd 14944
c7e4ee3a
CB
14945 default:
14946 return 1;
14947 }
5ff904cd
JL
14948}
14949
c7e4ee3a
CB
14950/* If DECL has a cleanup, build and return that cleanup here.
14951 This is a callback called by expand_expr. */
5ff904cd 14952
c7e4ee3a
CB
14953tree
14954maybe_build_cleanup (decl)
14955 tree decl UNUSED;
5ff904cd 14956{
c7e4ee3a
CB
14957 /* There are no cleanups in Fortran. */
14958 return NULL_TREE;
5ff904cd
JL
14959}
14960
c7e4ee3a
CB
14961/* Exit a binding level.
14962 Pop the level off, and restore the state of the identifier-decl mappings
14963 that were in effect when this level was entered.
5ff904cd 14964
c7e4ee3a
CB
14965 If KEEP is nonzero, this level had explicit declarations, so
14966 and create a "block" (a BLOCK node) for the level
14967 to record its declarations and subblocks for symbol table output.
5ff904cd 14968
c7e4ee3a
CB
14969 If FUNCTIONBODY is nonzero, this level is the body of a function,
14970 so create a block as if KEEP were set and also clear out all
14971 label names.
5ff904cd 14972
c7e4ee3a
CB
14973 If REVERSE is nonzero, reverse the order of decls before putting
14974 them into the BLOCK. */
5ff904cd 14975
c7e4ee3a
CB
14976tree
14977poplevel (keep, reverse, functionbody)
14978 int keep;
14979 int reverse;
14980 int functionbody;
5ff904cd 14981{
c7e4ee3a
CB
14982 register tree link;
14983 /* The chain of decls was accumulated in reverse order.
14984 Put it into forward order, just for cleanliness. */
14985 tree decls;
14986 tree subblocks = current_binding_level->blocks;
14987 tree block = 0;
14988 tree decl;
14989 int block_previously_created;
5ff904cd 14990
c7e4ee3a
CB
14991 /* Get the decls in the order they were written.
14992 Usually current_binding_level->names is in reverse order.
14993 But parameter decls were previously put in forward order. */
702edf1d 14994
c7e4ee3a
CB
14995 if (reverse)
14996 current_binding_level->names
14997 = decls = nreverse (current_binding_level->names);
14998 else
14999 decls = current_binding_level->names;
5ff904cd 15000
c7e4ee3a
CB
15001 /* Output any nested inline functions within this block
15002 if they weren't already output. */
5ff904cd 15003
c7e4ee3a
CB
15004 for (decl = decls; decl; decl = TREE_CHAIN (decl))
15005 if (TREE_CODE (decl) == FUNCTION_DECL
15006 && ! TREE_ASM_WRITTEN (decl)
15007 && DECL_INITIAL (decl) != 0
15008 && TREE_ADDRESSABLE (decl))
15009 {
15010 /* If this decl was copied from a file-scope decl
15011 on account of a block-scope extern decl,
15012 propagate TREE_ADDRESSABLE to the file-scope decl.
15013
15014 DECL_ABSTRACT_ORIGIN can be set to itself if warn_return_type is
15015 true, since then the decl goes through save_for_inline_copying. */
15016 if (DECL_ABSTRACT_ORIGIN (decl) != 0
15017 && DECL_ABSTRACT_ORIGIN (decl) != decl)
15018 TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1;
15019 else if (DECL_SAVED_INSNS (decl) != 0)
15020 {
15021 push_function_context ();
15022 output_inline_function (decl);
15023 pop_function_context ();
15024 }
15025 }
5ff904cd 15026
c7e4ee3a
CB
15027 /* If there were any declarations or structure tags in that level,
15028 or if this level is a function body,
15029 create a BLOCK to record them for the life of this function. */
5ff904cd 15030
c7e4ee3a
CB
15031 block = 0;
15032 block_previously_created = (current_binding_level->this_block != 0);
15033 if (block_previously_created)
15034 block = current_binding_level->this_block;
15035 else if (keep || functionbody)
15036 block = make_node (BLOCK);
15037 if (block != 0)
15038 {
15039 BLOCK_VARS (block) = decls;
15040 BLOCK_SUBBLOCKS (block) = subblocks;
15041 remember_end_note (block);
15042 }
5ff904cd 15043
c7e4ee3a 15044 /* In each subblock, record that this is its superior. */
5ff904cd 15045
c7e4ee3a
CB
15046 for (link = subblocks; link; link = TREE_CHAIN (link))
15047 BLOCK_SUPERCONTEXT (link) = block;
5ff904cd 15048
c7e4ee3a 15049 /* Clear out the meanings of the local variables of this level. */
5ff904cd 15050
c7e4ee3a 15051 for (link = decls; link; link = TREE_CHAIN (link))
5ff904cd 15052 {
c7e4ee3a
CB
15053 if (DECL_NAME (link) != 0)
15054 {
15055 /* If the ident. was used or addressed via a local extern decl,
15056 don't forget that fact. */
15057 if (DECL_EXTERNAL (link))
15058 {
15059 if (TREE_USED (link))
15060 TREE_USED (DECL_NAME (link)) = 1;
15061 if (TREE_ADDRESSABLE (link))
15062 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (link)) = 1;
15063 }
15064 IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = 0;
15065 }
5ff904cd 15066 }
5ff904cd 15067
c7e4ee3a
CB
15068 /* If the level being exited is the top level of a function,
15069 check over all the labels, and clear out the current
15070 (function local) meanings of their names. */
5ff904cd 15071
c7e4ee3a 15072 if (functionbody)
5ff904cd 15073 {
c7e4ee3a
CB
15074 /* If this is the top level block of a function,
15075 the vars are the function's parameters.
15076 Don't leave them in the BLOCK because they are
15077 found in the FUNCTION_DECL instead. */
15078
15079 BLOCK_VARS (block) = 0;
5ff904cd
JL
15080 }
15081
c7e4ee3a
CB
15082 /* Pop the current level, and free the structure for reuse. */
15083
15084 {
15085 register struct binding_level *level = current_binding_level;
15086 current_binding_level = current_binding_level->level_chain;
15087
15088 level->level_chain = free_binding_level;
15089 free_binding_level = level;
15090 }
15091
15092 /* Dispose of the block that we just made inside some higher level. */
15093 if (functionbody
15094 && current_function_decl != error_mark_node)
15095 DECL_INITIAL (current_function_decl) = block;
15096 else if (block)
5ff904cd 15097 {
c7e4ee3a
CB
15098 if (!block_previously_created)
15099 current_binding_level->blocks
15100 = chainon (current_binding_level->blocks, block);
5ff904cd 15101 }
c7e4ee3a
CB
15102 /* If we did not make a block for the level just exited,
15103 any blocks made for inner levels
15104 (since they cannot be recorded as subblocks in that level)
15105 must be carried forward so they will later become subblocks
15106 of something else. */
15107 else if (subblocks)
15108 current_binding_level->blocks
15109 = chainon (current_binding_level->blocks, subblocks);
5ff904cd 15110
c7e4ee3a
CB
15111 if (block)
15112 TREE_USED (block) = 1;
15113 return block;
5ff904cd
JL
15114}
15115
c7e4ee3a
CB
15116void
15117print_lang_decl (file, node, indent)
15118 FILE *file UNUSED;
15119 tree node UNUSED;
15120 int indent UNUSED;
15121{
15122}
5ff904cd 15123
c7e4ee3a
CB
15124void
15125print_lang_identifier (file, node, indent)
15126 FILE *file;
15127 tree node;
15128 int indent;
15129{
15130 print_node (file, "global", IDENTIFIER_GLOBAL_VALUE (node), indent + 4);
15131 print_node (file, "local", IDENTIFIER_LOCAL_VALUE (node), indent + 4);
15132}
5ff904cd 15133
c7e4ee3a
CB
15134void
15135print_lang_statistics ()
15136{
15137}
5ff904cd 15138
c7e4ee3a
CB
15139void
15140print_lang_type (file, node, indent)
15141 FILE *file UNUSED;
15142 tree node UNUSED;
15143 int indent UNUSED;
5ff904cd 15144{
c7e4ee3a 15145}
5ff904cd 15146
c7e4ee3a
CB
15147/* Record a decl-node X as belonging to the current lexical scope.
15148 Check for errors (such as an incompatible declaration for the same
15149 name already seen in the same scope).
5ff904cd 15150
c7e4ee3a
CB
15151 Returns either X or an old decl for the same name.
15152 If an old decl is returned, it may have been smashed
15153 to agree with what X says. */
5ff904cd 15154
c7e4ee3a
CB
15155tree
15156pushdecl (x)
15157 tree x;
15158{
15159 register tree t;
15160 register tree name = DECL_NAME (x);
15161 register struct binding_level *b = current_binding_level;
5ff904cd 15162
c7e4ee3a
CB
15163 if ((TREE_CODE (x) == FUNCTION_DECL)
15164 && (DECL_INITIAL (x) == 0)
15165 && DECL_EXTERNAL (x))
15166 DECL_CONTEXT (x) = NULL_TREE;
56a0044b 15167 else
c7e4ee3a
CB
15168 DECL_CONTEXT (x) = current_function_decl;
15169
15170 if (name)
56a0044b 15171 {
c7e4ee3a
CB
15172 if (IDENTIFIER_INVENTED (name))
15173 {
15174#if BUILT_FOR_270
15175 DECL_ARTIFICIAL (x) = 1;
15176#endif
15177 DECL_IN_SYSTEM_HEADER (x) = 1;
15178 }
5ff904cd 15179
c7e4ee3a 15180 t = lookup_name_current_level (name);
5ff904cd 15181
c7e4ee3a 15182 assert ((t == NULL_TREE) || (DECL_CONTEXT (x) == NULL_TREE));
5ff904cd 15183
c7e4ee3a
CB
15184 /* Don't push non-parms onto list for parms until we understand
15185 why we're doing this and whether it works. */
56a0044b 15186
c7e4ee3a
CB
15187 assert ((b == global_binding_level)
15188 || !ffecom_transform_only_dummies_
15189 || TREE_CODE (x) == PARM_DECL);
5ff904cd 15190
c7e4ee3a
CB
15191 if ((t != NULL_TREE) && duplicate_decls (x, t))
15192 return t;
5ff904cd 15193
c7e4ee3a
CB
15194 /* If we are processing a typedef statement, generate a whole new
15195 ..._TYPE node (which will be just an variant of the existing
15196 ..._TYPE node with identical properties) and then install the
15197 TYPE_DECL node generated to represent the typedef name as the
15198 TYPE_NAME of this brand new (duplicate) ..._TYPE node.
5ff904cd 15199
c7e4ee3a
CB
15200 The whole point here is to end up with a situation where each and every
15201 ..._TYPE node the compiler creates will be uniquely associated with
15202 AT MOST one node representing a typedef name. This way, even though
15203 the compiler substitutes corresponding ..._TYPE nodes for TYPE_DECL
15204 (i.e. "typedef name") nodes very early on, later parts of the
15205 compiler can always do the reverse translation and get back the
15206 corresponding typedef name. For example, given:
5ff904cd 15207
c7e4ee3a 15208 typedef struct S MY_TYPE; MY_TYPE object;
5ff904cd 15209
c7e4ee3a
CB
15210 Later parts of the compiler might only know that `object' was of type
15211 `struct S' if it were not for code just below. With this code
15212 however, later parts of the compiler see something like:
5ff904cd 15213
c7e4ee3a 15214 struct S' == struct S typedef struct S' MY_TYPE; struct S' object;
5ff904cd 15215
c7e4ee3a
CB
15216 And they can then deduce (from the node for type struct S') that the
15217 original object declaration was:
5ff904cd 15218
c7e4ee3a 15219 MY_TYPE object;
5ff904cd 15220
c7e4ee3a
CB
15221 Being able to do this is important for proper support of protoize, and
15222 also for generating precise symbolic debugging information which
15223 takes full account of the programmer's (typedef) vocabulary.
5ff904cd 15224
c7e4ee3a
CB
15225 Obviously, we don't want to generate a duplicate ..._TYPE node if the
15226 TYPE_DECL node that we are now processing really represents a
15227 standard built-in type.
5ff904cd 15228
c7e4ee3a
CB
15229 Since all standard types are effectively declared at line zero in the
15230 source file, we can easily check to see if we are working on a
15231 standard type by checking the current value of lineno. */
15232
15233 if (TREE_CODE (x) == TYPE_DECL)
15234 {
15235 if (DECL_SOURCE_LINE (x) == 0)
15236 {
15237 if (TYPE_NAME (TREE_TYPE (x)) == 0)
15238 TYPE_NAME (TREE_TYPE (x)) = x;
15239 }
15240 else if (TREE_TYPE (x) != error_mark_node)
15241 {
15242 tree tt = TREE_TYPE (x);
15243
15244 tt = build_type_copy (tt);
15245 TYPE_NAME (tt) = x;
15246 TREE_TYPE (x) = tt;
15247 }
15248 }
5ff904cd 15249
c7e4ee3a
CB
15250 /* This name is new in its binding level. Install the new declaration
15251 and return it. */
15252 if (b == global_binding_level)
15253 IDENTIFIER_GLOBAL_VALUE (name) = x;
15254 else
15255 IDENTIFIER_LOCAL_VALUE (name) = x;
15256 }
5ff904cd 15257
c7e4ee3a
CB
15258 /* Put decls on list in reverse order. We will reverse them later if
15259 necessary. */
15260 TREE_CHAIN (x) = b->names;
15261 b->names = x;
5ff904cd 15262
c7e4ee3a 15263 return x;
5ff904cd
JL
15264}
15265
c7e4ee3a 15266/* Nonzero if the current level needs to have a BLOCK made. */
5ff904cd 15267
c7e4ee3a
CB
15268static int
15269kept_level_p ()
5ff904cd 15270{
c7e4ee3a
CB
15271 tree decl;
15272
15273 for (decl = current_binding_level->names;
15274 decl;
15275 decl = TREE_CHAIN (decl))
15276 {
15277 if (TREE_USED (decl) || TREE_CODE (decl) != VAR_DECL
15278 || (DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl)))
15279 /* Currently, there aren't supposed to be non-artificial names
15280 at other than the top block for a function -- they're
15281 believed to always be temps. But it's wise to check anyway. */
15282 return 1;
15283 }
15284 return 0;
5ff904cd
JL
15285}
15286
c7e4ee3a
CB
15287/* Enter a new binding level.
15288 If TAG_TRANSPARENT is nonzero, do so only for the name space of variables,
15289 not for that of tags. */
5ff904cd
JL
15290
15291void
c7e4ee3a
CB
15292pushlevel (tag_transparent)
15293 int tag_transparent;
5ff904cd 15294{
c7e4ee3a 15295 register struct binding_level *newlevel = NULL_BINDING_LEVEL;
5ff904cd 15296
c7e4ee3a 15297 assert (! tag_transparent);
5ff904cd 15298
c7e4ee3a
CB
15299 if (current_binding_level == global_binding_level)
15300 {
15301 named_labels = 0;
15302 }
5ff904cd 15303
c7e4ee3a 15304 /* Reuse or create a struct for this binding level. */
5ff904cd 15305
c7e4ee3a 15306 if (free_binding_level)
77f77701 15307 {
c7e4ee3a
CB
15308 newlevel = free_binding_level;
15309 free_binding_level = free_binding_level->level_chain;
77f77701
DB
15310 }
15311 else
c7e4ee3a
CB
15312 {
15313 newlevel = make_binding_level ();
15314 }
77f77701 15315
c7e4ee3a
CB
15316 /* Add this level to the front of the chain (stack) of levels that
15317 are active. */
71b5e532 15318
c7e4ee3a
CB
15319 *newlevel = clear_binding_level;
15320 newlevel->level_chain = current_binding_level;
15321 current_binding_level = newlevel;
5ff904cd
JL
15322}
15323
c7e4ee3a
CB
15324/* Set the BLOCK node for the innermost scope
15325 (the one we are currently in). */
77f77701 15326
5ff904cd 15327void
c7e4ee3a
CB
15328set_block (block)
15329 register tree block;
5ff904cd 15330{
c7e4ee3a 15331 current_binding_level->this_block = block;
5ff904cd
JL
15332}
15333
c7e4ee3a 15334/* ~~gcc/tree.h *should* declare this, because toplev.c references it. */
5ff904cd 15335
c7e4ee3a 15336/* Can't 'yydebug' a front end not generated by yacc/bison! */
bc289659
ML
15337
15338void
c7e4ee3a
CB
15339set_yydebug (value)
15340 int value;
bc289659 15341{
c7e4ee3a
CB
15342 if (value)
15343 fprintf (stderr, "warning: no yacc/bison-generated output to debug!\n");
bc289659
ML
15344}
15345
c7e4ee3a
CB
15346tree
15347signed_or_unsigned_type (unsignedp, type)
15348 int unsignedp;
15349 tree type;
5ff904cd 15350{
c7e4ee3a 15351 tree type2;
5ff904cd 15352
c7e4ee3a
CB
15353 if (! INTEGRAL_TYPE_P (type))
15354 return type;
15355 if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node))
15356 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
15357 if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
15358 return unsignedp ? unsigned_type_node : integer_type_node;
15359 if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node))
15360 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
15361 if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node))
15362 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
15363 if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node))
15364 return (unsignedp ? long_long_unsigned_type_node
15365 : long_long_integer_type_node);
5ff904cd 15366
c7e4ee3a
CB
15367 type2 = type_for_size (TYPE_PRECISION (type), unsignedp);
15368 if (type2 == NULL_TREE)
15369 return type;
f84639ba 15370
c7e4ee3a 15371 return type2;
5ff904cd
JL
15372}
15373
c7e4ee3a
CB
15374tree
15375signed_type (type)
15376 tree type;
5ff904cd 15377{
c7e4ee3a
CB
15378 tree type1 = TYPE_MAIN_VARIANT (type);
15379 ffeinfoKindtype kt;
15380 tree type2;
5ff904cd 15381
c7e4ee3a
CB
15382 if (type1 == unsigned_char_type_node || type1 == char_type_node)
15383 return signed_char_type_node;
15384 if (type1 == unsigned_type_node)
15385 return integer_type_node;
15386 if (type1 == short_unsigned_type_node)
15387 return short_integer_type_node;
15388 if (type1 == long_unsigned_type_node)
15389 return long_integer_type_node;
15390 if (type1 == long_long_unsigned_type_node)
15391 return long_long_integer_type_node;
15392#if 0 /* gcc/c-* files only */
15393 if (type1 == unsigned_intDI_type_node)
15394 return intDI_type_node;
15395 if (type1 == unsigned_intSI_type_node)
15396 return intSI_type_node;
15397 if (type1 == unsigned_intHI_type_node)
15398 return intHI_type_node;
15399 if (type1 == unsigned_intQI_type_node)
15400 return intQI_type_node;
15401#endif
5ff904cd 15402
c7e4ee3a
CB
15403 type2 = type_for_size (TYPE_PRECISION (type1), 0);
15404 if (type2 != NULL_TREE)
15405 return type2;
5ff904cd 15406
c7e4ee3a
CB
15407 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
15408 {
15409 type2 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
5ff904cd 15410
c7e4ee3a
CB
15411 if (type1 == type2)
15412 return ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
15413 }
15414
15415 return type;
5ff904cd
JL
15416}
15417
c7e4ee3a
CB
15418/* Prepare expr to be an argument of a TRUTH_NOT_EXPR,
15419 or validate its data type for an `if' or `while' statement or ?..: exp.
15420
15421 This preparation consists of taking the ordinary
15422 representation of an expression expr and producing a valid tree
15423 boolean expression describing whether expr is nonzero. We could
15424 simply always do build_binary_op (NE_EXPR, expr, integer_zero_node, 1),
15425 but we optimize comparisons, &&, ||, and !.
15426
15427 The resulting type should always be `integer_type_node'. */
5ff904cd
JL
15428
15429tree
c7e4ee3a
CB
15430truthvalue_conversion (expr)
15431 tree expr;
5ff904cd 15432{
c7e4ee3a
CB
15433 if (TREE_CODE (expr) == ERROR_MARK)
15434 return expr;
5ff904cd 15435
c7e4ee3a
CB
15436#if 0 /* This appears to be wrong for C++. */
15437 /* These really should return error_mark_node after 2.4 is stable.
15438 But not all callers handle ERROR_MARK properly. */
15439 switch (TREE_CODE (TREE_TYPE (expr)))
15440 {
15441 case RECORD_TYPE:
15442 error ("struct type value used where scalar is required");
15443 return integer_zero_node;
5ff904cd 15444
c7e4ee3a
CB
15445 case UNION_TYPE:
15446 error ("union type value used where scalar is required");
15447 return integer_zero_node;
5ff904cd 15448
c7e4ee3a
CB
15449 case ARRAY_TYPE:
15450 error ("array type value used where scalar is required");
15451 return integer_zero_node;
5ff904cd 15452
c7e4ee3a
CB
15453 default:
15454 break;
15455 }
15456#endif /* 0 */
5ff904cd 15457
c7e4ee3a
CB
15458 switch (TREE_CODE (expr))
15459 {
15460 /* It is simpler and generates better code to have only TRUTH_*_EXPR
15461 or comparison expressions as truth values at this level. */
15462#if 0
15463 case COMPONENT_REF:
15464 /* A one-bit unsigned bit-field is already acceptable. */
15465 if (1 == TREE_INT_CST_LOW (DECL_SIZE (TREE_OPERAND (expr, 1)))
15466 && TREE_UNSIGNED (TREE_OPERAND (expr, 1)))
15467 return expr;
15468 break;
15469#endif
15470
15471 case EQ_EXPR:
15472 /* It is simpler and generates better code to have only TRUTH_*_EXPR
15473 or comparison expressions as truth values at this level. */
15474#if 0
15475 if (integer_zerop (TREE_OPERAND (expr, 1)))
15476 return build_unary_op (TRUTH_NOT_EXPR, TREE_OPERAND (expr, 0), 0);
15477#endif
15478 case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
15479 case TRUTH_ANDIF_EXPR:
15480 case TRUTH_ORIF_EXPR:
15481 case TRUTH_AND_EXPR:
15482 case TRUTH_OR_EXPR:
15483 case TRUTH_XOR_EXPR:
15484 TREE_TYPE (expr) = integer_type_node;
15485 return expr;
5ff904cd 15486
c7e4ee3a
CB
15487 case ERROR_MARK:
15488 return expr;
5ff904cd 15489
c7e4ee3a
CB
15490 case INTEGER_CST:
15491 return integer_zerop (expr) ? integer_zero_node : integer_one_node;
5ff904cd 15492
c7e4ee3a
CB
15493 case REAL_CST:
15494 return real_zerop (expr) ? integer_zero_node : integer_one_node;
5ff904cd 15495
c7e4ee3a
CB
15496 case ADDR_EXPR:
15497 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 0)))
15498 return build (COMPOUND_EXPR, integer_type_node,
15499 TREE_OPERAND (expr, 0), integer_one_node);
15500 else
15501 return integer_one_node;
5ff904cd 15502
c7e4ee3a
CB
15503 case COMPLEX_EXPR:
15504 return ffecom_2 ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))
15505 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
15506 integer_type_node,
15507 truthvalue_conversion (TREE_OPERAND (expr, 0)),
15508 truthvalue_conversion (TREE_OPERAND (expr, 1)));
5ff904cd 15509
c7e4ee3a
CB
15510 case NEGATE_EXPR:
15511 case ABS_EXPR:
15512 case FLOAT_EXPR:
15513 case FFS_EXPR:
15514 /* These don't change whether an object is non-zero or zero. */
15515 return truthvalue_conversion (TREE_OPERAND (expr, 0));
5ff904cd 15516
c7e4ee3a
CB
15517 case LROTATE_EXPR:
15518 case RROTATE_EXPR:
15519 /* These don't change whether an object is zero or non-zero, but
15520 we can't ignore them if their second arg has side-effects. */
15521 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)))
15522 return build (COMPOUND_EXPR, integer_type_node, TREE_OPERAND (expr, 1),
15523 truthvalue_conversion (TREE_OPERAND (expr, 0)));
15524 else
15525 return truthvalue_conversion (TREE_OPERAND (expr, 0));
5ff904cd 15526
c7e4ee3a
CB
15527 case COND_EXPR:
15528 /* Distribute the conversion into the arms of a COND_EXPR. */
15529 return fold (build (COND_EXPR, integer_type_node, TREE_OPERAND (expr, 0),
15530 truthvalue_conversion (TREE_OPERAND (expr, 1)),
15531 truthvalue_conversion (TREE_OPERAND (expr, 2))));
5ff904cd 15532
c7e4ee3a
CB
15533 case CONVERT_EXPR:
15534 /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
15535 since that affects how `default_conversion' will behave. */
15536 if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE
15537 || TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)
15538 break;
15539 /* fall through... */
15540 case NOP_EXPR:
15541 /* If this is widening the argument, we can ignore it. */
15542 if (TYPE_PRECISION (TREE_TYPE (expr))
15543 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
15544 return truthvalue_conversion (TREE_OPERAND (expr, 0));
15545 break;
5ff904cd 15546
c7e4ee3a
CB
15547 case MINUS_EXPR:
15548 /* With IEEE arithmetic, x - x may not equal 0, so we can't optimize
15549 this case. */
15550 if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
15551 && TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE)
15552 break;
15553 /* fall through... */
15554 case BIT_XOR_EXPR:
15555 /* This and MINUS_EXPR can be changed into a comparison of the
15556 two objects. */
15557 if (TREE_TYPE (TREE_OPERAND (expr, 0))
15558 == TREE_TYPE (TREE_OPERAND (expr, 1)))
15559 return ffecom_2 (NE_EXPR, integer_type_node,
15560 TREE_OPERAND (expr, 0),
15561 TREE_OPERAND (expr, 1));
15562 return ffecom_2 (NE_EXPR, integer_type_node,
15563 TREE_OPERAND (expr, 0),
15564 fold (build1 (NOP_EXPR,
15565 TREE_TYPE (TREE_OPERAND (expr, 0)),
15566 TREE_OPERAND (expr, 1))));
15567
15568 case BIT_AND_EXPR:
15569 if (integer_onep (TREE_OPERAND (expr, 1)))
15570 return expr;
15571 break;
15572
15573 case MODIFY_EXPR:
15574#if 0 /* No such thing in Fortran. */
15575 if (warn_parentheses && C_EXP_ORIGINAL_CODE (expr) == MODIFY_EXPR)
15576 warning ("suggest parentheses around assignment used as truth value");
15577#endif
15578 break;
15579
15580 default:
15581 break;
5ff904cd
JL
15582 }
15583
c7e4ee3a
CB
15584 if (TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE)
15585 return (ffecom_2
15586 ((TREE_SIDE_EFFECTS (expr)
15587 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
15588 integer_type_node,
15589 truthvalue_conversion (ffecom_1 (REALPART_EXPR,
15590 TREE_TYPE (TREE_TYPE (expr)),
15591 expr)),
15592 truthvalue_conversion (ffecom_1 (IMAGPART_EXPR,
15593 TREE_TYPE (TREE_TYPE (expr)),
15594 expr))));
15595
15596 return ffecom_2 (NE_EXPR, integer_type_node,
15597 expr,
15598 convert (TREE_TYPE (expr), integer_zero_node));
15599}
15600
15601tree
15602type_for_mode (mode, unsignedp)
15603 enum machine_mode mode;
15604 int unsignedp;
15605{
15606 int i;
15607 int j;
15608 tree t;
5ff904cd 15609
c7e4ee3a
CB
15610 if (mode == TYPE_MODE (integer_type_node))
15611 return unsignedp ? unsigned_type_node : integer_type_node;
5ff904cd 15612
c7e4ee3a
CB
15613 if (mode == TYPE_MODE (signed_char_type_node))
15614 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
5ff904cd 15615
c7e4ee3a
CB
15616 if (mode == TYPE_MODE (short_integer_type_node))
15617 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
5ff904cd 15618
c7e4ee3a
CB
15619 if (mode == TYPE_MODE (long_integer_type_node))
15620 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
5ff904cd 15621
c7e4ee3a
CB
15622 if (mode == TYPE_MODE (long_long_integer_type_node))
15623 return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node;
5ff904cd 15624
c7e4ee3a
CB
15625 if (mode == TYPE_MODE (float_type_node))
15626 return float_type_node;
5ff904cd 15627
c7e4ee3a
CB
15628 if (mode == TYPE_MODE (double_type_node))
15629 return double_type_node;
5ff904cd 15630
c7e4ee3a
CB
15631 if (mode == TYPE_MODE (build_pointer_type (char_type_node)))
15632 return build_pointer_type (char_type_node);
5ff904cd 15633
c7e4ee3a
CB
15634 if (mode == TYPE_MODE (build_pointer_type (integer_type_node)))
15635 return build_pointer_type (integer_type_node);
5ff904cd 15636
c7e4ee3a
CB
15637 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
15638 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
15639 {
15640 if (((t = ffecom_tree_type[i][j]) != NULL_TREE)
15641 && (mode == TYPE_MODE (t)))
15642 {
15643 if ((i == FFEINFO_basictypeINTEGER) && unsignedp)
15644 return ffecom_tree_type[FFEINFO_basictypeHOLLERITH][j];
15645 else
15646 return t;
15647 }
15648 }
5ff904cd 15649
c7e4ee3a 15650 return 0;
5ff904cd
JL
15651}
15652
c7e4ee3a
CB
15653tree
15654type_for_size (bits, unsignedp)
15655 unsigned bits;
15656 int unsignedp;
5ff904cd 15657{
c7e4ee3a
CB
15658 ffeinfoKindtype kt;
15659 tree type_node;
5ff904cd 15660
c7e4ee3a
CB
15661 if (bits == TYPE_PRECISION (integer_type_node))
15662 return unsignedp ? unsigned_type_node : integer_type_node;
5ff904cd 15663
c7e4ee3a
CB
15664 if (bits == TYPE_PRECISION (signed_char_type_node))
15665 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
5ff904cd 15666
c7e4ee3a
CB
15667 if (bits == TYPE_PRECISION (short_integer_type_node))
15668 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
5ff904cd 15669
c7e4ee3a
CB
15670 if (bits == TYPE_PRECISION (long_integer_type_node))
15671 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
5ff904cd 15672
c7e4ee3a
CB
15673 if (bits == TYPE_PRECISION (long_long_integer_type_node))
15674 return (unsignedp ? long_long_unsigned_type_node
15675 : long_long_integer_type_node);
5ff904cd 15676
c7e4ee3a 15677 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
5ff904cd 15678 {
c7e4ee3a 15679 type_node = ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
5ff904cd 15680
c7e4ee3a
CB
15681 if ((type_node != NULL_TREE) && (bits == TYPE_PRECISION (type_node)))
15682 return unsignedp ? ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt]
15683 : type_node;
15684 }
5ff904cd 15685
c7e4ee3a
CB
15686 return 0;
15687}
5ff904cd 15688
c7e4ee3a
CB
15689tree
15690unsigned_type (type)
15691 tree type;
15692{
15693 tree type1 = TYPE_MAIN_VARIANT (type);
15694 ffeinfoKindtype kt;
15695 tree type2;
5ff904cd 15696
c7e4ee3a
CB
15697 if (type1 == signed_char_type_node || type1 == char_type_node)
15698 return unsigned_char_type_node;
15699 if (type1 == integer_type_node)
15700 return unsigned_type_node;
15701 if (type1 == short_integer_type_node)
15702 return short_unsigned_type_node;
15703 if (type1 == long_integer_type_node)
15704 return long_unsigned_type_node;
15705 if (type1 == long_long_integer_type_node)
15706 return long_long_unsigned_type_node;
15707#if 0 /* gcc/c-* files only */
15708 if (type1 == intDI_type_node)
15709 return unsigned_intDI_type_node;
15710 if (type1 == intSI_type_node)
15711 return unsigned_intSI_type_node;
15712 if (type1 == intHI_type_node)
15713 return unsigned_intHI_type_node;
15714 if (type1 == intQI_type_node)
15715 return unsigned_intQI_type_node;
15716#endif
5ff904cd 15717
c7e4ee3a
CB
15718 type2 = type_for_size (TYPE_PRECISION (type1), 1);
15719 if (type2 != NULL_TREE)
15720 return type2;
5ff904cd 15721
c7e4ee3a
CB
15722 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
15723 {
15724 type2 = ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
5ff904cd 15725
c7e4ee3a
CB
15726 if (type1 == type2)
15727 return ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
15728 }
5ff904cd 15729
c7e4ee3a
CB
15730 return type;
15731}
5ff904cd 15732
c7e4ee3a
CB
15733#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
15734\f
15735#if FFECOM_GCC_INCLUDE
5ff904cd 15736
c7e4ee3a 15737/* From gcc/cccp.c, the code to handle -I. */
5ff904cd 15738
c7e4ee3a
CB
15739/* Skip leading "./" from a directory name.
15740 This may yield the empty string, which represents the current directory. */
5ff904cd 15741
c7e4ee3a
CB
15742static const char *
15743skip_redundant_dir_prefix (const char *dir)
15744{
15745 while (dir[0] == '.' && dir[1] == '/')
15746 for (dir += 2; *dir == '/'; dir++)
15747 continue;
15748 if (dir[0] == '.' && !dir[1])
15749 dir++;
15750 return dir;
15751}
5ff904cd 15752
c7e4ee3a
CB
15753/* The file_name_map structure holds a mapping of file names for a
15754 particular directory. This mapping is read from the file named
15755 FILE_NAME_MAP_FILE in that directory. Such a file can be used to
15756 map filenames on a file system with severe filename restrictions,
15757 such as DOS. The format of the file name map file is just a series
15758 of lines with two tokens on each line. The first token is the name
15759 to map, and the second token is the actual name to use. */
5ff904cd 15760
c7e4ee3a
CB
15761struct file_name_map
15762{
15763 struct file_name_map *map_next;
15764 char *map_from;
15765 char *map_to;
15766};
5ff904cd 15767
c7e4ee3a 15768#define FILE_NAME_MAP_FILE "header.gcc"
5ff904cd 15769
c7e4ee3a
CB
15770/* Current maximum length of directory names in the search path
15771 for include files. (Altered as we get more of them.) */
5ff904cd 15772
c7e4ee3a 15773static int max_include_len = 0;
5ff904cd 15774
c7e4ee3a
CB
15775struct file_name_list
15776 {
15777 struct file_name_list *next;
15778 char *fname;
15779 /* Mapping of file names for this directory. */
15780 struct file_name_map *name_map;
15781 /* Non-zero if name_map is valid. */
15782 int got_name_map;
15783 };
5ff904cd 15784
c7e4ee3a
CB
15785static struct file_name_list *include = NULL; /* First dir to search */
15786static struct file_name_list *last_include = NULL; /* Last in chain */
5ff904cd 15787
c7e4ee3a
CB
15788/* I/O buffer structure.
15789 The `fname' field is nonzero for source files and #include files
15790 and for the dummy text used for -D and -U.
15791 It is zero for rescanning results of macro expansion
15792 and for expanding macro arguments. */
15793#define INPUT_STACK_MAX 400
15794static struct file_buf {
15795 char *fname;
15796 /* Filename specified with #line command. */
15797 char *nominal_fname;
15798 /* Record where in the search path this file was found.
15799 For #include_next. */
15800 struct file_name_list *dir;
15801 ffewhereLine line;
15802 ffewhereColumn column;
15803} instack[INPUT_STACK_MAX];
5ff904cd 15804
c7e4ee3a
CB
15805static int last_error_tick = 0; /* Incremented each time we print it. */
15806static int input_file_stack_tick = 0; /* Incremented when status changes. */
5ff904cd 15807
c7e4ee3a
CB
15808/* Current nesting level of input sources.
15809 `instack[indepth]' is the level currently being read. */
15810static int indepth = -1;
5ff904cd 15811
c7e4ee3a 15812typedef struct file_buf FILE_BUF;
5ff904cd 15813
c7e4ee3a 15814typedef unsigned char U_CHAR;
5ff904cd 15815
c7e4ee3a
CB
15816/* table to tell if char can be part of a C identifier. */
15817U_CHAR is_idchar[256];
15818/* table to tell if char can be first char of a c identifier. */
15819U_CHAR is_idstart[256];
15820/* table to tell if c is horizontal space. */
15821U_CHAR is_hor_space[256];
15822/* table to tell if c is horizontal or vertical space. */
15823static U_CHAR is_space[256];
5ff904cd 15824
c7e4ee3a
CB
15825#define SKIP_WHITE_SPACE(p) do { while (is_hor_space[*p]) p++; } while (0)
15826#define SKIP_ALL_WHITE_SPACE(p) do { while (is_space[*p]) p++; } while (0)
5ff904cd 15827
c7e4ee3a
CB
15828/* Nonzero means -I- has been seen,
15829 so don't look for #include "foo" the source-file directory. */
15830static int ignore_srcdir;
5ff904cd 15831
c7e4ee3a
CB
15832#ifndef INCLUDE_LEN_FUDGE
15833#define INCLUDE_LEN_FUDGE 0
15834#endif
5ff904cd 15835
c7e4ee3a
CB
15836static void append_include_chain (struct file_name_list *first,
15837 struct file_name_list *last);
15838static FILE *open_include_file (char *filename,
15839 struct file_name_list *searchptr);
15840static void print_containing_files (ffebadSeverity sev);
15841static const char *skip_redundant_dir_prefix (const char *);
15842static char *read_filename_string (int ch, FILE *f);
15843static struct file_name_map *read_name_map (const char *dirname);
5ff904cd 15844
c7e4ee3a
CB
15845/* Append a chain of `struct file_name_list's
15846 to the end of the main include chain.
15847 FIRST is the beginning of the chain to append, and LAST is the end. */
5ff904cd 15848
c7e4ee3a
CB
15849static void
15850append_include_chain (first, last)
15851 struct file_name_list *first, *last;
5ff904cd 15852{
c7e4ee3a 15853 struct file_name_list *dir;
5ff904cd 15854
c7e4ee3a
CB
15855 if (!first || !last)
15856 return;
5ff904cd 15857
c7e4ee3a
CB
15858 if (include == 0)
15859 include = first;
15860 else
15861 last_include->next = first;
5ff904cd 15862
c7e4ee3a
CB
15863 for (dir = first; ; dir = dir->next) {
15864 int len = strlen (dir->fname) + INCLUDE_LEN_FUDGE;
15865 if (len > max_include_len)
15866 max_include_len = len;
15867 if (dir == last)
15868 break;
15869 }
15870
15871 last->next = NULL;
15872 last_include = last;
5ff904cd
JL
15873}
15874
c7e4ee3a
CB
15875/* Try to open include file FILENAME. SEARCHPTR is the directory
15876 being tried from the include file search path. This function maps
15877 filenames on file systems based on information read by
15878 read_name_map. */
15879
15880static FILE *
15881open_include_file (filename, searchptr)
15882 char *filename;
15883 struct file_name_list *searchptr;
5ff904cd 15884{
c7e4ee3a
CB
15885 register struct file_name_map *map;
15886 register char *from;
15887 char *p, *dir;
5ff904cd 15888
c7e4ee3a
CB
15889 if (searchptr && ! searchptr->got_name_map)
15890 {
15891 searchptr->name_map = read_name_map (searchptr->fname
15892 ? searchptr->fname : ".");
15893 searchptr->got_name_map = 1;
15894 }
5ff904cd 15895
c7e4ee3a
CB
15896 /* First check the mapping for the directory we are using. */
15897 if (searchptr && searchptr->name_map)
15898 {
15899 from = filename;
15900 if (searchptr->fname)
15901 from += strlen (searchptr->fname) + 1;
15902 for (map = searchptr->name_map; map; map = map->map_next)
15903 {
15904 if (! strcmp (map->map_from, from))
15905 {
15906 /* Found a match. */
15907 return fopen (map->map_to, "r");
15908 }
15909 }
15910 }
5ff904cd 15911
c7e4ee3a
CB
15912 /* Try to find a mapping file for the particular directory we are
15913 looking in. Thus #include <sys/types.h> will look up sys/types.h
15914 in /usr/include/header.gcc and look up types.h in
15915 /usr/include/sys/header.gcc. */
15916 p = rindex (filename, '/');
15917#ifdef DIR_SEPARATOR
15918 if (! p) p = rindex (filename, DIR_SEPARATOR);
15919 else {
15920 char *tmp = rindex (filename, DIR_SEPARATOR);
15921 if (tmp != NULL && tmp > p) p = tmp;
15922 }
15923#endif
15924 if (! p)
15925 p = filename;
15926 if (searchptr
15927 && searchptr->fname
15928 && strlen (searchptr->fname) == (size_t) (p - filename)
15929 && ! strncmp (searchptr->fname, filename, (int) (p - filename)))
15930 {
15931 /* FILENAME is in SEARCHPTR, which we've already checked. */
15932 return fopen (filename, "r");
15933 }
15934
15935 if (p == filename)
15936 {
15937 from = filename;
15938 map = read_name_map (".");
15939 }
15940 else
5ff904cd 15941 {
c7e4ee3a
CB
15942 dir = (char *) xmalloc (p - filename + 1);
15943 memcpy (dir, filename, p - filename);
15944 dir[p - filename] = '\0';
15945 from = p + 1;
15946 map = read_name_map (dir);
15947 free (dir);
5ff904cd 15948 }
c7e4ee3a
CB
15949 for (; map; map = map->map_next)
15950 if (! strcmp (map->map_from, from))
15951 return fopen (map->map_to, "r");
5ff904cd 15952
c7e4ee3a 15953 return fopen (filename, "r");
5ff904cd
JL
15954}
15955
c7e4ee3a
CB
15956/* Print the file names and line numbers of the #include
15957 commands which led to the current file. */
5ff904cd 15958
c7e4ee3a
CB
15959static void
15960print_containing_files (ffebadSeverity sev)
15961{
15962 FILE_BUF *ip = NULL;
15963 int i;
15964 int first = 1;
15965 const char *str1;
15966 const char *str2;
5ff904cd 15967
c7e4ee3a
CB
15968 /* If stack of files hasn't changed since we last printed
15969 this info, don't repeat it. */
15970 if (last_error_tick == input_file_stack_tick)
15971 return;
5ff904cd 15972
c7e4ee3a
CB
15973 for (i = indepth; i >= 0; i--)
15974 if (instack[i].fname != NULL) {
15975 ip = &instack[i];
15976 break;
15977 }
5ff904cd 15978
c7e4ee3a
CB
15979 /* Give up if we don't find a source file. */
15980 if (ip == NULL)
15981 return;
5ff904cd 15982
c7e4ee3a
CB
15983 /* Find the other, outer source files. */
15984 for (i--; i >= 0; i--)
15985 if (instack[i].fname != NULL)
15986 {
15987 ip = &instack[i];
15988 if (first)
15989 {
15990 first = 0;
15991 str1 = "In file included";
15992 }
15993 else
15994 {
15995 str1 = "... ...";
15996 }
5ff904cd 15997
c7e4ee3a
CB
15998 if (i == 1)
15999 str2 = ":";
16000 else
16001 str2 = "";
5ff904cd 16002
c7e4ee3a
CB
16003 ffebad_start_msg ("%A from %B at %0%C", sev);
16004 ffebad_here (0, ip->line, ip->column);
16005 ffebad_string (str1);
16006 ffebad_string (ip->nominal_fname);
16007 ffebad_string (str2);
16008 ffebad_finish ();
16009 }
5ff904cd 16010
c7e4ee3a
CB
16011 /* Record we have printed the status as of this time. */
16012 last_error_tick = input_file_stack_tick;
16013}
5ff904cd 16014
c7e4ee3a
CB
16015/* Read a space delimited string of unlimited length from a stdio
16016 file. */
5ff904cd 16017
c7e4ee3a
CB
16018static char *
16019read_filename_string (ch, f)
16020 int ch;
16021 FILE *f;
16022{
16023 char *alloc, *set;
16024 int len;
5ff904cd 16025
c7e4ee3a
CB
16026 len = 20;
16027 set = alloc = xmalloc (len + 1);
16028 if (! is_space[ch])
16029 {
16030 *set++ = ch;
16031 while ((ch = getc (f)) != EOF && ! is_space[ch])
16032 {
16033 if (set - alloc == len)
16034 {
16035 len *= 2;
16036 alloc = xrealloc (alloc, len + 1);
16037 set = alloc + len / 2;
16038 }
16039 *set++ = ch;
16040 }
16041 }
16042 *set = '\0';
16043 ungetc (ch, f);
16044 return alloc;
16045}
5ff904cd 16046
c7e4ee3a 16047/* Read the file name map file for DIRNAME. */
5ff904cd 16048
c7e4ee3a
CB
16049static struct file_name_map *
16050read_name_map (dirname)
16051 const char *dirname;
16052{
16053 /* This structure holds a linked list of file name maps, one per
16054 directory. */
16055 struct file_name_map_list
16056 {
16057 struct file_name_map_list *map_list_next;
16058 char *map_list_name;
16059 struct file_name_map *map_list_map;
16060 };
16061 static struct file_name_map_list *map_list;
16062 register struct file_name_map_list *map_list_ptr;
16063 char *name;
16064 FILE *f;
16065 size_t dirlen;
16066 int separator_needed;
5ff904cd 16067
c7e4ee3a 16068 dirname = skip_redundant_dir_prefix (dirname);
5ff904cd 16069
c7e4ee3a
CB
16070 for (map_list_ptr = map_list; map_list_ptr;
16071 map_list_ptr = map_list_ptr->map_list_next)
16072 if (! strcmp (map_list_ptr->map_list_name, dirname))
16073 return map_list_ptr->map_list_map;
5ff904cd 16074
c7e4ee3a
CB
16075 map_list_ptr = ((struct file_name_map_list *)
16076 xmalloc (sizeof (struct file_name_map_list)));
16077 map_list_ptr->map_list_name = xstrdup (dirname);
16078 map_list_ptr->map_list_map = NULL;
5ff904cd 16079
c7e4ee3a
CB
16080 dirlen = strlen (dirname);
16081 separator_needed = dirlen != 0 && dirname[dirlen - 1] != '/';
16082 name = (char *) xmalloc (dirlen + strlen (FILE_NAME_MAP_FILE) + 2);
16083 strcpy (name, dirname);
16084 name[dirlen] = '/';
16085 strcpy (name + dirlen + separator_needed, FILE_NAME_MAP_FILE);
16086 f = fopen (name, "r");
16087 free (name);
16088 if (!f)
16089 map_list_ptr->map_list_map = NULL;
16090 else
16091 {
16092 int ch;
5ff904cd 16093
c7e4ee3a
CB
16094 while ((ch = getc (f)) != EOF)
16095 {
16096 char *from, *to;
16097 struct file_name_map *ptr;
16098
16099 if (is_space[ch])
16100 continue;
16101 from = read_filename_string (ch, f);
16102 while ((ch = getc (f)) != EOF && is_hor_space[ch])
16103 ;
16104 to = read_filename_string (ch, f);
5ff904cd 16105
c7e4ee3a
CB
16106 ptr = ((struct file_name_map *)
16107 xmalloc (sizeof (struct file_name_map)));
16108 ptr->map_from = from;
5ff904cd 16109
c7e4ee3a
CB
16110 /* Make the real filename absolute. */
16111 if (*to == '/')
16112 ptr->map_to = to;
16113 else
16114 {
16115 ptr->map_to = xmalloc (dirlen + strlen (to) + 2);
16116 strcpy (ptr->map_to, dirname);
16117 ptr->map_to[dirlen] = '/';
16118 strcpy (ptr->map_to + dirlen + separator_needed, to);
16119 free (to);
16120 }
5ff904cd 16121
c7e4ee3a
CB
16122 ptr->map_next = map_list_ptr->map_list_map;
16123 map_list_ptr->map_list_map = ptr;
5ff904cd 16124
c7e4ee3a
CB
16125 while ((ch = getc (f)) != '\n')
16126 if (ch == EOF)
16127 break;
16128 }
16129 fclose (f);
5ff904cd
JL
16130 }
16131
c7e4ee3a
CB
16132 map_list_ptr->map_list_next = map_list;
16133 map_list = map_list_ptr;
5ff904cd 16134
c7e4ee3a 16135 return map_list_ptr->map_list_map;
5ff904cd
JL
16136}
16137
c7e4ee3a
CB
16138static void
16139ffecom_file_ (char *name)
5ff904cd 16140{
c7e4ee3a 16141 FILE_BUF *fp;
5ff904cd 16142
c7e4ee3a
CB
16143 /* Do partial setup of input buffer for the sake of generating
16144 early #line directives (when -g is in effect). */
5ff904cd 16145
c7e4ee3a
CB
16146 fp = &instack[++indepth];
16147 memset ((char *) fp, 0, sizeof (FILE_BUF));
16148 if (name == NULL)
16149 name = "";
16150 fp->nominal_fname = fp->fname = name;
16151}
5ff904cd 16152
c7e4ee3a 16153/* Initialize syntactic classifications of characters. */
5ff904cd 16154
c7e4ee3a
CB
16155static void
16156ffecom_initialize_char_syntax_ ()
16157{
16158 register int i;
5ff904cd 16159
c7e4ee3a
CB
16160 /*
16161 * Set up is_idchar and is_idstart tables. These should be
16162 * faster than saying (is_alpha (c) || c == '_'), etc.
16163 * Set up these things before calling any routines tthat
16164 * refer to them.
16165 */
16166 for (i = 'a'; i <= 'z'; i++) {
16167 is_idchar[i - 'a' + 'A'] = 1;
16168 is_idchar[i] = 1;
16169 is_idstart[i - 'a' + 'A'] = 1;
16170 is_idstart[i] = 1;
16171 }
16172 for (i = '0'; i <= '9'; i++)
16173 is_idchar[i] = 1;
16174 is_idchar['_'] = 1;
16175 is_idstart['_'] = 1;
5ff904cd 16176
c7e4ee3a
CB
16177 /* horizontal space table */
16178 is_hor_space[' '] = 1;
16179 is_hor_space['\t'] = 1;
16180 is_hor_space['\v'] = 1;
16181 is_hor_space['\f'] = 1;
16182 is_hor_space['\r'] = 1;
5ff904cd 16183
c7e4ee3a
CB
16184 is_space[' '] = 1;
16185 is_space['\t'] = 1;
16186 is_space['\v'] = 1;
16187 is_space['\f'] = 1;
16188 is_space['\n'] = 1;
16189 is_space['\r'] = 1;
16190}
5ff904cd 16191
c7e4ee3a
CB
16192static void
16193ffecom_close_include_ (FILE *f)
16194{
16195 fclose (f);
5ff904cd 16196
c7e4ee3a
CB
16197 indepth--;
16198 input_file_stack_tick++;
5ff904cd 16199
c7e4ee3a
CB
16200 ffewhere_line_kill (instack[indepth].line);
16201 ffewhere_column_kill (instack[indepth].column);
16202}
5ff904cd 16203
c7e4ee3a
CB
16204static int
16205ffecom_decode_include_option_ (char *spec)
16206{
16207 struct file_name_list *dirtmp;
16208
16209 if (! ignore_srcdir && !strcmp (spec, "-"))
16210 ignore_srcdir = 1;
16211 else
16212 {
16213 dirtmp = (struct file_name_list *)
16214 xmalloc (sizeof (struct file_name_list));
16215 dirtmp->next = 0; /* New one goes on the end */
16216 if (spec[0] != 0)
16217 dirtmp->fname = spec;
16218 else
16219 fatal ("Directory name must immediately follow -I option with no intervening spaces, as in `-Idir', not `-I dir'");
16220 dirtmp->got_name_map = 0;
16221 append_include_chain (dirtmp, dirtmp);
16222 }
16223 return 1;
5ff904cd
JL
16224}
16225
c7e4ee3a
CB
16226/* Open INCLUDEd file. */
16227
16228static FILE *
16229ffecom_open_include_ (char *name, ffewhereLine l, ffewhereColumn c)
5ff904cd 16230{
c7e4ee3a
CB
16231 char *fbeg = name;
16232 size_t flen = strlen (fbeg);
16233 struct file_name_list *search_start = include; /* Chain of dirs to search */
16234 struct file_name_list dsp[1]; /* First in chain, if #include "..." */
16235 struct file_name_list *searchptr = 0;
16236 char *fname; /* Dynamically allocated fname buffer */
16237 FILE *f;
16238 FILE_BUF *fp;
5ff904cd 16239
c7e4ee3a
CB
16240 if (flen == 0)
16241 return NULL;
5ff904cd 16242
c7e4ee3a 16243 dsp[0].fname = NULL;
5ff904cd 16244
c7e4ee3a
CB
16245 /* If -I- was specified, don't search current dir, only spec'd ones. */
16246 if (!ignore_srcdir)
16247 {
16248 for (fp = &instack[indepth]; fp >= instack; fp--)
16249 {
16250 int n;
16251 char *ep;
16252 char *nam;
5ff904cd 16253
c7e4ee3a
CB
16254 if ((nam = fp->nominal_fname) != NULL)
16255 {
16256 /* Found a named file. Figure out dir of the file,
16257 and put it in front of the search list. */
16258 dsp[0].next = search_start;
16259 search_start = dsp;
16260#ifndef VMS
16261 ep = rindex (nam, '/');
16262#ifdef DIR_SEPARATOR
16263 if (ep == NULL) ep = rindex (nam, DIR_SEPARATOR);
16264 else {
16265 char *tmp = rindex (nam, DIR_SEPARATOR);
16266 if (tmp != NULL && tmp > ep) ep = tmp;
16267 }
16268#endif
16269#else /* VMS */
16270 ep = rindex (nam, ']');
16271 if (ep == NULL) ep = rindex (nam, '>');
16272 if (ep == NULL) ep = rindex (nam, ':');
16273 if (ep != NULL) ep++;
16274#endif /* VMS */
16275 if (ep != NULL)
16276 {
16277 n = ep - nam;
16278 dsp[0].fname = (char *) xmalloc (n + 1);
16279 strncpy (dsp[0].fname, nam, n);
16280 dsp[0].fname[n] = '\0';
16281 if (n + INCLUDE_LEN_FUDGE > max_include_len)
16282 max_include_len = n + INCLUDE_LEN_FUDGE;
16283 }
16284 else
16285 dsp[0].fname = NULL; /* Current directory */
16286 dsp[0].got_name_map = 0;
16287 break;
16288 }
16289 }
16290 }
5ff904cd 16291
c7e4ee3a
CB
16292 /* Allocate this permanently, because it gets stored in the definitions
16293 of macros. */
16294 fname = xmalloc (max_include_len + flen + 4);
16295 /* + 2 above for slash and terminating null. */
16296 /* + 2 added for '.h' on VMS (to support '#include filename') (NOT USED
16297 for g77 yet). */
5ff904cd 16298
c7e4ee3a 16299 /* If specified file name is absolute, just open it. */
5ff904cd 16300
c7e4ee3a
CB
16301 if (*fbeg == '/'
16302#ifdef DIR_SEPARATOR
16303 || *fbeg == DIR_SEPARATOR
16304#endif
16305 )
16306 {
16307 strncpy (fname, (char *) fbeg, flen);
16308 fname[flen] = 0;
16309 f = open_include_file (fname, NULL_PTR);
5ff904cd 16310 }
c7e4ee3a
CB
16311 else
16312 {
16313 f = NULL;
5ff904cd 16314
c7e4ee3a
CB
16315 /* Search directory path, trying to open the file.
16316 Copy each filename tried into FNAME. */
5ff904cd 16317
c7e4ee3a
CB
16318 for (searchptr = search_start; searchptr; searchptr = searchptr->next)
16319 {
16320 if (searchptr->fname)
16321 {
16322 /* The empty string in a search path is ignored.
16323 This makes it possible to turn off entirely
16324 a standard piece of the list. */
16325 if (searchptr->fname[0] == 0)
16326 continue;
16327 strcpy (fname, skip_redundant_dir_prefix (searchptr->fname));
16328 if (fname[0] && fname[strlen (fname) - 1] != '/')
16329 strcat (fname, "/");
16330 fname[strlen (fname) + flen] = 0;
16331 }
16332 else
16333 fname[0] = 0;
5ff904cd 16334
c7e4ee3a
CB
16335 strncat (fname, fbeg, flen);
16336#ifdef VMS
16337 /* Change this 1/2 Unix 1/2 VMS file specification into a
16338 full VMS file specification */
16339 if (searchptr->fname && (searchptr->fname[0] != 0))
16340 {
16341 /* Fix up the filename */
16342 hack_vms_include_specification (fname);
16343 }
16344 else
16345 {
16346 /* This is a normal VMS filespec, so use it unchanged. */
16347 strncpy (fname, (char *) fbeg, flen);
16348 fname[flen] = 0;
16349#if 0 /* Not for g77. */
16350 /* if it's '#include filename', add the missing .h */
16351 if (index (fname, '.') == NULL)
16352 strcat (fname, ".h");
5ff904cd 16353#endif
c7e4ee3a
CB
16354 }
16355#endif /* VMS */
16356 f = open_include_file (fname, searchptr);
16357#ifdef EACCES
16358 if (f == NULL && errno == EACCES)
16359 {
16360 print_containing_files (FFEBAD_severityWARNING);
16361 ffebad_start_msg ("At %0, INCLUDE file %A exists, but is not readable",
16362 FFEBAD_severityWARNING);
16363 ffebad_string (fname);
16364 ffebad_here (0, l, c);
16365 ffebad_finish ();
16366 }
16367#endif
16368 if (f != NULL)
16369 break;
16370 }
16371 }
5ff904cd 16372
c7e4ee3a 16373 if (f == NULL)
5ff904cd 16374 {
c7e4ee3a 16375 /* A file that was not found. */
5ff904cd 16376
c7e4ee3a
CB
16377 strncpy (fname, (char *) fbeg, flen);
16378 fname[flen] = 0;
16379 print_containing_files (ffebad_severity (FFEBAD_OPEN_INCLUDE));
16380 ffebad_start (FFEBAD_OPEN_INCLUDE);
16381 ffebad_here (0, l, c);
16382 ffebad_string (fname);
16383 ffebad_finish ();
5ff904cd
JL
16384 }
16385
c7e4ee3a
CB
16386 if (dsp[0].fname != NULL)
16387 free (dsp[0].fname);
5ff904cd 16388
c7e4ee3a
CB
16389 if (f == NULL)
16390 return NULL;
5ff904cd 16391
c7e4ee3a
CB
16392 if (indepth >= (INPUT_STACK_MAX - 1))
16393 {
16394 print_containing_files (FFEBAD_severityFATAL);
16395 ffebad_start_msg ("At %0, INCLUDE nesting too deep",
16396 FFEBAD_severityFATAL);
16397 ffebad_string (fname);
16398 ffebad_here (0, l, c);
16399 ffebad_finish ();
16400 return NULL;
16401 }
5ff904cd 16402
c7e4ee3a
CB
16403 instack[indepth].line = ffewhere_line_use (l);
16404 instack[indepth].column = ffewhere_column_use (c);
5ff904cd 16405
c7e4ee3a
CB
16406 fp = &instack[indepth + 1];
16407 memset ((char *) fp, 0, sizeof (FILE_BUF));
16408 fp->nominal_fname = fp->fname = fname;
16409 fp->dir = searchptr;
5ff904cd 16410
c7e4ee3a
CB
16411 indepth++;
16412 input_file_stack_tick++;
5ff904cd 16413
c7e4ee3a
CB
16414 return f;
16415}
16416#endif /* FFECOM_GCC_INCLUDE */
5ff904cd 16417
c7e4ee3a
CB
16418/**INDENT* (Do not reformat this comment even with -fca option.)
16419 Data-gathering files: Given the source file listed below, compiled with
16420 f2c I obtained the output file listed after that, and from the output
16421 file I derived the above code.
5ff904cd 16422
c7e4ee3a
CB
16423-------- (begin input file to f2c)
16424 implicit none
16425 character*10 A1,A2
16426 complex C1,C2
16427 integer I1,I2
16428 real R1,R2
16429 double precision D1,D2
16430C
16431 call getem(A1,A2,C1,C2,I1,I2,R1,R2,D1,D2)
16432c /
16433 call fooI(I1/I2)
16434 call fooR(R1/I1)
16435 call fooD(D1/I1)
16436 call fooC(C1/I1)
16437 call fooR(R1/R2)
16438 call fooD(R1/D1)
16439 call fooD(D1/D2)
16440 call fooD(D1/R1)
16441 call fooC(C1/C2)
16442 call fooC(C1/R1)
16443 call fooZ(C1/D1)
16444c **
16445 call fooI(I1**I2)
16446 call fooR(R1**I1)
16447 call fooD(D1**I1)
16448 call fooC(C1**I1)
16449 call fooR(R1**R2)
16450 call fooD(R1**D1)
16451 call fooD(D1**D2)
16452 call fooD(D1**R1)
16453 call fooC(C1**C2)
16454 call fooC(C1**R1)
16455 call fooZ(C1**D1)
16456c FFEINTRIN_impABS
16457 call fooR(ABS(R1))
16458c FFEINTRIN_impACOS
16459 call fooR(ACOS(R1))
16460c FFEINTRIN_impAIMAG
16461 call fooR(AIMAG(C1))
16462c FFEINTRIN_impAINT
16463 call fooR(AINT(R1))
16464c FFEINTRIN_impALOG
16465 call fooR(ALOG(R1))
16466c FFEINTRIN_impALOG10
16467 call fooR(ALOG10(R1))
16468c FFEINTRIN_impAMAX0
16469 call fooR(AMAX0(I1,I2))
16470c FFEINTRIN_impAMAX1
16471 call fooR(AMAX1(R1,R2))
16472c FFEINTRIN_impAMIN0
16473 call fooR(AMIN0(I1,I2))
16474c FFEINTRIN_impAMIN1
16475 call fooR(AMIN1(R1,R2))
16476c FFEINTRIN_impAMOD
16477 call fooR(AMOD(R1,R2))
16478c FFEINTRIN_impANINT
16479 call fooR(ANINT(R1))
16480c FFEINTRIN_impASIN
16481 call fooR(ASIN(R1))
16482c FFEINTRIN_impATAN
16483 call fooR(ATAN(R1))
16484c FFEINTRIN_impATAN2
16485 call fooR(ATAN2(R1,R2))
16486c FFEINTRIN_impCABS
16487 call fooR(CABS(C1))
16488c FFEINTRIN_impCCOS
16489 call fooC(CCOS(C1))
16490c FFEINTRIN_impCEXP
16491 call fooC(CEXP(C1))
16492c FFEINTRIN_impCHAR
16493 call fooA(CHAR(I1))
16494c FFEINTRIN_impCLOG
16495 call fooC(CLOG(C1))
16496c FFEINTRIN_impCONJG
16497 call fooC(CONJG(C1))
16498c FFEINTRIN_impCOS
16499 call fooR(COS(R1))
16500c FFEINTRIN_impCOSH
16501 call fooR(COSH(R1))
16502c FFEINTRIN_impCSIN
16503 call fooC(CSIN(C1))
16504c FFEINTRIN_impCSQRT
16505 call fooC(CSQRT(C1))
16506c FFEINTRIN_impDABS
16507 call fooD(DABS(D1))
16508c FFEINTRIN_impDACOS
16509 call fooD(DACOS(D1))
16510c FFEINTRIN_impDASIN
16511 call fooD(DASIN(D1))
16512c FFEINTRIN_impDATAN
16513 call fooD(DATAN(D1))
16514c FFEINTRIN_impDATAN2
16515 call fooD(DATAN2(D1,D2))
16516c FFEINTRIN_impDCOS
16517 call fooD(DCOS(D1))
16518c FFEINTRIN_impDCOSH
16519 call fooD(DCOSH(D1))
16520c FFEINTRIN_impDDIM
16521 call fooD(DDIM(D1,D2))
16522c FFEINTRIN_impDEXP
16523 call fooD(DEXP(D1))
16524c FFEINTRIN_impDIM
16525 call fooR(DIM(R1,R2))
16526c FFEINTRIN_impDINT
16527 call fooD(DINT(D1))
16528c FFEINTRIN_impDLOG
16529 call fooD(DLOG(D1))
16530c FFEINTRIN_impDLOG10
16531 call fooD(DLOG10(D1))
16532c FFEINTRIN_impDMAX1
16533 call fooD(DMAX1(D1,D2))
16534c FFEINTRIN_impDMIN1
16535 call fooD(DMIN1(D1,D2))
16536c FFEINTRIN_impDMOD
16537 call fooD(DMOD(D1,D2))
16538c FFEINTRIN_impDNINT
16539 call fooD(DNINT(D1))
16540c FFEINTRIN_impDPROD
16541 call fooD(DPROD(R1,R2))
16542c FFEINTRIN_impDSIGN
16543 call fooD(DSIGN(D1,D2))
16544c FFEINTRIN_impDSIN
16545 call fooD(DSIN(D1))
16546c FFEINTRIN_impDSINH
16547 call fooD(DSINH(D1))
16548c FFEINTRIN_impDSQRT
16549 call fooD(DSQRT(D1))
16550c FFEINTRIN_impDTAN
16551 call fooD(DTAN(D1))
16552c FFEINTRIN_impDTANH
16553 call fooD(DTANH(D1))
16554c FFEINTRIN_impEXP
16555 call fooR(EXP(R1))
16556c FFEINTRIN_impIABS
16557 call fooI(IABS(I1))
16558c FFEINTRIN_impICHAR
16559 call fooI(ICHAR(A1))
16560c FFEINTRIN_impIDIM
16561 call fooI(IDIM(I1,I2))
16562c FFEINTRIN_impIDNINT
16563 call fooI(IDNINT(D1))
16564c FFEINTRIN_impINDEX
16565 call fooI(INDEX(A1,A2))
16566c FFEINTRIN_impISIGN
16567 call fooI(ISIGN(I1,I2))
16568c FFEINTRIN_impLEN
16569 call fooI(LEN(A1))
16570c FFEINTRIN_impLGE
16571 call fooL(LGE(A1,A2))
16572c FFEINTRIN_impLGT
16573 call fooL(LGT(A1,A2))
16574c FFEINTRIN_impLLE
16575 call fooL(LLE(A1,A2))
16576c FFEINTRIN_impLLT
16577 call fooL(LLT(A1,A2))
16578c FFEINTRIN_impMAX0
16579 call fooI(MAX0(I1,I2))
16580c FFEINTRIN_impMAX1
16581 call fooI(MAX1(R1,R2))
16582c FFEINTRIN_impMIN0
16583 call fooI(MIN0(I1,I2))
16584c FFEINTRIN_impMIN1
16585 call fooI(MIN1(R1,R2))
16586c FFEINTRIN_impMOD
16587 call fooI(MOD(I1,I2))
16588c FFEINTRIN_impNINT
16589 call fooI(NINT(R1))
16590c FFEINTRIN_impSIGN
16591 call fooR(SIGN(R1,R2))
16592c FFEINTRIN_impSIN
16593 call fooR(SIN(R1))
16594c FFEINTRIN_impSINH
16595 call fooR(SINH(R1))
16596c FFEINTRIN_impSQRT
16597 call fooR(SQRT(R1))
16598c FFEINTRIN_impTAN
16599 call fooR(TAN(R1))
16600c FFEINTRIN_impTANH
16601 call fooR(TANH(R1))
16602c FFEINTRIN_imp_CMPLX_C
16603 call fooC(cmplx(C1,C2))
16604c FFEINTRIN_imp_CMPLX_D
16605 call fooZ(cmplx(D1,D2))
16606c FFEINTRIN_imp_CMPLX_I
16607 call fooC(cmplx(I1,I2))
16608c FFEINTRIN_imp_CMPLX_R
16609 call fooC(cmplx(R1,R2))
16610c FFEINTRIN_imp_DBLE_C
16611 call fooD(dble(C1))
16612c FFEINTRIN_imp_DBLE_D
16613 call fooD(dble(D1))
16614c FFEINTRIN_imp_DBLE_I
16615 call fooD(dble(I1))
16616c FFEINTRIN_imp_DBLE_R
16617 call fooD(dble(R1))
16618c FFEINTRIN_imp_INT_C
16619 call fooI(int(C1))
16620c FFEINTRIN_imp_INT_D
16621 call fooI(int(D1))
16622c FFEINTRIN_imp_INT_I
16623 call fooI(int(I1))
16624c FFEINTRIN_imp_INT_R
16625 call fooI(int(R1))
16626c FFEINTRIN_imp_REAL_C
16627 call fooR(real(C1))
16628c FFEINTRIN_imp_REAL_D
16629 call fooR(real(D1))
16630c FFEINTRIN_imp_REAL_I
16631 call fooR(real(I1))
16632c FFEINTRIN_imp_REAL_R
16633 call fooR(real(R1))
16634c
16635c FFEINTRIN_imp_INT_D:
16636c
16637c FFEINTRIN_specIDINT
16638 call fooI(IDINT(D1))
16639c
16640c FFEINTRIN_imp_INT_R:
16641c
16642c FFEINTRIN_specIFIX
16643 call fooI(IFIX(R1))
16644c FFEINTRIN_specINT
16645 call fooI(INT(R1))
16646c
16647c FFEINTRIN_imp_REAL_D:
16648c
16649c FFEINTRIN_specSNGL
16650 call fooR(SNGL(D1))
16651c
16652c FFEINTRIN_imp_REAL_I:
16653c
16654c FFEINTRIN_specFLOAT
16655 call fooR(FLOAT(I1))
16656c FFEINTRIN_specREAL
16657 call fooR(REAL(I1))
16658c
16659 end
16660-------- (end input file to f2c)
5ff904cd 16661
c7e4ee3a
CB
16662-------- (begin output from providing above input file as input to:
16663-------- `f2c | gcc -E -C - | sed -e "s:/[*]*://:g" -e "s:[*]*[/]://:g" \
16664-------- -e "s:^#.*$::g"')
5ff904cd 16665
c7e4ee3a
CB
16666// -- translated by f2c (version 19950223).
16667 You must link the resulting object file with the libraries:
16668 -lf2c -lm (in that order)
16669//
5ff904cd 16670
5ff904cd 16671
c7e4ee3a 16672// f2c.h -- Standard Fortran to C header file //
5ff904cd 16673
c7e4ee3a 16674/// barf [ba:rf] 2. "He suggested using FORTRAN, and everybody barfed."
5ff904cd 16675
c7e4ee3a 16676 - From The Shogakukan DICTIONARY OF NEW ENGLISH (Second edition) //
5ff904cd 16677
5ff904cd 16678
5ff904cd 16679
5ff904cd 16680
c7e4ee3a
CB
16681// F2C_INTEGER will normally be `int' but would be `long' on 16-bit systems //
16682// we assume short, float are OK //
16683typedef long int // long int // integer;
16684typedef char *address;
16685typedef short int shortint;
16686typedef float real;
16687typedef double doublereal;
16688typedef struct { real r, i; } complex;
16689typedef struct { doublereal r, i; } doublecomplex;
16690typedef long int // long int // logical;
16691typedef short int shortlogical;
16692typedef char logical1;
16693typedef char integer1;
16694// typedef long long longint; // // system-dependent //
5ff904cd 16695
5ff904cd 16696
5ff904cd 16697
5ff904cd 16698
c7e4ee3a 16699// Extern is for use with -E //
5ff904cd 16700
5ff904cd 16701
5ff904cd 16702
5ff904cd 16703
c7e4ee3a 16704// I/O stuff //
5ff904cd 16705
5ff904cd 16706
5ff904cd 16707
5ff904cd 16708
5ff904cd 16709
5ff904cd 16710
5ff904cd 16711
5ff904cd 16712
c7e4ee3a
CB
16713typedef long int // int or long int // flag;
16714typedef long int // int or long int // ftnlen;
16715typedef long int // int or long int // ftnint;
5ff904cd 16716
5ff904cd 16717
c7e4ee3a
CB
16718//external read, write//
16719typedef struct
16720{ flag cierr;
16721 ftnint ciunit;
16722 flag ciend;
16723 char *cifmt;
16724 ftnint cirec;
16725} cilist;
5ff904cd 16726
c7e4ee3a
CB
16727//internal read, write//
16728typedef struct
16729{ flag icierr;
16730 char *iciunit;
16731 flag iciend;
16732 char *icifmt;
16733 ftnint icirlen;
16734 ftnint icirnum;
16735} icilist;
5ff904cd 16736
c7e4ee3a
CB
16737//open//
16738typedef struct
16739{ flag oerr;
16740 ftnint ounit;
16741 char *ofnm;
16742 ftnlen ofnmlen;
16743 char *osta;
16744 char *oacc;
16745 char *ofm;
16746 ftnint orl;
16747 char *oblnk;
16748} olist;
5ff904cd 16749
c7e4ee3a
CB
16750//close//
16751typedef struct
16752{ flag cerr;
16753 ftnint cunit;
16754 char *csta;
16755} cllist;
5ff904cd 16756
c7e4ee3a
CB
16757//rewind, backspace, endfile//
16758typedef struct
16759{ flag aerr;
16760 ftnint aunit;
16761} alist;
5ff904cd 16762
c7e4ee3a
CB
16763// inquire //
16764typedef struct
16765{ flag inerr;
16766 ftnint inunit;
16767 char *infile;
16768 ftnlen infilen;
16769 ftnint *inex; //parameters in standard's order//
16770 ftnint *inopen;
16771 ftnint *innum;
16772 ftnint *innamed;
16773 char *inname;
16774 ftnlen innamlen;
16775 char *inacc;
16776 ftnlen inacclen;
16777 char *inseq;
16778 ftnlen inseqlen;
16779 char *indir;
16780 ftnlen indirlen;
16781 char *infmt;
16782 ftnlen infmtlen;
16783 char *inform;
16784 ftnint informlen;
16785 char *inunf;
16786 ftnlen inunflen;
16787 ftnint *inrecl;
16788 ftnint *innrec;
16789 char *inblank;
16790 ftnlen inblanklen;
16791} inlist;
5ff904cd 16792
5ff904cd 16793
5ff904cd 16794
c7e4ee3a
CB
16795union Multitype { // for multiple entry points //
16796 integer1 g;
16797 shortint h;
16798 integer i;
16799 // longint j; //
16800 real r;
16801 doublereal d;
16802 complex c;
16803 doublecomplex z;
16804 };
16805
16806typedef union Multitype Multitype;
5ff904cd 16807
c7e4ee3a 16808typedef long Long; // No longer used; formerly in Namelist //
5ff904cd 16809
c7e4ee3a
CB
16810struct Vardesc { // for Namelist //
16811 char *name;
16812 char *addr;
16813 ftnlen *dims;
16814 int type;
16815 };
16816typedef struct Vardesc Vardesc;
5ff904cd 16817
c7e4ee3a
CB
16818struct Namelist {
16819 char *name;
16820 Vardesc **vars;
16821 int nvars;
16822 };
16823typedef struct Namelist Namelist;
5ff904cd 16824
5ff904cd 16825
5ff904cd 16826
5ff904cd 16827
5ff904cd 16828
5ff904cd 16829
5ff904cd 16830
5ff904cd 16831
c7e4ee3a 16832// procedure parameter types for -A and -C++ //
5ff904cd 16833
5ff904cd 16834
5ff904cd 16835
5ff904cd 16836
c7e4ee3a
CB
16837typedef int // Unknown procedure type // (*U_fp)();
16838typedef shortint (*J_fp)();
16839typedef integer (*I_fp)();
16840typedef real (*R_fp)();
16841typedef doublereal (*D_fp)(), (*E_fp)();
16842typedef // Complex // void (*C_fp)();
16843typedef // Double Complex // void (*Z_fp)();
16844typedef logical (*L_fp)();
16845typedef shortlogical (*K_fp)();
16846typedef // Character // void (*H_fp)();
16847typedef // Subroutine // int (*S_fp)();
5ff904cd 16848
c7e4ee3a
CB
16849// E_fp is for real functions when -R is not specified //
16850typedef void C_f; // complex function //
16851typedef void H_f; // character function //
16852typedef void Z_f; // double complex function //
16853typedef doublereal E_f; // real function with -R not specified //
5ff904cd 16854
c7e4ee3a 16855// undef any lower-case symbols that your C compiler predefines, e.g.: //
5ff904cd 16856
5ff904cd 16857
c7e4ee3a
CB
16858// (No such symbols should be defined in a strict ANSI C compiler.
16859 We can avoid trouble with f2c-translated code by using
16860 gcc -ansi [-traditional].) //
16861
5ff904cd 16862
5ff904cd 16863
5ff904cd 16864
5ff904cd 16865
5ff904cd 16866
5ff904cd 16867
5ff904cd 16868
5ff904cd 16869
5ff904cd 16870
5ff904cd 16871
5ff904cd 16872
5ff904cd 16873
5ff904cd 16874
5ff904cd 16875
5ff904cd 16876
5ff904cd 16877
5ff904cd 16878
5ff904cd 16879
5ff904cd 16880
5ff904cd 16881
5ff904cd 16882
5ff904cd 16883
c7e4ee3a
CB
16884// Main program // MAIN__()
16885{
16886 // System generated locals //
16887 integer i__1;
16888 real r__1, r__2;
16889 doublereal d__1, d__2;
16890 complex q__1;
16891 doublecomplex z__1, z__2, z__3;
16892 logical L__1;
16893 char ch__1[1];
16894
16895 // Builtin functions //
16896 void c_div();
16897 integer pow_ii();
16898 double pow_ri(), pow_di();
16899 void pow_ci();
16900 double pow_dd();
16901 void pow_zz();
16902 double acos(), r_imag(), r_int(), log(), r_lg10(), r_mod(), r_nint(),
16903 asin(), atan(), atan2(), c_abs();
16904 void c_cos(), c_exp(), c_log(), r_cnjg();
16905 double cos(), cosh();
16906 void c_sin(), c_sqrt();
16907 double d_dim(), exp(), r_dim(), d_int(), d_lg10(), d_mod(), d_nint(),
16908 d_sign(), sin(), sinh(), sqrt(), tan(), tanh();
16909 integer i_dim(), i_dnnt(), i_indx(), i_sign(), i_len();
16910 logical l_ge(), l_gt(), l_le(), l_lt();
16911 integer i_nint();
16912 double r_sign();
16913
16914 // Local variables //
16915 extern // Subroutine // int fooa_(), fooc_(), food_(), fooi_(), foor_(),
16916 fool_(), fooz_(), getem_();
16917 static char a1[10], a2[10];
16918 static complex c1, c2;
16919 static doublereal d1, d2;
16920 static integer i1, i2;
16921 static real r1, r2;
16922
16923
16924 getem_(a1, a2, &c1, &c2, &i1, &i2, &r1, &r2, &d1, &d2, 10L, 10L);
16925// / //
16926 i__1 = i1 / i2;
16927 fooi_(&i__1);
16928 r__1 = r1 / i1;
16929 foor_(&r__1);
16930 d__1 = d1 / i1;
16931 food_(&d__1);
16932 d__1 = (doublereal) i1;
16933 q__1.r = c1.r / d__1, q__1.i = c1.i / d__1;
16934 fooc_(&q__1);
16935 r__1 = r1 / r2;
16936 foor_(&r__1);
16937 d__1 = r1 / d1;
16938 food_(&d__1);
16939 d__1 = d1 / d2;
16940 food_(&d__1);
16941 d__1 = d1 / r1;
16942 food_(&d__1);
16943 c_div(&q__1, &c1, &c2);
16944 fooc_(&q__1);
16945 q__1.r = c1.r / r1, q__1.i = c1.i / r1;
16946 fooc_(&q__1);
16947 z__1.r = c1.r / d1, z__1.i = c1.i / d1;
16948 fooz_(&z__1);
16949// ** //
16950 i__1 = pow_ii(&i1, &i2);
16951 fooi_(&i__1);
16952 r__1 = pow_ri(&r1, &i1);
16953 foor_(&r__1);
16954 d__1 = pow_di(&d1, &i1);
16955 food_(&d__1);
16956 pow_ci(&q__1, &c1, &i1);
16957 fooc_(&q__1);
16958 d__1 = (doublereal) r1;
16959 d__2 = (doublereal) r2;
16960 r__1 = pow_dd(&d__1, &d__2);
16961 foor_(&r__1);
16962 d__2 = (doublereal) r1;
16963 d__1 = pow_dd(&d__2, &d1);
16964 food_(&d__1);
16965 d__1 = pow_dd(&d1, &d2);
16966 food_(&d__1);
16967 d__2 = (doublereal) r1;
16968 d__1 = pow_dd(&d1, &d__2);
16969 food_(&d__1);
16970 z__2.r = c1.r, z__2.i = c1.i;
16971 z__3.r = c2.r, z__3.i = c2.i;
16972 pow_zz(&z__1, &z__2, &z__3);
16973 q__1.r = z__1.r, q__1.i = z__1.i;
16974 fooc_(&q__1);
16975 z__2.r = c1.r, z__2.i = c1.i;
16976 z__3.r = r1, z__3.i = 0.;
16977 pow_zz(&z__1, &z__2, &z__3);
16978 q__1.r = z__1.r, q__1.i = z__1.i;
16979 fooc_(&q__1);
16980 z__2.r = c1.r, z__2.i = c1.i;
16981 z__3.r = d1, z__3.i = 0.;
16982 pow_zz(&z__1, &z__2, &z__3);
16983 fooz_(&z__1);
16984// FFEINTRIN_impABS //
16985 r__1 = (doublereal)(( r1 ) >= 0 ? ( r1 ) : -( r1 )) ;
16986 foor_(&r__1);
16987// FFEINTRIN_impACOS //
16988 r__1 = acos(r1);
16989 foor_(&r__1);
16990// FFEINTRIN_impAIMAG //
16991 r__1 = r_imag(&c1);
16992 foor_(&r__1);
16993// FFEINTRIN_impAINT //
16994 r__1 = r_int(&r1);
16995 foor_(&r__1);
16996// FFEINTRIN_impALOG //
16997 r__1 = log(r1);
16998 foor_(&r__1);
16999// FFEINTRIN_impALOG10 //
17000 r__1 = r_lg10(&r1);
17001 foor_(&r__1);
17002// FFEINTRIN_impAMAX0 //
17003 r__1 = (real) (( i1 ) >= ( i2 ) ? ( i1 ) : ( i2 )) ;
17004 foor_(&r__1);
17005// FFEINTRIN_impAMAX1 //
17006 r__1 = (doublereal)(( r1 ) >= ( r2 ) ? ( r1 ) : ( r2 )) ;
17007 foor_(&r__1);
17008// FFEINTRIN_impAMIN0 //
17009 r__1 = (real) (( i1 ) <= ( i2 ) ? ( i1 ) : ( i2 )) ;
17010 foor_(&r__1);
17011// FFEINTRIN_impAMIN1 //
17012 r__1 = (doublereal)(( r1 ) <= ( r2 ) ? ( r1 ) : ( r2 )) ;
17013 foor_(&r__1);
17014// FFEINTRIN_impAMOD //
17015 r__1 = r_mod(&r1, &r2);
17016 foor_(&r__1);
17017// FFEINTRIN_impANINT //
17018 r__1 = r_nint(&r1);
17019 foor_(&r__1);
17020// FFEINTRIN_impASIN //
17021 r__1 = asin(r1);
17022 foor_(&r__1);
17023// FFEINTRIN_impATAN //
17024 r__1 = atan(r1);
17025 foor_(&r__1);
17026// FFEINTRIN_impATAN2 //
17027 r__1 = atan2(r1, r2);
17028 foor_(&r__1);
17029// FFEINTRIN_impCABS //
17030 r__1 = c_abs(&c1);
17031 foor_(&r__1);
17032// FFEINTRIN_impCCOS //
17033 c_cos(&q__1, &c1);
17034 fooc_(&q__1);
17035// FFEINTRIN_impCEXP //
17036 c_exp(&q__1, &c1);
17037 fooc_(&q__1);
17038// FFEINTRIN_impCHAR //
17039 *(unsigned char *)&ch__1[0] = i1;
17040 fooa_(ch__1, 1L);
17041// FFEINTRIN_impCLOG //
17042 c_log(&q__1, &c1);
17043 fooc_(&q__1);
17044// FFEINTRIN_impCONJG //
17045 r_cnjg(&q__1, &c1);
17046 fooc_(&q__1);
17047// FFEINTRIN_impCOS //
17048 r__1 = cos(r1);
17049 foor_(&r__1);
17050// FFEINTRIN_impCOSH //
17051 r__1 = cosh(r1);
17052 foor_(&r__1);
17053// FFEINTRIN_impCSIN //
17054 c_sin(&q__1, &c1);
17055 fooc_(&q__1);
17056// FFEINTRIN_impCSQRT //
17057 c_sqrt(&q__1, &c1);
17058 fooc_(&q__1);
17059// FFEINTRIN_impDABS //
17060 d__1 = (( d1 ) >= 0 ? ( d1 ) : -( d1 )) ;
17061 food_(&d__1);
17062// FFEINTRIN_impDACOS //
17063 d__1 = acos(d1);
17064 food_(&d__1);
17065// FFEINTRIN_impDASIN //
17066 d__1 = asin(d1);
17067 food_(&d__1);
17068// FFEINTRIN_impDATAN //
17069 d__1 = atan(d1);
17070 food_(&d__1);
17071// FFEINTRIN_impDATAN2 //
17072 d__1 = atan2(d1, d2);
17073 food_(&d__1);
17074// FFEINTRIN_impDCOS //
17075 d__1 = cos(d1);
17076 food_(&d__1);
17077// FFEINTRIN_impDCOSH //
17078 d__1 = cosh(d1);
17079 food_(&d__1);
17080// FFEINTRIN_impDDIM //
17081 d__1 = d_dim(&d1, &d2);
17082 food_(&d__1);
17083// FFEINTRIN_impDEXP //
17084 d__1 = exp(d1);
17085 food_(&d__1);
17086// FFEINTRIN_impDIM //
17087 r__1 = r_dim(&r1, &r2);
17088 foor_(&r__1);
17089// FFEINTRIN_impDINT //
17090 d__1 = d_int(&d1);
17091 food_(&d__1);
17092// FFEINTRIN_impDLOG //
17093 d__1 = log(d1);
17094 food_(&d__1);
17095// FFEINTRIN_impDLOG10 //
17096 d__1 = d_lg10(&d1);
17097 food_(&d__1);
17098// FFEINTRIN_impDMAX1 //
17099 d__1 = (( d1 ) >= ( d2 ) ? ( d1 ) : ( d2 )) ;
17100 food_(&d__1);
17101// FFEINTRIN_impDMIN1 //
17102 d__1 = (( d1 ) <= ( d2 ) ? ( d1 ) : ( d2 )) ;
17103 food_(&d__1);
17104// FFEINTRIN_impDMOD //
17105 d__1 = d_mod(&d1, &d2);
17106 food_(&d__1);
17107// FFEINTRIN_impDNINT //
17108 d__1 = d_nint(&d1);
17109 food_(&d__1);
17110// FFEINTRIN_impDPROD //
17111 d__1 = (doublereal) r1 * r2;
17112 food_(&d__1);
17113// FFEINTRIN_impDSIGN //
17114 d__1 = d_sign(&d1, &d2);
17115 food_(&d__1);
17116// FFEINTRIN_impDSIN //
17117 d__1 = sin(d1);
17118 food_(&d__1);
17119// FFEINTRIN_impDSINH //
17120 d__1 = sinh(d1);
17121 food_(&d__1);
17122// FFEINTRIN_impDSQRT //
17123 d__1 = sqrt(d1);
17124 food_(&d__1);
17125// FFEINTRIN_impDTAN //
17126 d__1 = tan(d1);
17127 food_(&d__1);
17128// FFEINTRIN_impDTANH //
17129 d__1 = tanh(d1);
17130 food_(&d__1);
17131// FFEINTRIN_impEXP //
17132 r__1 = exp(r1);
17133 foor_(&r__1);
17134// FFEINTRIN_impIABS //
17135 i__1 = (( i1 ) >= 0 ? ( i1 ) : -( i1 )) ;
17136 fooi_(&i__1);
17137// FFEINTRIN_impICHAR //
17138 i__1 = *(unsigned char *)a1;
17139 fooi_(&i__1);
17140// FFEINTRIN_impIDIM //
17141 i__1 = i_dim(&i1, &i2);
17142 fooi_(&i__1);
17143// FFEINTRIN_impIDNINT //
17144 i__1 = i_dnnt(&d1);
17145 fooi_(&i__1);
17146// FFEINTRIN_impINDEX //
17147 i__1 = i_indx(a1, a2, 10L, 10L);
17148 fooi_(&i__1);
17149// FFEINTRIN_impISIGN //
17150 i__1 = i_sign(&i1, &i2);
17151 fooi_(&i__1);
17152// FFEINTRIN_impLEN //
17153 i__1 = i_len(a1, 10L);
17154 fooi_(&i__1);
17155// FFEINTRIN_impLGE //
17156 L__1 = l_ge(a1, a2, 10L, 10L);
17157 fool_(&L__1);
17158// FFEINTRIN_impLGT //
17159 L__1 = l_gt(a1, a2, 10L, 10L);
17160 fool_(&L__1);
17161// FFEINTRIN_impLLE //
17162 L__1 = l_le(a1, a2, 10L, 10L);
17163 fool_(&L__1);
17164// FFEINTRIN_impLLT //
17165 L__1 = l_lt(a1, a2, 10L, 10L);
17166 fool_(&L__1);
17167// FFEINTRIN_impMAX0 //
17168 i__1 = (( i1 ) >= ( i2 ) ? ( i1 ) : ( i2 )) ;
17169 fooi_(&i__1);
17170// FFEINTRIN_impMAX1 //
17171 i__1 = (integer) (doublereal)(( r1 ) >= ( r2 ) ? ( r1 ) : ( r2 )) ;
17172 fooi_(&i__1);
17173// FFEINTRIN_impMIN0 //
17174 i__1 = (( i1 ) <= ( i2 ) ? ( i1 ) : ( i2 )) ;
17175 fooi_(&i__1);
17176// FFEINTRIN_impMIN1 //
17177 i__1 = (integer) (doublereal)(( r1 ) <= ( r2 ) ? ( r1 ) : ( r2 )) ;
17178 fooi_(&i__1);
17179// FFEINTRIN_impMOD //
17180 i__1 = i1 % i2;
17181 fooi_(&i__1);
17182// FFEINTRIN_impNINT //
17183 i__1 = i_nint(&r1);
17184 fooi_(&i__1);
17185// FFEINTRIN_impSIGN //
17186 r__1 = r_sign(&r1, &r2);
17187 foor_(&r__1);
17188// FFEINTRIN_impSIN //
17189 r__1 = sin(r1);
17190 foor_(&r__1);
17191// FFEINTRIN_impSINH //
17192 r__1 = sinh(r1);
17193 foor_(&r__1);
17194// FFEINTRIN_impSQRT //
17195 r__1 = sqrt(r1);
17196 foor_(&r__1);
17197// FFEINTRIN_impTAN //
17198 r__1 = tan(r1);
17199 foor_(&r__1);
17200// FFEINTRIN_impTANH //
17201 r__1 = tanh(r1);
17202 foor_(&r__1);
17203// FFEINTRIN_imp_CMPLX_C //
17204 r__1 = c1.r;
17205 r__2 = c2.r;
17206 q__1.r = r__1, q__1.i = r__2;
17207 fooc_(&q__1);
17208// FFEINTRIN_imp_CMPLX_D //
17209 z__1.r = d1, z__1.i = d2;
17210 fooz_(&z__1);
17211// FFEINTRIN_imp_CMPLX_I //
17212 r__1 = (real) i1;
17213 r__2 = (real) i2;
17214 q__1.r = r__1, q__1.i = r__2;
17215 fooc_(&q__1);
17216// FFEINTRIN_imp_CMPLX_R //
17217 q__1.r = r1, q__1.i = r2;
17218 fooc_(&q__1);
17219// FFEINTRIN_imp_DBLE_C //
17220 d__1 = (doublereal) c1.r;
17221 food_(&d__1);
17222// FFEINTRIN_imp_DBLE_D //
17223 d__1 = d1;
17224 food_(&d__1);
17225// FFEINTRIN_imp_DBLE_I //
17226 d__1 = (doublereal) i1;
17227 food_(&d__1);
17228// FFEINTRIN_imp_DBLE_R //
17229 d__1 = (doublereal) r1;
17230 food_(&d__1);
17231// FFEINTRIN_imp_INT_C //
17232 i__1 = (integer) c1.r;
17233 fooi_(&i__1);
17234// FFEINTRIN_imp_INT_D //
17235 i__1 = (integer) d1;
17236 fooi_(&i__1);
17237// FFEINTRIN_imp_INT_I //
17238 i__1 = i1;
17239 fooi_(&i__1);
17240// FFEINTRIN_imp_INT_R //
17241 i__1 = (integer) r1;
17242 fooi_(&i__1);
17243// FFEINTRIN_imp_REAL_C //
17244 r__1 = c1.r;
17245 foor_(&r__1);
17246// FFEINTRIN_imp_REAL_D //
17247 r__1 = (real) d1;
17248 foor_(&r__1);
17249// FFEINTRIN_imp_REAL_I //
17250 r__1 = (real) i1;
17251 foor_(&r__1);
17252// FFEINTRIN_imp_REAL_R //
17253 r__1 = r1;
17254 foor_(&r__1);
17255
17256// FFEINTRIN_imp_INT_D: //
17257
17258// FFEINTRIN_specIDINT //
17259 i__1 = (integer) d1;
17260 fooi_(&i__1);
17261
17262// FFEINTRIN_imp_INT_R: //
17263
17264// FFEINTRIN_specIFIX //
17265 i__1 = (integer) r1;
17266 fooi_(&i__1);
17267// FFEINTRIN_specINT //
17268 i__1 = (integer) r1;
17269 fooi_(&i__1);
17270
17271// FFEINTRIN_imp_REAL_D: //
5ff904cd 17272
c7e4ee3a
CB
17273// FFEINTRIN_specSNGL //
17274 r__1 = (real) d1;
17275 foor_(&r__1);
5ff904cd 17276
c7e4ee3a 17277// FFEINTRIN_imp_REAL_I: //
5ff904cd 17278
c7e4ee3a
CB
17279// FFEINTRIN_specFLOAT //
17280 r__1 = (real) i1;
17281 foor_(&r__1);
17282// FFEINTRIN_specREAL //
17283 r__1 = (real) i1;
17284 foor_(&r__1);
5ff904cd 17285
c7e4ee3a 17286} // MAIN__ //
5ff904cd 17287
c7e4ee3a 17288-------- (end output file from f2c)
5ff904cd 17289
c7e4ee3a 17290*/
This page took 2.190423 seconds and 5 git commands to generate.