]> gcc.gnu.org Git - gcc.git/blame - gcc/f/com.c
safe-ctype.h: New file.
[gcc.git] / gcc / f / com.c
CommitLineData
5ff904cd 1/* com.c -- Implementation File (module.c template V1.0)
06ceef4e
RK
2 Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000
3 Free Software Foundation, Inc.
25d7717e 4 Contributed by James Craig Burley.
5ff904cd
JL
5
6This file is part of GNU Fortran.
7
8GNU Fortran is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2, or (at your option)
11any later version.
12
13GNU Fortran is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with GNU Fortran; see the file COPYING. If not, write to
20the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2102111-1307, USA.
22
23 Related Modules:
24 None
25
26 Description:
27 Contains compiler-specific functions.
28
29 Modifications:
30*/
31
32/* Understanding this module means understanding the interface between
33 the g77 front end and the gcc back end (or, perhaps, some other
34 back end). In here are the functions called by the front end proper
35 to notify whatever back end is in place about certain things, and
36 also the back-end-specific functions. It's a bear to deal with, so
37 lately I've been trying to simplify things, especially with regard
38 to the gcc-back-end-specific stuff.
39
40 Building expressions generally seems quite easy, but building decls
41 has been challenging and is undergoing revision. gcc has several
42 kinds of decls:
43
44 TYPE_DECL -- a type (int, float, struct, function, etc.)
45 CONST_DECL -- a constant of some type other than function
46 LABEL_DECL -- a variable or a constant?
47 PARM_DECL -- an argument to a function (a variable that is a dummy)
48 RESULT_DECL -- the return value of a function (a variable)
49 VAR_DECL -- other variable (can hold a ptr-to-function, struct, int, etc.)
50 FUNCTION_DECL -- a function (either the actual function or an extern ref)
51 FIELD_DECL -- a field in a struct or union (goes into types)
52
53 g77 has a set of functions that somewhat parallels the gcc front end
54 when it comes to building decls:
55
56 Internal Function (one we define, not just declare as extern):
5ff904cd
JL
57 if (is_nested) push_f_function_context ();
58 start_function (get_identifier ("function_name"), function_type,
59 is_nested, is_public);
60 // for each arg, build PARM_DECL and call push_parm_decl (decl) with it;
61 store_parm_decls (is_main_program);
c7e4ee3a 62 ffecom_start_compstmt ();
5ff904cd 63 // for stmts and decls inside function, do appropriate things;
c7e4ee3a 64 ffecom_end_compstmt ();
5ff904cd
JL
65 finish_function (is_nested);
66 if (is_nested) pop_f_function_context ();
5ff904cd
JL
67
68 Everything Else:
5ff904cd
JL
69 tree d;
70 tree init;
5ff904cd
JL
71 // fill in external, public, static, &c for decl, and
72 // set DECL_INITIAL to error_mark_node if going to initialize
73 // set is_top_level TRUE only if not at top level and decl
74 // must go in top level (i.e. not within current function decl context)
75 d = start_decl (decl, is_top_level);
76 init = ...; // if have initializer
77 finish_decl (d, init, is_top_level);
5ff904cd
JL
78
79*/
80
81/* Include files. */
82
95a1b676 83#include "proj.h"
5ff904cd 84#if FFECOM_targetCURRENT == FFECOM_targetGCC
15a40ced
ZW
85#include "flags.h"
86#include "rtl.h"
87#include "toplev.h"
88#include "tree.h"
89#include "output.h" /* Must follow tree.h so TREE_CODE is defined! */
90#include "convert.h"
91#include "ggc.h"
d8ea8f28 92#include "defaults.h"
5ff904cd
JL
93#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
94
95#define FFECOM_GCC_INCLUDE 1 /* Enable -I. */
96
97/* BEGIN stuff from gcc/cccp.c. */
98
99/* The following symbols should be autoconfigured:
100 HAVE_FCNTL_H
101 HAVE_STDLIB_H
102 HAVE_SYS_TIME_H
103 HAVE_UNISTD_H
104 STDC_HEADERS
105 TIME_WITH_SYS_TIME
106 In the mean time, we'll get by with approximations based
107 on existing GCC configuration symbols. */
108
109#ifdef POSIX
110# ifndef HAVE_STDLIB_H
111# define HAVE_STDLIB_H 1
112# endif
113# ifndef HAVE_UNISTD_H
114# define HAVE_UNISTD_H 1
115# endif
116# ifndef STDC_HEADERS
117# define STDC_HEADERS 1
118# endif
119#endif /* defined (POSIX) */
120
121#if defined (POSIX) || (defined (USG) && !defined (VMS))
122# ifndef HAVE_FCNTL_H
123# define HAVE_FCNTL_H 1
124# endif
125#endif
126
127#ifndef RLIMIT_STACK
128# include <time.h>
129#else
130# if TIME_WITH_SYS_TIME
131# include <sys/time.h>
132# include <time.h>
133# else
134# if HAVE_SYS_TIME_H
135# include <sys/time.h>
136# else
137# include <time.h>
138# endif
139# endif
140# include <sys/resource.h>
141#endif
142
143#if HAVE_FCNTL_H
144# include <fcntl.h>
145#endif
146
147/* This defines "errno" properly for VMS, and gives us EACCES. */
148#include <errno.h>
149
150#if HAVE_STDLIB_H
151# include <stdlib.h>
152#else
153char *getenv ();
154#endif
155
5ff904cd
JL
156#if HAVE_UNISTD_H
157# include <unistd.h>
158#endif
159
160/* VMS-specific definitions */
161#ifdef VMS
162#include <descrip.h>
163#define O_RDONLY 0 /* Open arg for Read/Only */
164#define O_WRONLY 1 /* Open arg for Write/Only */
165#define read(fd,buf,size) VMS_read (fd,buf,size)
166#define write(fd,buf,size) VMS_write (fd,buf,size)
167#define open(fname,mode,prot) VMS_open (fname,mode,prot)
168#define fopen(fname,mode) VMS_fopen (fname,mode)
169#define freopen(fname,mode,ofile) VMS_freopen (fname,mode,ofile)
170#define strncat(dst,src,cnt) VMS_strncat (dst,src,cnt)
171#define fstat(fd,stbuf) VMS_fstat (fd,stbuf)
172static int VMS_fstat (), VMS_stat ();
173static char * VMS_strncat ();
174static int VMS_read ();
175static int VMS_write ();
176static int VMS_open ();
177static FILE * VMS_fopen ();
178static FILE * VMS_freopen ();
179static void hack_vms_include_specification ();
180typedef struct { unsigned :16, :16, :16; } vms_ino_t;
181#define ino_t vms_ino_t
182#define INCLUDE_LEN_FUDGE 10 /* leave room for VMS syntax conversion */
183#ifdef __GNUC__
184#define BSTRING /* VMS/GCC supplies the bstring routines */
185#endif /* __GNUC__ */
186#endif /* VMS */
187
188#ifndef O_RDONLY
189#define O_RDONLY 0
190#endif
191
192/* END stuff from gcc/cccp.c. */
193
5ff904cd
JL
194#define FFECOM_DETERMINE_TYPES 1 /* for com.h */
195#include "com.h"
196#include "bad.h"
197#include "bld.h"
198#include "equiv.h"
199#include "expr.h"
200#include "implic.h"
201#include "info.h"
202#include "malloc.h"
203#include "src.h"
204#include "st.h"
205#include "storag.h"
206#include "symbol.h"
207#include "target.h"
208#include "top.h"
209#include "type.h"
210
211/* Externals defined here. */
212
5ff904cd
JL
213#if FFECOM_targetCURRENT == FFECOM_targetGCC
214
c7e4ee3a
CB
215/* ~~gcc/tree.h *should* declare this, because toplev.c and dwarfout.c
216 reference it. */
5ff904cd 217
f425a887 218const char * const language_string = "GNU F77";
5ff904cd 219
77f77701
DB
220/* Stream for reading from the input file. */
221FILE *finput;
222
5ff904cd
JL
223/* These definitions parallel those in c-decl.c so that code from that
224 module can be used pretty much as is. Much of these defs aren't
225 otherwise used, i.e. by g77 code per se, except some of them are used
226 to build some of them that are. The ones that are global (i.e. not
227 "static") are those that ste.c and such might use (directly
228 or by using com macros that reference them in their definitions). */
229
5ff904cd
JL
230tree string_type_node;
231
5ff904cd
JL
232/* The rest of these are inventions for g77, though there might be
233 similar things in the C front end. As they are found, these
234 inventions should be renamed to be canonical. Note that only
235 the ones currently required to be global are so. */
236
237static tree ffecom_tree_fun_type_void;
5ff904cd
JL
238
239tree ffecom_integer_type_node; /* Abbrev for _tree_type[blah][blah]. */
240tree ffecom_integer_zero_node; /* Like *_*_* with g77's integer type. */
241tree ffecom_integer_one_node; /* " */
242tree ffecom_tree_type[FFEINFO_basictype][FFEINFO_kindtype];
243
244/* _fun_type things are the f2c-specific versions. For -fno-f2c,
245 just use build_function_type and build_pointer_type on the
246 appropriate _tree_type array element. */
247
248static tree ffecom_tree_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
249static tree ffecom_tree_ptr_to_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
250static tree ffecom_tree_subr_type;
251static tree ffecom_tree_ptr_to_subr_type;
252static tree ffecom_tree_blockdata_type;
253
254static tree ffecom_tree_xargc_;
255
256ffecomSymbol ffecom_symbol_null_
257=
258{
259 NULL_TREE,
260 NULL_TREE,
261 NULL_TREE,
0816ebdd
KG
262 NULL_TREE,
263 false
5ff904cd
JL
264};
265ffeinfoKindtype ffecom_pointer_kind_ = FFEINFO_basictypeNONE;
266ffeinfoKindtype ffecom_label_kind_ = FFEINFO_basictypeNONE;
267
268int ffecom_f2c_typecode_[FFEINFO_basictype][FFEINFO_kindtype];
269tree ffecom_f2c_integer_type_node;
270tree ffecom_f2c_ptr_to_integer_type_node;
271tree ffecom_f2c_address_type_node;
272tree ffecom_f2c_real_type_node;
273tree ffecom_f2c_ptr_to_real_type_node;
274tree ffecom_f2c_doublereal_type_node;
275tree ffecom_f2c_complex_type_node;
276tree ffecom_f2c_doublecomplex_type_node;
277tree ffecom_f2c_longint_type_node;
278tree ffecom_f2c_logical_type_node;
279tree ffecom_f2c_flag_type_node;
280tree ffecom_f2c_ftnlen_type_node;
281tree ffecom_f2c_ftnlen_zero_node;
282tree ffecom_f2c_ftnlen_one_node;
283tree ffecom_f2c_ftnlen_two_node;
284tree ffecom_f2c_ptr_to_ftnlen_type_node;
285tree ffecom_f2c_ftnint_type_node;
286tree ffecom_f2c_ptr_to_ftnint_type_node;
287#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
288
289/* Simple definitions and enumerations. */
290
291#ifndef FFECOM_sizeMAXSTACKITEM
292#define FFECOM_sizeMAXSTACKITEM 32*1024 /* Keep user-declared things
293 larger than this # bytes
294 off stack if possible. */
295#endif
296
297/* For systems that have large enough stacks, they should define
298 this to 0, and here, for ease of use later on, we just undefine
299 it if it is 0. */
300
301#if FFECOM_sizeMAXSTACKITEM == 0
302#undef FFECOM_sizeMAXSTACKITEM
303#endif
304
305typedef enum
306 {
307 FFECOM_rttypeVOID_,
6d433196 308 FFECOM_rttypeVOIDSTAR_, /* C's `void *' type. */
795232f7
JL
309 FFECOM_rttypeFTNINT_, /* f2c's `ftnint' type. */
310 FFECOM_rttypeINTEGER_, /* f2c's `integer' type. */
311 FFECOM_rttypeLONGINT_, /* f2c's `longint' type. */
312 FFECOM_rttypeLOGICAL_, /* f2c's `logical' type. */
313 FFECOM_rttypeREAL_F2C_, /* f2c's `real' returned as `double'. */
314 FFECOM_rttypeREAL_GNU_, /* `real' returned as such. */
5ff904cd 315 FFECOM_rttypeCOMPLEX_F2C_, /* f2c's `complex' returned via 1st arg. */
795232f7 316 FFECOM_rttypeCOMPLEX_GNU_, /* f2c's `complex' returned directly. */
5ff904cd 317 FFECOM_rttypeDOUBLE_, /* C's `double' type. */
795232f7 318 FFECOM_rttypeDOUBLEREAL_, /* f2c's `doublereal' type. */
5ff904cd 319 FFECOM_rttypeDBLCMPLX_F2C_, /* f2c's `doublecomplex' returned via 1st arg. */
795232f7 320 FFECOM_rttypeDBLCMPLX_GNU_, /* f2c's `doublecomplex' returned directly. */
5ff904cd
JL
321 FFECOM_rttypeCHARACTER_, /* f2c `char *'/`ftnlen' pair. */
322 FFECOM_rttype_
323 } ffecomRttype_;
324
325/* Internal typedefs. */
326
327#if FFECOM_targetCURRENT == FFECOM_targetGCC
328typedef struct _ffecom_concat_list_ ffecomConcatList_;
5ff904cd
JL
329#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
330
331/* Private include files. */
332
333
334/* Internal structure definitions. */
335
336#if FFECOM_targetCURRENT == FFECOM_targetGCC
337struct _ffecom_concat_list_
338 {
339 ffebld *exprs;
340 int count;
341 int max;
342 ffetargetCharacterSize minlen;
343 ffetargetCharacterSize maxlen;
344 };
5ff904cd
JL
345#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
346
347/* Static functions (internal). */
348
349#if FFECOM_targetCURRENT == FFECOM_targetGCC
26f096f9 350static tree ffecom_arglist_expr_ (const char *argstring, ffebld args);
5ff904cd
JL
351static tree ffecom_widest_expr_type_ (ffebld list);
352static bool ffecom_overlap_ (tree dest_decl, tree dest_offset,
353 tree dest_size, tree source_tree,
354 ffebld source, bool scalar_arg);
355static bool ffecom_args_overlapping_ (tree dest_tree, ffebld dest,
356 tree args, tree callee_commons,
357 bool scalar_args);
26f096f9 358static tree ffecom_build_f2c_string_ (int i, const char *s);
5ff904cd
JL
359static tree ffecom_call_ (tree fn, ffeinfoKindtype kt,
360 bool is_f2c_complex, tree type,
361 tree args, tree dest_tree,
362 ffebld dest, bool *dest_used,
c7e4ee3a 363 tree callee_commons, bool scalar_args, tree hook);
5ff904cd
JL
364static tree ffecom_call_binop_ (tree fn, ffeinfoKindtype kt,
365 bool is_f2c_complex, tree type,
366 ffebld left, ffebld right,
367 tree dest_tree, ffebld dest,
368 bool *dest_used, tree callee_commons,
95eb4fd9 369 bool scalar_args, bool ref, tree hook);
86fc7a6c
CB
370static void ffecom_char_args_x_ (tree *xitem, tree *length,
371 ffebld expr, bool with_null);
5ff904cd
JL
372static tree ffecom_check_size_overflow_ (ffesymbol s, tree type, bool dummy);
373static tree ffecom_char_enhance_arg_ (tree *xtype, ffesymbol s);
374static ffecomConcatList_
375 ffecom_concat_list_gather_ (ffecomConcatList_ catlist,
376 ffebld expr,
377 ffetargetCharacterSize max);
378static void ffecom_concat_list_kill_ (ffecomConcatList_ catlist);
379static ffecomConcatList_ ffecom_concat_list_new_ (ffebld expr,
380 ffetargetCharacterSize max);
26f096f9
KG
381static void ffecom_debug_kludge_ (tree aggr, const char *aggr_type,
382 ffesymbol member, tree member_type,
383 ffetargetOffset offset);
5ff904cd 384static void ffecom_do_entry_ (ffesymbol fn, int entrynum);
092a4ef8
RH
385static tree ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest,
386 bool *dest_used, bool assignp, bool widenp);
5ff904cd
JL
387static tree ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree,
388 ffebld dest, bool *dest_used);
c7e4ee3a 389static tree ffecom_expr_power_integer_ (ffebld expr);
5ff904cd 390static void ffecom_expr_transform_ (ffebld expr);
26f096f9 391static void ffecom_f2c_make_type_ (tree *type, int tcode, const char *name);
5ff904cd
JL
392static void ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size,
393 int code);
394static ffeglobal ffecom_finish_global_ (ffeglobal global);
395static ffesymbol ffecom_finish_symbol_transform_ (ffesymbol s);
26f096f9 396static tree ffecom_get_appended_identifier_ (char us, const char *text);
5ff904cd 397static tree ffecom_get_external_identifier_ (ffesymbol s);
26f096f9 398static tree ffecom_get_identifier_ (const char *text);
5ff904cd
JL
399static tree ffecom_gen_sfuncdef_ (ffesymbol s,
400 ffeinfoBasictype bt,
401 ffeinfoKindtype kt);
26f096f9 402static const char *ffecom_gfrt_args_ (ffecomGfrt ix);
5ff904cd
JL
403static tree ffecom_gfrt_tree_ (ffecomGfrt ix);
404static tree ffecom_init_zero_ (tree decl);
405static tree ffecom_intrinsic_ichar_ (tree tree_type, ffebld arg,
406 tree *maybe_tree);
407static tree ffecom_intrinsic_len_ (ffebld expr);
408static void ffecom_let_char_ (tree dest_tree,
409 tree dest_length,
410 ffetargetCharacterSize dest_size,
411 ffebld source);
412static void ffecom_make_gfrt_ (ffecomGfrt ix);
413static void ffecom_member_phase1_ (ffestorag mst, ffestorag st);
5ff904cd 414static void ffecom_member_phase2_ (ffestorag mst, ffestorag st);
c7e4ee3a
CB
415static void ffecom_prepare_let_char_ (ffetargetCharacterSize dest_size,
416 ffebld source);
5ff904cd
JL
417static void ffecom_push_dummy_decls_ (ffebld dumlist,
418 bool stmtfunc);
419static void ffecom_start_progunit_ (void);
420static ffesymbol ffecom_sym_transform_ (ffesymbol s);
421static ffesymbol ffecom_sym_transform_assign_ (ffesymbol s);
422static void ffecom_transform_common_ (ffesymbol s);
423static void ffecom_transform_equiv_ (ffestorag st);
424static tree ffecom_transform_namelist_ (ffesymbol s);
425static void ffecom_tree_canonize_ptr_ (tree *decl, tree *offset,
426 tree t);
427static void ffecom_tree_canonize_ref_ (tree *decl, tree *offset,
428 tree *size, tree tree);
429static tree ffecom_tree_divide_ (tree tree_type, tree left, tree right,
430 tree dest_tree, ffebld dest,
c7e4ee3a 431 bool *dest_used, tree hook);
5ff904cd
JL
432static tree ffecom_type_localvar_ (ffesymbol s,
433 ffeinfoBasictype bt,
434 ffeinfoKindtype kt);
435static tree ffecom_type_namelist_ (void);
5ff904cd
JL
436static tree ffecom_type_vardesc_ (void);
437static tree ffecom_vardesc_ (ffebld expr);
438static tree ffecom_vardesc_array_ (ffesymbol s);
439static tree ffecom_vardesc_dims_ (ffesymbol s);
26f096f9
KG
440static tree ffecom_convert_narrow_ (tree type, tree expr);
441static tree ffecom_convert_widen_ (tree type, tree expr);
5ff904cd
JL
442#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
443
444/* These are static functions that parallel those found in the C front
445 end and thus have the same names. */
446
447#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a 448static tree bison_rule_compstmt_ (void);
5ff904cd 449static void bison_rule_pushlevel_ (void);
c7e4ee3a 450static void delete_block (tree block);
5ff904cd
JL
451static int duplicate_decls (tree newdecl, tree olddecl);
452static void finish_decl (tree decl, tree init, bool is_top_level);
453static void finish_function (int nested);
4b731ffa 454static const char *lang_printable_name (tree decl, int v);
5ff904cd
JL
455static tree lookup_name_current_level (tree name);
456static struct binding_level *make_binding_level (void);
457static void pop_f_function_context (void);
458static void push_f_function_context (void);
459static void push_parm_decl (tree parm);
460static tree pushdecl_top_level (tree decl);
c7e4ee3a 461static int kept_level_p (void);
5ff904cd
JL
462static tree storedecls (tree decls);
463static void store_parm_decls (int is_main_program);
464static tree start_decl (tree decl, bool is_top_level);
465static void start_function (tree name, tree type, int nested, int public);
466#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
467#if FFECOM_GCC_INCLUDE
b0791fa9 468static void ffecom_file_ (const char *name);
5ff904cd
JL
469static void ffecom_initialize_char_syntax_ (void);
470static void ffecom_close_include_ (FILE *f);
471static int ffecom_decode_include_option_ (char *spec);
472static FILE *ffecom_open_include_ (char *name, ffewhereLine l,
473 ffewhereColumn c);
474#endif /* FFECOM_GCC_INCLUDE */
475
476/* Static objects accessed by functions in this module. */
477
478static ffesymbol ffecom_primary_entry_ = NULL;
479static ffesymbol ffecom_nested_entry_ = NULL;
480static ffeinfoKind ffecom_primary_entry_kind_;
481static bool ffecom_primary_entry_is_proc_;
482#if FFECOM_targetCURRENT == FFECOM_targetGCC
483static tree ffecom_outer_function_decl_;
484static tree ffecom_previous_function_decl_;
485static tree ffecom_which_entrypoint_decl_;
5ff904cd
JL
486static tree ffecom_float_zero_ = NULL_TREE;
487static tree ffecom_float_half_ = NULL_TREE;
488static tree ffecom_double_zero_ = NULL_TREE;
489static tree ffecom_double_half_ = NULL_TREE;
490static tree ffecom_func_result_;/* For functions. */
491static tree ffecom_func_length_;/* For CHARACTER fns. */
492static ffebld ffecom_list_blockdata_;
493static ffebld ffecom_list_common_;
494static ffebld ffecom_master_arglist_;
495static ffeinfoBasictype ffecom_master_bt_;
496static ffeinfoKindtype ffecom_master_kt_;
497static ffetargetCharacterSize ffecom_master_size_;
498static int ffecom_num_fns_ = 0;
499static int ffecom_num_entrypoints_ = 0;
500static bool ffecom_is_altreturning_ = FALSE;
501static tree ffecom_multi_type_node_;
502static tree ffecom_multi_retval_;
503static tree
504 ffecom_multi_fields_[FFEINFO_basictype][FFEINFO_kindtype];
505static bool ffecom_member_namelisted_; /* _member_phase1_ namelisted? */
506static bool ffecom_doing_entry_ = FALSE;
507static bool ffecom_transform_only_dummies_ = FALSE;
ff852b44
CB
508static int ffecom_typesize_pointer_;
509static int ffecom_typesize_integer1_;
5ff904cd
JL
510
511/* Holds pointer-to-function expressions. */
512
513static tree ffecom_gfrt_[FFECOM_gfrt]
514=
515{
95eb4fd9 516#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) NULL_TREE,
5ff904cd
JL
517#include "com-rt.def"
518#undef DEFGFRT
519};
520
521/* Holds the external names of the functions. */
522
26f096f9 523static const char *ffecom_gfrt_name_[FFECOM_gfrt]
5ff904cd
JL
524=
525{
95eb4fd9 526#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) NAME,
5ff904cd
JL
527#include "com-rt.def"
528#undef DEFGFRT
529};
530
531/* Whether the function returns. */
532
533static bool ffecom_gfrt_volatile_[FFECOM_gfrt]
534=
535{
95eb4fd9 536#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) VOLATILE,
5ff904cd
JL
537#include "com-rt.def"
538#undef DEFGFRT
539};
540
541/* Whether the function returns type complex. */
542
543static bool ffecom_gfrt_complex_[FFECOM_gfrt]
544=
545{
95eb4fd9
TM
546#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) COMPLEX,
547#include "com-rt.def"
548#undef DEFGFRT
549};
550
551/* Whether the function is const
552 (i.e., has no side effects and only depends on its arguments). */
553
554static bool ffecom_gfrt_const_[FFECOM_gfrt]
555=
556{
557#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) CONST,
5ff904cd
JL
558#include "com-rt.def"
559#undef DEFGFRT
560};
561
562/* Type code for the function return value. */
563
564static ffecomRttype_ ffecom_gfrt_type_[FFECOM_gfrt]
565=
566{
95eb4fd9 567#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) TYPE,
5ff904cd
JL
568#include "com-rt.def"
569#undef DEFGFRT
570};
571
572/* String of codes for the function's arguments. */
573
26f096f9 574static const char *ffecom_gfrt_argstring_[FFECOM_gfrt]
5ff904cd
JL
575=
576{
95eb4fd9 577#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) ARGS,
5ff904cd
JL
578#include "com-rt.def"
579#undef DEFGFRT
580};
581#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
582
583/* Internal macros. */
584
585#if FFECOM_targetCURRENT == FFECOM_targetGCC
586
587/* We let tm.h override the types used here, to handle trivial differences
588 such as the choice of unsigned int or long unsigned int for size_t.
589 When machines start needing nontrivial differences in the size type,
590 it would be best to do something here to figure out automatically
591 from other information what type to use. */
592
ff852b44
CB
593#ifndef SIZE_TYPE
594#define SIZE_TYPE "long unsigned int"
595#endif
5ff904cd 596
5ff904cd
JL
597#define ffecom_concat_list_count_(catlist) ((catlist).count)
598#define ffecom_concat_list_expr_(catlist,i) ((catlist).exprs[(i)])
599#define ffecom_concat_list_maxlen_(catlist) ((catlist).maxlen)
600#define ffecom_concat_list_minlen_(catlist) ((catlist).minlen)
601
86fc7a6c
CB
602#define ffecom_char_args_(i,l,e) ffecom_char_args_x_((i),(l),(e),FALSE)
603#define ffecom_char_args_with_null_(i,l,e) ffecom_char_args_x_((i),(l),(e),TRUE)
604
5ff904cd
JL
605/* For each binding contour we allocate a binding_level structure
606 * which records the names defined in that contour.
607 * Contours include:
608 * 0) the global one
609 * 1) one for each function definition,
610 * where internal declarations of the parameters appear.
611 *
612 * The current meaning of a name can be found by searching the levels from
613 * the current one out to the global one.
614 */
615
616/* Note that the information in the `names' component of the global contour
617 is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */
618
619struct binding_level
620 {
c7e4ee3a
CB
621 /* A chain of _DECL nodes for all variables, constants, functions,
622 and typedef types. These are in the reverse of the order supplied.
623 */
5ff904cd
JL
624 tree names;
625
c7e4ee3a
CB
626 /* For each level (except not the global one),
627 a chain of BLOCK nodes for all the levels
628 that were entered and exited one level down. */
5ff904cd
JL
629 tree blocks;
630
c7e4ee3a
CB
631 /* The BLOCK node for this level, if one has been preallocated.
632 If 0, the BLOCK is allocated (if needed) when the level is popped. */
5ff904cd
JL
633 tree this_block;
634
635 /* The binding level which this one is contained in (inherits from). */
636 struct binding_level *level_chain;
c7e4ee3a
CB
637
638 /* 0: no ffecom_prepare_* functions called at this level yet;
639 1: ffecom_prepare* functions called, except not ffecom_prepare_end;
640 2: ffecom_prepare_end called. */
641 int prep_state;
5ff904cd
JL
642 };
643
644#define NULL_BINDING_LEVEL (struct binding_level *) NULL
645
646/* The binding level currently in effect. */
647
648static struct binding_level *current_binding_level;
649
650/* A chain of binding_level structures awaiting reuse. */
651
652static struct binding_level *free_binding_level;
653
654/* The outermost binding level, for names of file scope.
655 This is created when the compiler is started and exists
656 through the entire run. */
657
658static struct binding_level *global_binding_level;
659
660/* Binding level structures are initialized by copying this one. */
661
662static struct binding_level clear_binding_level
663=
c7e4ee3a 664{NULL, NULL, NULL, NULL_BINDING_LEVEL, 0};
5ff904cd
JL
665
666/* Language-dependent contents of an identifier. */
667
668struct lang_identifier
669 {
670 struct tree_identifier ignore;
671 tree global_value, local_value, label_value;
672 bool invented;
673 };
674
675/* Macros for access to language-specific slots in an identifier. */
676/* Each of these slots contains a DECL node or null. */
677
678/* This represents the value which the identifier has in the
679 file-scope namespace. */
680#define IDENTIFIER_GLOBAL_VALUE(NODE) \
681 (((struct lang_identifier *)(NODE))->global_value)
682/* This represents the value which the identifier has in the current
683 scope. */
684#define IDENTIFIER_LOCAL_VALUE(NODE) \
685 (((struct lang_identifier *)(NODE))->local_value)
686/* This represents the value which the identifier has as a label in
687 the current label scope. */
688#define IDENTIFIER_LABEL_VALUE(NODE) \
689 (((struct lang_identifier *)(NODE))->label_value)
690/* This is nonzero if the identifier was "made up" by g77 code. */
691#define IDENTIFIER_INVENTED(NODE) \
692 (((struct lang_identifier *)(NODE))->invented)
693
694/* In identifiers, C uses the following fields in a special way:
695 TREE_PUBLIC to record that there was a previous local extern decl.
696 TREE_USED to record that such a decl was used.
697 TREE_ADDRESSABLE to record that the address of such a decl was used. */
698
699/* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function
700 that have names. Here so we can clear out their names' definitions
701 at the end of the function. */
702
703static tree named_labels;
704
705/* A list of LABEL_DECLs from outer contexts that are currently shadowed. */
706
707static tree shadowed_labels;
708
709#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
710\f
6b55276e
CB
711/* Return the subscript expression, modified to do range-checking.
712
713 `array' is the array to be checked against.
714 `element' is the subscript expression to check.
715 `dim' is the dimension number (starting at 0).
716 `total_dims' is the total number of dimensions (0 for CHARACTER substring).
717*/
718
719static tree
720ffecom_subscript_check_ (tree array, tree element, int dim, int total_dims,
3b304f5b 721 const char *array_name)
6b55276e
CB
722{
723 tree low = TYPE_MIN_VALUE (TYPE_DOMAIN (array));
724 tree high = TYPE_MAX_VALUE (TYPE_DOMAIN (array));
725 tree cond;
726 tree die;
727 tree args;
728
729 if (element == error_mark_node)
730 return element;
731
ff852b44
CB
732 if (TREE_TYPE (low) != TREE_TYPE (element))
733 {
734 if (TYPE_PRECISION (TREE_TYPE (low))
735 > TYPE_PRECISION (TREE_TYPE (element)))
736 element = convert (TREE_TYPE (low), element);
737 else
738 {
739 low = convert (TREE_TYPE (element), low);
740 if (high)
741 high = convert (TREE_TYPE (element), high);
742 }
743 }
744
6b55276e
CB
745 element = ffecom_save_tree (element);
746 cond = ffecom_2 (LE_EXPR, integer_type_node,
747 low,
748 element);
749 if (high)
750 {
751 cond = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
752 cond,
753 ffecom_2 (LE_EXPR, integer_type_node,
754 element,
755 high));
756 }
757
758 {
759 int len;
760 char *proc;
761 char *var;
762 tree arg3;
763 tree arg2;
764 tree arg1;
765 tree arg4;
766
767 switch (total_dims)
768 {
769 case 0:
770 var = xmalloc (strlen (array_name) + 20);
3b304f5b 771 sprintf (var, "%s[%s-substring]",
6b55276e
CB
772 array_name,
773 dim ? "end" : "start");
774 len = strlen (var) + 1;
3b304f5b
ZW
775 arg1 = build_string (len, var);
776 free (var);
6b55276e
CB
777 break;
778
779 case 1:
780 len = strlen (array_name) + 1;
3b304f5b 781 arg1 = build_string (len, array_name);
6b55276e
CB
782 break;
783
784 default:
785 var = xmalloc (strlen (array_name) + 40);
3b304f5b 786 sprintf (var, "%s[subscript-%d-of-%d]",
6b55276e
CB
787 array_name,
788 dim + 1, total_dims);
789 len = strlen (var) + 1;
3b304f5b
ZW
790 arg1 = build_string (len, var);
791 free (var);
6b55276e
CB
792 break;
793 }
794
6b55276e
CB
795 TREE_TYPE (arg1)
796 = build_type_variant (build_array_type (char_type_node,
797 build_range_type
798 (integer_type_node,
799 integer_one_node,
800 build_int_2 (len, 0))),
801 1, 0);
802 TREE_CONSTANT (arg1) = 1;
803 TREE_STATIC (arg1) = 1;
804 arg1 = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg1)),
805 arg1);
806
807 /* s_rnge adds one to the element to print it, so bias against
808 that -- want to print a faithful *subscript* value. */
809 arg2 = convert (ffecom_f2c_ftnint_type_node,
810 ffecom_2 (MINUS_EXPR,
811 TREE_TYPE (element),
812 element,
813 convert (TREE_TYPE (element),
814 integer_one_node)));
815
816 proc = xmalloc ((len = strlen (input_filename)
817 + IDENTIFIER_LENGTH (DECL_NAME (current_function_decl))
818 + 2));
819
820 sprintf (&proc[0], "%s/%s",
821 input_filename,
822 IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));
823 arg3 = build_string (len, proc);
824
825 free (proc);
826
827 TREE_TYPE (arg3)
828 = build_type_variant (build_array_type (char_type_node,
829 build_range_type
830 (integer_type_node,
831 integer_one_node,
832 build_int_2 (len, 0))),
833 1, 0);
834 TREE_CONSTANT (arg3) = 1;
835 TREE_STATIC (arg3) = 1;
836 arg3 = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg3)),
837 arg3);
838
839 arg4 = convert (ffecom_f2c_ftnint_type_node,
840 build_int_2 (lineno, 0));
841
842 arg1 = build_tree_list (NULL_TREE, arg1);
843 arg2 = build_tree_list (NULL_TREE, arg2);
844 arg3 = build_tree_list (NULL_TREE, arg3);
845 arg4 = build_tree_list (NULL_TREE, arg4);
846 TREE_CHAIN (arg3) = arg4;
847 TREE_CHAIN (arg2) = arg3;
848 TREE_CHAIN (arg1) = arg2;
849
850 args = arg1;
851 }
852 die = ffecom_call_gfrt (FFECOM_gfrtRANGE,
853 args, NULL_TREE);
854 TREE_SIDE_EFFECTS (die) = 1;
855
856 element = ffecom_3 (COND_EXPR,
857 TREE_TYPE (element),
858 cond,
859 element,
860 die);
861
862 return element;
863}
864
865/* Return the computed element of an array reference.
866
ff852b44
CB
867 `item' is NULL_TREE, or the transformed pointer to the array.
868 `expr' is the original opARRAYREF expression, which is transformed
869 if `item' is NULL_TREE.
870 `want_ptr' is non-zero if a pointer to the element, instead of
6b55276e
CB
871 the element itself, is to be returned. */
872
873static tree
874ffecom_arrayref_ (tree item, ffebld expr, int want_ptr)
875{
876 ffebld dims[FFECOM_dimensionsMAX];
877 int i;
878 int total_dims;
ff852b44
CB
879 int flatten = ffe_is_flatten_arrays ();
880 int need_ptr;
6b55276e
CB
881 tree array;
882 tree element;
ff852b44
CB
883 tree tree_type;
884 tree tree_type_x;
3b304f5b 885 const char *array_name;
ff852b44
CB
886 ffetype type;
887 ffebld list;
6b55276e
CB
888
889 if (ffebld_op (ffebld_left (expr)) == FFEBLD_opSYMTER)
890 array_name = ffesymbol_text (ffebld_symter (ffebld_left (expr)));
891 else
892 array_name = "[expr?]";
893
894 /* Build up ARRAY_REFs in reverse order (since we're column major
895 here in Fortran land). */
896
ff852b44
CB
897 for (i = 0, list = ffebld_right (expr);
898 list != NULL;
899 ++i, list = ffebld_trail (list))
900 {
901 dims[i] = ffebld_head (list);
902 type = ffeinfo_type (ffebld_basictype (dims[i]),
903 ffebld_kindtype (dims[i]));
904 if (! flatten
905 && ffecom_typesize_pointer_ > ffecom_typesize_integer1_
906 && ffetype_size (type) > ffecom_typesize_integer1_)
907 /* E.g. ARRAY(INDEX), given INTEGER*8 INDEX, on a system with 64-bit
908 pointers and 32-bit integers. Do the full 64-bit pointer
909 arithmetic, for codes using arrays for nonstandard heap-like
910 work. */
911 flatten = 1;
912 }
6b55276e
CB
913
914 total_dims = i;
915
ff852b44
CB
916 need_ptr = want_ptr || flatten;
917
918 if (! item)
919 {
920 if (need_ptr)
921 item = ffecom_ptr_to_expr (ffebld_left (expr));
922 else
923 item = ffecom_expr (ffebld_left (expr));
924
925 if (item == error_mark_node)
926 return item;
927
928 if (ffeinfo_where (ffebld_info (expr)) == FFEINFO_whereFLEETING
929 && ! mark_addressable (item))
930 return error_mark_node;
931 }
932
933 if (item == error_mark_node)
934 return item;
935
6b55276e
CB
936 if (need_ptr)
937 {
ff852b44
CB
938 tree min;
939
6b55276e
CB
940 for (--i, array = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item)));
941 i >= 0;
942 --i, array = TYPE_MAIN_VARIANT (TREE_TYPE (array)))
943 {
ff852b44
CB
944 min = TYPE_MIN_VALUE (TYPE_DOMAIN (array));
945 element = ffecom_expr_ (dims[i], NULL, NULL, NULL, FALSE, TRUE);
02f06e64 946 if (flag_bounds_check)
6b55276e
CB
947 element = ffecom_subscript_check_ (array, element, i, total_dims,
948 array_name);
ff852b44
CB
949 if (element == error_mark_node)
950 return element;
951
952 /* Widen integral arithmetic as desired while preserving
953 signedness. */
954 tree_type = TREE_TYPE (element);
955 tree_type_x = tree_type;
956 if (tree_type
957 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
958 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
959 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
960
961 if (TREE_TYPE (min) != tree_type_x)
962 min = convert (tree_type_x, min);
963 if (TREE_TYPE (element) != tree_type_x)
964 element = convert (tree_type_x, element);
965
6b55276e
CB
966 item = ffecom_2 (PLUS_EXPR,
967 build_pointer_type (TREE_TYPE (array)),
968 item,
969 size_binop (MULT_EXPR,
970 size_in_bytes (TREE_TYPE (array)),
fed3cef0
RK
971 convert (sizetype,
972 fold (build (MINUS_EXPR,
973 tree_type_x,
974 element, min)))));
6b55276e
CB
975 }
976 if (! want_ptr)
977 {
978 item = ffecom_1 (INDIRECT_REF,
979 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item))),
980 item);
981 }
982 }
983 else
984 {
985 for (--i;
986 i >= 0;
987 --i)
988 {
989 array = TYPE_MAIN_VARIANT (TREE_TYPE (item));
990
991 element = ffecom_expr_ (dims[i], NULL, NULL, NULL, FALSE, TRUE);
02f06e64 992 if (flag_bounds_check)
6b55276e
CB
993 element = ffecom_subscript_check_ (array, element, i, total_dims,
994 array_name);
ff852b44
CB
995 if (element == error_mark_node)
996 return element;
997
998 /* Widen integral arithmetic as desired while preserving
999 signedness. */
1000 tree_type = TREE_TYPE (element);
1001 tree_type_x = tree_type;
1002 if (tree_type
1003 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
1004 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
1005 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
1006
1007 element = convert (tree_type_x, element);
1008
6b55276e
CB
1009 item = ffecom_2 (ARRAY_REF,
1010 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item))),
1011 item,
1012 element);
1013 }
1014 }
1015
1016 return item;
1017}
1018
5ff904cd
JL
1019/* This is like gcc's stabilize_reference -- in fact, most of the code
1020 comes from that -- but it handles the situation where the reference
1021 is going to have its subparts picked at, and it shouldn't change
1022 (or trigger extra invocations of functions in the subtrees) due to
1023 this. save_expr is a bit overzealous, because we don't need the
1024 entire thing calculated and saved like a temp. So, for DECLs, no
1025 change is needed, because these are stable aggregates, and ARRAY_REF
1026 and such might well be stable too, but for things like calculations,
1027 we do need to calculate a snapshot of a value before picking at it. */
1028
1029#if FFECOM_targetCURRENT == FFECOM_targetGCC
1030static tree
1031ffecom_stabilize_aggregate_ (tree ref)
1032{
1033 tree result;
1034 enum tree_code code = TREE_CODE (ref);
1035
1036 switch (code)
1037 {
1038 case VAR_DECL:
1039 case PARM_DECL:
1040 case RESULT_DECL:
1041 /* No action is needed in this case. */
1042 return ref;
1043
1044 case NOP_EXPR:
1045 case CONVERT_EXPR:
1046 case FLOAT_EXPR:
1047 case FIX_TRUNC_EXPR:
1048 case FIX_FLOOR_EXPR:
1049 case FIX_ROUND_EXPR:
1050 case FIX_CEIL_EXPR:
1051 result = build_nt (code, stabilize_reference (TREE_OPERAND (ref, 0)));
1052 break;
1053
1054 case INDIRECT_REF:
1055 result = build_nt (INDIRECT_REF,
1056 stabilize_reference_1 (TREE_OPERAND (ref, 0)));
1057 break;
1058
1059 case COMPONENT_REF:
1060 result = build_nt (COMPONENT_REF,
1061 stabilize_reference (TREE_OPERAND (ref, 0)),
1062 TREE_OPERAND (ref, 1));
1063 break;
1064
1065 case BIT_FIELD_REF:
1066 result = build_nt (BIT_FIELD_REF,
1067 stabilize_reference (TREE_OPERAND (ref, 0)),
1068 stabilize_reference_1 (TREE_OPERAND (ref, 1)),
1069 stabilize_reference_1 (TREE_OPERAND (ref, 2)));
1070 break;
1071
1072 case ARRAY_REF:
1073 result = build_nt (ARRAY_REF,
1074 stabilize_reference (TREE_OPERAND (ref, 0)),
1075 stabilize_reference_1 (TREE_OPERAND (ref, 1)));
1076 break;
1077
1078 case COMPOUND_EXPR:
1079 result = build_nt (COMPOUND_EXPR,
1080 stabilize_reference_1 (TREE_OPERAND (ref, 0)),
1081 stabilize_reference (TREE_OPERAND (ref, 1)));
1082 break;
1083
1084 case RTL_EXPR:
a8d0a42e 1085 abort ();
5ff904cd
JL
1086
1087
1088 default:
1089 return save_expr (ref);
1090
1091 case ERROR_MARK:
1092 return error_mark_node;
1093 }
1094
1095 TREE_TYPE (result) = TREE_TYPE (ref);
1096 TREE_READONLY (result) = TREE_READONLY (ref);
1097 TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (ref);
1098 TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (ref);
5ff904cd
JL
1099
1100 return result;
1101}
1102#endif
1103
1104/* A rip-off of gcc's convert.c convert_to_complex function,
1105 reworked to handle complex implemented as C structures
1106 (RECORD_TYPE with two fields, real and imaginary `r' and `i'). */
1107
1108#if FFECOM_targetCURRENT == FFECOM_targetGCC
1109static tree
1110ffecom_convert_to_complex_ (tree type, tree expr)
1111{
1112 register enum tree_code form = TREE_CODE (TREE_TYPE (expr));
1113 tree subtype;
1114
1115 assert (TREE_CODE (type) == RECORD_TYPE);
1116
1117 subtype = TREE_TYPE (TYPE_FIELDS (type));
1118
1119 if (form == REAL_TYPE || form == INTEGER_TYPE || form == ENUMERAL_TYPE)
1120 {
1121 expr = convert (subtype, expr);
1122 return ffecom_2 (COMPLEX_EXPR, type, expr,
1123 convert (subtype, integer_zero_node));
1124 }
1125
1126 if (form == RECORD_TYPE)
1127 {
1128 tree elt_type = TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr)));
1129 if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype))
1130 return expr;
1131 else
1132 {
1133 expr = save_expr (expr);
1134 return ffecom_2 (COMPLEX_EXPR,
1135 type,
1136 convert (subtype,
1137 ffecom_1 (REALPART_EXPR,
1138 TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))),
1139 expr)),
1140 convert (subtype,
1141 ffecom_1 (IMAGPART_EXPR,
1142 TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))),
1143 expr)));
1144 }
1145 }
1146
1147 if (form == POINTER_TYPE || form == REFERENCE_TYPE)
1148 error ("pointer value used where a complex was expected");
1149 else
1150 error ("aggregate value used where a complex was expected");
1151
1152 return ffecom_2 (COMPLEX_EXPR, type,
1153 convert (subtype, integer_zero_node),
1154 convert (subtype, integer_zero_node));
1155}
1156#endif
1157
1158/* Like gcc's convert(), but crashes if widening might happen. */
1159
1160#if FFECOM_targetCURRENT == FFECOM_targetGCC
1161static tree
1162ffecom_convert_narrow_ (type, expr)
1163 tree type, expr;
1164{
1165 register tree e = expr;
1166 register enum tree_code code = TREE_CODE (type);
1167
1168 if (type == TREE_TYPE (e)
1169 || TREE_CODE (e) == ERROR_MARK)
1170 return e;
1171 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
1172 return fold (build1 (NOP_EXPR, type, e));
1173 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
1174 || code == ERROR_MARK)
1175 return error_mark_node;
1176 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
1177 {
1178 assert ("void value not ignored as it ought to be" == NULL);
1179 return error_mark_node;
1180 }
1181 assert (code != VOID_TYPE);
1182 if ((code != RECORD_TYPE)
1183 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
1184 assert ("converting COMPLEX to REAL" == NULL);
1185 assert (code != ENUMERAL_TYPE);
1186 if (code == INTEGER_TYPE)
1187 {
a74de6ea
CB
1188 assert ((TREE_CODE (TREE_TYPE (e)) == INTEGER_TYPE
1189 && TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (e)))
1190 || (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE
1191 && (TYPE_PRECISION (type)
1192 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e))))));
5ff904cd
JL
1193 return fold (convert_to_integer (type, e));
1194 }
1195 if (code == POINTER_TYPE)
1196 {
1197 assert (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE);
1198 return fold (convert_to_pointer (type, e));
1199 }
1200 if (code == REAL_TYPE)
1201 {
1202 assert (TREE_CODE (TREE_TYPE (e)) == REAL_TYPE);
1203 assert (TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (e)));
1204 return fold (convert_to_real (type, e));
1205 }
1206 if (code == COMPLEX_TYPE)
1207 {
1208 assert (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE);
1209 assert (TYPE_PRECISION (TREE_TYPE (type)) <= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e))));
1210 return fold (convert_to_complex (type, e));
1211 }
1212 if (code == RECORD_TYPE)
1213 {
1214 assert (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE);
270fc4e8
CB
1215 /* Check that at least the first field name agrees. */
1216 assert (DECL_NAME (TYPE_FIELDS (type))
1217 == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e))));
5ff904cd
JL
1218 assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1219 <= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))));
270fc4e8
CB
1220 if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1221 == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))))
1222 return e;
5ff904cd
JL
1223 return fold (ffecom_convert_to_complex_ (type, e));
1224 }
1225
1226 assert ("conversion to non-scalar type requested" == NULL);
1227 return error_mark_node;
1228}
1229#endif
1230
1231/* Like gcc's convert(), but crashes if narrowing might happen. */
1232
1233#if FFECOM_targetCURRENT == FFECOM_targetGCC
1234static tree
1235ffecom_convert_widen_ (type, expr)
1236 tree type, expr;
1237{
1238 register tree e = expr;
1239 register enum tree_code code = TREE_CODE (type);
1240
1241 if (type == TREE_TYPE (e)
1242 || TREE_CODE (e) == ERROR_MARK)
1243 return e;
1244 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
1245 return fold (build1 (NOP_EXPR, type, e));
1246 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
1247 || code == ERROR_MARK)
1248 return error_mark_node;
1249 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
1250 {
1251 assert ("void value not ignored as it ought to be" == NULL);
1252 return error_mark_node;
1253 }
1254 assert (code != VOID_TYPE);
1255 if ((code != RECORD_TYPE)
1256 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
1257 assert ("narrowing COMPLEX to REAL" == NULL);
1258 assert (code != ENUMERAL_TYPE);
1259 if (code == INTEGER_TYPE)
1260 {
a74de6ea
CB
1261 assert ((TREE_CODE (TREE_TYPE (e)) == INTEGER_TYPE
1262 && TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (e)))
1263 || (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE
1264 && (TYPE_PRECISION (type)
1265 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e))))));
5ff904cd
JL
1266 return fold (convert_to_integer (type, e));
1267 }
1268 if (code == POINTER_TYPE)
1269 {
1270 assert (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE);
1271 return fold (convert_to_pointer (type, e));
1272 }
1273 if (code == REAL_TYPE)
1274 {
1275 assert (TREE_CODE (TREE_TYPE (e)) == REAL_TYPE);
1276 assert (TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (e)));
1277 return fold (convert_to_real (type, e));
1278 }
1279 if (code == COMPLEX_TYPE)
1280 {
1281 assert (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE);
1282 assert (TYPE_PRECISION (TREE_TYPE (type)) >= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e))));
1283 return fold (convert_to_complex (type, e));
1284 }
1285 if (code == RECORD_TYPE)
1286 {
1287 assert (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE);
270fc4e8
CB
1288 /* Check that at least the first field name agrees. */
1289 assert (DECL_NAME (TYPE_FIELDS (type))
1290 == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e))));
5ff904cd
JL
1291 assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1292 >= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))));
270fc4e8
CB
1293 if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1294 == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))))
1295 return e;
5ff904cd
JL
1296 return fold (ffecom_convert_to_complex_ (type, e));
1297 }
1298
1299 assert ("conversion to non-scalar type requested" == NULL);
1300 return error_mark_node;
1301}
1302#endif
1303
1304/* Handles making a COMPLEX type, either the standard
1305 (but buggy?) gbe way, or the safer (but less elegant?)
1306 f2c way. */
1307
1308#if FFECOM_targetCURRENT == FFECOM_targetGCC
1309static tree
1310ffecom_make_complex_type_ (tree subtype)
1311{
1312 tree type;
1313 tree realfield;
1314 tree imagfield;
1315
1316 if (ffe_is_emulate_complex ())
1317 {
1318 type = make_node (RECORD_TYPE);
1319 realfield = ffecom_decl_field (type, NULL_TREE, "r", subtype);
1320 imagfield = ffecom_decl_field (type, realfield, "i", subtype);
1321 TYPE_FIELDS (type) = realfield;
1322 layout_type (type);
1323 }
1324 else
1325 {
1326 type = make_node (COMPLEX_TYPE);
1327 TREE_TYPE (type) = subtype;
1328 layout_type (type);
1329 }
1330
1331 return type;
1332}
1333#endif
1334
1335/* Chooses either the gbe or the f2c way to build a
1336 complex constant. */
1337
1338#if FFECOM_targetCURRENT == FFECOM_targetGCC
1339static tree
1340ffecom_build_complex_constant_ (tree type, tree realpart, tree imagpart)
1341{
1342 tree bothparts;
1343
1344 if (ffe_is_emulate_complex ())
1345 {
1346 bothparts = build_tree_list (TYPE_FIELDS (type), realpart);
1347 TREE_CHAIN (bothparts) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), imagpart);
1348 bothparts = build (CONSTRUCTOR, type, NULL_TREE, bothparts);
1349 }
1350 else
1351 {
1352 bothparts = build_complex (type, realpart, imagpart);
1353 }
1354
1355 return bothparts;
1356}
1357#endif
1358
1359#if FFECOM_targetCURRENT == FFECOM_targetGCC
1360static tree
26f096f9 1361ffecom_arglist_expr_ (const char *c, ffebld expr)
5ff904cd
JL
1362{
1363 tree list;
1364 tree *plist = &list;
1365 tree trail = NULL_TREE; /* Append char length args here. */
1366 tree *ptrail = &trail;
1367 tree length;
1368 ffebld exprh;
1369 tree item;
1370 bool ptr = FALSE;
1371 tree wanted = NULL_TREE;
e2fa159e
JL
1372 static char zed[] = "0";
1373
1374 if (c == NULL)
1375 c = &zed[0];
5ff904cd
JL
1376
1377 while (expr != NULL)
1378 {
1379 if (*c != '\0')
1380 {
1381 ptr = FALSE;
1382 if (*c == '&')
1383 {
1384 ptr = TRUE;
1385 ++c;
1386 }
1387 switch (*(c++))
1388 {
1389 case '\0':
1390 ptr = TRUE;
1391 wanted = NULL_TREE;
1392 break;
1393
1394 case 'a':
1395 assert (ptr);
1396 wanted = NULL_TREE;
1397 break;
1398
1399 case 'c':
1400 wanted = ffecom_f2c_complex_type_node;
1401 break;
1402
1403 case 'd':
1404 wanted = ffecom_f2c_doublereal_type_node;
1405 break;
1406
1407 case 'e':
1408 wanted = ffecom_f2c_doublecomplex_type_node;
1409 break;
1410
1411 case 'f':
1412 wanted = ffecom_f2c_real_type_node;
1413 break;
1414
1415 case 'i':
1416 wanted = ffecom_f2c_integer_type_node;
1417 break;
1418
1419 case 'j':
1420 wanted = ffecom_f2c_longint_type_node;
1421 break;
1422
1423 default:
1424 assert ("bad argstring code" == NULL);
1425 wanted = NULL_TREE;
1426 break;
1427 }
1428 }
1429
1430 exprh = ffebld_head (expr);
1431 if (exprh == NULL)
1432 wanted = NULL_TREE;
1433
1434 if ((wanted == NULL_TREE)
1435 || (ptr
1436 && (TYPE_MODE
1437 (ffecom_tree_type[ffeinfo_basictype (ffebld_info (exprh))]
1438 [ffeinfo_kindtype (ffebld_info (exprh))])
1439 == TYPE_MODE (wanted))))
1440 *plist
1441 = build_tree_list (NULL_TREE,
1442 ffecom_arg_ptr_to_expr (exprh,
1443 &length));
1444 else
1445 {
1446 item = ffecom_arg_expr (exprh, &length);
1447 item = ffecom_convert_widen_ (wanted, item);
1448 if (ptr)
1449 {
1450 item = ffecom_1 (ADDR_EXPR,
1451 build_pointer_type (TREE_TYPE (item)),
1452 item);
1453 }
1454 *plist
1455 = build_tree_list (NULL_TREE,
1456 item);
1457 }
1458
1459 plist = &TREE_CHAIN (*plist);
1460 expr = ffebld_trail (expr);
1461 if (length != NULL_TREE)
1462 {
1463 *ptrail = build_tree_list (NULL_TREE, length);
1464 ptrail = &TREE_CHAIN (*ptrail);
1465 }
1466 }
1467
e2fa159e
JL
1468 /* We've run out of args in the call; if the implementation expects
1469 more, supply null pointers for them, which the implementation can
1470 check to see if an arg was omitted. */
1471
1472 while (*c != '\0' && *c != '0')
1473 {
1474 if (*c == '&')
1475 ++c;
1476 else
1477 assert ("missing arg to run-time routine!" == NULL);
1478
1479 switch (*(c++))
1480 {
1481 case '\0':
1482 case 'a':
1483 case 'c':
1484 case 'd':
1485 case 'e':
1486 case 'f':
1487 case 'i':
1488 case 'j':
1489 break;
1490
1491 default:
1492 assert ("bad arg string code" == NULL);
1493 break;
1494 }
1495 *plist
1496 = build_tree_list (NULL_TREE,
1497 null_pointer_node);
1498 plist = &TREE_CHAIN (*plist);
1499 }
1500
5ff904cd
JL
1501 *plist = trail;
1502
1503 return list;
1504}
1505#endif
1506
1507#if FFECOM_targetCURRENT == FFECOM_targetGCC
1508static tree
1509ffecom_widest_expr_type_ (ffebld list)
1510{
1511 ffebld item;
1512 ffebld widest = NULL;
1513 ffetype type;
1514 ffetype widest_type = NULL;
1515 tree t;
1516
1517 for (; list != NULL; list = ffebld_trail (list))
1518 {
1519 item = ffebld_head (list);
1520 if (item == NULL)
1521 continue;
1522 if ((widest != NULL)
1523 && (ffeinfo_basictype (ffebld_info (item))
1524 != ffeinfo_basictype (ffebld_info (widest))))
1525 continue;
1526 type = ffeinfo_type (ffeinfo_basictype (ffebld_info (item)),
1527 ffeinfo_kindtype (ffebld_info (item)));
1528 if ((widest == FFEINFO_kindtypeNONE)
1529 || (ffetype_size (type)
1530 > ffetype_size (widest_type)))
1531 {
1532 widest = item;
1533 widest_type = type;
1534 }
1535 }
1536
1537 assert (widest != NULL);
1538 t = ffecom_tree_type[ffeinfo_basictype (ffebld_info (widest))]
1539 [ffeinfo_kindtype (ffebld_info (widest))];
1540 assert (t != NULL_TREE);
1541 return t;
1542}
1543#endif
1544
d6cd84e0
CB
1545/* Check whether a partial overlap between two expressions is possible.
1546
1547 Can *starting* to write a portion of expr1 change the value
1548 computed (perhaps already, *partially*) by expr2?
1549
1550 Currently, this is a concern only for a COMPLEX expr1. But if it
1551 isn't in COMMON or local EQUIVALENCE, since we don't support
1552 aliasing of arguments, it isn't a concern. */
1553
1554static bool
b0791fa9 1555ffecom_possible_partial_overlap_ (ffebld expr1, ffebld expr2 ATTRIBUTE_UNUSED)
d6cd84e0
CB
1556{
1557 ffesymbol sym;
1558 ffestorag st;
1559
1560 switch (ffebld_op (expr1))
1561 {
1562 case FFEBLD_opSYMTER:
1563 sym = ffebld_symter (expr1);
1564 break;
1565
1566 case FFEBLD_opARRAYREF:
1567 if (ffebld_op (ffebld_left (expr1)) != FFEBLD_opSYMTER)
1568 return FALSE;
1569 sym = ffebld_symter (ffebld_left (expr1));
1570 break;
1571
1572 default:
1573 return FALSE;
1574 }
1575
1576 if (ffesymbol_where (sym) != FFEINFO_whereCOMMON
1577 && (ffesymbol_where (sym) != FFEINFO_whereLOCAL
1578 || ! (st = ffesymbol_storage (sym))
1579 || ! ffestorag_parent (st)))
1580 return FALSE;
1581
1582 /* It's in COMMON or local EQUIVALENCE. */
1583
1584 return TRUE;
1585}
1586
5ff904cd
JL
1587/* Check whether dest and source might overlap. ffebld versions of these
1588 might or might not be passed, will be NULL if not.
1589
1590 The test is really whether source_tree is modifiable and, if modified,
1591 might overlap destination such that the value(s) in the destination might
1592 change before it is finally modified. dest_* are the canonized
1593 destination itself. */
1594
1595#if FFECOM_targetCURRENT == FFECOM_targetGCC
1596static bool
1597ffecom_overlap_ (tree dest_decl, tree dest_offset, tree dest_size,
1598 tree source_tree, ffebld source UNUSED,
1599 bool scalar_arg)
1600{
1601 tree source_decl;
1602 tree source_offset;
1603 tree source_size;
1604 tree t;
1605
1606 if (source_tree == NULL_TREE)
1607 return FALSE;
1608
1609 switch (TREE_CODE (source_tree))
1610 {
1611 case ERROR_MARK:
1612 case IDENTIFIER_NODE:
1613 case INTEGER_CST:
1614 case REAL_CST:
1615 case COMPLEX_CST:
1616 case STRING_CST:
1617 case CONST_DECL:
1618 case VAR_DECL:
1619 case RESULT_DECL:
1620 case FIELD_DECL:
1621 case MINUS_EXPR:
1622 case MULT_EXPR:
1623 case TRUNC_DIV_EXPR:
1624 case CEIL_DIV_EXPR:
1625 case FLOOR_DIV_EXPR:
1626 case ROUND_DIV_EXPR:
1627 case TRUNC_MOD_EXPR:
1628 case CEIL_MOD_EXPR:
1629 case FLOOR_MOD_EXPR:
1630 case ROUND_MOD_EXPR:
1631 case RDIV_EXPR:
1632 case EXACT_DIV_EXPR:
1633 case FIX_TRUNC_EXPR:
1634 case FIX_CEIL_EXPR:
1635 case FIX_FLOOR_EXPR:
1636 case FIX_ROUND_EXPR:
1637 case FLOAT_EXPR:
1638 case EXPON_EXPR:
1639 case NEGATE_EXPR:
1640 case MIN_EXPR:
1641 case MAX_EXPR:
1642 case ABS_EXPR:
1643 case FFS_EXPR:
1644 case LSHIFT_EXPR:
1645 case RSHIFT_EXPR:
1646 case LROTATE_EXPR:
1647 case RROTATE_EXPR:
1648 case BIT_IOR_EXPR:
1649 case BIT_XOR_EXPR:
1650 case BIT_AND_EXPR:
1651 case BIT_ANDTC_EXPR:
1652 case BIT_NOT_EXPR:
1653 case TRUTH_ANDIF_EXPR:
1654 case TRUTH_ORIF_EXPR:
1655 case TRUTH_AND_EXPR:
1656 case TRUTH_OR_EXPR:
1657 case TRUTH_XOR_EXPR:
1658 case TRUTH_NOT_EXPR:
1659 case LT_EXPR:
1660 case LE_EXPR:
1661 case GT_EXPR:
1662 case GE_EXPR:
1663 case EQ_EXPR:
1664 case NE_EXPR:
1665 case COMPLEX_EXPR:
1666 case CONJ_EXPR:
1667 case REALPART_EXPR:
1668 case IMAGPART_EXPR:
1669 case LABEL_EXPR:
1670 case COMPONENT_REF:
1671 return FALSE;
1672
1673 case COMPOUND_EXPR:
1674 return ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1675 TREE_OPERAND (source_tree, 1), NULL,
1676 scalar_arg);
1677
1678 case MODIFY_EXPR:
1679 return ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1680 TREE_OPERAND (source_tree, 0), NULL,
1681 scalar_arg);
1682
1683 case CONVERT_EXPR:
1684 case NOP_EXPR:
1685 case NON_LVALUE_EXPR:
1686 case PLUS_EXPR:
1687 if (TREE_CODE (TREE_TYPE (source_tree)) != POINTER_TYPE)
1688 return TRUE;
1689
1690 ffecom_tree_canonize_ptr_ (&source_decl, &source_offset,
1691 source_tree);
1692 source_size = TYPE_SIZE (TREE_TYPE (TREE_TYPE (source_tree)));
1693 break;
1694
1695 case COND_EXPR:
1696 return
1697 ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1698 TREE_OPERAND (source_tree, 1), NULL,
1699 scalar_arg)
1700 || ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1701 TREE_OPERAND (source_tree, 2), NULL,
1702 scalar_arg);
1703
1704
1705 case ADDR_EXPR:
1706 ffecom_tree_canonize_ref_ (&source_decl, &source_offset,
1707 &source_size,
1708 TREE_OPERAND (source_tree, 0));
1709 break;
1710
1711 case PARM_DECL:
1712 if (TREE_CODE (TREE_TYPE (source_tree)) != POINTER_TYPE)
1713 return TRUE;
1714
1715 source_decl = source_tree;
76fa6b3b 1716 source_offset = bitsize_zero_node;
5ff904cd
JL
1717 source_size = TYPE_SIZE (TREE_TYPE (TREE_TYPE (source_tree)));
1718 break;
1719
1720 case SAVE_EXPR:
1721 case REFERENCE_EXPR:
1722 case PREDECREMENT_EXPR:
1723 case PREINCREMENT_EXPR:
1724 case POSTDECREMENT_EXPR:
1725 case POSTINCREMENT_EXPR:
1726 case INDIRECT_REF:
1727 case ARRAY_REF:
1728 case CALL_EXPR:
1729 default:
1730 return TRUE;
1731 }
1732
1733 /* Come here when source_decl, source_offset, and source_size filled
1734 in appropriately. */
1735
1736 if (source_decl == NULL_TREE)
1737 return FALSE; /* No decl involved, so no overlap. */
1738
1739 if (source_decl != dest_decl)
1740 return FALSE; /* Different decl, no overlap. */
1741
1742 if (TREE_CODE (dest_size) == ERROR_MARK)
1743 return TRUE; /* Assignment into entire assumed-size
1744 array? Shouldn't happen.... */
1745
1746 t = ffecom_2 (LE_EXPR, integer_type_node,
1747 ffecom_2 (PLUS_EXPR, TREE_TYPE (dest_offset),
1748 dest_offset,
1749 convert (TREE_TYPE (dest_offset),
1750 dest_size)),
1751 convert (TREE_TYPE (dest_offset),
1752 source_offset));
1753
1754 if (integer_onep (t))
1755 return FALSE; /* Destination precedes source. */
1756
1757 if (!scalar_arg
1758 || (source_size == NULL_TREE)
1759 || (TREE_CODE (source_size) == ERROR_MARK)
1760 || integer_zerop (source_size))
1761 return TRUE; /* No way to tell if dest follows source. */
1762
1763 t = ffecom_2 (LE_EXPR, integer_type_node,
1764 ffecom_2 (PLUS_EXPR, TREE_TYPE (source_offset),
1765 source_offset,
1766 convert (TREE_TYPE (source_offset),
1767 source_size)),
1768 convert (TREE_TYPE (source_offset),
1769 dest_offset));
1770
1771 if (integer_onep (t))
1772 return FALSE; /* Destination follows source. */
1773
1774 return TRUE; /* Destination and source overlap. */
1775}
1776#endif
1777
1778/* Check whether dest might overlap any of a list of arguments or is
1779 in a COMMON area the callee might know about (and thus modify). */
1780
1781#if FFECOM_targetCURRENT == FFECOM_targetGCC
1782static bool
1783ffecom_args_overlapping_ (tree dest_tree, ffebld dest UNUSED,
1784 tree args, tree callee_commons,
1785 bool scalar_args)
1786{
1787 tree arg;
1788 tree dest_decl;
1789 tree dest_offset;
1790 tree dest_size;
1791
1792 ffecom_tree_canonize_ref_ (&dest_decl, &dest_offset, &dest_size,
1793 dest_tree);
1794
1795 if (dest_decl == NULL_TREE)
1796 return FALSE; /* Seems unlikely! */
1797
1798 /* If the decl cannot be determined reliably, or if its in COMMON
1799 and the callee isn't known to not futz with COMMON via other
1800 means, overlap might happen. */
1801
1802 if ((TREE_CODE (dest_decl) == ERROR_MARK)
1803 || ((callee_commons != NULL_TREE)
1804 && TREE_PUBLIC (dest_decl)))
1805 return TRUE;
1806
1807 for (; args != NULL_TREE; args = TREE_CHAIN (args))
1808 {
1809 if (((arg = TREE_VALUE (args)) != NULL_TREE)
1810 && ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1811 arg, NULL, scalar_args))
1812 return TRUE;
1813 }
1814
1815 return FALSE;
1816}
1817#endif
1818
1819/* Build a string for a variable name as used by NAMELIST. This means that
1820 if we're using the f2c library, we build an uppercase string, since
1821 f2c does this. */
1822
1823#if FFECOM_targetCURRENT == FFECOM_targetGCC
1824static tree
26f096f9 1825ffecom_build_f2c_string_ (int i, const char *s)
5ff904cd
JL
1826{
1827 if (!ffe_is_f2c_library ())
1828 return build_string (i, s);
1829
1830 {
1831 char *tmp;
26f096f9 1832 const char *p;
5ff904cd
JL
1833 char *q;
1834 char space[34];
1835 tree t;
1836
1837 if (((size_t) i) > ARRAY_SIZE (space))
1838 tmp = malloc_new_ks (malloc_pool_image (), "f2c_string", i);
1839 else
1840 tmp = &space[0];
1841
1842 for (p = s, q = tmp; *p != '\0'; ++p, ++q)
f6bbde28 1843 *q = TOUPPER (*p);
5ff904cd
JL
1844 *q = '\0';
1845
1846 t = build_string (i, tmp);
1847
1848 if (((size_t) i) > ARRAY_SIZE (space))
1849 malloc_kill_ks (malloc_pool_image (), tmp, i);
1850
1851 return t;
1852 }
1853}
1854
1855#endif
1856/* Returns CALL_EXPR or equivalent with given type (pass NULL_TREE for
1857 type to just get whatever the function returns), handling the
1858 f2c value-returning convention, if required, by prepending
1859 to the arglist a pointer to a temporary to receive the return value. */
1860
1861#if FFECOM_targetCURRENT == FFECOM_targetGCC
1862static tree
1863ffecom_call_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex,
1864 tree type, tree args, tree dest_tree,
1865 ffebld dest, bool *dest_used, tree callee_commons,
c7e4ee3a 1866 bool scalar_args, tree hook)
5ff904cd
JL
1867{
1868 tree item;
1869 tree tempvar;
1870
1871 if (dest_used != NULL)
1872 *dest_used = FALSE;
1873
1874 if (is_f2c_complex)
1875 {
1876 if ((dest_used == NULL)
1877 || (dest == NULL)
1878 || (ffeinfo_basictype (ffebld_info (dest))
1879 != FFEINFO_basictypeCOMPLEX)
1880 || (ffeinfo_kindtype (ffebld_info (dest)) != kt)
1881 || ((type != NULL_TREE) && (TREE_TYPE (dest_tree) != type))
1882 || ffecom_args_overlapping_ (dest_tree, dest, args,
1883 callee_commons,
1884 scalar_args))
1885 {
c7e4ee3a
CB
1886#ifdef HOHO
1887 tempvar = ffecom_make_tempvar (ffecom_tree_type
5ff904cd
JL
1888 [FFEINFO_basictypeCOMPLEX][kt],
1889 FFETARGET_charactersizeNONE,
c7e4ee3a
CB
1890 -1);
1891#else
1892 tempvar = hook;
1893 assert (tempvar);
1894#endif
5ff904cd
JL
1895 }
1896 else
1897 {
1898 *dest_used = TRUE;
1899 tempvar = dest_tree;
1900 type = NULL_TREE;
1901 }
1902
1903 item
1904 = build_tree_list (NULL_TREE,
1905 ffecom_1 (ADDR_EXPR,
c7e4ee3a 1906 build_pointer_type (TREE_TYPE (tempvar)),
5ff904cd
JL
1907 tempvar));
1908 TREE_CHAIN (item) = args;
1909
1910 item = ffecom_3s (CALL_EXPR, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), fn,
1911 item, NULL_TREE);
1912
1913 if (tempvar != dest_tree)
1914 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), item, tempvar);
1915 }
1916 else
1917 item = ffecom_3s (CALL_EXPR, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), fn,
1918 args, NULL_TREE);
1919
1920 if ((type != NULL_TREE) && (TREE_TYPE (item) != type))
1921 item = ffecom_convert_narrow_ (type, item);
1922
1923 return item;
1924}
1925#endif
1926
1927/* Given two arguments, transform them and make a call to the given
1928 function via ffecom_call_. */
1929
1930#if FFECOM_targetCURRENT == FFECOM_targetGCC
1931static tree
1932ffecom_call_binop_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex,
1933 tree type, ffebld left, ffebld right,
1934 tree dest_tree, ffebld dest, bool *dest_used,
95eb4fd9 1935 tree callee_commons, bool scalar_args, bool ref, tree hook)
5ff904cd
JL
1936{
1937 tree left_tree;
1938 tree right_tree;
1939 tree left_length;
1940 tree right_length;
1941
95eb4fd9
TM
1942 if (ref)
1943 {
1944 /* Pass arguments by reference. */
1945 left_tree = ffecom_arg_ptr_to_expr (left, &left_length);
1946 right_tree = ffecom_arg_ptr_to_expr (right, &right_length);
1947 }
1948 else
1949 {
1950 /* Pass arguments by value. */
1951 left_tree = ffecom_arg_expr (left, &left_length);
1952 right_tree = ffecom_arg_expr (right, &right_length);
1953 }
1954
5ff904cd
JL
1955
1956 left_tree = build_tree_list (NULL_TREE, left_tree);
1957 right_tree = build_tree_list (NULL_TREE, right_tree);
1958 TREE_CHAIN (left_tree) = right_tree;
1959
1960 if (left_length != NULL_TREE)
1961 {
1962 left_length = build_tree_list (NULL_TREE, left_length);
1963 TREE_CHAIN (right_tree) = left_length;
1964 }
1965
1966 if (right_length != NULL_TREE)
1967 {
1968 right_length = build_tree_list (NULL_TREE, right_length);
1969 if (left_length != NULL_TREE)
1970 TREE_CHAIN (left_length) = right_length;
1971 else
1972 TREE_CHAIN (right_tree) = right_length;
1973 }
1974
1975 return ffecom_call_ (fn, kt, is_f2c_complex, type, left_tree,
1976 dest_tree, dest, dest_used, callee_commons,
c7e4ee3a 1977 scalar_args, hook);
5ff904cd
JL
1978}
1979#endif
1980
c7e4ee3a 1981/* Return ptr/length args for char subexpression
5ff904cd
JL
1982
1983 Handles CHARACTER-type CONTER, SYMTER, SUBSTR, ARRAYREF, and FUNCREF
1984 subexpressions by constructing the appropriate trees for the ptr-to-
1985 character-text and length-of-character-text arguments in a calling
86fc7a6c
CB
1986 sequence.
1987
1988 Note that if with_null is TRUE, and the expression is an opCONTER,
1989 a null byte is appended to the string. */
5ff904cd
JL
1990
1991#if FFECOM_targetCURRENT == FFECOM_targetGCC
1992static void
86fc7a6c 1993ffecom_char_args_x_ (tree *xitem, tree *length, ffebld expr, bool with_null)
5ff904cd
JL
1994{
1995 tree item;
1996 tree high;
1997 ffetargetCharacter1 val;
86fc7a6c 1998 ffetargetCharacterSize newlen;
5ff904cd
JL
1999
2000 switch (ffebld_op (expr))
2001 {
2002 case FFEBLD_opCONTER:
2003 val = ffebld_constant_character1 (ffebld_conter (expr));
86fc7a6c
CB
2004 newlen = ffetarget_length_character1 (val);
2005 if (with_null)
2006 {
c7e4ee3a 2007 /* Begin FFETARGET-NULL-KLUDGE. */
86fc7a6c 2008 if (newlen != 0)
c7e4ee3a 2009 ++newlen;
86fc7a6c
CB
2010 }
2011 *length = build_int_2 (newlen, 0);
5ff904cd 2012 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
86fc7a6c 2013 high = build_int_2 (newlen, 0);
5ff904cd 2014 TREE_TYPE (high) = ffecom_f2c_ftnlen_type_node;
c7e4ee3a 2015 item = build_string (newlen,
5ff904cd 2016 ffetarget_text_character1 (val));
c7e4ee3a 2017 /* End FFETARGET-NULL-KLUDGE. */
5ff904cd
JL
2018 TREE_TYPE (item)
2019 = build_type_variant
2020 (build_array_type
2021 (char_type_node,
2022 build_range_type
2023 (ffecom_f2c_ftnlen_type_node,
2024 ffecom_f2c_ftnlen_one_node,
2025 high)),
2026 1, 0);
2027 TREE_CONSTANT (item) = 1;
2028 TREE_STATIC (item) = 1;
2029 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
2030 item);
2031 break;
2032
2033 case FFEBLD_opSYMTER:
2034 {
2035 ffesymbol s = ffebld_symter (expr);
2036
2037 item = ffesymbol_hook (s).decl_tree;
2038 if (item == NULL_TREE)
2039 {
2040 s = ffecom_sym_transform_ (s);
2041 item = ffesymbol_hook (s).decl_tree;
2042 }
2043 if (ffesymbol_kind (s) == FFEINFO_kindENTITY)
2044 {
2045 if (ffesymbol_size (s) == FFETARGET_charactersizeNONE)
2046 *length = ffesymbol_hook (s).length_tree;
2047 else
2048 {
2049 *length = build_int_2 (ffesymbol_size (s), 0);
2050 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
2051 }
2052 }
2053 else if (item == error_mark_node)
2054 *length = error_mark_node;
c7e4ee3a
CB
2055 else
2056 /* FFEINFO_kindFUNCTION. */
5ff904cd
JL
2057 *length = NULL_TREE;
2058 if (!ffesymbol_hook (s).addr
2059 && (item != error_mark_node))
2060 item = ffecom_1 (ADDR_EXPR,
2061 build_pointer_type (TREE_TYPE (item)),
2062 item);
2063 }
2064 break;
2065
2066 case FFEBLD_opARRAYREF:
2067 {
5ff904cd 2068 ffecom_char_args_ (&item, length, ffebld_left (expr));
5ff904cd
JL
2069
2070 if (item == error_mark_node || *length == error_mark_node)
2071 {
2072 item = *length = error_mark_node;
2073 break;
2074 }
2075
6b55276e 2076 item = ffecom_arrayref_ (item, expr, 1);
5ff904cd
JL
2077 }
2078 break;
2079
2080 case FFEBLD_opSUBSTR:
2081 {
2082 ffebld start;
2083 ffebld end;
2084 ffebld thing = ffebld_right (expr);
2085 tree start_tree;
2086 tree end_tree;
3b304f5b 2087 const char *char_name;
6b55276e
CB
2088 ffebld left_symter;
2089 tree array;
5ff904cd
JL
2090
2091 assert (ffebld_op (thing) == FFEBLD_opITEM);
2092 start = ffebld_head (thing);
2093 thing = ffebld_trail (thing);
2094 assert (ffebld_trail (thing) == NULL);
2095 end = ffebld_head (thing);
2096
6b55276e
CB
2097 /* Determine name for pretty-printing range-check errors. */
2098 for (left_symter = ffebld_left (expr);
2099 left_symter && ffebld_op (left_symter) == FFEBLD_opARRAYREF;
2100 left_symter = ffebld_left (left_symter))
2101 ;
2102 if (ffebld_op (left_symter) == FFEBLD_opSYMTER)
2103 char_name = ffesymbol_text (ffebld_symter (left_symter));
2104 else
2105 char_name = "[expr?]";
2106
5ff904cd 2107 ffecom_char_args_ (&item, length, ffebld_left (expr));
5ff904cd
JL
2108
2109 if (item == error_mark_node || *length == error_mark_node)
2110 {
2111 item = *length = error_mark_node;
2112 break;
2113 }
2114
6b55276e
CB
2115 array = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item)));
2116
ff852b44
CB
2117 /* ~~~~Handle INTEGER*8 start/end, a la FFEBLD_opARRAYREF. */
2118
5ff904cd
JL
2119 if (start == NULL)
2120 {
2121 if (end == NULL)
2122 ;
2123 else
2124 {
6b55276e 2125 end_tree = ffecom_expr (end);
02f06e64 2126 if (flag_bounds_check)
6b55276e
CB
2127 end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0,
2128 char_name);
5ff904cd 2129 end_tree = convert (ffecom_f2c_ftnlen_type_node,
6b55276e 2130 end_tree);
5ff904cd
JL
2131
2132 if (end_tree == error_mark_node)
2133 {
2134 item = *length = error_mark_node;
2135 break;
2136 }
2137
2138 *length = end_tree;
2139 }
2140 }
2141 else
2142 {
6b55276e 2143 start_tree = ffecom_expr (start);
02f06e64 2144 if (flag_bounds_check)
6b55276e
CB
2145 start_tree = ffecom_subscript_check_ (array, start_tree, 0, 0,
2146 char_name);
5ff904cd 2147 start_tree = convert (ffecom_f2c_ftnlen_type_node,
6b55276e 2148 start_tree);
5ff904cd
JL
2149
2150 if (start_tree == error_mark_node)
2151 {
2152 item = *length = error_mark_node;
2153 break;
2154 }
2155
2156 start_tree = ffecom_save_tree (start_tree);
2157
2158 item = ffecom_2 (PLUS_EXPR, TREE_TYPE (item),
2159 item,
2160 ffecom_2 (MINUS_EXPR,
2161 TREE_TYPE (start_tree),
2162 start_tree,
2163 ffecom_f2c_ftnlen_one_node));
2164
2165 if (end == NULL)
2166 {
2167 *length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
2168 ffecom_f2c_ftnlen_one_node,
2169 ffecom_2 (MINUS_EXPR,
2170 ffecom_f2c_ftnlen_type_node,
2171 *length,
2172 start_tree));
2173 }
2174 else
2175 {
6b55276e 2176 end_tree = ffecom_expr (end);
02f06e64 2177 if (flag_bounds_check)
6b55276e
CB
2178 end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0,
2179 char_name);
5ff904cd 2180 end_tree = convert (ffecom_f2c_ftnlen_type_node,
6b55276e 2181 end_tree);
5ff904cd
JL
2182
2183 if (end_tree == error_mark_node)
2184 {
2185 item = *length = error_mark_node;
2186 break;
2187 }
2188
2189 *length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
2190 ffecom_f2c_ftnlen_one_node,
2191 ffecom_2 (MINUS_EXPR,
2192 ffecom_f2c_ftnlen_type_node,
2193 end_tree, start_tree));
2194 }
2195 }
2196 }
2197 break;
2198
2199 case FFEBLD_opFUNCREF:
2200 {
2201 ffesymbol s = ffebld_symter (ffebld_left (expr));
2202 tree tempvar;
2203 tree args;
2204 ffetargetCharacterSize size = ffeinfo_size (ffebld_info (expr));
2205 ffecomGfrt ix;
2206
2207 if (size == FFETARGET_charactersizeNONE)
c7e4ee3a
CB
2208 /* ~~Kludge alert! This should someday be fixed. */
2209 size = 24;
5ff904cd
JL
2210
2211 *length = build_int_2 (size, 0);
2212 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
2213
2214 if (ffeinfo_where (ffebld_info (ffebld_left (expr)))
2215 == FFEINFO_whereINTRINSIC)
2216 {
2217 if (size == 1)
c7e4ee3a
CB
2218 {
2219 /* Invocation of an intrinsic returning CHARACTER*1. */
5ff904cd
JL
2220 item = ffecom_expr_intrinsic_ (expr, NULL_TREE,
2221 NULL, NULL);
2222 break;
2223 }
2224 ix = ffeintrin_gfrt_direct (ffebld_symter_implementation (ffebld_left (expr)));
2225 assert (ix != FFECOM_gfrt);
2226 item = ffecom_gfrt_tree_ (ix);
2227 }
2228 else
2229 {
2230 ix = FFECOM_gfrt;
2231 item = ffesymbol_hook (s).decl_tree;
2232 if (item == NULL_TREE)
2233 {
2234 s = ffecom_sym_transform_ (s);
2235 item = ffesymbol_hook (s).decl_tree;
2236 }
2237 if (item == error_mark_node)
2238 {
2239 item = *length = error_mark_node;
2240 break;
2241 }
2242
2243 if (!ffesymbol_hook (s).addr)
2244 item = ffecom_1_fn (item);
2245 }
2246
c7e4ee3a 2247#ifdef HOHO
5ff904cd 2248 tempvar = ffecom_push_tempvar (char_type_node, size, -1, TRUE);
c7e4ee3a
CB
2249#else
2250 tempvar = ffebld_nonter_hook (expr);
2251 assert (tempvar);
2252#endif
5ff904cd
JL
2253 tempvar = ffecom_1 (ADDR_EXPR,
2254 build_pointer_type (TREE_TYPE (tempvar)),
2255 tempvar);
2256
5ff904cd
JL
2257 args = build_tree_list (NULL_TREE, tempvar);
2258
2259 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT) /* Sfunc args by value. */
2260 TREE_CHAIN (args) = ffecom_list_expr (ffebld_right (expr));
2261 else
2262 {
2263 TREE_CHAIN (args) = build_tree_list (NULL_TREE, *length);
2264 if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC)
2265 {
2266 TREE_CHAIN (TREE_CHAIN (args))
2267 = ffecom_arglist_expr_ (ffecom_gfrt_args_ (ix),
2268 ffebld_right (expr));
2269 }
2270 else
2271 {
2272 TREE_CHAIN (TREE_CHAIN (args))
2273 = ffecom_list_ptr_to_expr (ffebld_right (expr));
2274 }
2275 }
2276
2277 item = ffecom_3s (CALL_EXPR,
2278 TREE_TYPE (TREE_TYPE (TREE_TYPE (item))),
2279 item, args, NULL_TREE);
2280 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), item,
2281 tempvar);
5ff904cd
JL
2282 }
2283 break;
2284
2285 case FFEBLD_opCONVERT:
2286
5ff904cd 2287 ffecom_char_args_ (&item, length, ffebld_left (expr));
5ff904cd
JL
2288
2289 if (item == error_mark_node || *length == error_mark_node)
2290 {
2291 item = *length = error_mark_node;
2292 break;
2293 }
2294
2295 if ((ffebld_size_known (ffebld_left (expr))
2296 == FFETARGET_charactersizeNONE)
2297 || (ffebld_size_known (ffebld_left (expr)) < (ffebld_size (expr))))
2298 { /* Possible blank-padding needed, copy into
2299 temporary. */
2300 tree tempvar;
2301 tree args;
2302 tree newlen;
2303
c7e4ee3a
CB
2304#ifdef HOHO
2305 tempvar = ffecom_make_tempvar (char_type_node,
2306 ffebld_size (expr), -1);
2307#else
2308 tempvar = ffebld_nonter_hook (expr);
2309 assert (tempvar);
2310#endif
5ff904cd
JL
2311 tempvar = ffecom_1 (ADDR_EXPR,
2312 build_pointer_type (TREE_TYPE (tempvar)),
2313 tempvar);
2314
2315 newlen = build_int_2 (ffebld_size (expr), 0);
2316 TREE_TYPE (newlen) = ffecom_f2c_ftnlen_type_node;
2317
2318 args = build_tree_list (NULL_TREE, tempvar);
2319 TREE_CHAIN (args) = build_tree_list (NULL_TREE, item);
2320 TREE_CHAIN (TREE_CHAIN (args)) = build_tree_list (NULL_TREE, newlen);
2321 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (args)))
2322 = build_tree_list (NULL_TREE, *length);
2323
c7e4ee3a 2324 item = ffecom_call_gfrt (FFECOM_gfrtCOPY, args, NULL_TREE);
5ff904cd
JL
2325 TREE_SIDE_EFFECTS (item) = 1;
2326 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), fold (item),
2327 tempvar);
2328 *length = newlen;
2329 }
2330 else
2331 { /* Just truncate the length. */
2332 *length = build_int_2 (ffebld_size (expr), 0);
2333 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
2334 }
2335 break;
2336
2337 default:
2338 assert ("bad op for single char arg expr" == NULL);
2339 item = NULL_TREE;
2340 break;
2341 }
2342
2343 *xitem = item;
2344}
2345#endif
2346
2347/* Check the size of the type to be sure it doesn't overflow the
2348 "portable" capacities of the compiler back end. `dummy' types
2349 can generally overflow the normal sizes as long as the computations
2350 themselves don't overflow. A particular target of the back end
2351 must still enforce its size requirements, though, and the back
2352 end takes care of this in stor-layout.c. */
2353
2354#if FFECOM_targetCURRENT == FFECOM_targetGCC
2355static tree
2356ffecom_check_size_overflow_ (ffesymbol s, tree type, bool dummy)
2357{
2358 if (TREE_CODE (type) == ERROR_MARK)
2359 return type;
2360
2361 if (TYPE_SIZE (type) == NULL_TREE)
2362 return type;
2363
2364 if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
2365 return type;
2366
2367 if ((tree_int_cst_sgn (TYPE_SIZE (type)) < 0)
2b0c2df0
CB
2368 || (!dummy && (((TREE_INT_CST_HIGH (TYPE_SIZE (type)) != 0))
2369 || TREE_OVERFLOW (TYPE_SIZE (type)))))
5ff904cd
JL
2370 {
2371 ffebad_start (FFEBAD_ARRAY_LARGE);
2372 ffebad_string (ffesymbol_text (s));
2373 ffebad_here (0, ffesymbol_where_line (s), ffesymbol_where_column (s));
2374 ffebad_finish ();
2375
2376 return error_mark_node;
2377 }
2378
2379 return type;
2380}
2381#endif
2382
2383/* Builds a length argument (PARM_DECL). Also wraps type in an array type
2384 where the dimension info is (1:size) where <size> is ffesymbol_size(s) if
2385 known, length_arg if not known (FFETARGET_charactersizeNONE). */
2386
2387#if FFECOM_targetCURRENT == FFECOM_targetGCC
2388static tree
2389ffecom_char_enhance_arg_ (tree *xtype, ffesymbol s)
2390{
2391 ffetargetCharacterSize sz = ffesymbol_size (s);
2392 tree highval;
2393 tree tlen;
2394 tree type = *xtype;
2395
2396 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT)
2397 tlen = NULL_TREE; /* A statement function, no length passed. */
2398 else
2399 {
2400 if (ffesymbol_where (s) == FFEINFO_whereDUMMY)
2401 tlen = ffecom_get_invented_identifier ("__g77_length_%s",
14657de8 2402 ffesymbol_text (s));
5ff904cd 2403 else
14657de8 2404 tlen = ffecom_get_invented_identifier ("__g77_%s", "length");
5ff904cd
JL
2405 tlen = build_decl (PARM_DECL, tlen, ffecom_f2c_ftnlen_type_node);
2406#if BUILT_FOR_270
2407 DECL_ARTIFICIAL (tlen) = 1;
2408#endif
2409 }
2410
2411 if (sz == FFETARGET_charactersizeNONE)
2412 {
2413 assert (tlen != NULL_TREE);
2b0c2df0 2414 highval = variable_size (tlen);
5ff904cd
JL
2415 }
2416 else
2417 {
2418 highval = build_int_2 (sz, 0);
2419 TREE_TYPE (highval) = ffecom_f2c_ftnlen_type_node;
2420 }
2421
2422 type = build_array_type (type,
2423 build_range_type (ffecom_f2c_ftnlen_type_node,
2424 ffecom_f2c_ftnlen_one_node,
2425 highval));
2426
2427 *xtype = type;
2428 return tlen;
2429}
2430
2431#endif
2432/* ffecom_concat_list_gather_ -- Gather list of concatenated string exprs
2433
2434 ffecomConcatList_ catlist;
2435 ffebld expr; // expr of CHARACTER basictype.
2436 ffetargetCharacterSize max; // max chars to gather or _...NONE if no max
2437 catlist = ffecom_concat_list_gather_(catlist,expr,max);
2438
2439 Scans expr for character subexpressions, updates and returns catlist
2440 accordingly. */
2441
2442#if FFECOM_targetCURRENT == FFECOM_targetGCC
2443static ffecomConcatList_
2444ffecom_concat_list_gather_ (ffecomConcatList_ catlist, ffebld expr,
2445 ffetargetCharacterSize max)
2446{
2447 ffetargetCharacterSize sz;
2448
2449recurse: /* :::::::::::::::::::: */
2450
2451 if (expr == NULL)
2452 return catlist;
2453
2454 if ((max != FFETARGET_charactersizeNONE) && (catlist.minlen >= max))
2455 return catlist; /* Don't append any more items. */
2456
2457 switch (ffebld_op (expr))
2458 {
2459 case FFEBLD_opCONTER:
2460 case FFEBLD_opSYMTER:
2461 case FFEBLD_opARRAYREF:
2462 case FFEBLD_opFUNCREF:
2463 case FFEBLD_opSUBSTR:
2464 case FFEBLD_opCONVERT: /* Callers should strip this off beforehand
2465 if they don't need to preserve it. */
2466 if (catlist.count == catlist.max)
2467 { /* Make a (larger) list. */
2468 ffebld *newx;
2469 int newmax;
2470
2471 newmax = (catlist.max == 0) ? 8 : catlist.max * 2;
2472 newx = malloc_new_ks (malloc_pool_image (), "catlist",
2473 newmax * sizeof (newx[0]));
2474 if (catlist.max != 0)
2475 {
2476 memcpy (newx, catlist.exprs, catlist.max * sizeof (newx[0]));
2477 malloc_kill_ks (malloc_pool_image (), catlist.exprs,
2478 catlist.max * sizeof (newx[0]));
2479 }
2480 catlist.max = newmax;
2481 catlist.exprs = newx;
2482 }
2483 if ((sz = ffebld_size_known (expr)) != FFETARGET_charactersizeNONE)
2484 catlist.minlen += sz;
2485 else
2486 ++catlist.minlen; /* Not true for F90; can be 0 length. */
2487 if ((sz = ffebld_size_max (expr)) == FFETARGET_charactersizeNONE)
2488 catlist.maxlen = sz;
2489 else
2490 catlist.maxlen += sz;
2491 if ((max != FFETARGET_charactersizeNONE) && (catlist.minlen > max))
2492 { /* This item overlaps (or is beyond) the end
2493 of the destination. */
2494 switch (ffebld_op (expr))
2495 {
2496 case FFEBLD_opCONTER:
2497 case FFEBLD_opSYMTER:
2498 case FFEBLD_opARRAYREF:
2499 case FFEBLD_opFUNCREF:
2500 case FFEBLD_opSUBSTR:
c7e4ee3a
CB
2501 /* ~~Do useful truncations here. */
2502 break;
5ff904cd
JL
2503
2504 default:
2505 assert ("op changed or inconsistent switches!" == NULL);
2506 break;
2507 }
2508 }
2509 catlist.exprs[catlist.count++] = expr;
2510 return catlist;
2511
2512 case FFEBLD_opPAREN:
2513 expr = ffebld_left (expr);
2514 goto recurse; /* :::::::::::::::::::: */
2515
2516 case FFEBLD_opCONCATENATE:
2517 catlist = ffecom_concat_list_gather_ (catlist, ffebld_left (expr), max);
2518 expr = ffebld_right (expr);
2519 goto recurse; /* :::::::::::::::::::: */
2520
2521#if 0 /* Breaks passing small actual arg to larger
2522 dummy arg of sfunc */
2523 case FFEBLD_opCONVERT:
2524 expr = ffebld_left (expr);
2525 {
2526 ffetargetCharacterSize cmax;
2527
2528 cmax = catlist.len + ffebld_size_known (expr);
2529
2530 if ((max == FFETARGET_charactersizeNONE) || (max > cmax))
2531 max = cmax;
2532 }
2533 goto recurse; /* :::::::::::::::::::: */
2534#endif
2535
2536 case FFEBLD_opANY:
2537 return catlist;
2538
2539 default:
2540 assert ("bad op in _gather_" == NULL);
2541 return catlist;
2542 }
2543}
2544
2545#endif
2546/* ffecom_concat_list_kill_ -- Kill list of concatenated string exprs
2547
2548 ffecomConcatList_ catlist;
2549 ffecom_concat_list_kill_(catlist);
2550
2551 Anything allocated within the list info is deallocated. */
2552
2553#if FFECOM_targetCURRENT == FFECOM_targetGCC
2554static void
2555ffecom_concat_list_kill_ (ffecomConcatList_ catlist)
2556{
2557 if (catlist.max != 0)
2558 malloc_kill_ks (malloc_pool_image (), catlist.exprs,
2559 catlist.max * sizeof (catlist.exprs[0]));
2560}
2561
2562#endif
c7e4ee3a 2563/* Make list of concatenated string exprs.
5ff904cd
JL
2564
2565 Returns a flattened list of concatenated subexpressions given a
2566 tree of such expressions. */
2567
2568#if FFECOM_targetCURRENT == FFECOM_targetGCC
2569static ffecomConcatList_
2570ffecom_concat_list_new_ (ffebld expr, ffetargetCharacterSize max)
2571{
2572 ffecomConcatList_ catlist;
2573
2574 catlist.maxlen = catlist.minlen = catlist.max = catlist.count = 0;
2575 return ffecom_concat_list_gather_ (catlist, expr, max);
2576}
2577
2578#endif
2579
2580/* Provide some kind of useful info on member of aggregate area,
2581 since current g77/gcc technology does not provide debug info
2582 on these members. */
2583
2584#if FFECOM_targetCURRENT == FFECOM_targetGCC
2585static void
26f096f9 2586ffecom_debug_kludge_ (tree aggr, const char *aggr_type, ffesymbol member,
5ff904cd
JL
2587 tree member_type UNUSED, ffetargetOffset offset)
2588{
2589 tree value;
2590 tree decl;
2591 int len;
2592 char *buff;
2593 char space[120];
2594#if 0
2595 tree type_id;
2596
2597 for (type_id = member_type;
2598 TREE_CODE (type_id) != IDENTIFIER_NODE;
2599 )
2600 {
2601 switch (TREE_CODE (type_id))
2602 {
2603 case INTEGER_TYPE:
2604 case REAL_TYPE:
2605 type_id = TYPE_NAME (type_id);
2606 break;
2607
2608 case ARRAY_TYPE:
2609 case COMPLEX_TYPE:
2610 type_id = TREE_TYPE (type_id);
2611 break;
2612
2613 default:
2614 assert ("no IDENTIFIER_NODE for type!" == NULL);
2615 type_id = error_mark_node;
2616 break;
2617 }
2618 }
2619#endif
2620
2621 if (ffecom_transform_only_dummies_
2622 || !ffe_is_debug_kludge ())
2623 return; /* Can't do this yet, maybe later. */
2624
2625 len = 60
2626 + strlen (aggr_type)
2627 + IDENTIFIER_LENGTH (DECL_NAME (aggr));
2628#if 0
2629 + IDENTIFIER_LENGTH (type_id);
2630#endif
2631
2632 if (((size_t) len) >= ARRAY_SIZE (space))
2633 buff = malloc_new_ks (malloc_pool_image (), "debug_kludge", len + 1);
2634 else
2635 buff = &space[0];
2636
2637 sprintf (&buff[0], "At (%s) `%s' plus %ld bytes",
2638 aggr_type,
2639 IDENTIFIER_POINTER (DECL_NAME (aggr)),
2640 (long int) offset);
2641
2642 value = build_string (len, buff);
2643 TREE_TYPE (value)
2644 = build_type_variant (build_array_type (char_type_node,
2645 build_range_type
2646 (integer_type_node,
2647 integer_one_node,
2648 build_int_2 (strlen (buff), 0))),
2649 1, 0);
2650 decl = build_decl (VAR_DECL,
2651 ffecom_get_identifier_ (ffesymbol_text (member)),
2652 TREE_TYPE (value));
2653 TREE_CONSTANT (decl) = 1;
2654 TREE_STATIC (decl) = 1;
2655 DECL_INITIAL (decl) = error_mark_node;
2656 DECL_IN_SYSTEM_HEADER (decl) = 1; /* Don't let -Wunused complain. */
2657 decl = start_decl (decl, FALSE);
2658 finish_decl (decl, value, FALSE);
2659
2660 if (buff != &space[0])
2661 malloc_kill_ks (malloc_pool_image (), buff, len + 1);
2662}
2663#endif
2664
2665/* ffecom_do_entry_ -- Do compilation of a particular entrypoint
2666
2667 ffesymbol fn; // the SUBROUTINE, FUNCTION, or ENTRY symbol itself
2668 int i; // entry# for this entrypoint (used by master fn)
2669 ffecom_do_entrypoint_(s,i);
2670
2671 Makes a public entry point that calls our private master fn (already
2672 compiled). */
2673
2674#if FFECOM_targetCURRENT == FFECOM_targetGCC
2675static void
2676ffecom_do_entry_ (ffesymbol fn, int entrynum)
2677{
2678 ffebld item;
2679 tree type; /* Type of function. */
2680 tree multi_retval; /* Var holding return value (union). */
2681 tree result; /* Var holding result. */
2682 ffeinfoBasictype bt;
2683 ffeinfoKindtype kt;
2684 ffeglobal g;
2685 ffeglobalType gt;
2686 bool charfunc; /* All entry points return same type
2687 CHARACTER. */
2688 bool cmplxfunc; /* Use f2c way of returning COMPLEX. */
2689 bool multi; /* Master fn has multiple return types. */
2690 bool altreturning = FALSE; /* This entry point has alternate returns. */
44d2eabc 2691 int old_lineno = lineno;
3b304f5b 2692 const char *old_input_filename = input_filename;
44d2eabc
JL
2693
2694 input_filename = ffesymbol_where_filename (fn);
2695 lineno = ffesymbol_where_filelinenum (fn);
5ff904cd 2696
5ff904cd
JL
2697 ffecom_doing_entry_ = TRUE; /* Don't bother with array dimensions. */
2698
2699 switch (ffecom_primary_entry_kind_)
2700 {
2701 case FFEINFO_kindFUNCTION:
2702
2703 /* Determine actual return type for function. */
2704
2705 gt = FFEGLOBAL_typeFUNC;
2706 bt = ffesymbol_basictype (fn);
2707 kt = ffesymbol_kindtype (fn);
2708 if (bt == FFEINFO_basictypeNONE)
2709 {
2710 ffeimplic_establish_symbol (fn);
2711 if (ffesymbol_funcresult (fn) != NULL)
2712 ffeimplic_establish_symbol (ffesymbol_funcresult (fn));
2713 bt = ffesymbol_basictype (fn);
2714 kt = ffesymbol_kindtype (fn);
2715 }
2716
2717 if (bt == FFEINFO_basictypeCHARACTER)
2718 charfunc = TRUE, cmplxfunc = FALSE;
2719 else if ((bt == FFEINFO_basictypeCOMPLEX)
2720 && ffesymbol_is_f2c (fn))
2721 charfunc = FALSE, cmplxfunc = TRUE;
2722 else
2723 charfunc = cmplxfunc = FALSE;
2724
2725 if (charfunc)
2726 type = ffecom_tree_fun_type_void;
2727 else if (ffesymbol_is_f2c (fn))
2728 type = ffecom_tree_fun_type[bt][kt];
2729 else
2730 type = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
2731
2732 if ((type == NULL_TREE)
2733 || (TREE_TYPE (type) == NULL_TREE))
2734 type = ffecom_tree_fun_type_void; /* _sym_exec_transition. */
2735
2736 multi = (ffecom_master_bt_ == FFEINFO_basictypeNONE);
2737 break;
2738
2739 case FFEINFO_kindSUBROUTINE:
2740 gt = FFEGLOBAL_typeSUBR;
2741 bt = FFEINFO_basictypeNONE;
2742 kt = FFEINFO_kindtypeNONE;
2743 if (ffecom_is_altreturning_)
2744 { /* Am _I_ altreturning? */
2745 for (item = ffesymbol_dummyargs (fn);
2746 item != NULL;
2747 item = ffebld_trail (item))
2748 {
2749 if (ffebld_op (ffebld_head (item)) == FFEBLD_opSTAR)
2750 {
2751 altreturning = TRUE;
2752 break;
2753 }
2754 }
2755 if (altreturning)
2756 type = ffecom_tree_subr_type;
2757 else
2758 type = ffecom_tree_fun_type_void;
2759 }
2760 else
2761 type = ffecom_tree_fun_type_void;
2762 charfunc = FALSE;
2763 cmplxfunc = FALSE;
2764 multi = FALSE;
2765 break;
2766
2767 default:
2768 assert ("say what??" == NULL);
2769 /* Fall through. */
2770 case FFEINFO_kindANY:
2771 gt = FFEGLOBAL_typeANY;
2772 bt = FFEINFO_basictypeNONE;
2773 kt = FFEINFO_kindtypeNONE;
2774 type = error_mark_node;
2775 charfunc = FALSE;
2776 cmplxfunc = FALSE;
2777 multi = FALSE;
2778 break;
2779 }
2780
2781 /* build_decl uses the current lineno and input_filename to set the decl
2782 source info. So, I've putzed with ffestd and ffeste code to update that
2783 source info to point to the appropriate statement just before calling
2784 ffecom_do_entrypoint (which calls this fn). */
2785
2786 start_function (ffecom_get_external_identifier_ (fn),
2787 type,
2788 0, /* nested/inline */
2789 1); /* TREE_PUBLIC */
2790
2791 if (((g = ffesymbol_global (fn)) != NULL)
2792 && ((ffeglobal_type (g) == gt)
2793 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
2794 {
2795 ffeglobal_set_hook (g, current_function_decl);
2796 }
2797
2798 /* Reset args in master arg list so they get retransitioned. */
2799
2800 for (item = ffecom_master_arglist_;
2801 item != NULL;
2802 item = ffebld_trail (item))
2803 {
2804 ffebld arg;
2805 ffesymbol s;
2806
2807 arg = ffebld_head (item);
2808 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2809 continue; /* Alternate return or some such thing. */
2810 s = ffebld_symter (arg);
2811 ffesymbol_hook (s).decl_tree = NULL_TREE;
2812 ffesymbol_hook (s).length_tree = NULL_TREE;
2813 }
2814
2815 /* Build dummy arg list for this entry point. */
2816
5ff904cd
JL
2817 if (charfunc || cmplxfunc)
2818 { /* Prepend arg for where result goes. */
2819 tree type;
2820 tree length;
2821
2822 if (charfunc)
2823 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
2824 else
2825 type = ffecom_tree_type[FFEINFO_basictypeCOMPLEX][kt];
2826
14657de8 2827 result = ffecom_get_invented_identifier ("__g77_%s", "result");
5ff904cd
JL
2828
2829 /* Make length arg _and_ enhance type info for CHAR arg itself. */
2830
2831 if (charfunc)
2832 length = ffecom_char_enhance_arg_ (&type, fn);
2833 else
2834 length = NULL_TREE; /* Not ref'd if !charfunc. */
2835
2836 type = build_pointer_type (type);
2837 result = build_decl (PARM_DECL, result, type);
2838
2839 push_parm_decl (result);
2840 ffecom_func_result_ = result;
2841
2842 if (charfunc)
2843 {
2844 push_parm_decl (length);
2845 ffecom_func_length_ = length;
2846 }
2847 }
2848 else
2849 result = DECL_RESULT (current_function_decl);
2850
2851 ffecom_push_dummy_decls_ (ffesymbol_dummyargs (fn), FALSE);
2852
5ff904cd
JL
2853 store_parm_decls (0);
2854
c7e4ee3a
CB
2855 ffecom_start_compstmt ();
2856 /* Disallow temp vars at this level. */
2857 current_binding_level->prep_state = 2;
5ff904cd
JL
2858
2859 /* Make local var to hold return type for multi-type master fn. */
2860
2861 if (multi)
2862 {
5ff904cd 2863 multi_retval = ffecom_get_invented_identifier ("__g77_%s",
14657de8 2864 "multi_retval");
5ff904cd
JL
2865 multi_retval = build_decl (VAR_DECL, multi_retval,
2866 ffecom_multi_type_node_);
2867 multi_retval = start_decl (multi_retval, FALSE);
2868 finish_decl (multi_retval, NULL_TREE, FALSE);
5ff904cd
JL
2869 }
2870 else
2871 multi_retval = NULL_TREE; /* Not actually ref'd if !multi. */
2872
2873 /* Here we emit the actual code for the entry point. */
2874
2875 {
2876 ffebld list;
2877 ffebld arg;
2878 ffesymbol s;
2879 tree arglist = NULL_TREE;
2880 tree *plist = &arglist;
2881 tree prepend;
2882 tree call;
2883 tree actarg;
2884 tree master_fn;
2885
2886 /* Prepare actual arg list based on master arg list. */
2887
2888 for (list = ffecom_master_arglist_;
2889 list != NULL;
2890 list = ffebld_trail (list))
2891 {
2892 arg = ffebld_head (list);
2893 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2894 continue;
2895 s = ffebld_symter (arg);
702edf1d
CB
2896 if (ffesymbol_hook (s).decl_tree == NULL_TREE
2897 || ffesymbol_hook (s).decl_tree == error_mark_node)
5ff904cd
JL
2898 actarg = null_pointer_node; /* We don't have this arg. */
2899 else
2900 actarg = ffesymbol_hook (s).decl_tree;
2901 *plist = build_tree_list (NULL_TREE, actarg);
2902 plist = &TREE_CHAIN (*plist);
2903 }
2904
2905 /* This code appends the length arguments for character
2906 variables/arrays. */
2907
2908 for (list = ffecom_master_arglist_;
2909 list != NULL;
2910 list = ffebld_trail (list))
2911 {
2912 arg = ffebld_head (list);
2913 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2914 continue;
2915 s = ffebld_symter (arg);
2916 if (ffesymbol_basictype (s) != FFEINFO_basictypeCHARACTER)
2917 continue; /* Only looking for CHARACTER arguments. */
2918 if (ffesymbol_kind (s) != FFEINFO_kindENTITY)
2919 continue; /* Only looking for variables and arrays. */
702edf1d
CB
2920 if (ffesymbol_hook (s).length_tree == NULL_TREE
2921 || ffesymbol_hook (s).length_tree == error_mark_node)
5ff904cd
JL
2922 actarg = ffecom_f2c_ftnlen_zero_node; /* We don't have this arg. */
2923 else
2924 actarg = ffesymbol_hook (s).length_tree;
2925 *plist = build_tree_list (NULL_TREE, actarg);
2926 plist = &TREE_CHAIN (*plist);
2927 }
2928
2929 /* Prepend character-value return info to actual arg list. */
2930
2931 if (charfunc)
2932 {
2933 prepend = build_tree_list (NULL_TREE, ffecom_func_result_);
2934 TREE_CHAIN (prepend)
2935 = build_tree_list (NULL_TREE, ffecom_func_length_);
2936 TREE_CHAIN (TREE_CHAIN (prepend)) = arglist;
2937 arglist = prepend;
2938 }
2939
2940 /* Prepend multi-type return value to actual arg list. */
2941
2942 if (multi)
2943 {
2944 prepend
2945 = build_tree_list (NULL_TREE,
2946 ffecom_1 (ADDR_EXPR,
2947 build_pointer_type (TREE_TYPE (multi_retval)),
2948 multi_retval));
2949 TREE_CHAIN (prepend) = arglist;
2950 arglist = prepend;
2951 }
2952
2953 /* Prepend my entry-point number to the actual arg list. */
2954
2955 prepend = build_tree_list (NULL_TREE, build_int_2 (entrynum, 0));
2956 TREE_CHAIN (prepend) = arglist;
2957 arglist = prepend;
2958
2959 /* Build the call to the master function. */
2960
2961 master_fn = ffecom_1_fn (ffecom_previous_function_decl_);
2962 call = ffecom_3s (CALL_EXPR,
2963 TREE_TYPE (TREE_TYPE (TREE_TYPE (master_fn))),
2964 master_fn, arglist, NULL_TREE);
2965
2966 /* Decide whether the master function is a function or subroutine, and
2967 handle the return value for my entry point. */
2968
2969 if (charfunc || ((ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE)
2970 && !altreturning))
2971 {
2972 expand_expr_stmt (call);
2973 expand_null_return ();
2974 }
2975 else if (multi && cmplxfunc)
2976 {
2977 expand_expr_stmt (call);
2978 result
2979 = ffecom_1 (INDIRECT_REF,
2980 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result))),
2981 result);
2982 result = ffecom_modify (NULL_TREE, result,
2983 ffecom_2 (COMPONENT_REF, TREE_TYPE (result),
2984 multi_retval,
2985 ffecom_multi_fields_[bt][kt]));
2986 expand_expr_stmt (result);
2987 expand_null_return ();
2988 }
2989 else if (multi)
2990 {
2991 expand_expr_stmt (call);
2992 result
2993 = ffecom_modify (NULL_TREE, result,
2994 convert (TREE_TYPE (result),
2995 ffecom_2 (COMPONENT_REF,
2996 ffecom_tree_type[bt][kt],
2997 multi_retval,
2998 ffecom_multi_fields_[bt][kt])));
2999 expand_return (result);
3000 }
3001 else if (cmplxfunc)
3002 {
3003 result
3004 = ffecom_1 (INDIRECT_REF,
3005 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result))),
3006 result);
3007 result = ffecom_modify (NULL_TREE, result, call);
3008 expand_expr_stmt (result);
3009 expand_null_return ();
3010 }
3011 else
3012 {
3013 result = ffecom_modify (NULL_TREE,
3014 result,
3015 convert (TREE_TYPE (result),
3016 call));
3017 expand_return (result);
3018 }
5ff904cd
JL
3019 }
3020
c7e4ee3a 3021 ffecom_end_compstmt ();
5ff904cd
JL
3022
3023 finish_function (0);
3024
44d2eabc
JL
3025 lineno = old_lineno;
3026 input_filename = old_input_filename;
3027
5ff904cd
JL
3028 ffecom_doing_entry_ = FALSE;
3029}
3030
3031#endif
3032/* Transform expr into gcc tree with possible destination
3033
3034 Recursive descent on expr while making corresponding tree nodes and
3035 attaching type info and such. If destination supplied and compatible
3036 with temporary that would be made in certain cases, temporary isn't
092a4ef8 3037 made, destination used instead, and dest_used flag set TRUE. */
5ff904cd
JL
3038
3039#if FFECOM_targetCURRENT == FFECOM_targetGCC
3040static tree
092a4ef8
RH
3041ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest,
3042 bool *dest_used, bool assignp, bool widenp)
5ff904cd
JL
3043{
3044 tree item;
3045 tree list;
3046 tree args;
3047 ffeinfoBasictype bt;
3048 ffeinfoKindtype kt;
3049 tree t;
5ff904cd 3050 tree dt; /* decl_tree for an ffesymbol. */
092a4ef8 3051 tree tree_type, tree_type_x;
af752698 3052 tree left, right;
5ff904cd
JL
3053 ffesymbol s;
3054 enum tree_code code;
3055
3056 assert (expr != NULL);
3057
3058 if (dest_used != NULL)
3059 *dest_used = FALSE;
3060
3061 bt = ffeinfo_basictype (ffebld_info (expr));
3062 kt = ffeinfo_kindtype (ffebld_info (expr));
af752698 3063 tree_type = ffecom_tree_type[bt][kt];
5ff904cd 3064
092a4ef8
RH
3065 /* Widen integral arithmetic as desired while preserving signedness. */
3066 tree_type_x = NULL_TREE;
3067 if (widenp && tree_type
3068 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
3069 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
3070 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
3071
5ff904cd
JL
3072 switch (ffebld_op (expr))
3073 {
3074 case FFEBLD_opACCTER:
5ff904cd
JL
3075 {
3076 ffebitCount i;
3077 ffebit bits = ffebld_accter_bits (expr);
3078 ffetargetOffset source_offset = 0;
a6fa6420 3079 ffetargetOffset dest_offset = ffebld_accter_pad (expr);
5ff904cd
JL
3080 tree purpose;
3081
a6fa6420
CB
3082 assert (dest_offset == 0
3083 || (bt == FFEINFO_basictypeCHARACTER
3084 && kt == FFEINFO_kindtypeCHARACTER1));
5ff904cd
JL
3085
3086 list = item = NULL;
3087 for (;;)
3088 {
3089 ffebldConstantUnion cu;
3090 ffebitCount length;
3091 bool value;
3092 ffebldConstantArray ca = ffebld_accter (expr);
3093
3094 ffebit_test (bits, source_offset, &value, &length);
3095 if (length == 0)
3096 break;
3097
3098 if (value)
3099 {
3100 for (i = 0; i < length; ++i)
3101 {
3102 cu = ffebld_constantarray_get (ca, bt, kt,
3103 source_offset + i);
3104
3105 t = ffecom_constantunion (&cu, bt, kt, tree_type);
3106
a6fa6420
CB
3107 if (i == 0
3108 && dest_offset != 0)
3109 purpose = build_int_2 (dest_offset, 0);
5ff904cd
JL
3110 else
3111 purpose = NULL_TREE;
3112
3113 if (list == NULL_TREE)
3114 list = item = build_tree_list (purpose, t);
3115 else
3116 {
3117 TREE_CHAIN (item) = build_tree_list (purpose, t);
3118 item = TREE_CHAIN (item);
3119 }
3120 }
3121 }
3122 source_offset += length;
a6fa6420 3123 dest_offset += length;
5ff904cd
JL
3124 }
3125 }
3126
a6fa6420
CB
3127 item = build_int_2 ((ffebld_accter_size (expr)
3128 + ffebld_accter_pad (expr)) - 1, 0);
5ff904cd
JL
3129 ffebit_kill (ffebld_accter_bits (expr));
3130 TREE_TYPE (item) = ffecom_integer_type_node;
3131 item
3132 = build_array_type
3133 (tree_type,
3134 build_range_type (ffecom_integer_type_node,
3135 ffecom_integer_zero_node,
3136 item));
3137 list = build (CONSTRUCTOR, item, NULL_TREE, list);
3138 TREE_CONSTANT (list) = 1;
3139 TREE_STATIC (list) = 1;
3140 return list;
3141
3142 case FFEBLD_opARRTER:
5ff904cd
JL
3143 {
3144 ffetargetOffset i;
3145
a6fa6420
CB
3146 list = NULL_TREE;
3147 if (ffebld_arrter_pad (expr) == 0)
3148 item = NULL_TREE;
3149 else
3150 {
3151 assert (bt == FFEINFO_basictypeCHARACTER
3152 && kt == FFEINFO_kindtypeCHARACTER1);
3153
3154 /* Becomes PURPOSE first time through loop. */
3155 item = build_int_2 (ffebld_arrter_pad (expr), 0);
3156 }
3157
5ff904cd
JL
3158 for (i = 0; i < ffebld_arrter_size (expr); ++i)
3159 {
3160 ffebldConstantUnion cu
3161 = ffebld_constantarray_get (ffebld_arrter (expr), bt, kt, i);
3162
3163 t = ffecom_constantunion (&cu, bt, kt, tree_type);
3164
3165 if (list == NULL_TREE)
a6fa6420
CB
3166 /* Assume item is PURPOSE first time through loop. */
3167 list = item = build_tree_list (item, t);
5ff904cd
JL
3168 else
3169 {
3170 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
3171 item = TREE_CHAIN (item);
3172 }
3173 }
3174 }
3175
a6fa6420
CB
3176 item = build_int_2 ((ffebld_arrter_size (expr)
3177 + ffebld_arrter_pad (expr)) - 1, 0);
5ff904cd
JL
3178 TREE_TYPE (item) = ffecom_integer_type_node;
3179 item
3180 = build_array_type
3181 (tree_type,
3182 build_range_type (ffecom_integer_type_node,
a6fa6420 3183 ffecom_integer_zero_node,
5ff904cd
JL
3184 item));
3185 list = build (CONSTRUCTOR, item, NULL_TREE, list);
3186 TREE_CONSTANT (list) = 1;
3187 TREE_STATIC (list) = 1;
3188 return list;
3189
3190 case FFEBLD_opCONTER:
c264f113 3191 assert (ffebld_conter_pad (expr) == 0);
5ff904cd
JL
3192 item
3193 = ffecom_constantunion (&ffebld_constant_union (ffebld_conter (expr)),
3194 bt, kt, tree_type);
3195 return item;
3196
3197 case FFEBLD_opSYMTER:
3198 if ((ffebld_symter_generic (expr) != FFEINTRIN_genNONE)
3199 || (ffebld_symter_specific (expr) != FFEINTRIN_specNONE))
3200 return ffecom_ptr_to_expr (expr); /* Same as %REF(intrinsic). */
3201 s = ffebld_symter (expr);
3202 t = ffesymbol_hook (s).decl_tree;
3203
3204 if (assignp)
3205 { /* ASSIGN'ed-label expr. */
3206 if (ffe_is_ugly_assign ())
3207 {
3208 /* User explicitly wants ASSIGN'ed variables to be at the same
3209 memory address as the variables when used in non-ASSIGN
3210 contexts. That can make old, arcane, non-standard code
3211 work, but don't try to do it when a pointer wouldn't fit
3212 in the normal variable (take other approach, and warn,
3213 instead). */
3214
3215 if (t == NULL_TREE)
3216 {
3217 s = ffecom_sym_transform_ (s);
3218 t = ffesymbol_hook (s).decl_tree;
3219 assert (t != NULL_TREE);
3220 }
3221
3222 if (t == error_mark_node)
3223 return t;
3224
3225 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (t)))
3226 >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
3227 {
3228 if (ffesymbol_hook (s).addr)
3229 t = ffecom_1 (INDIRECT_REF,
3230 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), t);
3231 return t;
3232 }
3233
3234 if (ffesymbol_hook (s).assign_tree == NULL_TREE)
3235 {
3236 ffebad_start_msg ("ASSIGN'ed label cannot fit into `%A' at %0 -- using wider sibling",
3237 FFEBAD_severityWARNING);
3238 ffebad_string (ffesymbol_text (s));
3239 ffebad_here (0, ffesymbol_where_line (s),
3240 ffesymbol_where_column (s));
3241 ffebad_finish ();
3242 }
3243 }
3244
3245 /* Don't use the normal variable's tree for ASSIGN, though mark
3246 it as in the system header (housekeeping). Use an explicit,
3247 specially created sibling that is known to be wide enough
3248 to hold pointers to labels. */
3249
3250 if (t != NULL_TREE
3251 && TREE_CODE (t) == VAR_DECL)
3252 DECL_IN_SYSTEM_HEADER (t) = 1; /* Don't let -Wunused complain. */
3253
3254 t = ffesymbol_hook (s).assign_tree;
3255 if (t == NULL_TREE)
3256 {
3257 s = ffecom_sym_transform_assign_ (s);
3258 t = ffesymbol_hook (s).assign_tree;
3259 assert (t != NULL_TREE);
3260 }
3261 }
3262 else
3263 {
3264 if (t == NULL_TREE)
3265 {
3266 s = ffecom_sym_transform_ (s);
3267 t = ffesymbol_hook (s).decl_tree;
3268 assert (t != NULL_TREE);
3269 }
3270 if (ffesymbol_hook (s).addr)
3271 t = ffecom_1 (INDIRECT_REF,
3272 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), t);
3273 }
3274 return t;
3275
3276 case FFEBLD_opARRAYREF:
ff852b44 3277 return ffecom_arrayref_ (NULL_TREE, expr, 0);
5ff904cd
JL
3278
3279 case FFEBLD_opUPLUS:
092a4ef8 3280 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
af752698 3281 return ffecom_1 (NOP_EXPR, tree_type, left);
5ff904cd 3282
c7e4ee3a
CB
3283 case FFEBLD_opPAREN:
3284 /* ~~~Make sure Fortran rules respected here */
092a4ef8 3285 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
af752698 3286 return ffecom_1 (NOP_EXPR, tree_type, left);
5ff904cd
JL
3287
3288 case FFEBLD_opUMINUS:
092a4ef8 3289 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
af752698
RH
3290 if (tree_type_x)
3291 {
3292 tree_type = tree_type_x;
3293 left = convert (tree_type, left);
3294 }
3295 return ffecom_1 (NEGATE_EXPR, tree_type, left);
5ff904cd
JL
3296
3297 case FFEBLD_opADD:
092a4ef8
RH
3298 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3299 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
af752698
RH
3300 if (tree_type_x)
3301 {
3302 tree_type = tree_type_x;
3303 left = convert (tree_type, left);
3304 right = convert (tree_type, right);
3305 }
3306 return ffecom_2 (PLUS_EXPR, tree_type, left, right);
5ff904cd
JL
3307
3308 case FFEBLD_opSUBTRACT:
092a4ef8
RH
3309 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3310 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
af752698
RH
3311 if (tree_type_x)
3312 {
3313 tree_type = tree_type_x;
3314 left = convert (tree_type, left);
3315 right = convert (tree_type, right);
3316 }
3317 return ffecom_2 (MINUS_EXPR, tree_type, left, right);
5ff904cd
JL
3318
3319 case FFEBLD_opMULTIPLY:
092a4ef8
RH
3320 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3321 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
af752698
RH
3322 if (tree_type_x)
3323 {
3324 tree_type = tree_type_x;
3325 left = convert (tree_type, left);
3326 right = convert (tree_type, right);
3327 }
3328 return ffecom_2 (MULT_EXPR, tree_type, left, right);
5ff904cd
JL
3329
3330 case FFEBLD_opDIVIDE:
092a4ef8
RH
3331 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3332 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
af752698
RH
3333 if (tree_type_x)
3334 {
3335 tree_type = tree_type_x;
3336 left = convert (tree_type, left);
3337 right = convert (tree_type, right);
3338 }
3339 return ffecom_tree_divide_ (tree_type, left, right,
c7e4ee3a
CB
3340 dest_tree, dest, dest_used,
3341 ffebld_nonter_hook (expr));
5ff904cd
JL
3342
3343 case FFEBLD_opPOWER:
5ff904cd
JL
3344 {
3345 ffebld left = ffebld_left (expr);
3346 ffebld right = ffebld_right (expr);
3347 ffecomGfrt code;
3348 ffeinfoKindtype rtkt;
270fc4e8 3349 ffeinfoKindtype ltkt;
95eb4fd9 3350 bool ref = TRUE;
5ff904cd
JL
3351
3352 switch (ffeinfo_basictype (ffebld_info (right)))
3353 {
95eb4fd9 3354
5ff904cd
JL
3355 case FFEINFO_basictypeINTEGER:
3356 if (1 || optimize)
3357 {
c7e4ee3a 3358 item = ffecom_expr_power_integer_ (expr);
5ff904cd
JL
3359 if (item != NULL_TREE)
3360 return item;
3361 }
3362
3363 rtkt = FFEINFO_kindtypeINTEGER1;
3364 switch (ffeinfo_basictype (ffebld_info (left)))
3365 {
3366 case FFEINFO_basictypeINTEGER:
3367 if ((ffeinfo_kindtype (ffebld_info (left))
3368 == FFEINFO_kindtypeINTEGER4)
3369 || (ffeinfo_kindtype (ffebld_info (right))
3370 == FFEINFO_kindtypeINTEGER4))
3371 {
3372 code = FFECOM_gfrtPOW_QQ;
270fc4e8 3373 ltkt = FFEINFO_kindtypeINTEGER4;
5ff904cd
JL
3374 rtkt = FFEINFO_kindtypeINTEGER4;
3375 }
3376 else
6a047254
CB
3377 {
3378 code = FFECOM_gfrtPOW_II;
3379 ltkt = FFEINFO_kindtypeINTEGER1;
3380 }
5ff904cd
JL
3381 break;
3382
3383 case FFEINFO_basictypeREAL:
3384 if (ffeinfo_kindtype (ffebld_info (left))
3385 == FFEINFO_kindtypeREAL1)
6a047254
CB
3386 {
3387 code = FFECOM_gfrtPOW_RI;
3388 ltkt = FFEINFO_kindtypeREAL1;
3389 }
5ff904cd 3390 else
6a047254
CB
3391 {
3392 code = FFECOM_gfrtPOW_DI;
3393 ltkt = FFEINFO_kindtypeREAL2;
3394 }
5ff904cd
JL
3395 break;
3396
3397 case FFEINFO_basictypeCOMPLEX:
3398 if (ffeinfo_kindtype (ffebld_info (left))
3399 == FFEINFO_kindtypeREAL1)
6a047254
CB
3400 {
3401 code = FFECOM_gfrtPOW_CI; /* Overlapping result okay. */
3402 ltkt = FFEINFO_kindtypeREAL1;
3403 }
5ff904cd 3404 else
6a047254
CB
3405 {
3406 code = FFECOM_gfrtPOW_ZI; /* Overlapping result okay. */
3407 ltkt = FFEINFO_kindtypeREAL2;
3408 }
5ff904cd
JL
3409 break;
3410
3411 default:
3412 assert ("bad pow_*i" == NULL);
3413 code = FFECOM_gfrtPOW_CI; /* Overlapping result okay. */
6a047254 3414 ltkt = FFEINFO_kindtypeREAL1;
5ff904cd
JL
3415 break;
3416 }
270fc4e8 3417 if (ffeinfo_kindtype (ffebld_info (left)) != ltkt)
5ff904cd 3418 left = ffeexpr_convert (left, NULL, NULL,
6a047254 3419 ffeinfo_basictype (ffebld_info (left)),
270fc4e8 3420 ltkt, 0,
5ff904cd
JL
3421 FFETARGET_charactersizeNONE,
3422 FFEEXPR_contextLET);
3423 if (ffeinfo_kindtype (ffebld_info (right)) != rtkt)
3424 right = ffeexpr_convert (right, NULL, NULL,
3425 FFEINFO_basictypeINTEGER,
3426 rtkt, 0,
3427 FFETARGET_charactersizeNONE,
3428 FFEEXPR_contextLET);
3429 break;
3430
3431 case FFEINFO_basictypeREAL:
3432 if (ffeinfo_kindtype (ffebld_info (left)) == FFEINFO_kindtypeREAL1)
3433 left = ffeexpr_convert (left, NULL, NULL, FFEINFO_basictypeREAL,
3434 FFEINFO_kindtypeREALDOUBLE, 0,
3435 FFETARGET_charactersizeNONE,
3436 FFEEXPR_contextLET);
3437 if (ffeinfo_kindtype (ffebld_info (right))
3438 == FFEINFO_kindtypeREAL1)
3439 right = ffeexpr_convert (right, NULL, NULL,
3440 FFEINFO_basictypeREAL,
3441 FFEINFO_kindtypeREALDOUBLE, 0,
3442 FFETARGET_charactersizeNONE,
3443 FFEEXPR_contextLET);
95eb4fd9
TM
3444 /* We used to call FFECOM_gfrtPOW_DD here,
3445 which passes arguments by reference. */
3446 code = FFECOM_gfrtL_POW;
3447 /* Pass arguments by value. */
3448 ref = FALSE;
5ff904cd
JL
3449 break;
3450
3451 case FFEINFO_basictypeCOMPLEX:
3452 if (ffeinfo_kindtype (ffebld_info (left)) == FFEINFO_kindtypeREAL1)
3453 left = ffeexpr_convert (left, NULL, NULL,
3454 FFEINFO_basictypeCOMPLEX,
3455 FFEINFO_kindtypeREALDOUBLE, 0,
3456 FFETARGET_charactersizeNONE,
3457 FFEEXPR_contextLET);
3458 if (ffeinfo_kindtype (ffebld_info (right))
3459 == FFEINFO_kindtypeREAL1)
3460 right = ffeexpr_convert (right, NULL, NULL,
3461 FFEINFO_basictypeCOMPLEX,
3462 FFEINFO_kindtypeREALDOUBLE, 0,
3463 FFETARGET_charactersizeNONE,
3464 FFEEXPR_contextLET);
3465 code = FFECOM_gfrtPOW_ZZ; /* Overlapping result okay. */
95eb4fd9 3466 ref = TRUE; /* Pass arguments by reference. */
5ff904cd
JL
3467 break;
3468
3469 default:
3470 assert ("bad pow_x*" == NULL);
3471 code = FFECOM_gfrtPOW_II;
3472 break;
3473 }
3474 return ffecom_call_binop_ (ffecom_gfrt_tree_ (code),
3475 ffecom_gfrt_kindtype (code),
3476 (ffe_is_f2c_library ()
3477 && ffecom_gfrt_complex_[code]),
3478 tree_type, left, right,
3479 dest_tree, dest, dest_used,
95eb4fd9 3480 NULL_TREE, FALSE, ref,
c7e4ee3a 3481 ffebld_nonter_hook (expr));
5ff904cd
JL
3482 }
3483
3484 case FFEBLD_opNOT:
5ff904cd
JL
3485 switch (bt)
3486 {
3487 case FFEINFO_basictypeLOGICAL:
83ffecd2 3488 item = ffecom_truth_value_invert (ffecom_expr (ffebld_left (expr)));
5ff904cd
JL
3489 return convert (tree_type, item);
3490
3491 case FFEINFO_basictypeINTEGER:
3492 return ffecom_1 (BIT_NOT_EXPR, tree_type,
3493 ffecom_expr (ffebld_left (expr)));
3494
3495 default:
3496 assert ("NOT bad basictype" == NULL);
3497 /* Fall through. */
3498 case FFEINFO_basictypeANY:
3499 return error_mark_node;
3500 }
3501 break;
3502
3503 case FFEBLD_opFUNCREF:
3504 assert (ffeinfo_basictype (ffebld_info (expr))
3505 != FFEINFO_basictypeCHARACTER);
3506 /* Fall through. */
3507 case FFEBLD_opSUBRREF:
5ff904cd
JL
3508 if (ffeinfo_where (ffebld_info (ffebld_left (expr)))
3509 == FFEINFO_whereINTRINSIC)
3510 { /* Invocation of an intrinsic. */
3511 item = ffecom_expr_intrinsic_ (expr, dest_tree, dest,
3512 dest_used);
3513 return item;
3514 }
3515 s = ffebld_symter (ffebld_left (expr));
3516 dt = ffesymbol_hook (s).decl_tree;
3517 if (dt == NULL_TREE)
3518 {
3519 s = ffecom_sym_transform_ (s);
3520 dt = ffesymbol_hook (s).decl_tree;
3521 }
3522 if (dt == error_mark_node)
3523 return dt;
3524
3525 if (ffesymbol_hook (s).addr)
3526 item = dt;
3527 else
3528 item = ffecom_1_fn (dt);
3529
5ff904cd
JL
3530 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT)
3531 args = ffecom_list_expr (ffebld_right (expr));
3532 else
3533 args = ffecom_list_ptr_to_expr (ffebld_right (expr));
5ff904cd 3534
702edf1d
CB
3535 if (args == error_mark_node)
3536 return error_mark_node;
3537
5ff904cd
JL
3538 item = ffecom_call_ (item, kt,
3539 ffesymbol_is_f2c (s)
3540 && (bt == FFEINFO_basictypeCOMPLEX)
3541 && (ffesymbol_where (s)
3542 != FFEINFO_whereCONSTANT),
3543 tree_type,
3544 args,
3545 dest_tree, dest, dest_used,
c7e4ee3a
CB
3546 error_mark_node, FALSE,
3547 ffebld_nonter_hook (expr));
5ff904cd
JL
3548 TREE_SIDE_EFFECTS (item) = 1;
3549 return item;
3550
3551 case FFEBLD_opAND:
5ff904cd
JL
3552 switch (bt)
3553 {
3554 case FFEINFO_basictypeLOGICAL:
3555 item
3556 = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
3557 ffecom_truth_value (ffecom_expr (ffebld_left (expr))),
3558 ffecom_truth_value (ffecom_expr (ffebld_right (expr))));
3559 return convert (tree_type, item);
3560
3561 case FFEINFO_basictypeINTEGER:
3562 return ffecom_2 (BIT_AND_EXPR, tree_type,
3563 ffecom_expr (ffebld_left (expr)),
3564 ffecom_expr (ffebld_right (expr)));
3565
3566 default:
3567 assert ("AND bad basictype" == NULL);
3568 /* Fall through. */
3569 case FFEINFO_basictypeANY:
3570 return error_mark_node;
3571 }
3572 break;
3573
3574 case FFEBLD_opOR:
5ff904cd
JL
3575 switch (bt)
3576 {
3577 case FFEINFO_basictypeLOGICAL:
3578 item
3579 = ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
3580 ffecom_truth_value (ffecom_expr (ffebld_left (expr))),
3581 ffecom_truth_value (ffecom_expr (ffebld_right (expr))));
3582 return convert (tree_type, item);
3583
3584 case FFEINFO_basictypeINTEGER:
3585 return ffecom_2 (BIT_IOR_EXPR, tree_type,
3586 ffecom_expr (ffebld_left (expr)),
3587 ffecom_expr (ffebld_right (expr)));
3588
3589 default:
3590 assert ("OR bad basictype" == NULL);
3591 /* Fall through. */
3592 case FFEINFO_basictypeANY:
3593 return error_mark_node;
3594 }
3595 break;
3596
3597 case FFEBLD_opXOR:
3598 case FFEBLD_opNEQV:
5ff904cd
JL
3599 switch (bt)
3600 {
3601 case FFEINFO_basictypeLOGICAL:
3602 item
3603 = ffecom_2 (NE_EXPR, integer_type_node,
3604 ffecom_expr (ffebld_left (expr)),
3605 ffecom_expr (ffebld_right (expr)));
3606 return convert (tree_type, ffecom_truth_value (item));
3607
3608 case FFEINFO_basictypeINTEGER:
3609 return ffecom_2 (BIT_XOR_EXPR, tree_type,
3610 ffecom_expr (ffebld_left (expr)),
3611 ffecom_expr (ffebld_right (expr)));
3612
3613 default:
3614 assert ("XOR/NEQV bad basictype" == NULL);
3615 /* Fall through. */
3616 case FFEINFO_basictypeANY:
3617 return error_mark_node;
3618 }
3619 break;
3620
3621 case FFEBLD_opEQV:
5ff904cd
JL
3622 switch (bt)
3623 {
3624 case FFEINFO_basictypeLOGICAL:
3625 item
3626 = ffecom_2 (EQ_EXPR, integer_type_node,
3627 ffecom_expr (ffebld_left (expr)),
3628 ffecom_expr (ffebld_right (expr)));
3629 return convert (tree_type, ffecom_truth_value (item));
3630
3631 case FFEINFO_basictypeINTEGER:
3632 return
3633 ffecom_1 (BIT_NOT_EXPR, tree_type,
3634 ffecom_2 (BIT_XOR_EXPR, tree_type,
3635 ffecom_expr (ffebld_left (expr)),
3636 ffecom_expr (ffebld_right (expr))));
3637
3638 default:
3639 assert ("EQV bad basictype" == NULL);
3640 /* Fall through. */
3641 case FFEINFO_basictypeANY:
3642 return error_mark_node;
3643 }
3644 break;
3645
3646 case FFEBLD_opCONVERT:
3647 if (ffebld_op (ffebld_left (expr)) == FFEBLD_opANY)
3648 return error_mark_node;
3649
5ff904cd
JL
3650 switch (bt)
3651 {
3652 case FFEINFO_basictypeLOGICAL:
3653 case FFEINFO_basictypeINTEGER:
3654 case FFEINFO_basictypeREAL:
3655 return convert (tree_type, ffecom_expr (ffebld_left (expr)));
3656
3657 case FFEINFO_basictypeCOMPLEX:
3658 switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr))))
3659 {
3660 case FFEINFO_basictypeINTEGER:
3661 case FFEINFO_basictypeLOGICAL:
3662 case FFEINFO_basictypeREAL:
3663 item = ffecom_expr (ffebld_left (expr));
3664 if (item == error_mark_node)
3665 return error_mark_node;
3666 /* convert() takes care of converting to the subtype first,
3667 at least in gcc-2.7.2. */
3668 item = convert (tree_type, item);
3669 return item;
3670
3671 case FFEINFO_basictypeCOMPLEX:
3672 return convert (tree_type, ffecom_expr (ffebld_left (expr)));
3673
3674 default:
3675 assert ("CONVERT COMPLEX bad basictype" == NULL);
3676 /* Fall through. */
3677 case FFEINFO_basictypeANY:
3678 return error_mark_node;
3679 }
3680 break;
3681
3682 default:
3683 assert ("CONVERT bad basictype" == NULL);
3684 /* Fall through. */
3685 case FFEINFO_basictypeANY:
3686 return error_mark_node;
3687 }
3688 break;
3689
3690 case FFEBLD_opLT:
3691 code = LT_EXPR;
3692 goto relational; /* :::::::::::::::::::: */
3693
3694 case FFEBLD_opLE:
3695 code = LE_EXPR;
3696 goto relational; /* :::::::::::::::::::: */
3697
3698 case FFEBLD_opEQ:
3699 code = EQ_EXPR;
3700 goto relational; /* :::::::::::::::::::: */
3701
3702 case FFEBLD_opNE:
3703 code = NE_EXPR;
3704 goto relational; /* :::::::::::::::::::: */
3705
3706 case FFEBLD_opGT:
3707 code = GT_EXPR;
3708 goto relational; /* :::::::::::::::::::: */
3709
3710 case FFEBLD_opGE:
3711 code = GE_EXPR;
3712
3713 relational: /* :::::::::::::::::::: */
5ff904cd
JL
3714 switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr))))
3715 {
3716 case FFEINFO_basictypeLOGICAL:
3717 case FFEINFO_basictypeINTEGER:
3718 case FFEINFO_basictypeREAL:
3719 item = ffecom_2 (code, integer_type_node,
3720 ffecom_expr (ffebld_left (expr)),
3721 ffecom_expr (ffebld_right (expr)));
3722 return convert (tree_type, item);
3723
3724 case FFEINFO_basictypeCOMPLEX:
3725 assert (code == EQ_EXPR || code == NE_EXPR);
3726 {
3727 tree real_type;
3728 tree arg1 = ffecom_expr (ffebld_left (expr));
3729 tree arg2 = ffecom_expr (ffebld_right (expr));
3730
3731 if (arg1 == error_mark_node || arg2 == error_mark_node)
3732 return error_mark_node;
3733
3734 arg1 = ffecom_save_tree (arg1);
3735 arg2 = ffecom_save_tree (arg2);
3736
3737 if (TREE_CODE (TREE_TYPE (arg1)) == COMPLEX_TYPE)
3738 {
3739 real_type = TREE_TYPE (TREE_TYPE (arg1));
3740 assert (real_type == TREE_TYPE (TREE_TYPE (arg2)));
3741 }
3742 else
3743 {
3744 real_type = TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg1)));
3745 assert (real_type == TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg2))));
3746 }
3747
3748 item
3749 = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
3750 ffecom_2 (EQ_EXPR, integer_type_node,
3751 ffecom_1 (REALPART_EXPR, real_type, arg1),
3752 ffecom_1 (REALPART_EXPR, real_type, arg2)),
3753 ffecom_2 (EQ_EXPR, integer_type_node,
3754 ffecom_1 (IMAGPART_EXPR, real_type, arg1),
3755 ffecom_1 (IMAGPART_EXPR, real_type,
3756 arg2)));
3757 if (code == EQ_EXPR)
3758 item = ffecom_truth_value (item);
3759 else
3760 item = ffecom_truth_value_invert (item);
3761 return convert (tree_type, item);
3762 }
3763
3764 case FFEINFO_basictypeCHARACTER:
5ff904cd
JL
3765 {
3766 ffebld left = ffebld_left (expr);
3767 ffebld right = ffebld_right (expr);
3768 tree left_tree;
3769 tree right_tree;
3770 tree left_length;
3771 tree right_length;
3772
3773 /* f2c run-time functions do the implicit blank-padding for us,
3774 so we don't usually have to implement blank-padding ourselves.
3775 (The exception is when we pass an argument to a separately
3776 compiled statement function -- if we know the arg is not the
3777 same length as the dummy, we must truncate or extend it. If
3778 we "inline" statement functions, that necessity goes away as
3779 well.)
3780
3781 Strip off the CONVERT operators that blank-pad. (Truncation by
3782 CONVERT shouldn't happen here, but it can happen in
3783 assignments.) */
3784
3785 while (ffebld_op (left) == FFEBLD_opCONVERT)
3786 left = ffebld_left (left);
3787 while (ffebld_op (right) == FFEBLD_opCONVERT)
3788 right = ffebld_left (right);
3789
3790 left_tree = ffecom_arg_ptr_to_expr (left, &left_length);
3791 right_tree = ffecom_arg_ptr_to_expr (right, &right_length);
3792
3793 if (left_tree == error_mark_node || left_length == error_mark_node
3794 || right_tree == error_mark_node
3795 || right_length == error_mark_node)
c7e4ee3a 3796 return error_mark_node;
5ff904cd
JL
3797
3798 if ((ffebld_size_known (left) == 1)
3799 && (ffebld_size_known (right) == 1))
3800 {
3801 left_tree
3802 = ffecom_1 (INDIRECT_REF,
3803 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree))),
3804 left_tree);
3805 right_tree
3806 = ffecom_1 (INDIRECT_REF,
3807 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree))),
3808 right_tree);
3809
3810 item
3811 = ffecom_2 (code, integer_type_node,
3812 ffecom_2 (ARRAY_REF,
3813 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree))),
3814 left_tree,
3815 integer_one_node),
3816 ffecom_2 (ARRAY_REF,
3817 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree))),
3818 right_tree,
3819 integer_one_node));
3820 }
3821 else
3822 {
3823 item = build_tree_list (NULL_TREE, left_tree);
3824 TREE_CHAIN (item) = build_tree_list (NULL_TREE, right_tree);
3825 TREE_CHAIN (TREE_CHAIN (item)) = build_tree_list (NULL_TREE,
3826 left_length);
3827 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item)))
3828 = build_tree_list (NULL_TREE, right_length);
c7e4ee3a 3829 item = ffecom_call_gfrt (FFECOM_gfrtCMP, item, NULL_TREE);
5ff904cd
JL
3830 item = ffecom_2 (code, integer_type_node,
3831 item,
3832 convert (TREE_TYPE (item),
3833 integer_zero_node));
3834 }
3835 item = convert (tree_type, item);
3836 }
3837
5ff904cd
JL
3838 return item;
3839
3840 default:
3841 assert ("relational bad basictype" == NULL);
3842 /* Fall through. */
3843 case FFEINFO_basictypeANY:
3844 return error_mark_node;
3845 }
3846 break;
3847
3848 case FFEBLD_opPERCENT_LOC:
5ff904cd
JL
3849 item = ffecom_arg_ptr_to_expr (ffebld_left (expr), &list);
3850 return convert (tree_type, item);
3851
3852 case FFEBLD_opITEM:
3853 case FFEBLD_opSTAR:
3854 case FFEBLD_opBOUNDS:
3855 case FFEBLD_opREPEAT:
3856 case FFEBLD_opLABTER:
3857 case FFEBLD_opLABTOK:
3858 case FFEBLD_opIMPDO:
3859 case FFEBLD_opCONCATENATE:
3860 case FFEBLD_opSUBSTR:
3861 default:
3862 assert ("bad op" == NULL);
3863 /* Fall through. */
3864 case FFEBLD_opANY:
3865 return error_mark_node;
3866 }
3867
3868#if 1
3869 assert ("didn't think anything got here anymore!!" == NULL);
3870#else
3871 switch (ffebld_arity (expr))
3872 {
3873 case 2:
3874 TREE_OPERAND (item, 0) = ffecom_expr (ffebld_left (expr));
3875 TREE_OPERAND (item, 1) = ffecom_expr (ffebld_right (expr));
3876 if (TREE_OPERAND (item, 0) == error_mark_node
3877 || TREE_OPERAND (item, 1) == error_mark_node)
3878 return error_mark_node;
3879 break;
3880
3881 case 1:
3882 TREE_OPERAND (item, 0) = ffecom_expr (ffebld_left (expr));
3883 if (TREE_OPERAND (item, 0) == error_mark_node)
3884 return error_mark_node;
3885 break;
3886
3887 default:
3888 break;
3889 }
3890
3891 return fold (item);
3892#endif
3893}
3894
3895#endif
3896/* Returns the tree that does the intrinsic invocation.
3897
3898 Note: this function applies only to intrinsics returning
3899 CHARACTER*1 or non-CHARACTER results, and to intrinsic
3900 subroutines. */
3901
3902#if FFECOM_targetCURRENT == FFECOM_targetGCC
3903static tree
3904ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree,
3905 ffebld dest, bool *dest_used)
3906{
3907 tree expr_tree;
3908 tree saved_expr1; /* For those who need it. */
3909 tree saved_expr2; /* For those who need it. */
3910 ffeinfoBasictype bt;
3911 ffeinfoKindtype kt;
3912 tree tree_type;
3913 tree arg1_type;
3914 tree real_type; /* REAL type corresponding to COMPLEX. */
3915 tree tempvar;
3916 ffebld list = ffebld_right (expr); /* List of (some) args. */
3917 ffebld arg1; /* For handy reference. */
3918 ffebld arg2;
3919 ffebld arg3;
3920 ffeintrinImp codegen_imp;
3921 ffecomGfrt gfrt;
3922
3923 assert (ffebld_op (ffebld_left (expr)) == FFEBLD_opSYMTER);
3924
3925 if (dest_used != NULL)
3926 *dest_used = FALSE;
3927
3928 bt = ffeinfo_basictype (ffebld_info (expr));
3929 kt = ffeinfo_kindtype (ffebld_info (expr));
3930 tree_type = ffecom_tree_type[bt][kt];
3931
3932 if (list != NULL)
3933 {
3934 arg1 = ffebld_head (list);
3935 if (arg1 != NULL && ffebld_op (arg1) == FFEBLD_opANY)
3936 return error_mark_node;
3937 if ((list = ffebld_trail (list)) != NULL)
3938 {
3939 arg2 = ffebld_head (list);
3940 if (arg2 != NULL && ffebld_op (arg2) == FFEBLD_opANY)
3941 return error_mark_node;
3942 if ((list = ffebld_trail (list)) != NULL)
3943 {
3944 arg3 = ffebld_head (list);
3945 if (arg3 != NULL && ffebld_op (arg3) == FFEBLD_opANY)
3946 return error_mark_node;
3947 }
3948 else
3949 arg3 = NULL;
3950 }
3951 else
3952 arg2 = arg3 = NULL;
3953 }
3954 else
3955 arg1 = arg2 = arg3 = NULL;
3956
3957 /* <list> ends up at the opITEM of the 3rd arg, or NULL if there are < 3
3958 args. This is used by the MAX/MIN expansions. */
3959
3960 if (arg1 != NULL)
3961 arg1_type = ffecom_tree_type
3962 [ffeinfo_basictype (ffebld_info (arg1))]
3963 [ffeinfo_kindtype (ffebld_info (arg1))];
3964 else
3965 arg1_type = NULL_TREE; /* Really not needed, but might catch bugs
3966 here. */
3967
3968 /* There are several ways for each of the cases in the following switch
3969 statements to exit (from simplest to use to most complicated):
3970
3971 break; (when expr_tree == NULL)
3972
3973 A standard call is made to the specific intrinsic just as if it had been
3974 passed in as a dummy procedure and called as any old procedure. This
3975 method can produce slower code but in some cases it's the easiest way for
3976 now. However, if a (presumably faster) direct call is available,
3977 that is used, so this is the easiest way in many more cases now.
3978
3979 gfrt = FFECOM_gfrtWHATEVER;
3980 break;
3981
3982 gfrt contains the gfrt index of a library function to call, passing the
3983 argument(s) by value rather than by reference. Used when a more
3984 careful choice of library function is needed than that provided
3985 by the vanilla `break;'.
3986
3987 return expr_tree;
3988
3989 The expr_tree has been completely set up and is ready to be returned
3990 as is. No further actions are taken. Use this when the tree is not
3991 in the simple form for one of the arity_n labels. */
3992
3993 /* For info on how the switch statement cases were written, see the files
3994 enclosed in comments below the switch statement. */
3995
3996 codegen_imp = ffebld_symter_implementation (ffebld_left (expr));
3997 gfrt = ffeintrin_gfrt_direct (codegen_imp);
3998 if (gfrt == FFECOM_gfrt)
3999 gfrt = ffeintrin_gfrt_indirect (codegen_imp);
4000
4001 switch (codegen_imp)
4002 {
4003 case FFEINTRIN_impABS:
4004 case FFEINTRIN_impCABS:
4005 case FFEINTRIN_impCDABS:
4006 case FFEINTRIN_impDABS:
4007 case FFEINTRIN_impIABS:
4008 if (ffeinfo_basictype (ffebld_info (arg1))
4009 == FFEINFO_basictypeCOMPLEX)
4010 {
4011 if (kt == FFEINFO_kindtypeREAL1)
4012 gfrt = FFECOM_gfrtCABS;
4013 else if (kt == FFEINFO_kindtypeREAL2)
4014 gfrt = FFECOM_gfrtCDABS;
4015 break;
4016 }
4017 return ffecom_1 (ABS_EXPR, tree_type,
4018 convert (tree_type, ffecom_expr (arg1)));
4019
4020 case FFEINTRIN_impACOS:
4021 case FFEINTRIN_impDACOS:
4022 break;
4023
4024 case FFEINTRIN_impAIMAG:
4025 case FFEINTRIN_impDIMAG:
4026 case FFEINTRIN_impIMAGPART:
4027 if (TREE_CODE (arg1_type) == COMPLEX_TYPE)
4028 arg1_type = TREE_TYPE (arg1_type);
4029 else
4030 arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type));
4031
4032 return
4033 convert (tree_type,
4034 ffecom_1 (IMAGPART_EXPR, arg1_type,
4035 ffecom_expr (arg1)));
4036
4037 case FFEINTRIN_impAINT:
4038 case FFEINTRIN_impDINT:
c7e4ee3a
CB
4039#if 0
4040 /* ~~Someday implement FIX_TRUNC_EXPR yielding same type as arg. */
5ff904cd
JL
4041 return ffecom_1 (FIX_TRUNC_EXPR, tree_type, ffecom_expr (arg1));
4042#else /* in the meantime, must use floor to avoid range problems with ints */
4043 /* r__1 = r1 >= 0 ? floor(r1) : -floor(-r1); */
4044 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
4045 return
4046 convert (tree_type,
4047 ffecom_3 (COND_EXPR, double_type_node,
4048 ffecom_truth_value
4049 (ffecom_2 (GE_EXPR, integer_type_node,
4050 saved_expr1,
4051 convert (arg1_type,
4052 ffecom_float_zero_))),
4053 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
4054 build_tree_list (NULL_TREE,
4055 convert (double_type_node,
c7e4ee3a
CB
4056 saved_expr1)),
4057 NULL_TREE),
5ff904cd
JL
4058 ffecom_1 (NEGATE_EXPR, double_type_node,
4059 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
4060 build_tree_list (NULL_TREE,
4061 convert (double_type_node,
4062 ffecom_1 (NEGATE_EXPR,
4063 arg1_type,
c7e4ee3a
CB
4064 saved_expr1))),
4065 NULL_TREE)
5ff904cd
JL
4066 ))
4067 );
4068#endif
4069
4070 case FFEINTRIN_impANINT:
4071 case FFEINTRIN_impDNINT:
4072#if 0 /* This way of doing it won't handle real
4073 numbers of large magnitudes. */
4074 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
4075 expr_tree = convert (tree_type,
4076 convert (integer_type_node,
4077 ffecom_3 (COND_EXPR, tree_type,
4078 ffecom_truth_value
4079 (ffecom_2 (GE_EXPR,
4080 integer_type_node,
4081 saved_expr1,
4082 ffecom_float_zero_)),
4083 ffecom_2 (PLUS_EXPR,
4084 tree_type,
4085 saved_expr1,
4086 ffecom_float_half_),
4087 ffecom_2 (MINUS_EXPR,
4088 tree_type,
4089 saved_expr1,
4090 ffecom_float_half_))));
4091 return expr_tree;
4092#else /* So we instead call floor. */
4093 /* r__1 = r1 >= 0 ? floor(r1 + .5) : -floor(.5 - r1) */
4094 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
4095 return
4096 convert (tree_type,
4097 ffecom_3 (COND_EXPR, double_type_node,
4098 ffecom_truth_value
4099 (ffecom_2 (GE_EXPR, integer_type_node,
4100 saved_expr1,
4101 convert (arg1_type,
4102 ffecom_float_zero_))),
4103 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
4104 build_tree_list (NULL_TREE,
4105 convert (double_type_node,
4106 ffecom_2 (PLUS_EXPR,
4107 arg1_type,
4108 saved_expr1,
4109 convert (arg1_type,
c7e4ee3a
CB
4110 ffecom_float_half_)))),
4111 NULL_TREE),
5ff904cd
JL
4112 ffecom_1 (NEGATE_EXPR, double_type_node,
4113 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
4114 build_tree_list (NULL_TREE,
4115 convert (double_type_node,
4116 ffecom_2 (MINUS_EXPR,
4117 arg1_type,
4118 convert (arg1_type,
4119 ffecom_float_half_),
c7e4ee3a
CB
4120 saved_expr1))),
4121 NULL_TREE))
5ff904cd
JL
4122 )
4123 );
4124#endif
4125
4126 case FFEINTRIN_impASIN:
4127 case FFEINTRIN_impDASIN:
4128 case FFEINTRIN_impATAN:
4129 case FFEINTRIN_impDATAN:
4130 case FFEINTRIN_impATAN2:
4131 case FFEINTRIN_impDATAN2:
4132 break;
4133
4134 case FFEINTRIN_impCHAR:
4135 case FFEINTRIN_impACHAR:
c7e4ee3a
CB
4136#ifdef HOHO
4137 tempvar = ffecom_make_tempvar (char_type_node, 1, -1);
4138#else
4139 tempvar = ffebld_nonter_hook (expr);
4140 assert (tempvar);
4141#endif
5ff904cd
JL
4142 {
4143 tree tmv = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (tempvar)));
4144
4145 expr_tree = ffecom_modify (tmv,
4146 ffecom_2 (ARRAY_REF, tmv, tempvar,
4147 integer_one_node),
4148 convert (tmv, ffecom_expr (arg1)));
4149 }
4150 expr_tree = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar),
4151 expr_tree,
4152 tempvar);
4153 expr_tree = ffecom_1 (ADDR_EXPR,
4154 build_pointer_type (TREE_TYPE (expr_tree)),
4155 expr_tree);
4156 return expr_tree;
4157
4158 case FFEINTRIN_impCMPLX:
4159 case FFEINTRIN_impDCMPLX:
4160 if (arg2 == NULL)
4161 return
4162 convert (tree_type, ffecom_expr (arg1));
4163
4164 real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
4165 return
4166 ffecom_2 (COMPLEX_EXPR, tree_type,
4167 convert (real_type, ffecom_expr (arg1)),
4168 convert (real_type,
4169 ffecom_expr (arg2)));
4170
4171 case FFEINTRIN_impCOMPLEX:
4172 return
4173 ffecom_2 (COMPLEX_EXPR, tree_type,
4174 ffecom_expr (arg1),
4175 ffecom_expr (arg2));
4176
4177 case FFEINTRIN_impCONJG:
4178 case FFEINTRIN_impDCONJG:
4179 {
4180 tree arg1_tree;
4181
4182 real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
4183 arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4184 return
4185 ffecom_2 (COMPLEX_EXPR, tree_type,
4186 ffecom_1 (REALPART_EXPR, real_type, arg1_tree),
4187 ffecom_1 (NEGATE_EXPR, real_type,
4188 ffecom_1 (IMAGPART_EXPR, real_type, arg1_tree)));
4189 }
4190
4191 case FFEINTRIN_impCOS:
4192 case FFEINTRIN_impCCOS:
4193 case FFEINTRIN_impCDCOS:
4194 case FFEINTRIN_impDCOS:
4195 if (bt == FFEINFO_basictypeCOMPLEX)
4196 {
4197 if (kt == FFEINFO_kindtypeREAL1)
4198 gfrt = FFECOM_gfrtCCOS; /* Overlapping result okay. */
4199 else if (kt == FFEINFO_kindtypeREAL2)
4200 gfrt = FFECOM_gfrtCDCOS; /* Overlapping result okay. */
4201 }
4202 break;
4203
4204 case FFEINTRIN_impCOSH:
4205 case FFEINTRIN_impDCOSH:
4206 break;
4207
4208 case FFEINTRIN_impDBLE:
4209 case FFEINTRIN_impDFLOAT:
4210 case FFEINTRIN_impDREAL:
4211 case FFEINTRIN_impFLOAT:
4212 case FFEINTRIN_impIDINT:
4213 case FFEINTRIN_impIFIX:
4214 case FFEINTRIN_impINT2:
4215 case FFEINTRIN_impINT8:
4216 case FFEINTRIN_impINT:
4217 case FFEINTRIN_impLONG:
4218 case FFEINTRIN_impREAL:
4219 case FFEINTRIN_impSHORT:
4220 case FFEINTRIN_impSNGL:
4221 return convert (tree_type, ffecom_expr (arg1));
4222
4223 case FFEINTRIN_impDIM:
4224 case FFEINTRIN_impDDIM:
4225 case FFEINTRIN_impIDIM:
4226 saved_expr1 = ffecom_save_tree (convert (tree_type,
4227 ffecom_expr (arg1)));
4228 saved_expr2 = ffecom_save_tree (convert (tree_type,
4229 ffecom_expr (arg2)));
4230 return
4231 ffecom_3 (COND_EXPR, tree_type,
4232 ffecom_truth_value
4233 (ffecom_2 (GT_EXPR, integer_type_node,
4234 saved_expr1,
4235 saved_expr2)),
4236 ffecom_2 (MINUS_EXPR, tree_type,
4237 saved_expr1,
4238 saved_expr2),
4239 convert (tree_type, ffecom_float_zero_));
4240
4241 case FFEINTRIN_impDPROD:
4242 return
4243 ffecom_2 (MULT_EXPR, tree_type,
4244 convert (tree_type, ffecom_expr (arg1)),
4245 convert (tree_type, ffecom_expr (arg2)));
4246
4247 case FFEINTRIN_impEXP:
4248 case FFEINTRIN_impCDEXP:
4249 case FFEINTRIN_impCEXP:
4250 case FFEINTRIN_impDEXP:
4251 if (bt == FFEINFO_basictypeCOMPLEX)
4252 {
4253 if (kt == FFEINFO_kindtypeREAL1)
4254 gfrt = FFECOM_gfrtCEXP; /* Overlapping result okay. */
4255 else if (kt == FFEINFO_kindtypeREAL2)
4256 gfrt = FFECOM_gfrtCDEXP; /* Overlapping result okay. */
4257 }
4258 break;
4259
4260 case FFEINTRIN_impICHAR:
4261 case FFEINTRIN_impIACHAR:
4262#if 0 /* The simple approach. */
4263 ffecom_char_args_ (&expr_tree, &saved_expr1 /* Ignored */ , arg1);
4264 expr_tree
4265 = ffecom_1 (INDIRECT_REF,
4266 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
4267 expr_tree);
4268 expr_tree
4269 = ffecom_2 (ARRAY_REF,
4270 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
4271 expr_tree,
4272 integer_one_node);
4273 return convert (tree_type, expr_tree);
4274#else /* The more interesting (and more optimal) approach. */
4275 expr_tree = ffecom_intrinsic_ichar_ (tree_type, arg1, &saved_expr1);
4276 expr_tree = ffecom_3 (COND_EXPR, tree_type,
4277 saved_expr1,
4278 expr_tree,
4279 convert (tree_type, integer_zero_node));
4280 return expr_tree;
4281#endif
4282
4283 case FFEINTRIN_impINDEX:
4284 break;
4285
4286 case FFEINTRIN_impLEN:
4287#if 0
4288 break; /* The simple approach. */
4289#else
4290 return ffecom_intrinsic_len_ (arg1); /* The more optimal approach. */
4291#endif
4292
4293 case FFEINTRIN_impLGE:
4294 case FFEINTRIN_impLGT:
4295 case FFEINTRIN_impLLE:
4296 case FFEINTRIN_impLLT:
4297 break;
4298
4299 case FFEINTRIN_impLOG:
4300 case FFEINTRIN_impALOG:
4301 case FFEINTRIN_impCDLOG:
4302 case FFEINTRIN_impCLOG:
4303 case FFEINTRIN_impDLOG:
4304 if (bt == FFEINFO_basictypeCOMPLEX)
4305 {
4306 if (kt == FFEINFO_kindtypeREAL1)
4307 gfrt = FFECOM_gfrtCLOG; /* Overlapping result okay. */
4308 else if (kt == FFEINFO_kindtypeREAL2)
4309 gfrt = FFECOM_gfrtCDLOG; /* Overlapping result okay. */
4310 }
4311 break;
4312
4313 case FFEINTRIN_impLOG10:
4314 case FFEINTRIN_impALOG10:
4315 case FFEINTRIN_impDLOG10:
4316 if (gfrt != FFECOM_gfrt)
4317 break; /* Already picked one, stick with it. */
4318
4319 if (kt == FFEINFO_kindtypeREAL1)
95eb4fd9
TM
4320 /* We used to call FFECOM_gfrtALOG10 here. */
4321 gfrt = FFECOM_gfrtL_LOG10;
5ff904cd 4322 else if (kt == FFEINFO_kindtypeREAL2)
95eb4fd9
TM
4323 /* We used to call FFECOM_gfrtDLOG10 here. */
4324 gfrt = FFECOM_gfrtL_LOG10;
5ff904cd
JL
4325 break;
4326
4327 case FFEINTRIN_impMAX:
4328 case FFEINTRIN_impAMAX0:
4329 case FFEINTRIN_impAMAX1:
4330 case FFEINTRIN_impDMAX1:
4331 case FFEINTRIN_impMAX0:
4332 case FFEINTRIN_impMAX1:
4333 if (bt != ffeinfo_basictype (ffebld_info (arg1)))
4334 arg1_type = ffecom_widest_expr_type_ (ffebld_right (expr));
4335 else
4336 arg1_type = tree_type;
4337 expr_tree = ffecom_2 (MAX_EXPR, arg1_type,
4338 convert (arg1_type, ffecom_expr (arg1)),
4339 convert (arg1_type, ffecom_expr (arg2)));
4340 for (; list != NULL; list = ffebld_trail (list))
4341 {
4342 if ((ffebld_head (list) == NULL)
4343 || (ffebld_op (ffebld_head (list)) == FFEBLD_opANY))
4344 continue;
4345 expr_tree = ffecom_2 (MAX_EXPR, arg1_type,
4346 expr_tree,
4347 convert (arg1_type,
4348 ffecom_expr (ffebld_head (list))));
4349 }
4350 return convert (tree_type, expr_tree);
4351
4352 case FFEINTRIN_impMIN:
4353 case FFEINTRIN_impAMIN0:
4354 case FFEINTRIN_impAMIN1:
4355 case FFEINTRIN_impDMIN1:
4356 case FFEINTRIN_impMIN0:
4357 case FFEINTRIN_impMIN1:
4358 if (bt != ffeinfo_basictype (ffebld_info (arg1)))
4359 arg1_type = ffecom_widest_expr_type_ (ffebld_right (expr));
4360 else
4361 arg1_type = tree_type;
4362 expr_tree = ffecom_2 (MIN_EXPR, arg1_type,
4363 convert (arg1_type, ffecom_expr (arg1)),
4364 convert (arg1_type, ffecom_expr (arg2)));
4365 for (; list != NULL; list = ffebld_trail (list))
4366 {
4367 if ((ffebld_head (list) == NULL)
4368 || (ffebld_op (ffebld_head (list)) == FFEBLD_opANY))
4369 continue;
4370 expr_tree = ffecom_2 (MIN_EXPR, arg1_type,
4371 expr_tree,
4372 convert (arg1_type,
4373 ffecom_expr (ffebld_head (list))));
4374 }
4375 return convert (tree_type, expr_tree);
4376
4377 case FFEINTRIN_impMOD:
4378 case FFEINTRIN_impAMOD:
4379 case FFEINTRIN_impDMOD:
4380 if (bt != FFEINFO_basictypeREAL)
4381 return ffecom_2 (TRUNC_MOD_EXPR, tree_type,
4382 convert (tree_type, ffecom_expr (arg1)),
4383 convert (tree_type, ffecom_expr (arg2)));
4384
4385 if (kt == FFEINFO_kindtypeREAL1)
95eb4fd9
TM
4386 /* We used to call FFECOM_gfrtAMOD here. */
4387 gfrt = FFECOM_gfrtL_FMOD;
5ff904cd 4388 else if (kt == FFEINFO_kindtypeREAL2)
95eb4fd9
TM
4389 /* We used to call FFECOM_gfrtDMOD here. */
4390 gfrt = FFECOM_gfrtL_FMOD;
5ff904cd
JL
4391 break;
4392
4393 case FFEINTRIN_impNINT:
4394 case FFEINTRIN_impIDNINT:
c7e4ee3a
CB
4395#if 0
4396 /* ~~Ideally FIX_ROUND_EXPR would be implemented, but it ain't yet. */
5ff904cd
JL
4397 return ffecom_1 (FIX_ROUND_EXPR, tree_type, ffecom_expr (arg1));
4398#else
4399 /* i__1 = r1 >= 0 ? floor(r1 + .5) : -floor(.5 - r1); */
4400 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
4401 return
4402 convert (ffecom_integer_type_node,
4403 ffecom_3 (COND_EXPR, arg1_type,
4404 ffecom_truth_value
4405 (ffecom_2 (GE_EXPR, integer_type_node,
4406 saved_expr1,
4407 convert (arg1_type,
4408 ffecom_float_zero_))),
4409 ffecom_2 (PLUS_EXPR, arg1_type,
4410 saved_expr1,
4411 convert (arg1_type,
4412 ffecom_float_half_)),
4413 ffecom_2 (MINUS_EXPR, arg1_type,
4414 saved_expr1,
4415 convert (arg1_type,
4416 ffecom_float_half_))));
4417#endif
4418
4419 case FFEINTRIN_impSIGN:
4420 case FFEINTRIN_impDSIGN:
4421 case FFEINTRIN_impISIGN:
4422 {
4423 tree arg2_tree = ffecom_expr (arg2);
4424
4425 saved_expr1
4426 = ffecom_save_tree
4427 (ffecom_1 (ABS_EXPR, tree_type,
4428 convert (tree_type,
4429 ffecom_expr (arg1))));
4430 expr_tree
4431 = ffecom_3 (COND_EXPR, tree_type,
4432 ffecom_truth_value
4433 (ffecom_2 (GE_EXPR, integer_type_node,
4434 arg2_tree,
4435 convert (TREE_TYPE (arg2_tree),
4436 integer_zero_node))),
4437 saved_expr1,
4438 ffecom_1 (NEGATE_EXPR, tree_type, saved_expr1));
4439 /* Make sure SAVE_EXPRs get referenced early enough. */
4440 expr_tree
4441 = ffecom_2 (COMPOUND_EXPR, tree_type,
4442 convert (void_type_node, saved_expr1),
4443 expr_tree);
4444 }
4445 return expr_tree;
4446
4447 case FFEINTRIN_impSIN:
4448 case FFEINTRIN_impCDSIN:
4449 case FFEINTRIN_impCSIN:
4450 case FFEINTRIN_impDSIN:
4451 if (bt == FFEINFO_basictypeCOMPLEX)
4452 {
4453 if (kt == FFEINFO_kindtypeREAL1)
4454 gfrt = FFECOM_gfrtCSIN; /* Overlapping result okay. */
4455 else if (kt == FFEINFO_kindtypeREAL2)
4456 gfrt = FFECOM_gfrtCDSIN; /* Overlapping result okay. */
4457 }
4458 break;
4459
4460 case FFEINTRIN_impSINH:
4461 case FFEINTRIN_impDSINH:
4462 break;
4463
4464 case FFEINTRIN_impSQRT:
4465 case FFEINTRIN_impCDSQRT:
4466 case FFEINTRIN_impCSQRT:
4467 case FFEINTRIN_impDSQRT:
4468 if (bt == FFEINFO_basictypeCOMPLEX)
4469 {
4470 if (kt == FFEINFO_kindtypeREAL1)
4471 gfrt = FFECOM_gfrtCSQRT; /* Overlapping result okay. */
4472 else if (kt == FFEINFO_kindtypeREAL2)
4473 gfrt = FFECOM_gfrtCDSQRT; /* Overlapping result okay. */
4474 }
4475 break;
4476
4477 case FFEINTRIN_impTAN:
4478 case FFEINTRIN_impDTAN:
4479 case FFEINTRIN_impTANH:
4480 case FFEINTRIN_impDTANH:
4481 break;
4482
4483 case FFEINTRIN_impREALPART:
4484 if (TREE_CODE (arg1_type) == COMPLEX_TYPE)
4485 arg1_type = TREE_TYPE (arg1_type);
4486 else
4487 arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type));
4488
4489 return
4490 convert (tree_type,
4491 ffecom_1 (REALPART_EXPR, arg1_type,
4492 ffecom_expr (arg1)));
4493
4494 case FFEINTRIN_impIAND:
4495 case FFEINTRIN_impAND:
4496 return ffecom_2 (BIT_AND_EXPR, tree_type,
4497 convert (tree_type,
4498 ffecom_expr (arg1)),
4499 convert (tree_type,
4500 ffecom_expr (arg2)));
4501
4502 case FFEINTRIN_impIOR:
4503 case FFEINTRIN_impOR:
4504 return ffecom_2 (BIT_IOR_EXPR, tree_type,
4505 convert (tree_type,
4506 ffecom_expr (arg1)),
4507 convert (tree_type,
4508 ffecom_expr (arg2)));
4509
4510 case FFEINTRIN_impIEOR:
4511 case FFEINTRIN_impXOR:
4512 return ffecom_2 (BIT_XOR_EXPR, tree_type,
4513 convert (tree_type,
4514 ffecom_expr (arg1)),
4515 convert (tree_type,
4516 ffecom_expr (arg2)));
4517
4518 case FFEINTRIN_impLSHIFT:
4519 return ffecom_2 (LSHIFT_EXPR, tree_type,
4520 ffecom_expr (arg1),
4521 convert (integer_type_node,
4522 ffecom_expr (arg2)));
4523
4524 case FFEINTRIN_impRSHIFT:
4525 return ffecom_2 (RSHIFT_EXPR, tree_type,
4526 ffecom_expr (arg1),
4527 convert (integer_type_node,
4528 ffecom_expr (arg2)));
4529
4530 case FFEINTRIN_impNOT:
4531 return ffecom_1 (BIT_NOT_EXPR, tree_type, ffecom_expr (arg1));
4532
4533 case FFEINTRIN_impBIT_SIZE:
4534 return convert (tree_type, TYPE_SIZE (arg1_type));
4535
4536 case FFEINTRIN_impBTEST:
4537 {
4538 ffetargetLogical1 true;
4539 ffetargetLogical1 false;
4540 tree true_tree;
4541 tree false_tree;
4542
4543 ffetarget_logical1 (&true, TRUE);
4544 ffetarget_logical1 (&false, FALSE);
4545 if (true == 1)
4546 true_tree = convert (tree_type, integer_one_node);
4547 else
4548 true_tree = convert (tree_type, build_int_2 (true, 0));
4549 if (false == 0)
4550 false_tree = convert (tree_type, integer_zero_node);
4551 else
4552 false_tree = convert (tree_type, build_int_2 (false, 0));
4553
4554 return
4555 ffecom_3 (COND_EXPR, tree_type,
4556 ffecom_truth_value
4557 (ffecom_2 (EQ_EXPR, integer_type_node,
4558 ffecom_2 (BIT_AND_EXPR, arg1_type,
4559 ffecom_expr (arg1),
4560 ffecom_2 (LSHIFT_EXPR, arg1_type,
4561 convert (arg1_type,
4562 integer_one_node),
4563 convert (integer_type_node,
4564 ffecom_expr (arg2)))),
4565 convert (arg1_type,
4566 integer_zero_node))),
4567 false_tree,
4568 true_tree);
4569 }
4570
4571 case FFEINTRIN_impIBCLR:
4572 return
4573 ffecom_2 (BIT_AND_EXPR, tree_type,
4574 ffecom_expr (arg1),
4575 ffecom_1 (BIT_NOT_EXPR, tree_type,
4576 ffecom_2 (LSHIFT_EXPR, tree_type,
4577 convert (tree_type,
4578 integer_one_node),
4579 convert (integer_type_node,
4580 ffecom_expr (arg2)))));
4581
4582 case FFEINTRIN_impIBITS:
4583 {
4584 tree arg3_tree = ffecom_save_tree (convert (integer_type_node,
4585 ffecom_expr (arg3)));
4586 tree uns_type
4587 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4588
4589 expr_tree
4590 = ffecom_2 (BIT_AND_EXPR, tree_type,
4591 ffecom_2 (RSHIFT_EXPR, tree_type,
4592 ffecom_expr (arg1),
4593 convert (integer_type_node,
4594 ffecom_expr (arg2))),
4595 convert (tree_type,
4596 ffecom_2 (RSHIFT_EXPR, uns_type,
4597 ffecom_1 (BIT_NOT_EXPR,
4598 uns_type,
4599 convert (uns_type,
4600 integer_zero_node)),
4601 ffecom_2 (MINUS_EXPR,
4602 integer_type_node,
4603 TYPE_SIZE (uns_type),
4604 arg3_tree))));
4605#if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4606 expr_tree
4607 = ffecom_3 (COND_EXPR, tree_type,
4608 ffecom_truth_value
4609 (ffecom_2 (NE_EXPR, integer_type_node,
4610 arg3_tree,
4611 integer_zero_node)),
4612 expr_tree,
4613 convert (tree_type, integer_zero_node));
4614#endif
4615 }
4616 return expr_tree;
4617
4618 case FFEINTRIN_impIBSET:
4619 return
4620 ffecom_2 (BIT_IOR_EXPR, tree_type,
4621 ffecom_expr (arg1),
4622 ffecom_2 (LSHIFT_EXPR, tree_type,
4623 convert (tree_type, integer_one_node),
4624 convert (integer_type_node,
4625 ffecom_expr (arg2))));
4626
4627 case FFEINTRIN_impISHFT:
4628 {
4629 tree arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4630 tree arg2_tree = ffecom_save_tree (convert (integer_type_node,
4631 ffecom_expr (arg2)));
4632 tree uns_type
4633 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4634
4635 expr_tree
4636 = ffecom_3 (COND_EXPR, tree_type,
4637 ffecom_truth_value
4638 (ffecom_2 (GE_EXPR, integer_type_node,
4639 arg2_tree,
4640 integer_zero_node)),
4641 ffecom_2 (LSHIFT_EXPR, tree_type,
4642 arg1_tree,
4643 arg2_tree),
4644 convert (tree_type,
4645 ffecom_2 (RSHIFT_EXPR, uns_type,
4646 convert (uns_type, arg1_tree),
4647 ffecom_1 (NEGATE_EXPR,
4648 integer_type_node,
4649 arg2_tree))));
4650#if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4651 expr_tree
4652 = ffecom_3 (COND_EXPR, tree_type,
4653 ffecom_truth_value
4654 (ffecom_2 (NE_EXPR, integer_type_node,
4655 arg2_tree,
4656 TYPE_SIZE (uns_type))),
4657 expr_tree,
4658 convert (tree_type, integer_zero_node));
4659#endif
4660 /* Make sure SAVE_EXPRs get referenced early enough. */
4661 expr_tree
4662 = ffecom_2 (COMPOUND_EXPR, tree_type,
4663 convert (void_type_node, arg1_tree),
4664 ffecom_2 (COMPOUND_EXPR, tree_type,
4665 convert (void_type_node, arg2_tree),
4666 expr_tree));
4667 }
4668 return expr_tree;
4669
4670 case FFEINTRIN_impISHFTC:
4671 {
4672 tree arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4673 tree arg2_tree = ffecom_save_tree (convert (integer_type_node,
4674 ffecom_expr (arg2)));
4675 tree arg3_tree = (arg3 == NULL) ? TYPE_SIZE (tree_type)
4676 : ffecom_save_tree (convert (integer_type_node, ffecom_expr (arg3)));
4677 tree shift_neg;
4678 tree shift_pos;
4679 tree mask_arg1;
4680 tree masked_arg1;
4681 tree uns_type
4682 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4683
4684 mask_arg1
4685 = ffecom_2 (LSHIFT_EXPR, tree_type,
4686 ffecom_1 (BIT_NOT_EXPR, tree_type,
4687 convert (tree_type, integer_zero_node)),
4688 arg3_tree);
4689#if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4690 mask_arg1
4691 = ffecom_3 (COND_EXPR, tree_type,
4692 ffecom_truth_value
4693 (ffecom_2 (NE_EXPR, integer_type_node,
4694 arg3_tree,
4695 TYPE_SIZE (uns_type))),
4696 mask_arg1,
4697 convert (tree_type, integer_zero_node));
4698#endif
4699 mask_arg1 = ffecom_save_tree (mask_arg1);
4700 masked_arg1
4701 = ffecom_2 (BIT_AND_EXPR, tree_type,
4702 arg1_tree,
4703 ffecom_1 (BIT_NOT_EXPR, tree_type,
4704 mask_arg1));
4705 masked_arg1 = ffecom_save_tree (masked_arg1);
4706 shift_neg
4707 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4708 convert (tree_type,
4709 ffecom_2 (RSHIFT_EXPR, uns_type,
4710 convert (uns_type, masked_arg1),
4711 ffecom_1 (NEGATE_EXPR,
4712 integer_type_node,
4713 arg2_tree))),
4714 ffecom_2 (LSHIFT_EXPR, tree_type,
4715 arg1_tree,
4716 ffecom_2 (PLUS_EXPR, integer_type_node,
4717 arg2_tree,
4718 arg3_tree)));
4719 shift_pos
4720 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4721 ffecom_2 (LSHIFT_EXPR, tree_type,
4722 arg1_tree,
4723 arg2_tree),
4724 convert (tree_type,
4725 ffecom_2 (RSHIFT_EXPR, uns_type,
4726 convert (uns_type, masked_arg1),
4727 ffecom_2 (MINUS_EXPR,
4728 integer_type_node,
4729 arg3_tree,
4730 arg2_tree))));
4731 expr_tree
4732 = ffecom_3 (COND_EXPR, tree_type,
4733 ffecom_truth_value
4734 (ffecom_2 (LT_EXPR, integer_type_node,
4735 arg2_tree,
4736 integer_zero_node)),
4737 shift_neg,
4738 shift_pos);
4739 expr_tree
4740 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4741 ffecom_2 (BIT_AND_EXPR, tree_type,
4742 mask_arg1,
4743 arg1_tree),
4744 ffecom_2 (BIT_AND_EXPR, tree_type,
4745 ffecom_1 (BIT_NOT_EXPR, tree_type,
4746 mask_arg1),
4747 expr_tree));
4748 expr_tree
4749 = ffecom_3 (COND_EXPR, tree_type,
4750 ffecom_truth_value
4751 (ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
4752 ffecom_2 (EQ_EXPR, integer_type_node,
4753 ffecom_1 (ABS_EXPR,
4754 integer_type_node,
4755 arg2_tree),
4756 arg3_tree),
4757 ffecom_2 (EQ_EXPR, integer_type_node,
4758 arg2_tree,
4759 integer_zero_node))),
4760 arg1_tree,
4761 expr_tree);
4762 /* Make sure SAVE_EXPRs get referenced early enough. */
4763 expr_tree
4764 = ffecom_2 (COMPOUND_EXPR, tree_type,
4765 convert (void_type_node, arg1_tree),
4766 ffecom_2 (COMPOUND_EXPR, tree_type,
4767 convert (void_type_node, arg2_tree),
4768 ffecom_2 (COMPOUND_EXPR, tree_type,
4769 convert (void_type_node,
4770 mask_arg1),
4771 ffecom_2 (COMPOUND_EXPR, tree_type,
4772 convert (void_type_node,
4773 masked_arg1),
4774 expr_tree))));
4775 expr_tree
4776 = ffecom_2 (COMPOUND_EXPR, tree_type,
4777 convert (void_type_node,
4778 arg3_tree),
4779 expr_tree);
4780 }
4781 return expr_tree;
4782
4783 case FFEINTRIN_impLOC:
4784 {
4785 tree arg1_tree = ffecom_expr (arg1);
4786
4787 expr_tree
4788 = convert (tree_type,
4789 ffecom_1 (ADDR_EXPR,
4790 build_pointer_type (TREE_TYPE (arg1_tree)),
4791 arg1_tree));
4792 }
4793 return expr_tree;
4794
4795 case FFEINTRIN_impMVBITS:
4796 {
4797 tree arg1_tree;
4798 tree arg2_tree;
4799 tree arg3_tree;
4800 ffebld arg4 = ffebld_head (ffebld_trail (list));
4801 tree arg4_tree;
4802 tree arg4_type;
4803 ffebld arg5 = ffebld_head (ffebld_trail (ffebld_trail (list)));
4804 tree arg5_tree;
4805 tree prep_arg1;
4806 tree prep_arg4;
4807 tree arg5_plus_arg3;
4808
5ff904cd
JL
4809 arg2_tree = convert (integer_type_node,
4810 ffecom_expr (arg2));
4811 arg3_tree = ffecom_save_tree (convert (integer_type_node,
4812 ffecom_expr (arg3)));
c7e4ee3a 4813 arg4_tree = ffecom_expr_rw (NULL_TREE, arg4);
5ff904cd
JL
4814 arg4_type = TREE_TYPE (arg4_tree);
4815
4816 arg1_tree = ffecom_save_tree (convert (arg4_type,
4817 ffecom_expr (arg1)));
4818
4819 arg5_tree = ffecom_save_tree (convert (integer_type_node,
4820 ffecom_expr (arg5)));
4821
5ff904cd
JL
4822 prep_arg1
4823 = ffecom_2 (LSHIFT_EXPR, arg4_type,
4824 ffecom_2 (BIT_AND_EXPR, arg4_type,
4825 ffecom_2 (RSHIFT_EXPR, arg4_type,
4826 arg1_tree,
4827 arg2_tree),
4828 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4829 ffecom_2 (LSHIFT_EXPR, arg4_type,
4830 ffecom_1 (BIT_NOT_EXPR,
4831 arg4_type,
4832 convert
4833 (arg4_type,
4834 integer_zero_node)),
4835 arg3_tree))),
4836 arg5_tree);
4837 arg5_plus_arg3
4838 = ffecom_save_tree (ffecom_2 (PLUS_EXPR, arg4_type,
4839 arg5_tree,
4840 arg3_tree));
4841 prep_arg4
4842 = ffecom_2 (LSHIFT_EXPR, arg4_type,
4843 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4844 convert (arg4_type,
4845 integer_zero_node)),
4846 arg5_plus_arg3);
4847#if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4848 prep_arg4
4849 = ffecom_3 (COND_EXPR, arg4_type,
4850 ffecom_truth_value
4851 (ffecom_2 (NE_EXPR, integer_type_node,
4852 arg5_plus_arg3,
4853 convert (TREE_TYPE (arg5_plus_arg3),
4854 TYPE_SIZE (arg4_type)))),
4855 prep_arg4,
4856 convert (arg4_type, integer_zero_node));
4857#endif
4858 prep_arg4
4859 = ffecom_2 (BIT_AND_EXPR, arg4_type,
4860 arg4_tree,
4861 ffecom_2 (BIT_IOR_EXPR, arg4_type,
4862 prep_arg4,
4863 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4864 ffecom_2 (LSHIFT_EXPR, arg4_type,
4865 ffecom_1 (BIT_NOT_EXPR,
4866 arg4_type,
4867 convert
4868 (arg4_type,
4869 integer_zero_node)),
4870 arg5_tree))));
4871 prep_arg1
4872 = ffecom_2 (BIT_IOR_EXPR, arg4_type,
4873 prep_arg1,
4874 prep_arg4);
4875#if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4876 prep_arg1
4877 = ffecom_3 (COND_EXPR, arg4_type,
4878 ffecom_truth_value
4879 (ffecom_2 (NE_EXPR, integer_type_node,
4880 arg3_tree,
4881 convert (TREE_TYPE (arg3_tree),
4882 integer_zero_node))),
4883 prep_arg1,
4884 arg4_tree);
4885 prep_arg1
4886 = ffecom_3 (COND_EXPR, arg4_type,
4887 ffecom_truth_value
4888 (ffecom_2 (NE_EXPR, integer_type_node,
4889 arg3_tree,
4890 convert (TREE_TYPE (arg3_tree),
4891 TYPE_SIZE (arg4_type)))),
4892 prep_arg1,
4893 arg1_tree);
4894#endif
4895 expr_tree
4896 = ffecom_2s (MODIFY_EXPR, void_type_node,
4897 arg4_tree,
4898 prep_arg1);
4899 /* Make sure SAVE_EXPRs get referenced early enough. */
4900 expr_tree
4901 = ffecom_2 (COMPOUND_EXPR, void_type_node,
4902 arg1_tree,
4903 ffecom_2 (COMPOUND_EXPR, void_type_node,
4904 arg3_tree,
4905 ffecom_2 (COMPOUND_EXPR, void_type_node,
4906 arg5_tree,
4907 ffecom_2 (COMPOUND_EXPR, void_type_node,
4908 arg5_plus_arg3,
4909 expr_tree))));
4910 expr_tree
4911 = ffecom_2 (COMPOUND_EXPR, void_type_node,
4912 arg4_tree,
4913 expr_tree);
4914
4915 }
4916 return expr_tree;
4917
4918 case FFEINTRIN_impDERF:
4919 case FFEINTRIN_impERF:
4920 case FFEINTRIN_impDERFC:
4921 case FFEINTRIN_impERFC:
4922 break;
4923
4924 case FFEINTRIN_impIARGC:
4925 /* extern int xargc; i__1 = xargc - 1; */
4926 expr_tree = ffecom_2 (MINUS_EXPR, TREE_TYPE (ffecom_tree_xargc_),
4927 ffecom_tree_xargc_,
4928 convert (TREE_TYPE (ffecom_tree_xargc_),
4929 integer_one_node));
4930 return expr_tree;
4931
4932 case FFEINTRIN_impSIGNAL_func:
4933 case FFEINTRIN_impSIGNAL_subr:
4934 {
4935 tree arg1_tree;
4936 tree arg2_tree;
4937 tree arg3_tree;
4938
5ff904cd
JL
4939 arg1_tree = convert (ffecom_f2c_integer_type_node,
4940 ffecom_expr (arg1));
4941 arg1_tree = ffecom_1 (ADDR_EXPR,
4942 build_pointer_type (TREE_TYPE (arg1_tree)),
4943 arg1_tree);
4944
4945 /* Pass procedure as a pointer to it, anything else by value. */
4946 if (ffeinfo_kind (ffebld_info (arg2)) == FFEINFO_kindENTITY)
4947 arg2_tree = convert (integer_type_node, ffecom_expr (arg2));
4948 else
4949 arg2_tree = ffecom_ptr_to_expr (arg2);
4950 arg2_tree = convert (TREE_TYPE (null_pointer_node),
4951 arg2_tree);
4952
4953 if (arg3 != NULL)
c7e4ee3a 4954 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
4955 else
4956 arg3_tree = NULL_TREE;
4957
5ff904cd
JL
4958 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4959 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
4960 TREE_CHAIN (arg1_tree) = arg2_tree;
4961
4962 expr_tree
4963 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4964 ffecom_gfrt_kindtype (gfrt),
4965 FALSE,
4966 ((codegen_imp == FFEINTRIN_impSIGNAL_subr) ?
4967 NULL_TREE :
4968 tree_type),
4969 arg1_tree,
c7e4ee3a
CB
4970 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4971 ffebld_nonter_hook (expr));
5ff904cd
JL
4972
4973 if (arg3_tree != NULL_TREE)
4974 expr_tree
4975 = ffecom_modify (NULL_TREE, arg3_tree,
4976 convert (TREE_TYPE (arg3_tree),
4977 expr_tree));
4978 }
4979 return expr_tree;
4980
4981 case FFEINTRIN_impALARM:
4982 {
4983 tree arg1_tree;
4984 tree arg2_tree;
4985 tree arg3_tree;
4986
5ff904cd
JL
4987 arg1_tree = convert (ffecom_f2c_integer_type_node,
4988 ffecom_expr (arg1));
4989 arg1_tree = ffecom_1 (ADDR_EXPR,
4990 build_pointer_type (TREE_TYPE (arg1_tree)),
4991 arg1_tree);
4992
4993 /* Pass procedure as a pointer to it, anything else by value. */
4994 if (ffeinfo_kind (ffebld_info (arg2)) == FFEINFO_kindENTITY)
4995 arg2_tree = convert (integer_type_node, ffecom_expr (arg2));
4996 else
4997 arg2_tree = ffecom_ptr_to_expr (arg2);
4998 arg2_tree = convert (TREE_TYPE (null_pointer_node),
4999 arg2_tree);
5000
5001 if (arg3 != NULL)
c7e4ee3a 5002 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
5003 else
5004 arg3_tree = NULL_TREE;
5005
5ff904cd
JL
5006 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5007 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5008 TREE_CHAIN (arg1_tree) = arg2_tree;
5009
5010 expr_tree
5011 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5012 ffecom_gfrt_kindtype (gfrt),
5013 FALSE,
5014 NULL_TREE,
5015 arg1_tree,
c7e4ee3a
CB
5016 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5017 ffebld_nonter_hook (expr));
5ff904cd
JL
5018
5019 if (arg3_tree != NULL_TREE)
5020 expr_tree
5021 = ffecom_modify (NULL_TREE, arg3_tree,
5022 convert (TREE_TYPE (arg3_tree),
5023 expr_tree));
5024 }
5025 return expr_tree;
5026
5027 case FFEINTRIN_impCHDIR_subr:
5028 case FFEINTRIN_impFDATE_subr:
5029 case FFEINTRIN_impFGET_subr:
5030 case FFEINTRIN_impFPUT_subr:
5031 case FFEINTRIN_impGETCWD_subr:
5032 case FFEINTRIN_impHOSTNM_subr:
5033 case FFEINTRIN_impSYSTEM_subr:
5034 case FFEINTRIN_impUNLINK_subr:
5035 {
5036 tree arg1_len = integer_zero_node;
5037 tree arg1_tree;
5038 tree arg2_tree;
5039
5ff904cd
JL
5040 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
5041
5042 if (arg2 != NULL)
c7e4ee3a 5043 arg2_tree = ffecom_expr_w (NULL_TREE, arg2);
5ff904cd
JL
5044 else
5045 arg2_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 TREE_CHAIN (arg1_tree) = arg1_len;
5050
5051 expr_tree
5052 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5053 ffecom_gfrt_kindtype (gfrt),
5054 FALSE,
5055 NULL_TREE,
5056 arg1_tree,
c7e4ee3a
CB
5057 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5058 ffebld_nonter_hook (expr));
5ff904cd
JL
5059
5060 if (arg2_tree != NULL_TREE)
5061 expr_tree
5062 = ffecom_modify (NULL_TREE, arg2_tree,
5063 convert (TREE_TYPE (arg2_tree),
5064 expr_tree));
5065 }
5066 return expr_tree;
5067
5068 case FFEINTRIN_impEXIT:
5069 if (arg1 != NULL)
5070 break;
5071
5072 expr_tree = build_tree_list (NULL_TREE,
5073 ffecom_1 (ADDR_EXPR,
5074 build_pointer_type
5075 (ffecom_integer_type_node),
5076 integer_zero_node));
5077
5078 return
5079 ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5080 ffecom_gfrt_kindtype (gfrt),
5081 FALSE,
5082 void_type_node,
5083 expr_tree,
c7e4ee3a
CB
5084 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5085 ffebld_nonter_hook (expr));
5ff904cd
JL
5086
5087 case FFEINTRIN_impFLUSH:
5088 if (arg1 == NULL)
5089 gfrt = FFECOM_gfrtFLUSH;
5090 else
5091 gfrt = FFECOM_gfrtFLUSH1;
5092 break;
5093
5094 case FFEINTRIN_impCHMOD_subr:
5095 case FFEINTRIN_impLINK_subr:
5096 case FFEINTRIN_impRENAME_subr:
5097 case FFEINTRIN_impSYMLNK_subr:
5098 {
5099 tree arg1_len = integer_zero_node;
5100 tree arg1_tree;
5101 tree arg2_len = integer_zero_node;
5102 tree arg2_tree;
5103 tree arg3_tree;
5104
5ff904cd
JL
5105 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
5106 arg2_tree = ffecom_arg_ptr_to_expr (arg2, &arg2_len);
5107 if (arg3 != NULL)
c7e4ee3a 5108 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
5109 else
5110 arg3_tree = NULL_TREE;
5111
5ff904cd
JL
5112 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5113 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5114 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5115 arg2_len = build_tree_list (NULL_TREE, arg2_len);
5116 TREE_CHAIN (arg1_tree) = arg2_tree;
5117 TREE_CHAIN (arg2_tree) = arg1_len;
5118 TREE_CHAIN (arg1_len) = arg2_len;
5119 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5120 ffecom_gfrt_kindtype (gfrt),
5121 FALSE,
5122 NULL_TREE,
5123 arg1_tree,
c7e4ee3a
CB
5124 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5125 ffebld_nonter_hook (expr));
5ff904cd
JL
5126 if (arg3_tree != NULL_TREE)
5127 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5128 convert (TREE_TYPE (arg3_tree),
5129 expr_tree));
5130 }
5131 return expr_tree;
5132
5133 case FFEINTRIN_impLSTAT_subr:
5134 case FFEINTRIN_impSTAT_subr:
5135 {
5136 tree arg1_len = integer_zero_node;
5137 tree arg1_tree;
5138 tree arg2_tree;
5139 tree arg3_tree;
5140
5ff904cd
JL
5141 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
5142
5143 arg2_tree = ffecom_ptr_to_expr (arg2);
5144
5145 if (arg3 != NULL)
c7e4ee3a 5146 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
5147 else
5148 arg3_tree = NULL_TREE;
5149
5ff904cd
JL
5150 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5151 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5152 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5153 TREE_CHAIN (arg1_tree) = arg2_tree;
5154 TREE_CHAIN (arg2_tree) = arg1_len;
5155 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5156 ffecom_gfrt_kindtype (gfrt),
5157 FALSE,
5158 NULL_TREE,
5159 arg1_tree,
c7e4ee3a
CB
5160 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5161 ffebld_nonter_hook (expr));
5ff904cd
JL
5162 if (arg3_tree != NULL_TREE)
5163 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5164 convert (TREE_TYPE (arg3_tree),
5165 expr_tree));
5166 }
5167 return expr_tree;
5168
5169 case FFEINTRIN_impFGETC_subr:
5170 case FFEINTRIN_impFPUTC_subr:
5171 {
5172 tree arg1_tree;
5173 tree arg2_tree;
5174 tree arg2_len = integer_zero_node;
5175 tree arg3_tree;
5176
5ff904cd
JL
5177 arg1_tree = convert (ffecom_f2c_integer_type_node,
5178 ffecom_expr (arg1));
5179 arg1_tree = ffecom_1 (ADDR_EXPR,
5180 build_pointer_type (TREE_TYPE (arg1_tree)),
5181 arg1_tree);
5182
5183 arg2_tree = ffecom_arg_ptr_to_expr (arg2, &arg2_len);
62b3b9db
TM
5184 if (arg3 != NULL)
5185 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5186 else
5187 arg3_tree = NULL_TREE;
5ff904cd
JL
5188
5189 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5190 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5191 arg2_len = build_tree_list (NULL_TREE, arg2_len);
5192 TREE_CHAIN (arg1_tree) = arg2_tree;
5193 TREE_CHAIN (arg2_tree) = arg2_len;
5194
5195 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5196 ffecom_gfrt_kindtype (gfrt),
5197 FALSE,
5198 NULL_TREE,
5199 arg1_tree,
c7e4ee3a
CB
5200 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5201 ffebld_nonter_hook (expr));
62b3b9db
TM
5202 if (arg3_tree != NULL_TREE)
5203 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5204 convert (TREE_TYPE (arg3_tree),
5205 expr_tree));
5ff904cd
JL
5206 }
5207 return expr_tree;
5208
5209 case FFEINTRIN_impFSTAT_subr:
5210 {
5211 tree arg1_tree;
5212 tree arg2_tree;
5213 tree arg3_tree;
5214
5ff904cd
JL
5215 arg1_tree = convert (ffecom_f2c_integer_type_node,
5216 ffecom_expr (arg1));
5217 arg1_tree = ffecom_1 (ADDR_EXPR,
5218 build_pointer_type (TREE_TYPE (arg1_tree)),
5219 arg1_tree);
5220
5221 arg2_tree = convert (ffecom_f2c_ptr_to_integer_type_node,
5222 ffecom_ptr_to_expr (arg2));
5223
5224 if (arg3 == NULL)
5225 arg3_tree = NULL_TREE;
5226 else
c7e4ee3a 5227 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
5228
5229 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5230 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5231 TREE_CHAIN (arg1_tree) = arg2_tree;
5232 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5233 ffecom_gfrt_kindtype (gfrt),
5234 FALSE,
5235 NULL_TREE,
5236 arg1_tree,
c7e4ee3a
CB
5237 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5238 ffebld_nonter_hook (expr));
5ff904cd
JL
5239 if (arg3_tree != NULL_TREE) {
5240 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5241 convert (TREE_TYPE (arg3_tree),
5242 expr_tree));
5243 }
5244 }
5245 return expr_tree;
5246
5247 case FFEINTRIN_impKILL_subr:
5248 {
5249 tree arg1_tree;
5250 tree arg2_tree;
5251 tree arg3_tree;
5252
5ff904cd
JL
5253 arg1_tree = convert (ffecom_f2c_integer_type_node,
5254 ffecom_expr (arg1));
5255 arg1_tree = ffecom_1 (ADDR_EXPR,
5256 build_pointer_type (TREE_TYPE (arg1_tree)),
5257 arg1_tree);
5258
5259 arg2_tree = convert (ffecom_f2c_integer_type_node,
5260 ffecom_expr (arg2));
5261 arg2_tree = ffecom_1 (ADDR_EXPR,
5262 build_pointer_type (TREE_TYPE (arg2_tree)),
5263 arg2_tree);
5264
5265 if (arg3 == NULL)
5266 arg3_tree = NULL_TREE;
5267 else
c7e4ee3a 5268 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
5269
5270 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5271 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5272 TREE_CHAIN (arg1_tree) = arg2_tree;
5273 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5274 ffecom_gfrt_kindtype (gfrt),
5275 FALSE,
5276 NULL_TREE,
5277 arg1_tree,
c7e4ee3a
CB
5278 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5279 ffebld_nonter_hook (expr));
5ff904cd
JL
5280 if (arg3_tree != NULL_TREE) {
5281 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5282 convert (TREE_TYPE (arg3_tree),
5283 expr_tree));
5284 }
5285 }
5286 return expr_tree;
5287
5288 case FFEINTRIN_impCTIME_subr:
5289 case FFEINTRIN_impTTYNAM_subr:
5290 {
5291 tree arg1_len = integer_zero_node;
5292 tree arg1_tree;
5293 tree arg2_tree;
5294
2b0bdd9a 5295 arg1_tree = ffecom_arg_ptr_to_expr (arg2, &arg1_len);
5ff904cd 5296
c56f65d6 5297 arg2_tree = convert (((codegen_imp == FFEINTRIN_impCTIME_subr) ?
5ff904cd
JL
5298 ffecom_f2c_longint_type_node :
5299 ffecom_f2c_integer_type_node),
2b0bdd9a 5300 ffecom_expr (arg1));
5ff904cd
JL
5301 arg2_tree = ffecom_1 (ADDR_EXPR,
5302 build_pointer_type (TREE_TYPE (arg2_tree)),
5303 arg2_tree);
5304
5ff904cd
JL
5305 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5306 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5307 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5308 TREE_CHAIN (arg1_len) = arg2_tree;
5309 TREE_CHAIN (arg1_tree) = arg1_len;
5310
5311 expr_tree
5312 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5313 ffecom_gfrt_kindtype (gfrt),
5314 FALSE,
5315 NULL_TREE,
5316 arg1_tree,
c7e4ee3a
CB
5317 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5318 ffebld_nonter_hook (expr));
2b0bdd9a 5319 TREE_SIDE_EFFECTS (expr_tree) = 1;
5ff904cd
JL
5320 }
5321 return expr_tree;
5322
5323 case FFEINTRIN_impIRAND:
5324 case FFEINTRIN_impRAND:
5325 /* Arg defaults to 0 (normal random case) */
5326 {
5327 tree arg1_tree;
5328
5329 if (arg1 == NULL)
5330 arg1_tree = ffecom_integer_zero_node;
5331 else
5332 arg1_tree = ffecom_expr (arg1);
5333 arg1_tree = convert (ffecom_f2c_integer_type_node,
5334 arg1_tree);
5335 arg1_tree = ffecom_1 (ADDR_EXPR,
5336 build_pointer_type (TREE_TYPE (arg1_tree)),
5337 arg1_tree);
5338 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5339
5340 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5341 ffecom_gfrt_kindtype (gfrt),
5342 FALSE,
5343 ((codegen_imp == FFEINTRIN_impIRAND) ?
5344 ffecom_f2c_integer_type_node :
de7f278a 5345 ffecom_f2c_real_type_node),
5ff904cd
JL
5346 arg1_tree,
5347 dest_tree, dest, dest_used,
c7e4ee3a
CB
5348 NULL_TREE, TRUE,
5349 ffebld_nonter_hook (expr));
5ff904cd
JL
5350 }
5351 return expr_tree;
5352
5353 case FFEINTRIN_impFTELL_subr:
5354 case FFEINTRIN_impUMASK_subr:
5355 {
5356 tree arg1_tree;
5357 tree arg2_tree;
5358
5ff904cd
JL
5359 arg1_tree = convert (ffecom_f2c_integer_type_node,
5360 ffecom_expr (arg1));
5361 arg1_tree = ffecom_1 (ADDR_EXPR,
5362 build_pointer_type (TREE_TYPE (arg1_tree)),
5363 arg1_tree);
5364
5365 if (arg2 == NULL)
5366 arg2_tree = NULL_TREE;
5367 else
c7e4ee3a 5368 arg2_tree = ffecom_expr_w (NULL_TREE, arg2);
5ff904cd
JL
5369
5370 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5371 ffecom_gfrt_kindtype (gfrt),
5372 FALSE,
5373 NULL_TREE,
5374 build_tree_list (NULL_TREE, arg1_tree),
5375 NULL_TREE, NULL, NULL, NULL_TREE,
c7e4ee3a
CB
5376 TRUE,
5377 ffebld_nonter_hook (expr));
5ff904cd
JL
5378 if (arg2_tree != NULL_TREE) {
5379 expr_tree = ffecom_modify (NULL_TREE, arg2_tree,
5380 convert (TREE_TYPE (arg2_tree),
5381 expr_tree));
5382 }
5383 }
5384 return expr_tree;
5385
5386 case FFEINTRIN_impCPU_TIME:
5387 case FFEINTRIN_impSECOND_subr:
5388 {
5389 tree arg1_tree;
5390
c7e4ee3a 5391 arg1_tree = ffecom_expr_w (NULL_TREE, arg1);
5ff904cd
JL
5392
5393 expr_tree
5394 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5395 ffecom_gfrt_kindtype (gfrt),
5396 FALSE,
5397 NULL_TREE,
5398 NULL_TREE,
c7e4ee3a
CB
5399 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5400 ffebld_nonter_hook (expr));
5ff904cd
JL
5401
5402 expr_tree
5403 = ffecom_modify (NULL_TREE, arg1_tree,
5404 convert (TREE_TYPE (arg1_tree),
5405 expr_tree));
5406 }
5407 return expr_tree;
5408
5409 case FFEINTRIN_impDTIME_subr:
5410 case FFEINTRIN_impETIME_subr:
5411 {
5412 tree arg1_tree;
2b0bdd9a 5413 tree result_tree;
5ff904cd 5414
2b0bdd9a 5415 result_tree = ffecom_expr_w (NULL_TREE, arg2);
5ff904cd 5416
2b0bdd9a 5417 arg1_tree = ffecom_ptr_to_expr (arg1);
5ff904cd 5418
5ff904cd
JL
5419 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5420 ffecom_gfrt_kindtype (gfrt),
5421 FALSE,
5422 NULL_TREE,
2b0bdd9a 5423 build_tree_list (NULL_TREE, arg1_tree),
5ff904cd 5424 NULL_TREE, NULL, NULL, NULL_TREE,
c7e4ee3a
CB
5425 TRUE,
5426 ffebld_nonter_hook (expr));
2b0bdd9a
CB
5427 expr_tree = ffecom_modify (NULL_TREE, result_tree,
5428 convert (TREE_TYPE (result_tree),
5ff904cd
JL
5429 expr_tree));
5430 }
5431 return expr_tree;
5432
c7e4ee3a 5433 /* Straightforward calls of libf2c routines: */
5ff904cd
JL
5434 case FFEINTRIN_impABORT:
5435 case FFEINTRIN_impACCESS:
5436 case FFEINTRIN_impBESJ0:
5437 case FFEINTRIN_impBESJ1:
5438 case FFEINTRIN_impBESJN:
5439 case FFEINTRIN_impBESY0:
5440 case FFEINTRIN_impBESY1:
5441 case FFEINTRIN_impBESYN:
5442 case FFEINTRIN_impCHDIR_func:
5443 case FFEINTRIN_impCHMOD_func:
5444 case FFEINTRIN_impDATE:
9e8e701d 5445 case FFEINTRIN_impDATE_AND_TIME:
5ff904cd
JL
5446 case FFEINTRIN_impDBESJ0:
5447 case FFEINTRIN_impDBESJ1:
5448 case FFEINTRIN_impDBESJN:
5449 case FFEINTRIN_impDBESY0:
5450 case FFEINTRIN_impDBESY1:
5451 case FFEINTRIN_impDBESYN:
5452 case FFEINTRIN_impDTIME_func:
5453 case FFEINTRIN_impETIME_func:
5454 case FFEINTRIN_impFGETC_func:
5455 case FFEINTRIN_impFGET_func:
5456 case FFEINTRIN_impFNUM:
5457 case FFEINTRIN_impFPUTC_func:
5458 case FFEINTRIN_impFPUT_func:
5459 case FFEINTRIN_impFSEEK:
5460 case FFEINTRIN_impFSTAT_func:
5461 case FFEINTRIN_impFTELL_func:
5462 case FFEINTRIN_impGERROR:
5463 case FFEINTRIN_impGETARG:
5464 case FFEINTRIN_impGETCWD_func:
5465 case FFEINTRIN_impGETENV:
5466 case FFEINTRIN_impGETGID:
5467 case FFEINTRIN_impGETLOG:
5468 case FFEINTRIN_impGETPID:
5469 case FFEINTRIN_impGETUID:
5470 case FFEINTRIN_impGMTIME:
5471 case FFEINTRIN_impHOSTNM_func:
5472 case FFEINTRIN_impIDATE_unix:
5473 case FFEINTRIN_impIDATE_vxt:
5474 case FFEINTRIN_impIERRNO:
5475 case FFEINTRIN_impISATTY:
5476 case FFEINTRIN_impITIME:
5477 case FFEINTRIN_impKILL_func:
5478 case FFEINTRIN_impLINK_func:
5479 case FFEINTRIN_impLNBLNK:
5480 case FFEINTRIN_impLSTAT_func:
5481 case FFEINTRIN_impLTIME:
5482 case FFEINTRIN_impMCLOCK8:
5483 case FFEINTRIN_impMCLOCK:
5484 case FFEINTRIN_impPERROR:
5485 case FFEINTRIN_impRENAME_func:
5486 case FFEINTRIN_impSECNDS:
5487 case FFEINTRIN_impSECOND_func:
5488 case FFEINTRIN_impSLEEP:
5489 case FFEINTRIN_impSRAND:
5490 case FFEINTRIN_impSTAT_func:
5491 case FFEINTRIN_impSYMLNK_func:
5492 case FFEINTRIN_impSYSTEM_CLOCK:
5493 case FFEINTRIN_impSYSTEM_func:
5494 case FFEINTRIN_impTIME8:
5495 case FFEINTRIN_impTIME_unix:
5496 case FFEINTRIN_impTIME_vxt:
5497 case FFEINTRIN_impUMASK_func:
5498 case FFEINTRIN_impUNLINK_func:
5499 break;
5500
5501 case FFEINTRIN_impCTIME_func: /* CHARACTER functions not handled here. */
5502 case FFEINTRIN_impFDATE_func: /* CHARACTER functions not handled here. */
5503 case FFEINTRIN_impTTYNAM_func: /* CHARACTER functions not handled here. */
5504 case FFEINTRIN_impNONE:
5505 case FFEINTRIN_imp: /* Hush up gcc warning. */
5506 fprintf (stderr, "No %s implementation.\n",
5507 ffeintrin_name_implementation (ffebld_symter_implementation (ffebld_left (expr))));
5508 assert ("unimplemented intrinsic" == NULL);
5509 return error_mark_node;
5510 }
5511
5512 assert (gfrt != FFECOM_gfrt); /* Must have an implementation! */
5513
5ff904cd
JL
5514 expr_tree = ffecom_arglist_expr_ (ffecom_gfrt_args_ (gfrt),
5515 ffebld_right (expr));
5ff904cd
JL
5516
5517 return ffecom_call_ (ffecom_gfrt_tree_ (gfrt), ffecom_gfrt_kindtype (gfrt),
5518 (ffe_is_f2c_library () && ffecom_gfrt_complex_[gfrt]),
5519 tree_type,
5520 expr_tree, dest_tree, dest, dest_used,
c7e4ee3a
CB
5521 NULL_TREE, TRUE,
5522 ffebld_nonter_hook (expr));
5ff904cd 5523
c7e4ee3a
CB
5524 /* See bottom of this file for f2c transforms used to determine
5525 many of the above implementations. The info seems to confuse
5526 Emacs's C mode indentation, which is why it's been moved to
5527 the bottom of this source file. */
5528}
5ff904cd 5529
c7e4ee3a
CB
5530#endif
5531/* For power (exponentiation) where right-hand operand is type INTEGER,
5532 generate in-line code to do it the fast way (which, if the operand
5533 is a constant, might just mean a series of multiplies). */
5ff904cd 5534
c7e4ee3a
CB
5535#if FFECOM_targetCURRENT == FFECOM_targetGCC
5536static tree
5537ffecom_expr_power_integer_ (ffebld expr)
5538{
5539 tree l = ffecom_expr (ffebld_left (expr));
5540 tree r = ffecom_expr (ffebld_right (expr));
5541 tree ltype = TREE_TYPE (l);
5542 tree rtype = TREE_TYPE (r);
5543 tree result = NULL_TREE;
5ff904cd 5544
c7e4ee3a
CB
5545 if (l == error_mark_node
5546 || r == error_mark_node)
5547 return error_mark_node;
5ff904cd 5548
c7e4ee3a
CB
5549 if (TREE_CODE (r) == INTEGER_CST)
5550 {
5551 int sgn = tree_int_cst_sgn (r);
5ff904cd 5552
c7e4ee3a
CB
5553 if (sgn == 0)
5554 return convert (ltype, integer_one_node);
5ff904cd 5555
c7e4ee3a
CB
5556 if ((TREE_CODE (ltype) == INTEGER_TYPE)
5557 && (sgn < 0))
5558 {
5559 /* Reciprocal of integer is either 0, -1, or 1, so after
5560 calculating that (which we leave to the back end to do
5561 or not do optimally), don't bother with any multiplying. */
5ff904cd 5562
c7e4ee3a
CB
5563 result = ffecom_tree_divide_ (ltype,
5564 convert (ltype, integer_one_node),
5565 l,
5566 NULL_TREE, NULL, NULL, NULL_TREE);
5567 r = ffecom_1 (NEGATE_EXPR,
5568 rtype,
5569 r);
5570 if ((TREE_INT_CST_LOW (r) & 1) == 0)
5571 result = ffecom_1 (ABS_EXPR, rtype,
5572 result);
5573 }
5ff904cd 5574
c7e4ee3a
CB
5575 /* Generate appropriate series of multiplies, preceded
5576 by divide if the exponent is negative. */
5ff904cd 5577
c7e4ee3a 5578 l = save_expr (l);
5ff904cd 5579
c7e4ee3a
CB
5580 if (sgn < 0)
5581 {
5582 l = ffecom_tree_divide_ (ltype,
5583 convert (ltype, integer_one_node),
5584 l,
5585 NULL_TREE, NULL, NULL,
5586 ffebld_nonter_hook (expr));
5587 r = ffecom_1 (NEGATE_EXPR, rtype, r);
5588 assert (TREE_CODE (r) == INTEGER_CST);
5ff904cd 5589
c7e4ee3a
CB
5590 if (tree_int_cst_sgn (r) < 0)
5591 { /* The "most negative" number. */
5592 r = ffecom_1 (NEGATE_EXPR, rtype,
5593 ffecom_2 (RSHIFT_EXPR, rtype,
5594 r,
5595 integer_one_node));
5596 l = save_expr (l);
5597 l = ffecom_2 (MULT_EXPR, ltype,
5598 l,
5599 l);
5600 }
5601 }
5ff904cd 5602
c7e4ee3a
CB
5603 for (;;)
5604 {
5605 if (TREE_INT_CST_LOW (r) & 1)
5606 {
5607 if (result == NULL_TREE)
5608 result = l;
5609 else
5610 result = ffecom_2 (MULT_EXPR, ltype,
5611 result,
5612 l);
5613 }
5ff904cd 5614
c7e4ee3a
CB
5615 r = ffecom_2 (RSHIFT_EXPR, rtype,
5616 r,
5617 integer_one_node);
5618 if (integer_zerop (r))
5619 break;
5620 assert (TREE_CODE (r) == INTEGER_CST);
5ff904cd 5621
c7e4ee3a
CB
5622 l = save_expr (l);
5623 l = ffecom_2 (MULT_EXPR, ltype,
5624 l,
5625 l);
5626 }
5627 return result;
5628 }
5ff904cd 5629
c7e4ee3a
CB
5630 /* Though rhs isn't a constant, in-line code cannot be expanded
5631 while transforming dummies
5632 because the back end cannot be easily convinced to generate
5633 stores (MODIFY_EXPR), handle temporaries, and so on before
5634 all the appropriate rtx's have been generated for things like
5635 dummy args referenced in rhs -- which doesn't happen until
5636 store_parm_decls() is called (expand_function_start, I believe,
5637 does the actual rtx-stuffing of PARM_DECLs).
5ff904cd 5638
c7e4ee3a
CB
5639 So, in this case, let the caller generate the call to the
5640 run-time-library function to evaluate the power for us. */
5ff904cd 5641
c7e4ee3a
CB
5642 if (ffecom_transform_only_dummies_)
5643 return NULL_TREE;
5ff904cd 5644
c7e4ee3a
CB
5645 /* Right-hand operand not a constant, expand in-line code to figure
5646 out how to do the multiplies, &c.
5ff904cd 5647
c7e4ee3a
CB
5648 The returned expression is expressed this way in GNU C, where l and
5649 r are the "inputs":
5ff904cd 5650
c7e4ee3a
CB
5651 ({ typeof (r) rtmp = r;
5652 typeof (l) ltmp = l;
5653 typeof (l) result;
5ff904cd 5654
c7e4ee3a
CB
5655 if (rtmp == 0)
5656 result = 1;
5657 else
5658 {
5659 if ((basetypeof (l) == basetypeof (int))
5660 && (rtmp < 0))
5661 {
5662 result = ((typeof (l)) 1) / ltmp;
5663 if ((ltmp < 0) && (((-rtmp) & 1) == 0))
5664 result = -result;
5665 }
5666 else
5667 {
5668 result = 1;
5669 if ((basetypeof (l) != basetypeof (int))
5670 && (rtmp < 0))
5671 {
5672 ltmp = ((typeof (l)) 1) / ltmp;
5673 rtmp = -rtmp;
5674 if (rtmp < 0)
5675 {
5676 rtmp = -(rtmp >> 1);
5677 ltmp *= ltmp;
5678 }
5679 }
5680 for (;;)
5681 {
5682 if (rtmp & 1)
5683 result *= ltmp;
5684 if ((rtmp >>= 1) == 0)
5685 break;
5686 ltmp *= ltmp;
5687 }
5688 }
5689 }
5690 result;
5691 })
5ff904cd 5692
c7e4ee3a
CB
5693 Note that some of the above is compile-time collapsable, such as
5694 the first part of the if statements that checks the base type of
5695 l against int. The if statements are phrased that way to suggest
5696 an easy way to generate the if/else constructs here, knowing that
5697 the back end should (and probably does) eliminate the resulting
5698 dead code (either the int case or the non-int case), something
5699 it couldn't do without the redundant phrasing, requiring explicit
5700 dead-code elimination here, which would be kind of difficult to
5701 read. */
5ff904cd 5702
c7e4ee3a
CB
5703 {
5704 tree rtmp;
5705 tree ltmp;
5706 tree divide;
5707 tree basetypeof_l_is_int;
5708 tree se;
5709 tree t;
5ff904cd 5710
c7e4ee3a
CB
5711 basetypeof_l_is_int
5712 = build_int_2 ((TREE_CODE (ltype) == INTEGER_TYPE), 0);
5ff904cd 5713
c7e4ee3a 5714 se = expand_start_stmt_expr ();
5ff904cd 5715
c7e4ee3a
CB
5716 ffecom_start_compstmt ();
5717
5718#ifndef HAHA
5719 rtmp = ffecom_make_tempvar ("power_r", rtype,
5720 FFETARGET_charactersizeNONE, -1);
5721 ltmp = ffecom_make_tempvar ("power_l", ltype,
5722 FFETARGET_charactersizeNONE, -1);
5723 result = ffecom_make_tempvar ("power_res", ltype,
5724 FFETARGET_charactersizeNONE, -1);
5725 if (TREE_CODE (ltype) == COMPLEX_TYPE
5726 || TREE_CODE (ltype) == RECORD_TYPE)
5727 divide = ffecom_make_tempvar ("power_div", ltype,
5728 FFETARGET_charactersizeNONE, -1);
5729 else
5730 divide = NULL_TREE;
5731#else /* HAHA */
5732 {
5733 tree hook;
5734
5735 hook = ffebld_nonter_hook (expr);
5736 assert (hook);
5737 assert (TREE_CODE (hook) == TREE_VEC);
5738 assert (TREE_VEC_LENGTH (hook) == 4);
5739 rtmp = TREE_VEC_ELT (hook, 0);
5740 ltmp = TREE_VEC_ELT (hook, 1);
5741 result = TREE_VEC_ELT (hook, 2);
5742 divide = TREE_VEC_ELT (hook, 3);
5743 if (TREE_CODE (ltype) == COMPLEX_TYPE
5744 || TREE_CODE (ltype) == RECORD_TYPE)
5745 assert (divide);
5746 else
5747 assert (! divide);
5748 }
5749#endif /* HAHA */
5ff904cd 5750
c7e4ee3a
CB
5751 expand_expr_stmt (ffecom_modify (void_type_node,
5752 rtmp,
5753 r));
5754 expand_expr_stmt (ffecom_modify (void_type_node,
5755 ltmp,
5756 l));
5757 expand_start_cond (ffecom_truth_value
5758 (ffecom_2 (EQ_EXPR, integer_type_node,
5759 rtmp,
5760 convert (rtype, integer_zero_node))),
5761 0);
5762 expand_expr_stmt (ffecom_modify (void_type_node,
5763 result,
5764 convert (ltype, integer_one_node)));
5765 expand_start_else ();
5766 if (! integer_zerop (basetypeof_l_is_int))
5767 {
5768 expand_start_cond (ffecom_2 (LT_EXPR, integer_type_node,
5769 rtmp,
5770 convert (rtype,
5771 integer_zero_node)),
5772 0);
5773 expand_expr_stmt (ffecom_modify (void_type_node,
5774 result,
5775 ffecom_tree_divide_
5776 (ltype,
5777 convert (ltype, integer_one_node),
5778 ltmp,
5779 NULL_TREE, NULL, NULL,
5780 divide)));
5781 expand_start_cond (ffecom_truth_value
5782 (ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
5783 ffecom_2 (LT_EXPR, integer_type_node,
5784 ltmp,
5785 convert (ltype,
5786 integer_zero_node)),
5787 ffecom_2 (EQ_EXPR, integer_type_node,
5788 ffecom_2 (BIT_AND_EXPR,
5789 rtype,
5790 ffecom_1 (NEGATE_EXPR,
5791 rtype,
5792 rtmp),
5793 convert (rtype,
5794 integer_one_node)),
5795 convert (rtype,
5796 integer_zero_node)))),
5797 0);
5798 expand_expr_stmt (ffecom_modify (void_type_node,
5799 result,
5800 ffecom_1 (NEGATE_EXPR,
5801 ltype,
5802 result)));
5803 expand_end_cond ();
5804 expand_start_else ();
5805 }
5806 expand_expr_stmt (ffecom_modify (void_type_node,
5807 result,
5808 convert (ltype, integer_one_node)));
5809 expand_start_cond (ffecom_truth_value
5810 (ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
5811 ffecom_truth_value_invert
5812 (basetypeof_l_is_int),
5813 ffecom_2 (LT_EXPR, integer_type_node,
5814 rtmp,
5815 convert (rtype,
5816 integer_zero_node)))),
5817 0);
5818 expand_expr_stmt (ffecom_modify (void_type_node,
5819 ltmp,
5820 ffecom_tree_divide_
5821 (ltype,
5822 convert (ltype, integer_one_node),
5823 ltmp,
5824 NULL_TREE, NULL, NULL,
5825 divide)));
5826 expand_expr_stmt (ffecom_modify (void_type_node,
5827 rtmp,
5828 ffecom_1 (NEGATE_EXPR, rtype,
5829 rtmp)));
5830 expand_start_cond (ffecom_truth_value
5831 (ffecom_2 (LT_EXPR, integer_type_node,
5832 rtmp,
5833 convert (rtype, integer_zero_node))),
5834 0);
5835 expand_expr_stmt (ffecom_modify (void_type_node,
5836 rtmp,
5837 ffecom_1 (NEGATE_EXPR, rtype,
5838 ffecom_2 (RSHIFT_EXPR,
5839 rtype,
5840 rtmp,
5841 integer_one_node))));
5842 expand_expr_stmt (ffecom_modify (void_type_node,
5843 ltmp,
5844 ffecom_2 (MULT_EXPR, ltype,
5845 ltmp,
5846 ltmp)));
5847 expand_end_cond ();
5848 expand_end_cond ();
5849 expand_start_loop (1);
5850 expand_start_cond (ffecom_truth_value
5851 (ffecom_2 (BIT_AND_EXPR, rtype,
5852 rtmp,
5853 convert (rtype, integer_one_node))),
5854 0);
5855 expand_expr_stmt (ffecom_modify (void_type_node,
5856 result,
5857 ffecom_2 (MULT_EXPR, ltype,
5858 result,
5859 ltmp)));
5860 expand_end_cond ();
5861 expand_exit_loop_if_false (NULL,
5862 ffecom_truth_value
5863 (ffecom_modify (rtype,
5864 rtmp,
5865 ffecom_2 (RSHIFT_EXPR,
5866 rtype,
5867 rtmp,
5868 integer_one_node))));
5869 expand_expr_stmt (ffecom_modify (void_type_node,
5870 ltmp,
5871 ffecom_2 (MULT_EXPR, ltype,
5872 ltmp,
5873 ltmp)));
5874 expand_end_loop ();
5875 expand_end_cond ();
5876 if (!integer_zerop (basetypeof_l_is_int))
5877 expand_end_cond ();
5878 expand_expr_stmt (result);
5ff904cd 5879
c7e4ee3a 5880 t = ffecom_end_compstmt ();
5ff904cd 5881
c7e4ee3a 5882 result = expand_end_stmt_expr (se);
5ff904cd 5883
c7e4ee3a 5884 /* This code comes from c-parse.in, after its expand_end_stmt_expr. */
5ff904cd 5885
c7e4ee3a
CB
5886 if (TREE_CODE (t) == BLOCK)
5887 {
5888 /* Make a BIND_EXPR for the BLOCK already made. */
5889 result = build (BIND_EXPR, TREE_TYPE (result),
5890 NULL_TREE, result, t);
5891 /* Remove the block from the tree at this point.
5892 It gets put back at the proper place
5893 when the BIND_EXPR is expanded. */
5894 delete_block (t);
5895 }
5896 else
5897 result = t;
5898 }
5ff904cd 5899
c7e4ee3a
CB
5900 return result;
5901}
5ff904cd 5902
c7e4ee3a
CB
5903#endif
5904/* ffecom_expr_transform_ -- Transform symbols in expr
5ff904cd 5905
c7e4ee3a
CB
5906 ffebld expr; // FFE expression.
5907 ffecom_expr_transform_ (expr);
5ff904cd 5908
c7e4ee3a 5909 Recursive descent on expr while transforming any untransformed SYMTERs. */
5ff904cd 5910
c7e4ee3a
CB
5911#if FFECOM_targetCURRENT == FFECOM_targetGCC
5912static void
5913ffecom_expr_transform_ (ffebld expr)
5914{
5915 tree t;
5916 ffesymbol s;
5ff904cd 5917
c7e4ee3a 5918tail_recurse: /* :::::::::::::::::::: */
5ff904cd 5919
c7e4ee3a
CB
5920 if (expr == NULL)
5921 return;
5ff904cd 5922
c7e4ee3a
CB
5923 switch (ffebld_op (expr))
5924 {
5925 case FFEBLD_opSYMTER:
5926 s = ffebld_symter (expr);
5927 t = ffesymbol_hook (s).decl_tree;
5928 if ((t == NULL_TREE)
5929 && ((ffesymbol_kind (s) != FFEINFO_kindNONE)
5930 || ((ffesymbol_where (s) != FFEINFO_whereNONE)
5931 && (ffesymbol_where (s) != FFEINFO_whereINTRINSIC))))
5932 {
5933 s = ffecom_sym_transform_ (s);
5934 t = ffesymbol_hook (s).decl_tree; /* Sfunc expr non-dummy,
5935 DIMENSION expr? */
5936 }
5937 break; /* Ok if (t == NULL) here. */
5ff904cd 5938
c7e4ee3a
CB
5939 case FFEBLD_opITEM:
5940 ffecom_expr_transform_ (ffebld_head (expr));
5941 expr = ffebld_trail (expr);
5942 goto tail_recurse; /* :::::::::::::::::::: */
5ff904cd 5943
c7e4ee3a
CB
5944 default:
5945 break;
5946 }
5ff904cd 5947
c7e4ee3a
CB
5948 switch (ffebld_arity (expr))
5949 {
5950 case 2:
5951 ffecom_expr_transform_ (ffebld_left (expr));
5952 expr = ffebld_right (expr);
5953 goto tail_recurse; /* :::::::::::::::::::: */
5ff904cd 5954
c7e4ee3a
CB
5955 case 1:
5956 expr = ffebld_left (expr);
5957 goto tail_recurse; /* :::::::::::::::::::: */
5ff904cd 5958
c7e4ee3a
CB
5959 default:
5960 break;
5961 }
5ff904cd 5962
c7e4ee3a
CB
5963 return;
5964}
5ff904cd 5965
c7e4ee3a
CB
5966#endif
5967/* Make a type based on info in live f2c.h file. */
5ff904cd 5968
c7e4ee3a
CB
5969#if FFECOM_targetCURRENT == FFECOM_targetGCC
5970static void
5971ffecom_f2c_make_type_ (tree *type, int tcode, const char *name)
5972{
5973 switch (tcode)
5974 {
5975 case FFECOM_f2ccodeCHAR:
5976 *type = make_signed_type (CHAR_TYPE_SIZE);
5977 break;
5ff904cd 5978
c7e4ee3a
CB
5979 case FFECOM_f2ccodeSHORT:
5980 *type = make_signed_type (SHORT_TYPE_SIZE);
5981 break;
5ff904cd 5982
c7e4ee3a
CB
5983 case FFECOM_f2ccodeINT:
5984 *type = make_signed_type (INT_TYPE_SIZE);
5985 break;
5ff904cd 5986
c7e4ee3a
CB
5987 case FFECOM_f2ccodeLONG:
5988 *type = make_signed_type (LONG_TYPE_SIZE);
5989 break;
5ff904cd 5990
c7e4ee3a
CB
5991 case FFECOM_f2ccodeLONGLONG:
5992 *type = make_signed_type (LONG_LONG_TYPE_SIZE);
5993 break;
5ff904cd 5994
c7e4ee3a
CB
5995 case FFECOM_f2ccodeCHARPTR:
5996 *type = build_pointer_type (DEFAULT_SIGNED_CHAR
5997 ? signed_char_type_node
5998 : unsigned_char_type_node);
5999 break;
5ff904cd 6000
c7e4ee3a
CB
6001 case FFECOM_f2ccodeFLOAT:
6002 *type = make_node (REAL_TYPE);
6003 TYPE_PRECISION (*type) = FLOAT_TYPE_SIZE;
6004 layout_type (*type);
6005 break;
6006
6007 case FFECOM_f2ccodeDOUBLE:
6008 *type = make_node (REAL_TYPE);
6009 TYPE_PRECISION (*type) = DOUBLE_TYPE_SIZE;
6010 layout_type (*type);
6011 break;
6012
6013 case FFECOM_f2ccodeLONGDOUBLE:
6014 *type = make_node (REAL_TYPE);
6015 TYPE_PRECISION (*type) = LONG_DOUBLE_TYPE_SIZE;
6016 layout_type (*type);
6017 break;
5ff904cd 6018
c7e4ee3a
CB
6019 case FFECOM_f2ccodeTWOREALS:
6020 *type = ffecom_make_complex_type_ (ffecom_f2c_real_type_node);
6021 break;
5ff904cd 6022
c7e4ee3a
CB
6023 case FFECOM_f2ccodeTWODOUBLEREALS:
6024 *type = ffecom_make_complex_type_ (ffecom_f2c_doublereal_type_node);
6025 break;
5ff904cd 6026
c7e4ee3a
CB
6027 default:
6028 assert ("unexpected FFECOM_f2ccodeXYZZY!" == NULL);
6029 *type = error_mark_node;
6030 return;
6031 }
5ff904cd 6032
c7e4ee3a 6033 pushdecl (build_decl (TYPE_DECL,
14657de8 6034 ffecom_get_invented_identifier ("__g77_f2c_%s", name),
c7e4ee3a
CB
6035 *type));
6036}
5ff904cd 6037
c7e4ee3a
CB
6038#endif
6039#if FFECOM_targetCURRENT == FFECOM_targetGCC
6040/* Set the f2c list-directed-I/O code for whatever (integral) type has the
6041 given size. */
5ff904cd 6042
c7e4ee3a
CB
6043static void
6044ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size,
6045 int code)
6046{
6047 int j;
6048 tree t;
5ff904cd 6049
c7e4ee3a 6050 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
05bccae2
RK
6051 if ((t = ffecom_tree_type[bt][j]) != NULL_TREE
6052 && compare_tree_int (TYPE_SIZE (t), size) == 0)
c7e4ee3a
CB
6053 {
6054 assert (code != -1);
6055 ffecom_f2c_typecode_[bt][j] = code;
6056 code = -1;
6057 }
6058}
5ff904cd 6059
c7e4ee3a
CB
6060#endif
6061/* Finish up globals after doing all program units in file
5ff904cd 6062
c7e4ee3a 6063 Need to handle only uninitialized COMMON areas. */
5ff904cd 6064
c7e4ee3a
CB
6065#if FFECOM_targetCURRENT == FFECOM_targetGCC
6066static ffeglobal
6067ffecom_finish_global_ (ffeglobal global)
6068{
6069 tree cbtype;
6070 tree cbt;
6071 tree size;
5ff904cd 6072
c7e4ee3a
CB
6073 if (ffeglobal_type (global) != FFEGLOBAL_typeCOMMON)
6074 return global;
5ff904cd 6075
c7e4ee3a
CB
6076 if (ffeglobal_common_init (global))
6077 return global;
5ff904cd 6078
c7e4ee3a
CB
6079 cbt = ffeglobal_hook (global);
6080 if ((cbt == NULL_TREE)
6081 || !ffeglobal_common_have_size (global))
6082 return global; /* No need to make common, never ref'd. */
5ff904cd 6083
c7e4ee3a 6084 DECL_EXTERNAL (cbt) = 0;
5ff904cd 6085
c7e4ee3a 6086 /* Give the array a size now. */
5ff904cd 6087
c7e4ee3a
CB
6088 size = build_int_2 ((ffeglobal_common_size (global)
6089 + ffeglobal_common_pad (global)) - 1,
6090 0);
5ff904cd 6091
c7e4ee3a
CB
6092 cbtype = TREE_TYPE (cbt);
6093 TYPE_DOMAIN (cbtype) = build_range_type (integer_type_node,
6094 integer_zero_node,
6095 size);
6096 if (!TREE_TYPE (size))
6097 TREE_TYPE (size) = TYPE_DOMAIN (cbtype);
6098 layout_type (cbtype);
5ff904cd 6099
c7e4ee3a
CB
6100 cbt = start_decl (cbt, FALSE);
6101 assert (cbt == ffeglobal_hook (global));
5ff904cd 6102
c7e4ee3a 6103 finish_decl (cbt, NULL_TREE, FALSE);
5ff904cd 6104
c7e4ee3a
CB
6105 return global;
6106}
5ff904cd 6107
c7e4ee3a
CB
6108#endif
6109/* Finish up any untransformed symbols. */
5ff904cd 6110
c7e4ee3a
CB
6111#if FFECOM_targetCURRENT == FFECOM_targetGCC
6112static ffesymbol
6113ffecom_finish_symbol_transform_ (ffesymbol s)
5ff904cd 6114{
c7e4ee3a
CB
6115 if ((s == NULL) || (TREE_CODE (current_function_decl) == ERROR_MARK))
6116 return s;
5ff904cd 6117
c7e4ee3a
CB
6118 /* It's easy to know to transform an untransformed symbol, to make sure
6119 we put out debugging info for it. But COMMON variables, unlike
6120 EQUIVALENCE ones, aren't given declarations in addition to the
6121 tree expressions that specify offsets, because COMMON variables
6122 can be referenced in the outer scope where only dummy arguments
6123 (PARM_DECLs) should really be seen. To be safe, just don't do any
6124 VAR_DECLs for COMMON variables when we transform them for real
6125 use, and therefore we do all the VAR_DECL creating here. */
5ff904cd 6126
c7e4ee3a
CB
6127 if (ffesymbol_hook (s).decl_tree == NULL_TREE)
6128 {
6129 if (ffesymbol_kind (s) != FFEINFO_kindNONE
6130 || (ffesymbol_where (s) != FFEINFO_whereNONE
6131 && ffesymbol_where (s) != FFEINFO_whereINTRINSIC
6132 && ffesymbol_where (s) != FFEINFO_whereDUMMY))
6133 /* Not transformed, and not CHARACTER*(*), and not a dummy
6134 argument, which can happen only if the entry point names
6135 it "rides in on" are all invalidated for other reasons. */
6136 s = ffecom_sym_transform_ (s);
6137 }
5ff904cd 6138
c7e4ee3a
CB
6139 if ((ffesymbol_where (s) == FFEINFO_whereCOMMON)
6140 && (ffesymbol_hook (s).decl_tree != error_mark_node))
6141 {
c7e4ee3a
CB
6142 /* This isn't working, at least for dbxout. The .s file looks
6143 okay to me (burley), but in gdb 4.9 at least, the variables
6144 appear to reside somewhere outside of the common area, so
6145 it doesn't make sense to mislead anyone by generating the info
6146 on those variables until this is fixed. NOTE: Same problem
6147 with EQUIVALENCE, sadly...see similar #if later. */
6148 ffecom_member_phase2_ (ffesymbol_storage (ffesymbol_common (s)),
6149 ffesymbol_storage (s));
5ff904cd
JL
6150 }
6151
c7e4ee3a
CB
6152 return s;
6153}
5ff904cd 6154
c7e4ee3a
CB
6155#endif
6156/* Append underscore(s) to name before calling get_identifier. "us"
6157 is nonzero if the name already contains an underscore and thus
6158 needs two underscores appended. */
5ff904cd 6159
c7e4ee3a
CB
6160#if FFECOM_targetCURRENT == FFECOM_targetGCC
6161static tree
6162ffecom_get_appended_identifier_ (char us, const char *name)
6163{
6164 int i;
6165 char *newname;
6166 tree id;
5ff904cd 6167
c7e4ee3a
CB
6168 newname = xmalloc ((i = strlen (name)) + 1
6169 + ffe_is_underscoring ()
6170 + us);
6171 memcpy (newname, name, i);
6172 newname[i] = '_';
6173 newname[i + us] = '_';
6174 newname[i + 1 + us] = '\0';
6175 id = get_identifier (newname);
5ff904cd 6176
c7e4ee3a 6177 free (newname);
5ff904cd 6178
c7e4ee3a
CB
6179 return id;
6180}
5ff904cd 6181
c7e4ee3a
CB
6182#endif
6183/* Decide whether to append underscore to name before calling
6184 get_identifier. */
5ff904cd 6185
c7e4ee3a
CB
6186#if FFECOM_targetCURRENT == FFECOM_targetGCC
6187static tree
6188ffecom_get_external_identifier_ (ffesymbol s)
6189{
6190 char us;
6191 const char *name = ffesymbol_text (s);
5ff904cd 6192
c7e4ee3a 6193 /* If name is a built-in name, just return it as is. */
5ff904cd 6194
c7e4ee3a
CB
6195 if (!ffe_is_underscoring ()
6196 || (strcmp (name, FFETARGET_nameBLANK_COMMON) == 0)
6197#if FFETARGET_isENFORCED_MAIN_NAME
6198 || (strcmp (name, FFETARGET_nameENFORCED_NAME) == 0)
6199#else
6200 || (strcmp (name, FFETARGET_nameUNNAMED_MAIN) == 0)
6201#endif
6202 || (strcmp (name, FFETARGET_nameUNNAMED_BLOCK_DATA) == 0))
6203 return get_identifier (name);
5ff904cd 6204
c7e4ee3a
CB
6205 us = ffe_is_second_underscore ()
6206 ? (strchr (name, '_') != NULL)
6207 : 0;
5ff904cd 6208
c7e4ee3a
CB
6209 return ffecom_get_appended_identifier_ (us, name);
6210}
5ff904cd 6211
c7e4ee3a
CB
6212#endif
6213/* Decide whether to append underscore to internal name before calling
6214 get_identifier.
6215
6216 This is for non-external, top-function-context names only. Transform
6217 identifier so it doesn't conflict with the transformed result
6218 of using a _different_ external name. E.g. if "CALL FOO" is
6219 transformed into "FOO_();", then the variable in "FOO_ = 3"
6220 must be transformed into something that does not conflict, since
6221 these two things should be independent.
5ff904cd 6222
c7e4ee3a
CB
6223 The transformation is as follows. If the name does not contain
6224 an underscore, there is no possible conflict, so just return.
6225 If the name does contain an underscore, then transform it just
6226 like we transform an external identifier. */
5ff904cd 6227
c7e4ee3a
CB
6228#if FFECOM_targetCURRENT == FFECOM_targetGCC
6229static tree
6230ffecom_get_identifier_ (const char *name)
6231{
6232 /* If name does not contain an underscore, just return it as is. */
6233
6234 if (!ffe_is_underscoring ()
6235 || (strchr (name, '_') == NULL))
6236 return get_identifier (name);
6237
6238 return ffecom_get_appended_identifier_ (ffe_is_second_underscore (),
6239 name);
5ff904cd
JL
6240}
6241
6242#endif
c7e4ee3a 6243/* ffecom_gen_sfuncdef_ -- Generate definition of statement function
5ff904cd 6244
c7e4ee3a
CB
6245 tree t;
6246 ffesymbol s; // kindFUNCTION, whereIMMEDIATE.
6247 t = ffecom_gen_sfuncdef_(s,ffesymbol_basictype(s),
6248 ffesymbol_kindtype(s));
5ff904cd 6249
c7e4ee3a
CB
6250 Call after setting up containing function and getting trees for all
6251 other symbols. */
5ff904cd
JL
6252
6253#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
6254static tree
6255ffecom_gen_sfuncdef_ (ffesymbol s, ffeinfoBasictype bt, ffeinfoKindtype kt)
5ff904cd 6256{
c7e4ee3a
CB
6257 ffebld expr = ffesymbol_sfexpr (s);
6258 tree type;
6259 tree func;
6260 tree result;
6261 bool charfunc = (bt == FFEINFO_basictypeCHARACTER);
6262 static bool recurse = FALSE;
c7e4ee3a 6263 int old_lineno = lineno;
3b304f5b 6264 const char *old_input_filename = input_filename;
5ff904cd 6265
c7e4ee3a 6266 ffecom_nested_entry_ = s;
5ff904cd 6267
c7e4ee3a
CB
6268 /* For now, we don't have a handy pointer to where the sfunc is actually
6269 defined, though that should be easy to add to an ffesymbol. (The
6270 token/where info available might well point to the place where the type
6271 of the sfunc is declared, especially if that precedes the place where
6272 the sfunc itself is defined, which is typically the case.) We should
6273 put out a null pointer rather than point somewhere wrong, but I want to
6274 see how it works at this point. */
5ff904cd 6275
c7e4ee3a
CB
6276 input_filename = ffesymbol_where_filename (s);
6277 lineno = ffesymbol_where_filelinenum (s);
5ff904cd 6278
c7e4ee3a
CB
6279 /* Pretransform the expression so any newly discovered things belong to the
6280 outer program unit, not to the statement function. */
5ff904cd 6281
c7e4ee3a 6282 ffecom_expr_transform_ (expr);
5ff904cd 6283
c7e4ee3a
CB
6284 /* Make sure no recursive invocation of this fn (a specific case of failing
6285 to pretransform an sfunc's expression, i.e. where its expression
6286 references another untransformed sfunc) happens. */
6287
6288 assert (!recurse);
6289 recurse = TRUE;
6290
c7e4ee3a
CB
6291 push_f_function_context ();
6292
6293 if (charfunc)
6294 type = void_type_node;
6295 else
5ff904cd 6296 {
c7e4ee3a
CB
6297 type = ffecom_tree_type[bt][kt];
6298 if (type == NULL_TREE)
6299 type = integer_type_node; /* _sym_exec_transition reports
6300 error. */
6301 }
5ff904cd 6302
c7e4ee3a
CB
6303 start_function (ffecom_get_identifier_ (ffesymbol_text (s)),
6304 build_function_type (type, NULL_TREE),
6305 1, /* nested/inline */
6306 0); /* TREE_PUBLIC */
5ff904cd 6307
c7e4ee3a
CB
6308 /* We don't worry about COMPLEX return values here, because this is
6309 entirely internal to our code, and gcc has the ability to return COMPLEX
6310 directly as a value. */
6311
c7e4ee3a
CB
6312 if (charfunc)
6313 { /* Prepend arg for where result goes. */
6314 tree type;
6315
6316 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
6317
14657de8 6318 result = ffecom_get_invented_identifier ("__g77_%s", "result");
c7e4ee3a
CB
6319
6320 ffecom_char_enhance_arg_ (&type, s); /* Ignore returned length. */
6321
6322 type = build_pointer_type (type);
6323 result = build_decl (PARM_DECL, result, type);
6324
6325 push_parm_decl (result);
5ff904cd 6326 }
c7e4ee3a
CB
6327 else
6328 result = NULL_TREE; /* Not ref'd if !charfunc. */
5ff904cd 6329
c7e4ee3a 6330 ffecom_push_dummy_decls_ (ffesymbol_dummyargs (s), TRUE);
5ff904cd 6331
c7e4ee3a
CB
6332 store_parm_decls (0);
6333
6334 ffecom_start_compstmt ();
6335
6336 if (expr != NULL)
5ff904cd 6337 {
c7e4ee3a
CB
6338 if (charfunc)
6339 {
6340 ffetargetCharacterSize sz = ffesymbol_size (s);
6341 tree result_length;
5ff904cd 6342
c7e4ee3a
CB
6343 result_length = build_int_2 (sz, 0);
6344 TREE_TYPE (result_length) = ffecom_f2c_ftnlen_type_node;
5ff904cd 6345
c7e4ee3a 6346 ffecom_prepare_let_char_ (sz, expr);
5ff904cd 6347
c7e4ee3a 6348 ffecom_prepare_end ();
5ff904cd 6349
c7e4ee3a
CB
6350 ffecom_let_char_ (result, result_length, sz, expr);
6351 expand_null_return ();
6352 }
6353 else
6354 {
6355 ffecom_prepare_expr (expr);
5ff904cd 6356
c7e4ee3a 6357 ffecom_prepare_end ();
5ff904cd 6358
c7e4ee3a
CB
6359 expand_return (ffecom_modify (NULL_TREE,
6360 DECL_RESULT (current_function_decl),
6361 ffecom_expr (expr)));
6362 }
c7e4ee3a 6363 }
5ff904cd 6364
c7e4ee3a 6365 ffecom_end_compstmt ();
5ff904cd 6366
c7e4ee3a
CB
6367 func = current_function_decl;
6368 finish_function (1);
5ff904cd 6369
c7e4ee3a 6370 pop_f_function_context ();
5ff904cd 6371
c7e4ee3a
CB
6372 recurse = FALSE;
6373
6374 lineno = old_lineno;
6375 input_filename = old_input_filename;
6376
6377 ffecom_nested_entry_ = NULL;
6378
6379 return func;
5ff904cd
JL
6380}
6381
6382#endif
5ff904cd 6383
c7e4ee3a
CB
6384#if FFECOM_targetCURRENT == FFECOM_targetGCC
6385static const char *
6386ffecom_gfrt_args_ (ffecomGfrt ix)
5ff904cd 6387{
c7e4ee3a
CB
6388 return ffecom_gfrt_argstring_[ix];
6389}
5ff904cd 6390
c7e4ee3a
CB
6391#endif
6392#if FFECOM_targetCURRENT == FFECOM_targetGCC
6393static tree
6394ffecom_gfrt_tree_ (ffecomGfrt ix)
6395{
6396 if (ffecom_gfrt_[ix] == NULL_TREE)
6397 ffecom_make_gfrt_ (ix);
6398
6399 return ffecom_1 (ADDR_EXPR,
6400 build_pointer_type (TREE_TYPE (ffecom_gfrt_[ix])),
6401 ffecom_gfrt_[ix]);
5ff904cd
JL
6402}
6403
6404#endif
c7e4ee3a 6405/* Return initialize-to-zero expression for this VAR_DECL. */
5ff904cd
JL
6406
6407#if FFECOM_targetCURRENT == FFECOM_targetGCC
7189a4b0
GK
6408/* A somewhat evil way to prevent the garbage collector
6409 from collecting 'tree' structures. */
6410#define NUM_TRACKED_CHUNK 63
6411static struct tree_ggc_tracker
6412{
6413 struct tree_ggc_tracker *next;
6414 tree trees[NUM_TRACKED_CHUNK];
6415} *tracker_head = NULL;
6416
6417static void
54551044 6418mark_tracker_head (void *arg)
7189a4b0
GK
6419{
6420 struct tree_ggc_tracker *head;
6421 int i;
6422
6423 for (head = * (struct tree_ggc_tracker **) arg;
6424 head != NULL;
6425 head = head->next)
6426 {
6427 ggc_mark (head);
6428 for (i = 0; i < NUM_TRACKED_CHUNK; i++)
6429 ggc_mark_tree (head->trees[i]);
6430 }
6431}
6432
6433void
6434ffecom_save_tree_forever (tree t)
6435{
6436 int i;
6437 if (tracker_head != NULL)
6438 for (i = 0; i < NUM_TRACKED_CHUNK; i++)
6439 if (tracker_head->trees[i] == NULL)
6440 {
6441 tracker_head->trees[i] = t;
6442 return;
6443 }
6444
6445 {
6446 /* Need to allocate a new block. */
6447 struct tree_ggc_tracker *old_head = tracker_head;
6448
6449 tracker_head = ggc_alloc (sizeof (*tracker_head));
6450 tracker_head->next = old_head;
6451 tracker_head->trees[0] = t;
6452 for (i = 1; i < NUM_TRACKED_CHUNK; i++)
6453 tracker_head->trees[i] = NULL;
6454 }
6455}
6456
c7e4ee3a
CB
6457static tree
6458ffecom_init_zero_ (tree decl)
5ff904cd 6459{
c7e4ee3a
CB
6460 tree init;
6461 int incremental = TREE_STATIC (decl);
6462 tree type = TREE_TYPE (decl);
5ff904cd 6463
c7e4ee3a
CB
6464 if (incremental)
6465 {
c7e4ee3a
CB
6466 make_decl_rtl (decl, NULL, TREE_PUBLIC (decl) ? 1 : 0);
6467 assemble_variable (decl, TREE_PUBLIC (decl) ? 1 : 0, 0, 1);
c7e4ee3a 6468 }
5ff904cd 6469
c7e4ee3a
CB
6470 if ((TREE_CODE (type) != ARRAY_TYPE)
6471 && (TREE_CODE (type) != RECORD_TYPE)
6472 && (TREE_CODE (type) != UNION_TYPE)
6473 && !incremental)
6474 init = convert (type, integer_zero_node);
6475 else if (!incremental)
6476 {
c7e4ee3a
CB
6477 init = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
6478 TREE_CONSTANT (init) = 1;
6479 TREE_STATIC (init) = 1;
c7e4ee3a
CB
6480 }
6481 else
6482 {
c7e4ee3a
CB
6483 assemble_zeros (int_size_in_bytes (type));
6484 init = error_mark_node;
c7e4ee3a 6485 }
5ff904cd 6486
c7e4ee3a 6487 return init;
5ff904cd
JL
6488}
6489
6490#endif
5ff904cd 6491#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
6492static tree
6493ffecom_intrinsic_ichar_ (tree tree_type, ffebld arg,
6494 tree *maybe_tree)
5ff904cd 6495{
c7e4ee3a
CB
6496 tree expr_tree;
6497 tree length_tree;
5ff904cd 6498
c7e4ee3a 6499 switch (ffebld_op (arg))
6829256f 6500 {
c7e4ee3a
CB
6501 case FFEBLD_opCONTER: /* For F90, check 0-length. */
6502 if (ffetarget_length_character1
6503 (ffebld_constant_character1
6504 (ffebld_conter (arg))) == 0)
6505 {
6506 *maybe_tree = integer_zero_node;
6507 return convert (tree_type, integer_zero_node);
6508 }
5ff904cd 6509
c7e4ee3a
CB
6510 *maybe_tree = integer_one_node;
6511 expr_tree = build_int_2 (*ffetarget_text_character1
6512 (ffebld_constant_character1
6513 (ffebld_conter (arg))),
6514 0);
6515 TREE_TYPE (expr_tree) = tree_type;
6516 return expr_tree;
5ff904cd 6517
c7e4ee3a
CB
6518 case FFEBLD_opSYMTER:
6519 case FFEBLD_opARRAYREF:
6520 case FFEBLD_opFUNCREF:
6521 case FFEBLD_opSUBSTR:
6522 ffecom_char_args_ (&expr_tree, &length_tree, arg);
5ff904cd 6523
c7e4ee3a
CB
6524 if ((expr_tree == error_mark_node)
6525 || (length_tree == error_mark_node))
6526 {
6527 *maybe_tree = error_mark_node;
6528 return error_mark_node;
6529 }
5ff904cd 6530
c7e4ee3a
CB
6531 if (integer_zerop (length_tree))
6532 {
6533 *maybe_tree = integer_zero_node;
6534 return convert (tree_type, integer_zero_node);
6535 }
6536
6537 expr_tree
6538 = ffecom_1 (INDIRECT_REF,
6539 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
6540 expr_tree);
6541 expr_tree
6542 = ffecom_2 (ARRAY_REF,
6543 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
6544 expr_tree,
6545 integer_one_node);
6546 expr_tree = convert (tree_type, expr_tree);
6547
6548 if (TREE_CODE (length_tree) == INTEGER_CST)
6549 *maybe_tree = integer_one_node;
6550 else /* Must check length at run time. */
6551 *maybe_tree
6552 = ffecom_truth_value
6553 (ffecom_2 (GT_EXPR, integer_type_node,
6554 length_tree,
6555 ffecom_f2c_ftnlen_zero_node));
6556 return expr_tree;
6557
6558 case FFEBLD_opPAREN:
6559 case FFEBLD_opCONVERT:
6560 if (ffeinfo_size (ffebld_info (arg)) == 0)
6561 {
6562 *maybe_tree = integer_zero_node;
6563 return convert (tree_type, integer_zero_node);
6564 }
6565 return ffecom_intrinsic_ichar_ (tree_type, ffebld_left (arg),
6566 maybe_tree);
6567
6568 case FFEBLD_opCONCATENATE:
6569 {
6570 tree maybe_left;
6571 tree maybe_right;
6572 tree expr_left;
6573 tree expr_right;
6574
6575 expr_left = ffecom_intrinsic_ichar_ (tree_type, ffebld_left (arg),
6576 &maybe_left);
6577 expr_right = ffecom_intrinsic_ichar_ (tree_type, ffebld_right (arg),
6578 &maybe_right);
6579 *maybe_tree = ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
6580 maybe_left,
6581 maybe_right);
6582 expr_tree = ffecom_3 (COND_EXPR, tree_type,
6583 maybe_left,
6584 expr_left,
6585 expr_right);
6586 return expr_tree;
6587 }
6588
6589 default:
6590 assert ("bad op in ICHAR" == NULL);
6591 return error_mark_node;
6592 }
5ff904cd
JL
6593}
6594
6595#endif
c7e4ee3a
CB
6596/* ffecom_intrinsic_len_ -- Return length info for char arg (LEN())
6597
6598 tree length_arg;
6599 ffebld expr;
6600 length_arg = ffecom_intrinsic_len_ (expr);
6601
6602 Handles CHARACTER-type CONTER, SYMTER, SUBSTR, ARRAYREF, and FUNCREF
6603 subexpressions by constructing the appropriate tree for the
6604 length-of-character-text argument in a calling sequence. */
5ff904cd
JL
6605
6606#if FFECOM_targetCURRENT == FFECOM_targetGCC
6607static tree
c7e4ee3a 6608ffecom_intrinsic_len_ (ffebld expr)
5ff904cd 6609{
c7e4ee3a
CB
6610 ffetargetCharacter1 val;
6611 tree length;
6612
6613 switch (ffebld_op (expr))
6614 {
6615 case FFEBLD_opCONTER:
6616 val = ffebld_constant_character1 (ffebld_conter (expr));
6617 length = build_int_2 (ffetarget_length_character1 (val), 0);
6618 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6619 break;
6620
6621 case FFEBLD_opSYMTER:
6622 {
6623 ffesymbol s = ffebld_symter (expr);
6624 tree item;
6625
6626 item = ffesymbol_hook (s).decl_tree;
6627 if (item == NULL_TREE)
6628 {
6629 s = ffecom_sym_transform_ (s);
6630 item = ffesymbol_hook (s).decl_tree;
6631 }
6632 if (ffesymbol_kind (s) == FFEINFO_kindENTITY)
6633 {
6634 if (ffesymbol_size (s) == FFETARGET_charactersizeNONE)
6635 length = ffesymbol_hook (s).length_tree;
6636 else
6637 {
6638 length = build_int_2 (ffesymbol_size (s), 0);
6639 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6640 }
6641 }
6642 else if (item == error_mark_node)
6643 length = error_mark_node;
6644 else /* FFEINFO_kindFUNCTION: */
6645 length = NULL_TREE;
6646 }
6647 break;
5ff904cd 6648
c7e4ee3a
CB
6649 case FFEBLD_opARRAYREF:
6650 length = ffecom_intrinsic_len_ (ffebld_left (expr));
6651 break;
5ff904cd 6652
c7e4ee3a
CB
6653 case FFEBLD_opSUBSTR:
6654 {
6655 ffebld start;
6656 ffebld end;
6657 ffebld thing = ffebld_right (expr);
6658 tree start_tree;
6659 tree end_tree;
5ff904cd 6660
c7e4ee3a
CB
6661 assert (ffebld_op (thing) == FFEBLD_opITEM);
6662 start = ffebld_head (thing);
6663 thing = ffebld_trail (thing);
6664 assert (ffebld_trail (thing) == NULL);
6665 end = ffebld_head (thing);
5ff904cd 6666
c7e4ee3a 6667 length = ffecom_intrinsic_len_ (ffebld_left (expr));
5ff904cd 6668
c7e4ee3a
CB
6669 if (length == error_mark_node)
6670 break;
5ff904cd 6671
c7e4ee3a
CB
6672 if (start == NULL)
6673 {
6674 if (end == NULL)
6675 ;
6676 else
6677 {
6678 length = convert (ffecom_f2c_ftnlen_type_node,
6679 ffecom_expr (end));
6680 }
6681 }
6682 else
6683 {
6684 start_tree = convert (ffecom_f2c_ftnlen_type_node,
6685 ffecom_expr (start));
5ff904cd 6686
c7e4ee3a
CB
6687 if (start_tree == error_mark_node)
6688 {
6689 length = error_mark_node;
6690 break;
6691 }
5ff904cd 6692
c7e4ee3a
CB
6693 if (end == NULL)
6694 {
6695 length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6696 ffecom_f2c_ftnlen_one_node,
6697 ffecom_2 (MINUS_EXPR,
6698 ffecom_f2c_ftnlen_type_node,
6699 length,
6700 start_tree));
6701 }
6702 else
6703 {
6704 end_tree = convert (ffecom_f2c_ftnlen_type_node,
6705 ffecom_expr (end));
5ff904cd 6706
c7e4ee3a
CB
6707 if (end_tree == error_mark_node)
6708 {
6709 length = error_mark_node;
6710 break;
6711 }
5ff904cd 6712
c7e4ee3a
CB
6713 length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6714 ffecom_f2c_ftnlen_one_node,
6715 ffecom_2 (MINUS_EXPR,
6716 ffecom_f2c_ftnlen_type_node,
6717 end_tree, start_tree));
6718 }
6719 }
6720 }
6721 break;
5ff904cd 6722
c7e4ee3a
CB
6723 case FFEBLD_opCONCATENATE:
6724 length
6725 = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6726 ffecom_intrinsic_len_ (ffebld_left (expr)),
6727 ffecom_intrinsic_len_ (ffebld_right (expr)));
6728 break;
5ff904cd 6729
c7e4ee3a
CB
6730 case FFEBLD_opFUNCREF:
6731 case FFEBLD_opCONVERT:
6732 length = build_int_2 (ffebld_size (expr), 0);
6733 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6734 break;
5ff904cd 6735
c7e4ee3a
CB
6736 default:
6737 assert ("bad op for single char arg expr" == NULL);
6738 length = ffecom_f2c_ftnlen_zero_node;
6739 break;
6740 }
5ff904cd 6741
c7e4ee3a 6742 assert (length != NULL_TREE);
5ff904cd 6743
c7e4ee3a 6744 return length;
5ff904cd
JL
6745}
6746
6747#endif
c7e4ee3a 6748/* Handle CHARACTER assignments.
5ff904cd 6749
c7e4ee3a
CB
6750 Generates code to do the assignment. Used by ordinary assignment
6751 statement handler ffecom_let_stmt and by statement-function
6752 handler to generate code for a statement function. */
5ff904cd
JL
6753
6754#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
6755static void
6756ffecom_let_char_ (tree dest_tree, tree dest_length,
6757 ffetargetCharacterSize dest_size, ffebld source)
5ff904cd 6758{
c7e4ee3a
CB
6759 ffecomConcatList_ catlist;
6760 tree source_length;
6761 tree source_tree;
6762 tree expr_tree;
5ff904cd 6763
c7e4ee3a
CB
6764 if ((dest_tree == error_mark_node)
6765 || (dest_length == error_mark_node))
6766 return;
5ff904cd 6767
c7e4ee3a
CB
6768 assert (dest_tree != NULL_TREE);
6769 assert (dest_length != NULL_TREE);
5ff904cd 6770
c7e4ee3a
CB
6771 /* Source might be an opCONVERT, which just means it is a different size
6772 than the destination. Since the underlying implementation here handles
6773 that (directly or via the s_copy or s_cat run-time-library functions),
6774 we don't need the "convenience" of an opCONVERT that tells us to
6775 truncate or blank-pad, particularly since the resulting implementation
6776 would probably be slower than otherwise. */
5ff904cd 6777
c7e4ee3a
CB
6778 while (ffebld_op (source) == FFEBLD_opCONVERT)
6779 source = ffebld_left (source);
5ff904cd 6780
c7e4ee3a
CB
6781 catlist = ffecom_concat_list_new_ (source, dest_size);
6782 switch (ffecom_concat_list_count_ (catlist))
6783 {
6784 case 0: /* Shouldn't happen, but in case it does... */
6785 ffecom_concat_list_kill_ (catlist);
6786 source_tree = null_pointer_node;
6787 source_length = ffecom_f2c_ftnlen_zero_node;
6788 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6789 TREE_CHAIN (expr_tree) = build_tree_list (NULL_TREE, source_tree);
6790 TREE_CHAIN (TREE_CHAIN (expr_tree))
6791 = build_tree_list (NULL_TREE, dest_length);
6792 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6793 = build_tree_list (NULL_TREE, source_length);
5ff904cd 6794
c7e4ee3a
CB
6795 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCOPY, expr_tree, NULL_TREE);
6796 TREE_SIDE_EFFECTS (expr_tree) = 1;
5ff904cd 6797
c7e4ee3a 6798 expand_expr_stmt (expr_tree);
5ff904cd 6799
c7e4ee3a 6800 return;
5ff904cd 6801
c7e4ee3a
CB
6802 case 1: /* The (fairly) easy case. */
6803 ffecom_char_args_ (&source_tree, &source_length,
6804 ffecom_concat_list_expr_ (catlist, 0));
6805 ffecom_concat_list_kill_ (catlist);
6806 assert (source_tree != NULL_TREE);
6807 assert (source_length != NULL_TREE);
6808
6809 if ((source_tree == error_mark_node)
6810 || (source_length == error_mark_node))
6811 return;
6812
6813 if (dest_size == 1)
6814 {
6815 dest_tree
6816 = ffecom_1 (INDIRECT_REF,
6817 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6818 (dest_tree))),
6819 dest_tree);
6820 dest_tree
6821 = ffecom_2 (ARRAY_REF,
6822 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6823 (dest_tree))),
6824 dest_tree,
6825 integer_one_node);
6826 source_tree
6827 = ffecom_1 (INDIRECT_REF,
6828 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6829 (source_tree))),
6830 source_tree);
6831 source_tree
6832 = ffecom_2 (ARRAY_REF,
6833 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6834 (source_tree))),
6835 source_tree,
6836 integer_one_node);
5ff904cd 6837
c7e4ee3a 6838 expr_tree = ffecom_modify (void_type_node, dest_tree, source_tree);
5ff904cd 6839
c7e4ee3a 6840 expand_expr_stmt (expr_tree);
5ff904cd 6841
c7e4ee3a
CB
6842 return;
6843 }
5ff904cd 6844
c7e4ee3a
CB
6845 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6846 TREE_CHAIN (expr_tree) = build_tree_list (NULL_TREE, source_tree);
6847 TREE_CHAIN (TREE_CHAIN (expr_tree))
6848 = build_tree_list (NULL_TREE, dest_length);
6849 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6850 = build_tree_list (NULL_TREE, source_length);
5ff904cd 6851
c7e4ee3a
CB
6852 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCOPY, expr_tree, NULL_TREE);
6853 TREE_SIDE_EFFECTS (expr_tree) = 1;
5ff904cd 6854
c7e4ee3a 6855 expand_expr_stmt (expr_tree);
5ff904cd 6856
c7e4ee3a 6857 return;
5ff904cd 6858
c7e4ee3a
CB
6859 default: /* Must actually concatenate things. */
6860 break;
6861 }
5ff904cd 6862
c7e4ee3a 6863 /* Heavy-duty concatenation. */
5ff904cd 6864
c7e4ee3a
CB
6865 {
6866 int count = ffecom_concat_list_count_ (catlist);
6867 int i;
6868 tree lengths;
6869 tree items;
6870 tree length_array;
6871 tree item_array;
6872 tree citem;
6873 tree clength;
5ff904cd 6874
c7e4ee3a
CB
6875#ifdef HOHO
6876 length_array
6877 = lengths
6878 = ffecom_push_tempvar (ffecom_f2c_ftnlen_type_node,
6879 FFETARGET_charactersizeNONE, count, TRUE);
6880 item_array = items = ffecom_push_tempvar (ffecom_f2c_address_type_node,
6881 FFETARGET_charactersizeNONE,
6882 count, TRUE);
6883#else
6884 {
6885 tree hook;
6886
6887 hook = ffebld_nonter_hook (source);
6888 assert (hook);
6889 assert (TREE_CODE (hook) == TREE_VEC);
6890 assert (TREE_VEC_LENGTH (hook) == 2);
6891 length_array = lengths = TREE_VEC_ELT (hook, 0);
6892 item_array = items = TREE_VEC_ELT (hook, 1);
5ff904cd 6893 }
c7e4ee3a 6894#endif
5ff904cd 6895
c7e4ee3a
CB
6896 for (i = 0; i < count; ++i)
6897 {
6898 ffecom_char_args_ (&citem, &clength,
6899 ffecom_concat_list_expr_ (catlist, i));
6900 if ((citem == error_mark_node)
6901 || (clength == error_mark_node))
6902 {
6903 ffecom_concat_list_kill_ (catlist);
6904 return;
6905 }
5ff904cd 6906
c7e4ee3a
CB
6907 items
6908 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (items),
6909 ffecom_modify (void_type_node,
6910 ffecom_2 (ARRAY_REF,
6911 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array))),
6912 item_array,
6913 build_int_2 (i, 0)),
6914 citem),
6915 items);
6916 lengths
6917 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (lengths),
6918 ffecom_modify (void_type_node,
6919 ffecom_2 (ARRAY_REF,
6920 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array))),
6921 length_array,
6922 build_int_2 (i, 0)),
6923 clength),
6924 lengths);
6925 }
5ff904cd 6926
c7e4ee3a
CB
6927 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6928 TREE_CHAIN (expr_tree)
6929 = build_tree_list (NULL_TREE,
6930 ffecom_1 (ADDR_EXPR,
6931 build_pointer_type (TREE_TYPE (items)),
6932 items));
6933 TREE_CHAIN (TREE_CHAIN (expr_tree))
6934 = build_tree_list (NULL_TREE,
6935 ffecom_1 (ADDR_EXPR,
6936 build_pointer_type (TREE_TYPE (lengths)),
6937 lengths));
6938 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6939 = build_tree_list
6940 (NULL_TREE,
6941 ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
6942 convert (ffecom_f2c_ftnlen_type_node,
6943 build_int_2 (count, 0))));
6944 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree))))
6945 = build_tree_list (NULL_TREE, dest_length);
5ff904cd 6946
c7e4ee3a
CB
6947 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCAT, expr_tree, NULL_TREE);
6948 TREE_SIDE_EFFECTS (expr_tree) = 1;
5ff904cd 6949
c7e4ee3a
CB
6950 expand_expr_stmt (expr_tree);
6951 }
5ff904cd 6952
c7e4ee3a
CB
6953 ffecom_concat_list_kill_ (catlist);
6954}
5ff904cd 6955
c7e4ee3a
CB
6956#endif
6957/* ffecom_make_gfrt_ -- Make initial info for run-time routine
5ff904cd 6958
c7e4ee3a
CB
6959 ffecomGfrt ix;
6960 ffecom_make_gfrt_(ix);
5ff904cd 6961
c7e4ee3a
CB
6962 Assumes gfrt_[ix] is NULL_TREE, and replaces it with the FUNCTION_DECL
6963 for the indicated run-time routine (ix). */
5ff904cd 6964
c7e4ee3a
CB
6965#if FFECOM_targetCURRENT == FFECOM_targetGCC
6966static void
6967ffecom_make_gfrt_ (ffecomGfrt ix)
6968{
6969 tree t;
6970 tree ttype;
5ff904cd 6971
c7e4ee3a
CB
6972 switch (ffecom_gfrt_type_[ix])
6973 {
6974 case FFECOM_rttypeVOID_:
6975 ttype = void_type_node;
6976 break;
5ff904cd 6977
c7e4ee3a
CB
6978 case FFECOM_rttypeVOIDSTAR_:
6979 ttype = TREE_TYPE (null_pointer_node); /* `void *'. */
6980 break;
5ff904cd 6981
c7e4ee3a
CB
6982 case FFECOM_rttypeFTNINT_:
6983 ttype = ffecom_f2c_ftnint_type_node;
6984 break;
5ff904cd 6985
c7e4ee3a
CB
6986 case FFECOM_rttypeINTEGER_:
6987 ttype = ffecom_f2c_integer_type_node;
6988 break;
5ff904cd 6989
c7e4ee3a
CB
6990 case FFECOM_rttypeLONGINT_:
6991 ttype = ffecom_f2c_longint_type_node;
6992 break;
5ff904cd 6993
c7e4ee3a
CB
6994 case FFECOM_rttypeLOGICAL_:
6995 ttype = ffecom_f2c_logical_type_node;
6996 break;
5ff904cd 6997
c7e4ee3a
CB
6998 case FFECOM_rttypeREAL_F2C_:
6999 ttype = double_type_node;
7000 break;
5ff904cd 7001
c7e4ee3a
CB
7002 case FFECOM_rttypeREAL_GNU_:
7003 ttype = float_type_node;
7004 break;
5ff904cd 7005
c7e4ee3a
CB
7006 case FFECOM_rttypeCOMPLEX_F2C_:
7007 ttype = void_type_node;
7008 break;
5ff904cd 7009
c7e4ee3a
CB
7010 case FFECOM_rttypeCOMPLEX_GNU_:
7011 ttype = ffecom_f2c_complex_type_node;
7012 break;
5ff904cd 7013
c7e4ee3a
CB
7014 case FFECOM_rttypeDOUBLE_:
7015 ttype = double_type_node;
7016 break;
5ff904cd 7017
c7e4ee3a
CB
7018 case FFECOM_rttypeDOUBLEREAL_:
7019 ttype = ffecom_f2c_doublereal_type_node;
7020 break;
5ff904cd 7021
c7e4ee3a
CB
7022 case FFECOM_rttypeDBLCMPLX_F2C_:
7023 ttype = void_type_node;
7024 break;
5ff904cd 7025
c7e4ee3a
CB
7026 case FFECOM_rttypeDBLCMPLX_GNU_:
7027 ttype = ffecom_f2c_doublecomplex_type_node;
7028 break;
5ff904cd 7029
c7e4ee3a
CB
7030 case FFECOM_rttypeCHARACTER_:
7031 ttype = void_type_node;
7032 break;
7033
7034 default:
7035 ttype = NULL;
7036 assert ("bad rttype" == NULL);
7037 break;
5ff904cd 7038 }
5ff904cd 7039
c7e4ee3a
CB
7040 ttype = build_function_type (ttype, NULL_TREE);
7041 t = build_decl (FUNCTION_DECL,
7042 get_identifier (ffecom_gfrt_name_[ix]),
7043 ttype);
7044 DECL_EXTERNAL (t) = 1;
95eb4fd9 7045 TREE_READONLY (t) = ffecom_gfrt_const_[ix] ? 1 : 0;
c7e4ee3a
CB
7046 TREE_PUBLIC (t) = 1;
7047 TREE_THIS_VOLATILE (t) = ffecom_gfrt_volatile_[ix] ? 1 : 0;
5ff904cd 7048
95eb4fd9
TM
7049 /* Sanity check: A function that's const cannot be volatile. */
7050
7051 assert (ffecom_gfrt_const_[ix] ? !ffecom_gfrt_volatile_[ix] : 1);
7052
7053 /* Sanity check: A function that's const cannot return complex. */
7054
7055 assert (ffecom_gfrt_const_[ix] ? !ffecom_gfrt_complex_[ix] : 1);
7056
c7e4ee3a 7057 t = start_decl (t, TRUE);
5ff904cd 7058
c7e4ee3a 7059 finish_decl (t, NULL_TREE, TRUE);
5ff904cd 7060
c7e4ee3a 7061 ffecom_gfrt_[ix] = t;
5ff904cd
JL
7062}
7063
7064#endif
c7e4ee3a
CB
7065/* Phase 1 pass over each member of a COMMON/EQUIVALENCE group. */
7066
5ff904cd 7067#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
7068static void
7069ffecom_member_phase1_ (ffestorag mst UNUSED, ffestorag st)
5ff904cd 7070{
c7e4ee3a 7071 ffesymbol s = ffestorag_symbol (st);
5ff904cd 7072
c7e4ee3a
CB
7073 if (ffesymbol_namelisted (s))
7074 ffecom_member_namelisted_ = TRUE;
7075}
5ff904cd 7076
c7e4ee3a
CB
7077#endif
7078/* Phase 2 pass over each member of a COMMON/EQUIVALENCE group. Declare
7079 the member so debugger will see it. Otherwise nobody should be
7080 referencing the member. */
5ff904cd 7081
c7e4ee3a 7082#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
7083static void
7084ffecom_member_phase2_ (ffestorag mst, ffestorag st)
7085{
7086 ffesymbol s;
7087 tree t;
7088 tree mt;
7089 tree type;
5ff904cd 7090
c7e4ee3a
CB
7091 if ((mst == NULL)
7092 || ((mt = ffestorag_hook (mst)) == NULL)
7093 || (mt == error_mark_node))
7094 return;
5ff904cd 7095
c7e4ee3a
CB
7096 if ((st == NULL)
7097 || ((s = ffestorag_symbol (st)) == NULL))
7098 return;
5ff904cd 7099
c7e4ee3a
CB
7100 type = ffecom_type_localvar_ (s,
7101 ffesymbol_basictype (s),
7102 ffesymbol_kindtype (s));
7103 if (type == error_mark_node)
7104 return;
5ff904cd 7105
c7e4ee3a
CB
7106 t = build_decl (VAR_DECL,
7107 ffecom_get_identifier_ (ffesymbol_text (s)),
7108 type);
5ff904cd 7109
c7e4ee3a
CB
7110 TREE_STATIC (t) = TREE_STATIC (mt);
7111 DECL_INITIAL (t) = NULL_TREE;
7112 TREE_ASM_WRITTEN (t) = 1;
045edebe 7113 TREE_USED (t) = 1;
5ff904cd 7114
c7e4ee3a
CB
7115 DECL_RTL (t)
7116 = gen_rtx (MEM, TYPE_MODE (type),
7117 plus_constant (XEXP (DECL_RTL (mt), 0),
7118 ffestorag_modulo (mst)
7119 + ffestorag_offset (st)
7120 - ffestorag_offset (mst)));
5ff904cd 7121
c7e4ee3a 7122 t = start_decl (t, FALSE);
5ff904cd 7123
c7e4ee3a 7124 finish_decl (t, NULL_TREE, FALSE);
5ff904cd
JL
7125}
7126
c7e4ee3a
CB
7127#endif
7128/* Prepare source expression for assignment into a destination perhaps known
7129 to be of a specific size. */
5ff904cd 7130
c7e4ee3a
CB
7131static void
7132ffecom_prepare_let_char_ (ffetargetCharacterSize dest_size, ffebld source)
5ff904cd 7133{
c7e4ee3a
CB
7134 ffecomConcatList_ catlist;
7135 int count;
7136 int i;
7137 tree ltmp;
7138 tree itmp;
7139 tree tempvar = NULL_TREE;
5ff904cd 7140
c7e4ee3a
CB
7141 while (ffebld_op (source) == FFEBLD_opCONVERT)
7142 source = ffebld_left (source);
5ff904cd 7143
c7e4ee3a
CB
7144 catlist = ffecom_concat_list_new_ (source, dest_size);
7145 count = ffecom_concat_list_count_ (catlist);
5ff904cd 7146
c7e4ee3a
CB
7147 if (count >= 2)
7148 {
7149 ltmp
7150 = ffecom_make_tempvar ("let_char_len", ffecom_f2c_ftnlen_type_node,
7151 FFETARGET_charactersizeNONE, count);
7152 itmp
7153 = ffecom_make_tempvar ("let_char_item", ffecom_f2c_address_type_node,
7154 FFETARGET_charactersizeNONE, count);
7155
7156 tempvar = make_tree_vec (2);
7157 TREE_VEC_ELT (tempvar, 0) = ltmp;
7158 TREE_VEC_ELT (tempvar, 1) = itmp;
7159 }
5ff904cd 7160
c7e4ee3a
CB
7161 for (i = 0; i < count; ++i)
7162 ffecom_prepare_arg_ptr_to_expr (ffecom_concat_list_expr_ (catlist, i));
5ff904cd 7163
c7e4ee3a 7164 ffecom_concat_list_kill_ (catlist);
5ff904cd 7165
c7e4ee3a
CB
7166 if (tempvar)
7167 {
7168 ffebld_nonter_set_hook (source, tempvar);
7169 current_binding_level->prep_state = 1;
7170 }
7171}
5ff904cd 7172
c7e4ee3a 7173/* ffecom_push_dummy_decls_ -- Transform dummy args, push parm decls in order
5ff904cd 7174
c7e4ee3a
CB
7175 Ignores STAR (alternate-return) dummies. All other get exec-transitioned
7176 (which generates their trees) and then their trees get push_parm_decl'd.
5ff904cd 7177
c7e4ee3a
CB
7178 The second arg is TRUE if the dummies are for a statement function, in
7179 which case lengths are not pushed for character arguments (since they are
7180 always known by both the caller and the callee, though the code allows
7181 for someday permitting CHAR*(*) stmtfunc dummies). */
5ff904cd 7182
c7e4ee3a
CB
7183#if FFECOM_targetCURRENT == FFECOM_targetGCC
7184static void
7185ffecom_push_dummy_decls_ (ffebld dummy_list, bool stmtfunc)
7186{
7187 ffebld dummy;
7188 ffebld dumlist;
7189 ffesymbol s;
7190 tree parm;
5ff904cd 7191
c7e4ee3a 7192 ffecom_transform_only_dummies_ = TRUE;
5ff904cd 7193
c7e4ee3a 7194 /* First push the parms corresponding to actual dummy "contents". */
5ff904cd 7195
c7e4ee3a
CB
7196 for (dumlist = dummy_list; dumlist != NULL; dumlist = ffebld_trail (dumlist))
7197 {
7198 dummy = ffebld_head (dumlist);
7199 switch (ffebld_op (dummy))
7200 {
7201 case FFEBLD_opSTAR:
7202 case FFEBLD_opANY:
7203 continue; /* Forget alternate returns. */
5ff904cd 7204
c7e4ee3a
CB
7205 default:
7206 break;
7207 }
7208 assert (ffebld_op (dummy) == FFEBLD_opSYMTER);
7209 s = ffebld_symter (dummy);
7210 parm = ffesymbol_hook (s).decl_tree;
7211 if (parm == NULL_TREE)
7212 {
7213 s = ffecom_sym_transform_ (s);
7214 parm = ffesymbol_hook (s).decl_tree;
7215 assert (parm != NULL_TREE);
7216 }
7217 if (parm != error_mark_node)
7218 push_parm_decl (parm);
5ff904cd
JL
7219 }
7220
c7e4ee3a 7221 /* Then, for CHARACTER dummies, push the parms giving their lengths. */
5ff904cd 7222
c7e4ee3a
CB
7223 for (dumlist = dummy_list; dumlist != NULL; dumlist = ffebld_trail (dumlist))
7224 {
7225 dummy = ffebld_head (dumlist);
7226 switch (ffebld_op (dummy))
7227 {
7228 case FFEBLD_opSTAR:
7229 case FFEBLD_opANY:
7230 continue; /* Forget alternate returns, they mean
7231 NOTHING! */
7232
7233 default:
7234 break;
7235 }
7236 s = ffebld_symter (dummy);
7237 if (ffesymbol_basictype (s) != FFEINFO_basictypeCHARACTER)
7238 continue; /* Only looking for CHARACTER arguments. */
7239 if (stmtfunc && (ffesymbol_size (s) != FFETARGET_charactersizeNONE))
7240 continue; /* Stmtfunc arg with known size needs no
7241 length param. */
7242 if (ffesymbol_kind (s) != FFEINFO_kindENTITY)
7243 continue; /* Only looking for variables and arrays. */
7244 parm = ffesymbol_hook (s).length_tree;
7245 assert (parm != NULL_TREE);
7246 if (parm != error_mark_node)
7247 push_parm_decl (parm);
7248 }
7249
7250 ffecom_transform_only_dummies_ = FALSE;
5ff904cd
JL
7251}
7252
7253#endif
c7e4ee3a 7254/* ffecom_start_progunit_ -- Beginning of program unit
5ff904cd 7255
c7e4ee3a
CB
7256 Does GNU back end stuff necessary to teach it about the start of its
7257 equivalent of a Fortran program unit. */
5ff904cd
JL
7258
7259#if FFECOM_targetCURRENT == FFECOM_targetGCC
7260static void
c7e4ee3a 7261ffecom_start_progunit_ ()
5ff904cd 7262{
c7e4ee3a
CB
7263 ffesymbol fn = ffecom_primary_entry_;
7264 ffebld arglist;
7265 tree id; /* Identifier (name) of function. */
7266 tree type; /* Type of function. */
7267 tree result; /* Result of function. */
7268 ffeinfoBasictype bt;
7269 ffeinfoKindtype kt;
7270 ffeglobal g;
7271 ffeglobalType gt;
7272 ffeglobalType egt = FFEGLOBAL_type;
7273 bool charfunc;
7274 bool cmplxfunc;
7275 bool altentries = (ffecom_num_entrypoints_ != 0);
7276 bool multi
7277 = altentries
7278 && (ffecom_primary_entry_kind_ == FFEINFO_kindFUNCTION)
7279 && (ffecom_master_bt_ == FFEINFO_basictypeNONE);
7280 bool main_program = FALSE;
7281 int old_lineno = lineno;
3b304f5b 7282 const char *old_input_filename = input_filename;
5ff904cd 7283
c7e4ee3a
CB
7284 assert (fn != NULL);
7285 assert (ffesymbol_hook (fn).decl_tree == NULL_TREE);
5ff904cd 7286
c7e4ee3a
CB
7287 input_filename = ffesymbol_where_filename (fn);
7288 lineno = ffesymbol_where_filelinenum (fn);
5ff904cd 7289
c7e4ee3a
CB
7290 switch (ffecom_primary_entry_kind_)
7291 {
7292 case FFEINFO_kindPROGRAM:
7293 main_program = TRUE;
7294 gt = FFEGLOBAL_typeMAIN;
7295 bt = FFEINFO_basictypeNONE;
7296 kt = FFEINFO_kindtypeNONE;
7297 type = ffecom_tree_fun_type_void;
7298 charfunc = FALSE;
7299 cmplxfunc = FALSE;
7300 break;
7301
7302 case FFEINFO_kindBLOCKDATA:
7303 gt = FFEGLOBAL_typeBDATA;
7304 bt = FFEINFO_basictypeNONE;
7305 kt = FFEINFO_kindtypeNONE;
7306 type = ffecom_tree_fun_type_void;
7307 charfunc = FALSE;
7308 cmplxfunc = FALSE;
7309 break;
7310
7311 case FFEINFO_kindFUNCTION:
7312 gt = FFEGLOBAL_typeFUNC;
7313 egt = FFEGLOBAL_typeEXT;
7314 bt = ffesymbol_basictype (fn);
7315 kt = ffesymbol_kindtype (fn);
7316 if (bt == FFEINFO_basictypeNONE)
7317 {
7318 ffeimplic_establish_symbol (fn);
7319 if (ffesymbol_funcresult (fn) != NULL)
7320 ffeimplic_establish_symbol (ffesymbol_funcresult (fn));
7321 bt = ffesymbol_basictype (fn);
7322 kt = ffesymbol_kindtype (fn);
7323 }
7324
7325 if (multi)
7326 charfunc = cmplxfunc = FALSE;
7327 else if (bt == FFEINFO_basictypeCHARACTER)
7328 charfunc = TRUE, cmplxfunc = FALSE;
7329 else if ((bt == FFEINFO_basictypeCOMPLEX)
7330 && ffesymbol_is_f2c (fn)
7331 && !altentries)
7332 charfunc = FALSE, cmplxfunc = TRUE;
7333 else
7334 charfunc = cmplxfunc = FALSE;
7335
7336 if (multi || charfunc)
7337 type = ffecom_tree_fun_type_void;
7338 else if (ffesymbol_is_f2c (fn) && !altentries)
7339 type = ffecom_tree_fun_type[bt][kt];
7340 else
7341 type = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
7342
7343 if ((type == NULL_TREE)
7344 || (TREE_TYPE (type) == NULL_TREE))
7345 type = ffecom_tree_fun_type_void; /* _sym_exec_transition. */
7346 break;
7347
7348 case FFEINFO_kindSUBROUTINE:
7349 gt = FFEGLOBAL_typeSUBR;
7350 egt = FFEGLOBAL_typeEXT;
7351 bt = FFEINFO_basictypeNONE;
7352 kt = FFEINFO_kindtypeNONE;
7353 if (ffecom_is_altreturning_)
7354 type = ffecom_tree_subr_type;
7355 else
7356 type = ffecom_tree_fun_type_void;
7357 charfunc = FALSE;
7358 cmplxfunc = FALSE;
7359 break;
5ff904cd 7360
c7e4ee3a
CB
7361 default:
7362 assert ("say what??" == NULL);
7363 /* Fall through. */
7364 case FFEINFO_kindANY:
7365 gt = FFEGLOBAL_typeANY;
7366 bt = FFEINFO_basictypeNONE;
7367 kt = FFEINFO_kindtypeNONE;
7368 type = error_mark_node;
7369 charfunc = FALSE;
7370 cmplxfunc = FALSE;
7371 break;
7372 }
5ff904cd 7373
c7e4ee3a 7374 if (altentries)
5ff904cd 7375 {
c7e4ee3a 7376 id = ffecom_get_invented_identifier ("__g77_masterfun_%s",
14657de8 7377 ffesymbol_text (fn));
c7e4ee3a
CB
7378 }
7379#if FFETARGET_isENFORCED_MAIN
7380 else if (main_program)
7381 id = get_identifier (FFETARGET_nameENFORCED_MAIN_NAME);
7382#endif
7383 else
7384 id = ffecom_get_external_identifier_ (fn);
5ff904cd 7385
c7e4ee3a
CB
7386 start_function (id,
7387 type,
7388 0, /* nested/inline */
7389 !altentries); /* TREE_PUBLIC */
5ff904cd 7390
c7e4ee3a 7391 TREE_USED (current_function_decl) = 1; /* Avoid spurious warning if altentries. */
5ff904cd 7392
c7e4ee3a
CB
7393 if (!altentries
7394 && ((g = ffesymbol_global (fn)) != NULL)
7395 && ((ffeglobal_type (g) == gt)
7396 || (ffeglobal_type (g) == egt)))
7397 {
7398 ffeglobal_set_hook (g, current_function_decl);
7399 }
5ff904cd 7400
c7e4ee3a
CB
7401 /* Arg handling needs exec-transitioned ffesymbols to work with. But
7402 exec-transitioning needs current_function_decl to be filled in. So we
7403 do these things in two phases. */
5ff904cd 7404
c7e4ee3a
CB
7405 if (altentries)
7406 { /* 1st arg identifies which entrypoint. */
7407 ffecom_which_entrypoint_decl_
7408 = build_decl (PARM_DECL,
7409 ffecom_get_invented_identifier ("__g77_%s",
14657de8 7410 "which_entrypoint"),
c7e4ee3a
CB
7411 integer_type_node);
7412 push_parm_decl (ffecom_which_entrypoint_decl_);
7413 }
5ff904cd 7414
c7e4ee3a
CB
7415 if (charfunc
7416 || cmplxfunc
7417 || multi)
7418 { /* Arg for result (return value). */
7419 tree type;
7420 tree length;
5ff904cd 7421
c7e4ee3a
CB
7422 if (charfunc)
7423 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
7424 else if (cmplxfunc)
7425 type = ffecom_tree_type[FFEINFO_basictypeCOMPLEX][kt];
7426 else
7427 type = ffecom_multi_type_node_;
5ff904cd 7428
14657de8 7429 result = ffecom_get_invented_identifier ("__g77_%s", "result");
5ff904cd 7430
c7e4ee3a 7431 /* Make length arg _and_ enhance type info for CHAR arg itself. */
5ff904cd 7432
c7e4ee3a
CB
7433 if (charfunc)
7434 length = ffecom_char_enhance_arg_ (&type, fn);
7435 else
7436 length = NULL_TREE; /* Not ref'd if !charfunc. */
5ff904cd 7437
c7e4ee3a
CB
7438 type = build_pointer_type (type);
7439 result = build_decl (PARM_DECL, result, type);
5ff904cd 7440
c7e4ee3a
CB
7441 push_parm_decl (result);
7442 if (multi)
7443 ffecom_multi_retval_ = result;
7444 else
7445 ffecom_func_result_ = result;
5ff904cd 7446
c7e4ee3a
CB
7447 if (charfunc)
7448 {
7449 push_parm_decl (length);
7450 ffecom_func_length_ = length;
7451 }
5ff904cd
JL
7452 }
7453
c7e4ee3a
CB
7454 if (ffecom_primary_entry_is_proc_)
7455 {
7456 if (altentries)
7457 arglist = ffecom_master_arglist_;
7458 else
7459 arglist = ffesymbol_dummyargs (fn);
7460 ffecom_push_dummy_decls_ (arglist, FALSE);
7461 }
5ff904cd 7462
c7e4ee3a
CB
7463 if (TREE_CODE (current_function_decl) != ERROR_MARK)
7464 store_parm_decls (main_program ? 1 : 0);
5ff904cd 7465
c7e4ee3a
CB
7466 ffecom_start_compstmt ();
7467 /* Disallow temp vars at this level. */
7468 current_binding_level->prep_state = 2;
5ff904cd 7469
c7e4ee3a
CB
7470 lineno = old_lineno;
7471 input_filename = old_input_filename;
5ff904cd 7472
c7e4ee3a
CB
7473 /* This handles any symbols still untransformed, in case -g specified.
7474 This used to be done in ffecom_finish_progunit, but it turns out to
7475 be necessary to do it here so that statement functions are
7476 expanded before code. But don't bother for BLOCK DATA. */
5ff904cd 7477
c7e4ee3a
CB
7478 if (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA)
7479 ffesymbol_drive (ffecom_finish_symbol_transform_);
5ff904cd
JL
7480}
7481
7482#endif
c7e4ee3a 7483/* ffecom_sym_transform_ -- Transform FFE sym into backend sym
5ff904cd 7484
c7e4ee3a
CB
7485 ffesymbol s;
7486 ffecom_sym_transform_(s);
7487
7488 The ffesymbol_hook info for s is updated with appropriate backend info
7489 on the symbol. */
7490
7491#if FFECOM_targetCURRENT == FFECOM_targetGCC
7492static ffesymbol
7493ffecom_sym_transform_ (ffesymbol s)
7494{
7495 tree t; /* Transformed thingy. */
7496 tree tlen; /* Length if CHAR*(*). */
7497 bool addr; /* Is t the address of the thingy? */
7498 ffeinfoBasictype bt;
7499 ffeinfoKindtype kt;
7500 ffeglobal g;
c7e4ee3a 7501 int old_lineno = lineno;
3b304f5b 7502 const char *old_input_filename = input_filename;
5ff904cd 7503
c7e4ee3a
CB
7504 /* Must ensure special ASSIGN variables are declared at top of outermost
7505 block, else they'll end up in the innermost block when their first
7506 ASSIGN is seen, which leaves them out of scope when they're the
7507 subject of a GOTO or I/O statement.
5ff904cd 7508
c7e4ee3a
CB
7509 We make this variable even if -fugly-assign. Just let it go unused,
7510 in case it turns out there are cases where we really want to use this
7511 variable anyway (e.g. ASSIGN to INTEGER*2 variable). */
5ff904cd 7512
c7e4ee3a
CB
7513 if (! ffecom_transform_only_dummies_
7514 && ffesymbol_assigned (s)
7515 && ! ffesymbol_hook (s).assign_tree)
7516 s = ffecom_sym_transform_assign_ (s);
5ff904cd 7517
c7e4ee3a 7518 if (ffesymbol_sfdummyparent (s) == NULL)
5ff904cd 7519 {
c7e4ee3a
CB
7520 input_filename = ffesymbol_where_filename (s);
7521 lineno = ffesymbol_where_filelinenum (s);
7522 }
7523 else
7524 {
7525 ffesymbol sf = ffesymbol_sfdummyparent (s);
5ff904cd 7526
c7e4ee3a
CB
7527 input_filename = ffesymbol_where_filename (sf);
7528 lineno = ffesymbol_where_filelinenum (sf);
7529 }
6d433196 7530
c7e4ee3a
CB
7531 bt = ffeinfo_basictype (ffebld_info (s));
7532 kt = ffeinfo_kindtype (ffebld_info (s));
5ff904cd 7533
c7e4ee3a
CB
7534 t = NULL_TREE;
7535 tlen = NULL_TREE;
7536 addr = FALSE;
5ff904cd 7537
c7e4ee3a
CB
7538 switch (ffesymbol_kind (s))
7539 {
7540 case FFEINFO_kindNONE:
7541 switch (ffesymbol_where (s))
7542 {
7543 case FFEINFO_whereDUMMY: /* Subroutine or function. */
7544 assert (ffecom_transform_only_dummies_);
5ff904cd 7545
c7e4ee3a
CB
7546 /* Before 0.4, this could be ENTITY/DUMMY, but see
7547 ffestu_sym_end_transition -- no longer true (in particular, if
7548 it could be an ENTITY, it _will_ be made one, so that
7549 possibility won't come through here). So we never make length
7550 arg for CHARACTER type. */
5ff904cd 7551
c7e4ee3a
CB
7552 t = build_decl (PARM_DECL,
7553 ffecom_get_identifier_ (ffesymbol_text (s)),
7554 ffecom_tree_ptr_to_subr_type);
7555#if BUILT_FOR_270
7556 DECL_ARTIFICIAL (t) = 1;
7557#endif
7558 addr = TRUE;
7559 break;
5ff904cd 7560
c7e4ee3a
CB
7561 case FFEINFO_whereGLOBAL: /* Subroutine or function. */
7562 assert (!ffecom_transform_only_dummies_);
5ff904cd 7563
c7e4ee3a
CB
7564 if (((g = ffesymbol_global (s)) != NULL)
7565 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
7566 || (ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
7567 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
7568 && (ffeglobal_hook (g) != NULL_TREE)
7569 && ffe_is_globals ())
7570 {
7571 t = ffeglobal_hook (g);
7572 break;
7573 }
5ff904cd 7574
c7e4ee3a
CB
7575 t = build_decl (FUNCTION_DECL,
7576 ffecom_get_external_identifier_ (s),
7577 ffecom_tree_subr_type); /* Assume subr. */
7578 DECL_EXTERNAL (t) = 1;
7579 TREE_PUBLIC (t) = 1;
5ff904cd 7580
c7e4ee3a
CB
7581 t = start_decl (t, FALSE);
7582 finish_decl (t, NULL_TREE, FALSE);
795232f7 7583
c7e4ee3a
CB
7584 if ((g != NULL)
7585 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
7586 || (ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
7587 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
7588 ffeglobal_set_hook (g, t);
5ff904cd 7589
7189a4b0 7590 ffecom_save_tree_forever (t);
5ff904cd 7591
c7e4ee3a 7592 break;
5ff904cd 7593
c7e4ee3a
CB
7594 default:
7595 assert ("NONE where unexpected" == NULL);
7596 /* Fall through. */
7597 case FFEINFO_whereANY:
7598 break;
7599 }
5ff904cd 7600 break;
5ff904cd 7601
c7e4ee3a
CB
7602 case FFEINFO_kindENTITY:
7603 switch (ffeinfo_where (ffesymbol_info (s)))
7604 {
5ff904cd 7605
c7e4ee3a
CB
7606 case FFEINFO_whereCONSTANT:
7607 /* ~~Debugging info needed? */
7608 assert (!ffecom_transform_only_dummies_);
7609 t = error_mark_node; /* Shouldn't ever see this in expr. */
7610 break;
5ff904cd 7611
c7e4ee3a
CB
7612 case FFEINFO_whereLOCAL:
7613 assert (!ffecom_transform_only_dummies_);
5ff904cd 7614
c7e4ee3a
CB
7615 {
7616 ffestorag st = ffesymbol_storage (s);
7617 tree type;
5ff904cd 7618
c7e4ee3a
CB
7619 if ((st != NULL)
7620 && (ffestorag_size (st) == 0))
7621 {
7622 t = error_mark_node;
7623 break;
7624 }
5ff904cd 7625
c7e4ee3a 7626 type = ffecom_type_localvar_ (s, bt, kt);
5ff904cd 7627
c7e4ee3a
CB
7628 if (type == error_mark_node)
7629 {
7630 t = error_mark_node;
7631 break;
7632 }
5ff904cd 7633
c7e4ee3a
CB
7634 if ((st != NULL)
7635 && (ffestorag_parent (st) != NULL))
7636 { /* Child of EQUIVALENCE parent. */
7637 ffestorag est;
7638 tree et;
c7e4ee3a 7639 ffetargetOffset offset;
5ff904cd 7640
c7e4ee3a
CB
7641 est = ffestorag_parent (st);
7642 ffecom_transform_equiv_ (est);
5ff904cd 7643
c7e4ee3a
CB
7644 et = ffestorag_hook (est);
7645 assert (et != NULL_TREE);
5ff904cd 7646
c7e4ee3a
CB
7647 if (! TREE_STATIC (et))
7648 put_var_into_stack (et);
5ff904cd 7649
c7e4ee3a
CB
7650 offset = ffestorag_modulo (est)
7651 + ffestorag_offset (ffesymbol_storage (s))
7652 - ffestorag_offset (est);
5ff904cd 7653
c7e4ee3a 7654 ffecom_debug_kludge_ (et, "EQUIVALENCE", s, type, offset);
5ff904cd 7655
c7e4ee3a 7656 /* (t_type *) (((char *) &et) + offset) */
5ff904cd 7657
c7e4ee3a
CB
7658 t = convert (string_type_node, /* (char *) */
7659 ffecom_1 (ADDR_EXPR,
7660 build_pointer_type (TREE_TYPE (et)),
7661 et));
7662 t = ffecom_2 (PLUS_EXPR, TREE_TYPE (t),
7663 t,
7664 build_int_2 (offset, 0));
7665 t = convert (build_pointer_type (type),
7666 t);
d50108c7 7667 TREE_CONSTANT (t) = staticp (et);
5ff904cd 7668
c7e4ee3a 7669 addr = TRUE;
c7e4ee3a
CB
7670 }
7671 else
7672 {
7673 tree initexpr;
7674 bool init = ffesymbol_is_init (s);
5ff904cd 7675
c7e4ee3a
CB
7676 t = build_decl (VAR_DECL,
7677 ffecom_get_identifier_ (ffesymbol_text (s)),
7678 type);
5ff904cd 7679
c7e4ee3a
CB
7680 if (init
7681 || ffesymbol_namelisted (s)
7682#ifdef FFECOM_sizeMAXSTACKITEM
7683 || ((st != NULL)
7684 && (ffestorag_size (st) > FFECOM_sizeMAXSTACKITEM))
7685#endif
7686 || ((ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
7687 && (ffecom_primary_entry_kind_
7688 != FFEINFO_kindBLOCKDATA)
7689 && (ffesymbol_is_save (s) || ffe_is_saveall ())))
7690 TREE_STATIC (t) = !ffesymbol_attr (s, FFESYMBOL_attrADJUSTABLE);
7691 else
7692 TREE_STATIC (t) = 0; /* No need to make static. */
5ff904cd 7693
c7e4ee3a
CB
7694 if (init || ffe_is_init_local_zero ())
7695 DECL_INITIAL (t) = error_mark_node;
5ff904cd 7696
c7e4ee3a
CB
7697 /* Keep -Wunused from complaining about var if it
7698 is used as sfunc arg or DATA implied-DO. */
7699 if (ffesymbol_attrs (s) & FFESYMBOL_attrsSFARG)
7700 DECL_IN_SYSTEM_HEADER (t) = 1;
5ff904cd 7701
c7e4ee3a 7702 t = start_decl (t, FALSE);
5ff904cd 7703
c7e4ee3a
CB
7704 if (init)
7705 {
7706 if (ffesymbol_init (s) != NULL)
7707 initexpr = ffecom_expr (ffesymbol_init (s));
7708 else
7709 initexpr = ffecom_init_zero_ (t);
7710 }
7711 else if (ffe_is_init_local_zero ())
7712 initexpr = ffecom_init_zero_ (t);
7713 else
7714 initexpr = NULL_TREE; /* Not ref'd if !init. */
5ff904cd 7715
c7e4ee3a 7716 finish_decl (t, initexpr, FALSE);
5ff904cd 7717
06ceef4e 7718 if (st != NULL && DECL_SIZE (t) != error_mark_node)
c7e4ee3a 7719 {
06ceef4e 7720 assert (TREE_CODE (DECL_SIZE_UNIT (t)) == INTEGER_CST);
05bccae2
RK
7721 assert (0 == compare_tree_int (DECL_SIZE_UNIT (t),
7722 ffestorag_size (st)));
c7e4ee3a 7723 }
c7e4ee3a
CB
7724 }
7725 }
5ff904cd 7726 break;
5ff904cd 7727
c7e4ee3a
CB
7728 case FFEINFO_whereRESULT:
7729 assert (!ffecom_transform_only_dummies_);
5ff904cd 7730
c7e4ee3a
CB
7731 if (bt == FFEINFO_basictypeCHARACTER)
7732 { /* Result is already in list of dummies, use
7733 it (& length). */
7734 t = ffecom_func_result_;
7735 tlen = ffecom_func_length_;
7736 addr = TRUE;
7737 break;
7738 }
7739 if ((ffecom_num_entrypoints_ == 0)
7740 && (bt == FFEINFO_basictypeCOMPLEX)
7741 && (ffesymbol_is_f2c (ffecom_primary_entry_)))
7742 { /* Result is already in list of dummies, use
7743 it. */
7744 t = ffecom_func_result_;
7745 addr = TRUE;
7746 break;
7747 }
7748 if (ffecom_func_result_ != NULL_TREE)
7749 {
7750 t = ffecom_func_result_;
7751 break;
7752 }
7753 if ((ffecom_num_entrypoints_ != 0)
7754 && (ffecom_master_bt_ == FFEINFO_basictypeNONE))
7755 {
c7e4ee3a
CB
7756 assert (ffecom_multi_retval_ != NULL_TREE);
7757 t = ffecom_1 (INDIRECT_REF, ffecom_multi_type_node_,
7758 ffecom_multi_retval_);
7759 t = ffecom_2 (COMPONENT_REF, ffecom_tree_type[bt][kt],
7760 t, ffecom_multi_fields_[bt][kt]);
5ff904cd 7761
c7e4ee3a
CB
7762 break;
7763 }
5ff904cd 7764
c7e4ee3a
CB
7765 t = build_decl (VAR_DECL,
7766 ffecom_get_identifier_ (ffesymbol_text (s)),
7767 ffecom_tree_type[bt][kt]);
7768 TREE_STATIC (t) = 0; /* Put result on stack. */
7769 t = start_decl (t, FALSE);
7770 finish_decl (t, NULL_TREE, FALSE);
5ff904cd 7771
c7e4ee3a 7772 ffecom_func_result_ = t;
5ff904cd 7773
c7e4ee3a 7774 break;
5ff904cd 7775
c7e4ee3a
CB
7776 case FFEINFO_whereDUMMY:
7777 {
7778 tree type;
7779 ffebld dl;
7780 ffebld dim;
7781 tree low;
7782 tree high;
7783 tree old_sizes;
7784 bool adjustable = FALSE; /* Conditionally adjustable? */
5ff904cd 7785
c7e4ee3a
CB
7786 type = ffecom_tree_type[bt][kt];
7787 if (ffesymbol_sfdummyparent (s) != NULL)
7788 {
7789 if (current_function_decl == ffecom_outer_function_decl_)
7790 { /* Exec transition before sfunc
7791 context; get it later. */
7792 break;
7793 }
7794 t = ffecom_get_identifier_ (ffesymbol_text
7795 (ffesymbol_sfdummyparent (s)));
7796 }
7797 else
7798 t = ffecom_get_identifier_ (ffesymbol_text (s));
5ff904cd 7799
c7e4ee3a 7800 assert (ffecom_transform_only_dummies_);
5ff904cd 7801
c7e4ee3a
CB
7802 old_sizes = get_pending_sizes ();
7803 put_pending_sizes (old_sizes);
5ff904cd 7804
c7e4ee3a
CB
7805 if (bt == FFEINFO_basictypeCHARACTER)
7806 tlen = ffecom_char_enhance_arg_ (&type, s);
7807 type = ffecom_check_size_overflow_ (s, type, TRUE);
5ff904cd 7808
c7e4ee3a
CB
7809 for (dl = ffesymbol_dims (s); dl != NULL; dl = ffebld_trail (dl))
7810 {
7811 if (type == error_mark_node)
7812 break;
5ff904cd 7813
c7e4ee3a
CB
7814 dim = ffebld_head (dl);
7815 assert (ffebld_op (dim) == FFEBLD_opBOUNDS);
7816 if ((ffebld_left (dim) == NULL) || ffecom_doing_entry_)
7817 low = ffecom_integer_one_node;
7818 else
7819 low = ffecom_expr (ffebld_left (dim));
7820 assert (ffebld_right (dim) != NULL);
7821 if ((ffebld_op (ffebld_right (dim)) == FFEBLD_opSTAR)
7822 || ffecom_doing_entry_)
7823 {
7824 /* Used to just do high=low. But for ffecom_tree_
7825 canonize_ref_, it probably is important to correctly
7826 assess the size. E.g. given COMPLEX C(*),CFUNC and
7827 C(2)=CFUNC(C), overlap can happen, while it can't
7828 for, say, C(1)=CFUNC(C(2)). */
7829 /* Even more recently used to set to INT_MAX, but that
7830 broke when some overflow checking went into the back
7831 end. Now we just leave the upper bound unspecified. */
7832 high = NULL;
7833 }
7834 else
7835 high = ffecom_expr (ffebld_right (dim));
5ff904cd 7836
c7e4ee3a
CB
7837 /* Determine whether array is conditionally adjustable,
7838 to decide whether back-end magic is needed.
5ff904cd 7839
c7e4ee3a
CB
7840 Normally the front end uses the back-end function
7841 variable_size to wrap SAVE_EXPR's around expressions
7842 affecting the size/shape of an array so that the
7843 size/shape info doesn't change during execution
7844 of the compiled code even though variables and
7845 functions referenced in those expressions might.
5ff904cd 7846
c7e4ee3a
CB
7847 variable_size also makes sure those saved expressions
7848 get evaluated immediately upon entry to the
7849 compiled procedure -- the front end normally doesn't
7850 have to worry about that.
3cf0cea4 7851
c7e4ee3a
CB
7852 However, there is a problem with this that affects
7853 g77's implementation of entry points, and that is
7854 that it is _not_ true that each invocation of the
7855 compiled procedure is permitted to evaluate
7856 array size/shape info -- because it is possible
7857 that, for some invocations, that info is invalid (in
7858 which case it is "promised" -- i.e. a violation of
7859 the Fortran standard -- that the compiled code
7860 won't reference the array or its size/shape
7861 during that particular invocation).
5ff904cd 7862
c7e4ee3a 7863 To phrase this in C terms, consider this gcc function:
5ff904cd 7864
c7e4ee3a
CB
7865 void foo (int *n, float (*a)[*n])
7866 {
7867 // a is "pointer to array ...", fyi.
7868 }
5ff904cd 7869
c7e4ee3a
CB
7870 Suppose that, for some invocations, it is permitted
7871 for a caller of foo to do this:
5ff904cd 7872
c7e4ee3a 7873 foo (NULL, NULL);
5ff904cd 7874
c7e4ee3a
CB
7875 Now the _written_ code for foo can take such a call
7876 into account by either testing explicitly for whether
7877 (a == NULL) || (n == NULL) -- presumably it is
7878 not permitted to reference *a in various fashions
7879 if (n == NULL) I suppose -- or it can avoid it by
7880 looking at other info (other arguments, static/global
7881 data, etc.).
5ff904cd 7882
c7e4ee3a
CB
7883 However, this won't work in gcc 2.5.8 because it'll
7884 automatically emit the code to save the "*n"
7885 expression, which'll yield a NULL dereference for
7886 the "foo (NULL, NULL)" call, something the code
7887 for foo cannot prevent.
5ff904cd 7888
c7e4ee3a
CB
7889 g77 definitely needs to avoid executing such
7890 code anytime the pointer to the adjustable array
7891 is NULL, because even if its bounds expressions
7892 don't have any references to possible "absent"
7893 variables like "*n" -- say all variable references
7894 are to COMMON variables, i.e. global (though in C,
7895 local static could actually make sense) -- the
7896 expressions could yield other run-time problems
7897 for allowably "dead" values in those variables.
5ff904cd 7898
c7e4ee3a
CB
7899 For example, let's consider a more complicated
7900 version of foo:
5ff904cd 7901
c7e4ee3a
CB
7902 extern int i;
7903 extern int j;
5ff904cd 7904
c7e4ee3a
CB
7905 void foo (float (*a)[i/j])
7906 {
7907 ...
7908 }
5ff904cd 7909
c7e4ee3a
CB
7910 The above is (essentially) quite valid for Fortran
7911 but, again, for a call like "foo (NULL);", it is
7912 permitted for i and j to be undefined when the
7913 call is made. If j happened to be zero, for
7914 example, emitting the code to evaluate "i/j"
7915 could result in a run-time error.
5ff904cd 7916
c7e4ee3a
CB
7917 Offhand, though I don't have my F77 or F90
7918 standards handy, it might even be valid for a
7919 bounds expression to contain a function reference,
7920 in which case I doubt it is permitted for an
7921 implementation to invoke that function in the
7922 Fortran case involved here (invocation of an
7923 alternate ENTRY point that doesn't have the adjustable
7924 array as one of its arguments).
5ff904cd 7925
c7e4ee3a
CB
7926 So, the code that the compiler would normally emit
7927 to preevaluate the size/shape info for an
7928 adjustable array _must not_ be executed at run time
7929 in certain cases. Specifically, for Fortran,
7930 the case is when the pointer to the adjustable
7931 array == NULL. (For gnu-ish C, it might be nice
7932 for the source code itself to specify an expression
7933 that, if TRUE, inhibits execution of the code. Or
7934 reverse the sense for elegance.)
5ff904cd 7935
c7e4ee3a
CB
7936 (Note that g77 could use a different test than NULL,
7937 actually, since it happens to always pass an
7938 integer to the called function that specifies which
7939 entry point is being invoked. Hmm, this might
7940 solve the next problem.)
7941
7942 One way a user could, I suppose, write "foo" so
7943 it works is to insert COND_EXPR's for the
7944 size/shape info so the dangerous stuff isn't
7945 actually done, as in:
7946
7947 void foo (int *n, float (*a)[(a == NULL) ? 0 : *n])
7948 {
7949 ...
7950 }
5ff904cd 7951
c7e4ee3a
CB
7952 The next problem is that the front end needs to
7953 be able to tell the back end about the array's
7954 decl _before_ it tells it about the conditional
7955 expression to inhibit evaluation of size/shape info,
7956 as shown above.
5ff904cd 7957
c7e4ee3a
CB
7958 To solve this, the front end needs to be able
7959 to give the back end the expression to inhibit
7960 generation of the preevaluation code _after_
7961 it makes the decl for the adjustable array.
5ff904cd 7962
c7e4ee3a
CB
7963 Until then, the above example using the COND_EXPR
7964 doesn't pass muster with gcc because the "(a == NULL)"
7965 part has a reference to "a", which is still
7966 undefined at that point.
5ff904cd 7967
c7e4ee3a
CB
7968 g77 will therefore use a different mechanism in the
7969 meantime. */
5ff904cd 7970
c7e4ee3a
CB
7971 if (!adjustable
7972 && ((TREE_CODE (low) != INTEGER_CST)
7973 || (high && TREE_CODE (high) != INTEGER_CST)))
7974 adjustable = TRUE;
5ff904cd 7975
c7e4ee3a
CB
7976#if 0 /* Old approach -- see below. */
7977 if (TREE_CODE (low) != INTEGER_CST)
7978 low = ffecom_3 (COND_EXPR, integer_type_node,
7979 ffecom_adjarray_passed_ (s),
7980 low,
7981 ffecom_integer_zero_node);
5ff904cd 7982
c7e4ee3a
CB
7983 if (high && TREE_CODE (high) != INTEGER_CST)
7984 high = ffecom_3 (COND_EXPR, integer_type_node,
7985 ffecom_adjarray_passed_ (s),
7986 high,
7987 ffecom_integer_zero_node);
7988#endif
5ff904cd 7989
c7e4ee3a
CB
7990 /* ~~~gcc/stor-layout.c (layout_type) should do this,
7991 probably. Fixes 950302-1.f. */
5ff904cd 7992
c7e4ee3a
CB
7993 if (TREE_CODE (low) != INTEGER_CST)
7994 low = variable_size (low);
5ff904cd 7995
c7e4ee3a
CB
7996 /* ~~~Similarly, this fixes dumb0.f. The C front end
7997 does this, which is why dumb0.c would work. */
5ff904cd 7998
c7e4ee3a
CB
7999 if (high && TREE_CODE (high) != INTEGER_CST)
8000 high = variable_size (high);
5ff904cd 8001
c7e4ee3a
CB
8002 type
8003 = build_array_type
8004 (type,
8005 build_range_type (ffecom_integer_type_node,
8006 low, high));
8007 type = ffecom_check_size_overflow_ (s, type, TRUE);
8008 }
5ff904cd 8009
c7e4ee3a
CB
8010 if (type == error_mark_node)
8011 {
8012 t = error_mark_node;
8013 break;
8014 }
5ff904cd 8015
c7e4ee3a
CB
8016 if ((ffesymbol_sfdummyparent (s) == NULL)
8017 || (ffesymbol_basictype (s) == FFEINFO_basictypeCHARACTER))
8018 {
8019 type = build_pointer_type (type);
8020 addr = TRUE;
8021 }
5ff904cd 8022
c7e4ee3a 8023 t = build_decl (PARM_DECL, t, type);
5ff904cd 8024#if BUILT_FOR_270
c7e4ee3a 8025 DECL_ARTIFICIAL (t) = 1;
5ff904cd 8026#endif
5ff904cd 8027
c7e4ee3a
CB
8028 /* If this arg is present in every entry point's list of
8029 dummy args, then we're done. */
5ff904cd 8030
c7e4ee3a
CB
8031 if (ffesymbol_numentries (s)
8032 == (ffecom_num_entrypoints_ + 1))
5ff904cd 8033 break;
5ff904cd 8034
c7e4ee3a 8035#if 1
5ff904cd 8036
c7e4ee3a
CB
8037 /* If variable_size in stor-layout has been called during
8038 the above, then get_pending_sizes should have the
8039 yet-to-be-evaluated saved expressions pending.
8040 Make the whole lot of them get emitted, conditionally
8041 on whether the array decl ("t" above) is not NULL. */
5ff904cd 8042
c7e4ee3a
CB
8043 {
8044 tree sizes = get_pending_sizes ();
8045 tree tem;
5ff904cd 8046
c7e4ee3a
CB
8047 for (tem = sizes;
8048 tem != old_sizes;
8049 tem = TREE_CHAIN (tem))
8050 {
8051 tree temv = TREE_VALUE (tem);
5ff904cd 8052
c7e4ee3a
CB
8053 if (sizes == tem)
8054 sizes = temv;
8055 else
8056 sizes
8057 = ffecom_2 (COMPOUND_EXPR,
8058 TREE_TYPE (sizes),
8059 temv,
8060 sizes);
8061 }
5ff904cd 8062
c7e4ee3a
CB
8063 if (sizes != tem)
8064 {
8065 sizes
8066 = ffecom_3 (COND_EXPR,
8067 TREE_TYPE (sizes),
8068 ffecom_2 (NE_EXPR,
8069 integer_type_node,
8070 t,
8071 null_pointer_node),
8072 sizes,
8073 convert (TREE_TYPE (sizes),
8074 integer_zero_node));
8075 sizes = ffecom_save_tree (sizes);
5ff904cd 8076
c7e4ee3a
CB
8077 sizes
8078 = tree_cons (NULL_TREE, sizes, tem);
8079 }
5ff904cd 8080
c7e4ee3a
CB
8081 if (sizes)
8082 put_pending_sizes (sizes);
8083 }
5ff904cd 8084
c7e4ee3a
CB
8085#else
8086#if 0
8087 if (adjustable
8088 && (ffesymbol_numentries (s)
8089 != ffecom_num_entrypoints_ + 1))
8090 DECL_SOMETHING (t)
8091 = ffecom_2 (NE_EXPR, integer_type_node,
8092 t,
8093 null_pointer_node);
8094#else
8095#if 0
8096 if (adjustable
8097 && (ffesymbol_numentries (s)
8098 != ffecom_num_entrypoints_ + 1))
8099 {
8100 ffebad_start (FFEBAD_MISSING_ADJARRAY_UNSUPPORTED);
8101 ffebad_here (0, ffesymbol_where_line (s),
8102 ffesymbol_where_column (s));
8103 ffebad_string (ffesymbol_text (s));
8104 ffebad_finish ();
8105 }
8106#endif
8107#endif
8108#endif
8109 }
5ff904cd
JL
8110 break;
8111
c7e4ee3a 8112 case FFEINFO_whereCOMMON:
5ff904cd 8113 {
c7e4ee3a
CB
8114 ffesymbol cs;
8115 ffeglobal cg;
8116 tree ct;
5ff904cd
JL
8117 ffestorag st = ffesymbol_storage (s);
8118 tree type;
8119
c7e4ee3a
CB
8120 cs = ffesymbol_common (s); /* The COMMON area itself. */
8121 if (st != NULL) /* Else not laid out. */
5ff904cd 8122 {
c7e4ee3a
CB
8123 ffecom_transform_common_ (cs);
8124 st = ffesymbol_storage (s);
5ff904cd
JL
8125 }
8126
c7e4ee3a 8127 type = ffecom_type_localvar_ (s, bt, kt);
5ff904cd 8128
c7e4ee3a
CB
8129 cg = ffesymbol_global (cs); /* The global COMMON info. */
8130 if ((cg == NULL)
8131 || (ffeglobal_type (cg) != FFEGLOBAL_typeCOMMON))
8132 ct = NULL_TREE;
8133 else
8134 ct = ffeglobal_hook (cg); /* The common area's tree. */
5ff904cd 8135
c7e4ee3a
CB
8136 if ((ct == NULL_TREE)
8137 || (st == NULL)
8138 || (type == error_mark_node))
8139 t = error_mark_node;
8140 else
8141 {
8142 ffetargetOffset offset;
8143 ffestorag cst;
5ff904cd 8144
c7e4ee3a
CB
8145 cst = ffestorag_parent (st);
8146 assert (cst == ffesymbol_storage (cs));
5ff904cd 8147
c7e4ee3a
CB
8148 offset = ffestorag_modulo (cst)
8149 + ffestorag_offset (st)
8150 - ffestorag_offset (cst);
5ff904cd 8151
c7e4ee3a 8152 ffecom_debug_kludge_ (ct, "COMMON", s, type, offset);
5ff904cd 8153
c7e4ee3a 8154 /* (t_type *) (((char *) &ct) + offset) */
5ff904cd
JL
8155
8156 t = convert (string_type_node, /* (char *) */
8157 ffecom_1 (ADDR_EXPR,
c7e4ee3a
CB
8158 build_pointer_type (TREE_TYPE (ct)),
8159 ct));
5ff904cd
JL
8160 t = ffecom_2 (PLUS_EXPR, TREE_TYPE (t),
8161 t,
8162 build_int_2 (offset, 0));
8163 t = convert (build_pointer_type (type),
8164 t);
d50108c7 8165 TREE_CONSTANT (t) = 1;
5ff904cd
JL
8166
8167 addr = TRUE;
5ff904cd 8168 }
c7e4ee3a
CB
8169 }
8170 break;
5ff904cd 8171
c7e4ee3a
CB
8172 case FFEINFO_whereIMMEDIATE:
8173 case FFEINFO_whereGLOBAL:
8174 case FFEINFO_whereFLEETING:
8175 case FFEINFO_whereFLEETING_CADDR:
8176 case FFEINFO_whereFLEETING_IADDR:
8177 case FFEINFO_whereINTRINSIC:
8178 case FFEINFO_whereCONSTANT_SUBOBJECT:
8179 default:
8180 assert ("ENTITY where unheard of" == NULL);
8181 /* Fall through. */
8182 case FFEINFO_whereANY:
8183 t = error_mark_node;
8184 break;
8185 }
8186 break;
5ff904cd 8187
c7e4ee3a
CB
8188 case FFEINFO_kindFUNCTION:
8189 switch (ffeinfo_where (ffesymbol_info (s)))
8190 {
8191 case FFEINFO_whereLOCAL: /* Me. */
8192 assert (!ffecom_transform_only_dummies_);
8193 t = current_function_decl;
5ff904cd
JL
8194 break;
8195
c7e4ee3a 8196 case FFEINFO_whereGLOBAL:
5ff904cd
JL
8197 assert (!ffecom_transform_only_dummies_);
8198
c7e4ee3a
CB
8199 if (((g = ffesymbol_global (s)) != NULL)
8200 && ((ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
8201 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
8202 && (ffeglobal_hook (g) != NULL_TREE)
8203 && ffe_is_globals ())
5ff904cd 8204 {
c7e4ee3a 8205 t = ffeglobal_hook (g);
5ff904cd
JL
8206 break;
8207 }
5ff904cd 8208
c7e4ee3a
CB
8209 if (ffesymbol_is_f2c (s)
8210 && (ffesymbol_where (s) != FFEINFO_whereCONSTANT))
8211 t = ffecom_tree_fun_type[bt][kt];
8212 else
8213 t = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
5ff904cd 8214
c7e4ee3a
CB
8215 t = build_decl (FUNCTION_DECL,
8216 ffecom_get_external_identifier_ (s),
8217 t);
8218 DECL_EXTERNAL (t) = 1;
8219 TREE_PUBLIC (t) = 1;
5ff904cd 8220
5ff904cd
JL
8221 t = start_decl (t, FALSE);
8222 finish_decl (t, NULL_TREE, FALSE);
8223
c7e4ee3a
CB
8224 if ((g != NULL)
8225 && ((ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
8226 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
8227 ffeglobal_set_hook (g, t);
8228
7189a4b0 8229 ffecom_save_tree_forever (t);
5ff904cd 8230
5ff904cd
JL
8231 break;
8232
8233 case FFEINFO_whereDUMMY:
c7e4ee3a 8234 assert (ffecom_transform_only_dummies_);
5ff904cd 8235
c7e4ee3a
CB
8236 if (ffesymbol_is_f2c (s)
8237 && (ffesymbol_where (s) != FFEINFO_whereCONSTANT))
8238 t = ffecom_tree_ptr_to_fun_type[bt][kt];
8239 else
8240 t = build_pointer_type
8241 (build_function_type (ffecom_tree_type[bt][kt], NULL_TREE));
8242
8243 t = build_decl (PARM_DECL,
8244 ffecom_get_identifier_ (ffesymbol_text (s)),
8245 t);
8246#if BUILT_FOR_270
8247 DECL_ARTIFICIAL (t) = 1;
8248#endif
8249 addr = TRUE;
8250 break;
8251
8252 case FFEINFO_whereCONSTANT: /* Statement function. */
8253 assert (!ffecom_transform_only_dummies_);
8254 t = ffecom_gen_sfuncdef_ (s, bt, kt);
8255 break;
8256
8257 case FFEINFO_whereINTRINSIC:
8258 assert (!ffecom_transform_only_dummies_);
8259 break; /* Let actual references generate their
8260 decls. */
8261
8262 default:
8263 assert ("FUNCTION where unheard of" == NULL);
8264 /* Fall through. */
8265 case FFEINFO_whereANY:
8266 t = error_mark_node;
8267 break;
8268 }
8269 break;
8270
8271 case FFEINFO_kindSUBROUTINE:
8272 switch (ffeinfo_where (ffesymbol_info (s)))
8273 {
8274 case FFEINFO_whereLOCAL: /* Me. */
8275 assert (!ffecom_transform_only_dummies_);
8276 t = current_function_decl;
8277 break;
5ff904cd 8278
c7e4ee3a
CB
8279 case FFEINFO_whereGLOBAL:
8280 assert (!ffecom_transform_only_dummies_);
5ff904cd 8281
c7e4ee3a
CB
8282 if (((g = ffesymbol_global (s)) != NULL)
8283 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
8284 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
8285 && (ffeglobal_hook (g) != NULL_TREE)
8286 && ffe_is_globals ())
8287 {
8288 t = ffeglobal_hook (g);
8289 break;
8290 }
5ff904cd 8291
c7e4ee3a
CB
8292 t = build_decl (FUNCTION_DECL,
8293 ffecom_get_external_identifier_ (s),
8294 ffecom_tree_subr_type);
8295 DECL_EXTERNAL (t) = 1;
8296 TREE_PUBLIC (t) = 1;
5ff904cd 8297
c7e4ee3a
CB
8298 t = start_decl (t, FALSE);
8299 finish_decl (t, NULL_TREE, FALSE);
5ff904cd 8300
c7e4ee3a
CB
8301 if ((g != NULL)
8302 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
8303 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
8304 ffeglobal_set_hook (g, t);
5ff904cd 8305
7189a4b0 8306 ffecom_save_tree_forever (t);
5ff904cd 8307
c7e4ee3a 8308 break;
5ff904cd 8309
c7e4ee3a
CB
8310 case FFEINFO_whereDUMMY:
8311 assert (ffecom_transform_only_dummies_);
5ff904cd 8312
c7e4ee3a
CB
8313 t = build_decl (PARM_DECL,
8314 ffecom_get_identifier_ (ffesymbol_text (s)),
8315 ffecom_tree_ptr_to_subr_type);
8316#if BUILT_FOR_270
8317 DECL_ARTIFICIAL (t) = 1;
8318#endif
8319 addr = TRUE;
8320 break;
5ff904cd 8321
c7e4ee3a
CB
8322 case FFEINFO_whereINTRINSIC:
8323 assert (!ffecom_transform_only_dummies_);
8324 break; /* Let actual references generate their
8325 decls. */
5ff904cd 8326
c7e4ee3a
CB
8327 default:
8328 assert ("SUBROUTINE where unheard of" == NULL);
8329 /* Fall through. */
8330 case FFEINFO_whereANY:
8331 t = error_mark_node;
8332 break;
8333 }
8334 break;
5ff904cd 8335
c7e4ee3a
CB
8336 case FFEINFO_kindPROGRAM:
8337 switch (ffeinfo_where (ffesymbol_info (s)))
8338 {
8339 case FFEINFO_whereLOCAL: /* Me. */
8340 assert (!ffecom_transform_only_dummies_);
8341 t = current_function_decl;
8342 break;
5ff904cd 8343
c7e4ee3a
CB
8344 case FFEINFO_whereCOMMON:
8345 case FFEINFO_whereDUMMY:
8346 case FFEINFO_whereGLOBAL:
8347 case FFEINFO_whereRESULT:
8348 case FFEINFO_whereFLEETING:
8349 case FFEINFO_whereFLEETING_CADDR:
8350 case FFEINFO_whereFLEETING_IADDR:
8351 case FFEINFO_whereIMMEDIATE:
8352 case FFEINFO_whereINTRINSIC:
8353 case FFEINFO_whereCONSTANT:
8354 case FFEINFO_whereCONSTANT_SUBOBJECT:
8355 default:
8356 assert ("PROGRAM where unheard of" == NULL);
8357 /* Fall through. */
8358 case FFEINFO_whereANY:
8359 t = error_mark_node;
8360 break;
8361 }
8362 break;
5ff904cd 8363
c7e4ee3a
CB
8364 case FFEINFO_kindBLOCKDATA:
8365 switch (ffeinfo_where (ffesymbol_info (s)))
8366 {
8367 case FFEINFO_whereLOCAL: /* Me. */
8368 assert (!ffecom_transform_only_dummies_);
8369 t = current_function_decl;
8370 break;
5ff904cd 8371
c7e4ee3a
CB
8372 case FFEINFO_whereGLOBAL:
8373 assert (!ffecom_transform_only_dummies_);
5ff904cd 8374
c7e4ee3a
CB
8375 t = build_decl (FUNCTION_DECL,
8376 ffecom_get_external_identifier_ (s),
8377 ffecom_tree_blockdata_type);
8378 DECL_EXTERNAL (t) = 1;
8379 TREE_PUBLIC (t) = 1;
5ff904cd 8380
c7e4ee3a
CB
8381 t = start_decl (t, FALSE);
8382 finish_decl (t, NULL_TREE, FALSE);
5ff904cd 8383
7189a4b0 8384 ffecom_save_tree_forever (t);
5ff904cd 8385
c7e4ee3a 8386 break;
5ff904cd 8387
c7e4ee3a
CB
8388 case FFEINFO_whereCOMMON:
8389 case FFEINFO_whereDUMMY:
8390 case FFEINFO_whereRESULT:
8391 case FFEINFO_whereFLEETING:
8392 case FFEINFO_whereFLEETING_CADDR:
8393 case FFEINFO_whereFLEETING_IADDR:
8394 case FFEINFO_whereIMMEDIATE:
8395 case FFEINFO_whereINTRINSIC:
8396 case FFEINFO_whereCONSTANT:
8397 case FFEINFO_whereCONSTANT_SUBOBJECT:
8398 default:
8399 assert ("BLOCKDATA where unheard of" == NULL);
8400 /* Fall through. */
8401 case FFEINFO_whereANY:
8402 t = error_mark_node;
8403 break;
8404 }
8405 break;
5ff904cd 8406
c7e4ee3a
CB
8407 case FFEINFO_kindCOMMON:
8408 switch (ffeinfo_where (ffesymbol_info (s)))
8409 {
8410 case FFEINFO_whereLOCAL:
8411 assert (!ffecom_transform_only_dummies_);
8412 ffecom_transform_common_ (s);
8413 break;
8414
8415 case FFEINFO_whereNONE:
8416 case FFEINFO_whereCOMMON:
8417 case FFEINFO_whereDUMMY:
8418 case FFEINFO_whereGLOBAL:
8419 case FFEINFO_whereRESULT:
8420 case FFEINFO_whereFLEETING:
8421 case FFEINFO_whereFLEETING_CADDR:
8422 case FFEINFO_whereFLEETING_IADDR:
8423 case FFEINFO_whereIMMEDIATE:
8424 case FFEINFO_whereINTRINSIC:
8425 case FFEINFO_whereCONSTANT:
8426 case FFEINFO_whereCONSTANT_SUBOBJECT:
8427 default:
8428 assert ("COMMON where unheard of" == NULL);
8429 /* Fall through. */
8430 case FFEINFO_whereANY:
8431 t = error_mark_node;
8432 break;
8433 }
8434 break;
5ff904cd 8435
c7e4ee3a
CB
8436 case FFEINFO_kindCONSTRUCT:
8437 switch (ffeinfo_where (ffesymbol_info (s)))
8438 {
8439 case FFEINFO_whereLOCAL:
8440 assert (!ffecom_transform_only_dummies_);
8441 break;
5ff904cd 8442
c7e4ee3a
CB
8443 case FFEINFO_whereNONE:
8444 case FFEINFO_whereCOMMON:
8445 case FFEINFO_whereDUMMY:
8446 case FFEINFO_whereGLOBAL:
8447 case FFEINFO_whereRESULT:
8448 case FFEINFO_whereFLEETING:
8449 case FFEINFO_whereFLEETING_CADDR:
8450 case FFEINFO_whereFLEETING_IADDR:
8451 case FFEINFO_whereIMMEDIATE:
8452 case FFEINFO_whereINTRINSIC:
8453 case FFEINFO_whereCONSTANT:
8454 case FFEINFO_whereCONSTANT_SUBOBJECT:
8455 default:
8456 assert ("CONSTRUCT where unheard of" == NULL);
8457 /* Fall through. */
8458 case FFEINFO_whereANY:
8459 t = error_mark_node;
8460 break;
8461 }
8462 break;
5ff904cd 8463
c7e4ee3a
CB
8464 case FFEINFO_kindNAMELIST:
8465 switch (ffeinfo_where (ffesymbol_info (s)))
8466 {
8467 case FFEINFO_whereLOCAL:
8468 assert (!ffecom_transform_only_dummies_);
8469 t = ffecom_transform_namelist_ (s);
8470 break;
5ff904cd 8471
c7e4ee3a
CB
8472 case FFEINFO_whereNONE:
8473 case FFEINFO_whereCOMMON:
8474 case FFEINFO_whereDUMMY:
8475 case FFEINFO_whereGLOBAL:
8476 case FFEINFO_whereRESULT:
8477 case FFEINFO_whereFLEETING:
8478 case FFEINFO_whereFLEETING_CADDR:
8479 case FFEINFO_whereFLEETING_IADDR:
8480 case FFEINFO_whereIMMEDIATE:
8481 case FFEINFO_whereINTRINSIC:
8482 case FFEINFO_whereCONSTANT:
8483 case FFEINFO_whereCONSTANT_SUBOBJECT:
8484 default:
8485 assert ("NAMELIST where unheard of" == NULL);
8486 /* Fall through. */
8487 case FFEINFO_whereANY:
8488 t = error_mark_node;
8489 break;
8490 }
8491 break;
5ff904cd 8492
c7e4ee3a
CB
8493 default:
8494 assert ("kind unheard of" == NULL);
8495 /* Fall through. */
8496 case FFEINFO_kindANY:
8497 t = error_mark_node;
8498 break;
8499 }
5ff904cd 8500
c7e4ee3a
CB
8501 ffesymbol_hook (s).decl_tree = t;
8502 ffesymbol_hook (s).length_tree = tlen;
8503 ffesymbol_hook (s).addr = addr;
5ff904cd 8504
c7e4ee3a
CB
8505 lineno = old_lineno;
8506 input_filename = old_input_filename;
5ff904cd 8507
c7e4ee3a
CB
8508 return s;
8509}
5ff904cd 8510
5ff904cd 8511#endif
c7e4ee3a 8512/* Transform into ASSIGNable symbol.
5ff904cd 8513
c7e4ee3a
CB
8514 Symbol has already been transformed, but for whatever reason, the
8515 resulting decl_tree has been deemed not usable for an ASSIGN target.
8516 (E.g. it isn't wide enough to hold a pointer.) So, here we invent
8517 another local symbol of type void * and stuff that in the assign_tree
8518 argument. The F77/F90 standards allow this implementation. */
5ff904cd 8519
c7e4ee3a
CB
8520#if FFECOM_targetCURRENT == FFECOM_targetGCC
8521static ffesymbol
8522ffecom_sym_transform_assign_ (ffesymbol s)
8523{
8524 tree t; /* Transformed thingy. */
c7e4ee3a 8525 int old_lineno = lineno;
3b304f5b 8526 const char *old_input_filename = input_filename;
5ff904cd 8527
c7e4ee3a
CB
8528 if (ffesymbol_sfdummyparent (s) == NULL)
8529 {
8530 input_filename = ffesymbol_where_filename (s);
8531 lineno = ffesymbol_where_filelinenum (s);
8532 }
8533 else
8534 {
8535 ffesymbol sf = ffesymbol_sfdummyparent (s);
5ff904cd 8536
c7e4ee3a
CB
8537 input_filename = ffesymbol_where_filename (sf);
8538 lineno = ffesymbol_where_filelinenum (sf);
8539 }
5ff904cd 8540
c7e4ee3a 8541 assert (!ffecom_transform_only_dummies_);
5ff904cd 8542
c7e4ee3a
CB
8543 t = build_decl (VAR_DECL,
8544 ffecom_get_invented_identifier ("__g77_ASSIGN_%s",
14657de8 8545 ffesymbol_text (s)),
c7e4ee3a 8546 TREE_TYPE (null_pointer_node));
5ff904cd 8547
c7e4ee3a
CB
8548 switch (ffesymbol_where (s))
8549 {
8550 case FFEINFO_whereLOCAL:
8551 /* Unlike for regular vars, SAVE status is easy to determine for
8552 ASSIGNed vars, since there's no initialization, there's no
8553 effective storage association (so "SAVE J" does not apply to
8554 K even given "EQUIVALENCE (J,K)"), there's no size issue
8555 to worry about, etc. */
8556 if ((ffesymbol_is_save (s) || ffe_is_saveall ())
8557 && (ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
8558 && (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA))
8559 TREE_STATIC (t) = 1; /* SAVEd in proc, make static. */
8560 else
8561 TREE_STATIC (t) = 0; /* No need to make static. */
8562 break;
5ff904cd 8563
c7e4ee3a
CB
8564 case FFEINFO_whereCOMMON:
8565 TREE_STATIC (t) = 1; /* Assume COMMONs always SAVEd. */
8566 break;
5ff904cd 8567
c7e4ee3a
CB
8568 case FFEINFO_whereDUMMY:
8569 /* Note that twinning a DUMMY means the caller won't see
8570 the ASSIGNed value. But both F77 and F90 allow implementations
8571 to do this, i.e. disallow Fortran code that would try and
8572 take advantage of actually putting a label into a variable
8573 via a dummy argument (or any other storage association, for
8574 that matter). */
8575 TREE_STATIC (t) = 0;
8576 break;
5ff904cd 8577
c7e4ee3a
CB
8578 default:
8579 TREE_STATIC (t) = 0;
8580 break;
8581 }
5ff904cd 8582
c7e4ee3a
CB
8583 t = start_decl (t, FALSE);
8584 finish_decl (t, NULL_TREE, FALSE);
5ff904cd 8585
c7e4ee3a 8586 ffesymbol_hook (s).assign_tree = t;
5ff904cd 8587
c7e4ee3a
CB
8588 lineno = old_lineno;
8589 input_filename = old_input_filename;
5ff904cd 8590
c7e4ee3a
CB
8591 return s;
8592}
5ff904cd 8593
c7e4ee3a
CB
8594#endif
8595/* Implement COMMON area in back end.
5ff904cd 8596
c7e4ee3a
CB
8597 Because COMMON-based variables can be referenced in the dimension
8598 expressions of dummy (adjustable) arrays, and because dummies
8599 (in the gcc back end) need to be put in the outer binding level
8600 of a function (which has two binding levels, the outer holding
8601 the dummies and the inner holding the other vars), special care
8602 must be taken to handle COMMON areas.
5ff904cd 8603
c7e4ee3a
CB
8604 The current strategy is basically to always tell the back end about
8605 the COMMON area as a top-level external reference to just a block
8606 of storage of the master type of that area (e.g. integer, real,
8607 character, whatever -- not a structure). As a distinct action,
8608 if initial values are provided, tell the back end about the area
8609 as a top-level non-external (initialized) area and remember not to
8610 allow further initialization or expansion of the area. Meanwhile,
8611 if no initialization happens at all, tell the back end about
8612 the largest size we've seen declared so the space does get reserved.
8613 (This function doesn't handle all that stuff, but it does some
8614 of the important things.)
5ff904cd 8615
c7e4ee3a
CB
8616 Meanwhile, for COMMON variables themselves, just keep creating
8617 references like *((float *) (&common_area + offset)) each time
8618 we reference the variable. In other words, don't make a VAR_DECL
8619 or any kind of component reference (like we used to do before 0.4),
8620 though we might do that as well just for debugging purposes (and
8621 stuff the rtl with the appropriate offset expression). */
5ff904cd 8622
c7e4ee3a
CB
8623#if FFECOM_targetCURRENT == FFECOM_targetGCC
8624static void
8625ffecom_transform_common_ (ffesymbol s)
8626{
8627 ffestorag st = ffesymbol_storage (s);
8628 ffeglobal g = ffesymbol_global (s);
8629 tree cbt;
8630 tree cbtype;
8631 tree init;
8632 tree high;
8633 bool is_init = ffestorag_is_init (st);
5ff904cd 8634
c7e4ee3a 8635 assert (st != NULL);
5ff904cd 8636
c7e4ee3a
CB
8637 if ((g == NULL)
8638 || (ffeglobal_type (g) != FFEGLOBAL_typeCOMMON))
8639 return;
5ff904cd 8640
c7e4ee3a 8641 /* First update the size of the area in global terms. */
5ff904cd 8642
c7e4ee3a 8643 ffeglobal_size_common (s, ffestorag_size (st));
5ff904cd 8644
c7e4ee3a
CB
8645 if (!ffeglobal_common_init (g))
8646 is_init = FALSE; /* No explicit init, don't let erroneous joins init. */
5ff904cd 8647
c7e4ee3a 8648 cbt = ffeglobal_hook (g);
5ff904cd 8649
c7e4ee3a
CB
8650 /* If we already have declared this common block for a previous program
8651 unit, and either we already initialized it or we don't have new
8652 initialization for it, just return what we have without changing it. */
5ff904cd 8653
c7e4ee3a
CB
8654 if ((cbt != NULL_TREE)
8655 && (!is_init
8656 || !DECL_EXTERNAL (cbt)))
b7a80862
AV
8657 {
8658 if (st->hook == NULL) ffestorag_set_hook (st, cbt);
8659 return;
8660 }
5ff904cd 8661
c7e4ee3a 8662 /* Process inits. */
5ff904cd 8663
c7e4ee3a
CB
8664 if (is_init)
8665 {
8666 if (ffestorag_init (st) != NULL)
5ff904cd 8667 {
c7e4ee3a 8668 ffebld sexp;
5ff904cd 8669
c7e4ee3a
CB
8670 /* Set the padding for the expression, so ffecom_expr
8671 knows to insert that many zeros. */
8672 switch (ffebld_op (sexp = ffestorag_init (st)))
5ff904cd 8673 {
c7e4ee3a
CB
8674 case FFEBLD_opCONTER:
8675 ffebld_conter_set_pad (sexp, ffestorag_modulo (st));
5ff904cd 8676 break;
5ff904cd 8677
c7e4ee3a
CB
8678 case FFEBLD_opARRTER:
8679 ffebld_arrter_set_pad (sexp, ffestorag_modulo (st));
8680 break;
5ff904cd 8681
c7e4ee3a
CB
8682 case FFEBLD_opACCTER:
8683 ffebld_accter_set_pad (sexp, ffestorag_modulo (st));
8684 break;
5ff904cd 8685
c7e4ee3a
CB
8686 default:
8687 assert ("bad op for cmn init (pad)" == NULL);
8688 break;
8689 }
5ff904cd 8690
c7e4ee3a
CB
8691 init = ffecom_expr (sexp);
8692 if (init == error_mark_node)
8693 { /* Hopefully the back end complained! */
8694 init = NULL_TREE;
8695 if (cbt != NULL_TREE)
8696 return;
8697 }
8698 }
8699 else
8700 init = error_mark_node;
8701 }
8702 else
8703 init = NULL_TREE;
5ff904cd 8704
c7e4ee3a 8705 /* cbtype must be permanently allocated! */
5ff904cd 8706
c7e4ee3a
CB
8707 /* Allocate the MAX of the areas so far, seen filewide. */
8708 high = build_int_2 ((ffeglobal_common_size (g)
8709 + ffeglobal_common_pad (g)) - 1, 0);
8710 TREE_TYPE (high) = ffecom_integer_type_node;
5ff904cd 8711
c7e4ee3a
CB
8712 if (init)
8713 cbtype = build_array_type (char_type_node,
8714 build_range_type (integer_type_node,
8715 integer_zero_node,
8716 high));
8717 else
8718 cbtype = build_array_type (char_type_node, NULL_TREE);
5ff904cd 8719
c7e4ee3a
CB
8720 if (cbt == NULL_TREE)
8721 {
8722 cbt
8723 = build_decl (VAR_DECL,
8724 ffecom_get_external_identifier_ (s),
8725 cbtype);
8726 TREE_STATIC (cbt) = 1;
8727 TREE_PUBLIC (cbt) = 1;
8728 }
8729 else
8730 {
8731 assert (is_init);
8732 TREE_TYPE (cbt) = cbtype;
8733 }
8734 DECL_EXTERNAL (cbt) = init ? 0 : 1;
8735 DECL_INITIAL (cbt) = init ? error_mark_node : NULL_TREE;
5ff904cd 8736
c7e4ee3a
CB
8737 cbt = start_decl (cbt, TRUE);
8738 if (ffeglobal_hook (g) != NULL)
8739 assert (cbt == ffeglobal_hook (g));
5ff904cd 8740
c7e4ee3a 8741 assert (!init || !DECL_EXTERNAL (cbt));
5ff904cd 8742
c7e4ee3a
CB
8743 /* Make sure that any type can live in COMMON and be referenced
8744 without getting a bus error. We could pick the most restrictive
8745 alignment of all entities actually placed in the COMMON, but
8746 this seems easy enough. */
5ff904cd 8747
c7e4ee3a 8748 DECL_ALIGN (cbt) = BIGGEST_ALIGNMENT;
11cf4d18 8749 DECL_USER_ALIGN (cbt) = 0;
5ff904cd 8750
c7e4ee3a
CB
8751 if (is_init && (ffestorag_init (st) == NULL))
8752 init = ffecom_init_zero_ (cbt);
5ff904cd 8753
c7e4ee3a 8754 finish_decl (cbt, init, TRUE);
5ff904cd 8755
c7e4ee3a
CB
8756 if (is_init)
8757 ffestorag_set_init (st, ffebld_new_any ());
5ff904cd 8758
c7e4ee3a
CB
8759 if (init)
8760 {
06ceef4e
RK
8761 assert (DECL_SIZE_UNIT (cbt) != NULL_TREE);
8762 assert (TREE_CODE (DECL_SIZE_UNIT (cbt)) == INTEGER_CST);
05bccae2
RK
8763 assert (0 == compare_tree_int (DECL_SIZE_UNIT (cbt),
8764 (ffeglobal_common_size (g)
8765 + ffeglobal_common_pad (g))));
c7e4ee3a 8766 }
5ff904cd 8767
c7e4ee3a 8768 ffeglobal_set_hook (g, cbt);
5ff904cd 8769
c7e4ee3a 8770 ffestorag_set_hook (st, cbt);
5ff904cd 8771
7189a4b0 8772 ffecom_save_tree_forever (cbt);
c7e4ee3a 8773}
5ff904cd 8774
c7e4ee3a
CB
8775#endif
8776/* Make master area for local EQUIVALENCE. */
5ff904cd 8777
c7e4ee3a
CB
8778#if FFECOM_targetCURRENT == FFECOM_targetGCC
8779static void
8780ffecom_transform_equiv_ (ffestorag eqst)
8781{
8782 tree eqt;
8783 tree eqtype;
8784 tree init;
8785 tree high;
8786 bool is_init = ffestorag_is_init (eqst);
5ff904cd 8787
c7e4ee3a 8788 assert (eqst != NULL);
5ff904cd 8789
c7e4ee3a 8790 eqt = ffestorag_hook (eqst);
5ff904cd 8791
c7e4ee3a
CB
8792 if (eqt != NULL_TREE)
8793 return;
5ff904cd 8794
c7e4ee3a
CB
8795 /* Process inits. */
8796
8797 if (is_init)
8798 {
8799 if (ffestorag_init (eqst) != NULL)
5ff904cd 8800 {
c7e4ee3a 8801 ffebld sexp;
5ff904cd 8802
c7e4ee3a
CB
8803 /* Set the padding for the expression, so ffecom_expr
8804 knows to insert that many zeros. */
8805 switch (ffebld_op (sexp = ffestorag_init (eqst)))
8806 {
8807 case FFEBLD_opCONTER:
8808 ffebld_conter_set_pad (sexp, ffestorag_modulo (eqst));
8809 break;
5ff904cd 8810
c7e4ee3a
CB
8811 case FFEBLD_opARRTER:
8812 ffebld_arrter_set_pad (sexp, ffestorag_modulo (eqst));
8813 break;
5ff904cd 8814
c7e4ee3a
CB
8815 case FFEBLD_opACCTER:
8816 ffebld_accter_set_pad (sexp, ffestorag_modulo (eqst));
8817 break;
5ff904cd 8818
c7e4ee3a
CB
8819 default:
8820 assert ("bad op for eqv init (pad)" == NULL);
8821 break;
8822 }
5ff904cd 8823
c7e4ee3a
CB
8824 init = ffecom_expr (sexp);
8825 if (init == error_mark_node)
8826 init = NULL_TREE; /* Hopefully the back end complained! */
8827 }
8828 else
8829 init = error_mark_node;
8830 }
8831 else if (ffe_is_init_local_zero ())
8832 init = error_mark_node;
8833 else
8834 init = NULL_TREE;
5ff904cd 8835
c7e4ee3a
CB
8836 ffecom_member_namelisted_ = FALSE;
8837 ffestorag_drive (ffestorag_list_equivs (eqst),
8838 &ffecom_member_phase1_,
8839 eqst);
5ff904cd 8840
c7e4ee3a
CB
8841 high = build_int_2 ((ffestorag_size (eqst)
8842 + ffestorag_modulo (eqst)) - 1, 0);
8843 TREE_TYPE (high) = ffecom_integer_type_node;
5ff904cd 8844
c7e4ee3a
CB
8845 eqtype = build_array_type (char_type_node,
8846 build_range_type (ffecom_integer_type_node,
8847 ffecom_integer_zero_node,
8848 high));
8849
8850 eqt = build_decl (VAR_DECL,
8851 ffecom_get_invented_identifier ("__g77_equiv_%s",
8852 ffesymbol_text
14657de8 8853 (ffestorag_symbol (eqst))),
c7e4ee3a
CB
8854 eqtype);
8855 DECL_EXTERNAL (eqt) = 0;
8856 if (is_init
8857 || ffecom_member_namelisted_
8858#ifdef FFECOM_sizeMAXSTACKITEM
8859 || (ffestorag_size (eqst) > FFECOM_sizeMAXSTACKITEM)
8860#endif
8861 || ((ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
8862 && (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA)
8863 && (ffestorag_is_save (eqst) || ffe_is_saveall ())))
8864 TREE_STATIC (eqt) = 1;
8865 else
8866 TREE_STATIC (eqt) = 0;
8867 TREE_PUBLIC (eqt) = 0;
a8e2bb76 8868 TREE_ADDRESSABLE (eqt) = 1; /* Ensure non-register allocation */
c7e4ee3a
CB
8869 DECL_CONTEXT (eqt) = current_function_decl;
8870 if (init)
8871 DECL_INITIAL (eqt) = error_mark_node;
8872 else
8873 DECL_INITIAL (eqt) = NULL_TREE;
5ff904cd 8874
c7e4ee3a 8875 eqt = start_decl (eqt, FALSE);
5ff904cd 8876
c7e4ee3a
CB
8877 /* Make sure that any type can live in EQUIVALENCE and be referenced
8878 without getting a bus error. We could pick the most restrictive
8879 alignment of all entities actually placed in the EQUIVALENCE, but
8880 this seems easy enough. */
5ff904cd 8881
c7e4ee3a 8882 DECL_ALIGN (eqt) = BIGGEST_ALIGNMENT;
11cf4d18 8883 DECL_USER_ALIGN (eqt) = 0;
5ff904cd 8884
c7e4ee3a
CB
8885 if ((!is_init && ffe_is_init_local_zero ())
8886 || (is_init && (ffestorag_init (eqst) == NULL)))
8887 init = ffecom_init_zero_ (eqt);
5ff904cd 8888
c7e4ee3a 8889 finish_decl (eqt, init, FALSE);
5ff904cd 8890
c7e4ee3a
CB
8891 if (is_init)
8892 ffestorag_set_init (eqst, ffebld_new_any ());
5ff904cd 8893
c7e4ee3a 8894 {
06ceef4e 8895 assert (TREE_CODE (DECL_SIZE_UNIT (eqt)) == INTEGER_CST);
05bccae2
RK
8896 assert (0 == compare_tree_int (DECL_SIZE_UNIT (eqt),
8897 (ffestorag_size (eqst)
8898 + ffestorag_modulo (eqst))));
c7e4ee3a 8899 }
5ff904cd 8900
c7e4ee3a 8901 ffestorag_set_hook (eqst, eqt);
5ff904cd 8902
c7e4ee3a
CB
8903 ffestorag_drive (ffestorag_list_equivs (eqst),
8904 &ffecom_member_phase2_,
8905 eqst);
5ff904cd
JL
8906}
8907
8908#endif
c7e4ee3a 8909/* Implement NAMELIST in back end. See f2c/format.c for more info. */
5ff904cd
JL
8910
8911#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
8912static tree
8913ffecom_transform_namelist_ (ffesymbol s)
5ff904cd 8914{
c7e4ee3a
CB
8915 tree nmlt;
8916 tree nmltype = ffecom_type_namelist_ ();
8917 tree nmlinits;
8918 tree nameinit;
8919 tree varsinit;
8920 tree nvarsinit;
8921 tree field;
8922 tree high;
c7e4ee3a
CB
8923 int i;
8924 static int mynumber = 0;
5ff904cd 8925
c7e4ee3a
CB
8926 nmlt = build_decl (VAR_DECL,
8927 ffecom_get_invented_identifier ("__g77_namelist_%d",
14657de8 8928 mynumber++),
c7e4ee3a
CB
8929 nmltype);
8930 TREE_STATIC (nmlt) = 1;
8931 DECL_INITIAL (nmlt) = error_mark_node;
5ff904cd 8932
c7e4ee3a 8933 nmlt = start_decl (nmlt, FALSE);
5ff904cd 8934
c7e4ee3a 8935 /* Process inits. */
5ff904cd 8936
c7e4ee3a 8937 i = strlen (ffesymbol_text (s));
5ff904cd 8938
c7e4ee3a
CB
8939 high = build_int_2 (i, 0);
8940 TREE_TYPE (high) = ffecom_f2c_ftnlen_type_node;
8941
8942 nameinit = ffecom_build_f2c_string_ (i + 1,
8943 ffesymbol_text (s));
8944 TREE_TYPE (nameinit)
8945 = build_type_variant
8946 (build_array_type
8947 (char_type_node,
8948 build_range_type (ffecom_f2c_ftnlen_type_node,
8949 ffecom_f2c_ftnlen_one_node,
8950 high)),
8951 1, 0);
8952 TREE_CONSTANT (nameinit) = 1;
8953 TREE_STATIC (nameinit) = 1;
8954 nameinit = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (nameinit)),
8955 nameinit);
8956
8957 varsinit = ffecom_vardesc_array_ (s);
8958 varsinit = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (varsinit)),
8959 varsinit);
8960 TREE_CONSTANT (varsinit) = 1;
8961 TREE_STATIC (varsinit) = 1;
8962
8963 {
8964 ffebld b;
8965
8966 for (i = 0, b = ffesymbol_namelist (s); b != NULL; b = ffebld_trail (b))
8967 ++i;
8968 }
8969 nvarsinit = build_int_2 (i, 0);
8970 TREE_TYPE (nvarsinit) = integer_type_node;
8971 TREE_CONSTANT (nvarsinit) = 1;
8972 TREE_STATIC (nvarsinit) = 1;
8973
8974 nmlinits = build_tree_list ((field = TYPE_FIELDS (nmltype)), nameinit);
8975 TREE_CHAIN (nmlinits) = build_tree_list ((field = TREE_CHAIN (field)),
8976 varsinit);
8977 TREE_CHAIN (TREE_CHAIN (nmlinits))
8978 = build_tree_list ((field = TREE_CHAIN (field)), nvarsinit);
8979
8980 nmlinits = build (CONSTRUCTOR, nmltype, NULL_TREE, nmlinits);
8981 TREE_CONSTANT (nmlinits) = 1;
8982 TREE_STATIC (nmlinits) = 1;
8983
8984 finish_decl (nmlt, nmlinits, FALSE);
8985
8986 nmlt = ffecom_1 (ADDR_EXPR, build_pointer_type (nmltype), nmlt);
8987
c7e4ee3a
CB
8988 return nmlt;
8989}
8990
8991#endif
8992
8993/* A subroutine of ffecom_tree_canonize_ref_. The incoming tree is
8994 analyzed on the assumption it is calculating a pointer to be
8995 indirected through. It must return the proper decl and offset,
8996 taking into account different units of measurements for offsets. */
8997
8998#if FFECOM_targetCURRENT == FFECOM_targetGCC
8999static void
9000ffecom_tree_canonize_ptr_ (tree *decl, tree *offset,
9001 tree t)
9002{
9003 switch (TREE_CODE (t))
9004 {
9005 case NOP_EXPR:
9006 case CONVERT_EXPR:
9007 case NON_LVALUE_EXPR:
9008 ffecom_tree_canonize_ptr_ (decl, offset, TREE_OPERAND (t, 0));
5ff904cd
JL
9009 break;
9010
c7e4ee3a
CB
9011 case PLUS_EXPR:
9012 ffecom_tree_canonize_ptr_ (decl, offset, TREE_OPERAND (t, 0));
9013 if ((*decl == NULL_TREE)
9014 || (*decl == error_mark_node))
9015 break;
9016
9017 if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST)
9018 {
9019 /* An offset into COMMON. */
fed3cef0
RK
9020 *offset = fold (build (PLUS_EXPR, TREE_TYPE (*offset),
9021 *offset, TREE_OPERAND (t, 1)));
c7e4ee3a
CB
9022 /* Convert offset (presumably in bytes) into canonical units
9023 (presumably bits). */
76fa6b3b
ZW
9024 *offset = size_binop (MULT_EXPR,
9025 convert (bitsizetype, *offset),
9026 TYPE_SIZE (TREE_TYPE (TREE_TYPE (t))));
c7e4ee3a
CB
9027 break;
9028 }
9029 /* Not a COMMON reference, so an unrecognized pattern. */
9030 *decl = error_mark_node;
5ff904cd
JL
9031 break;
9032
c7e4ee3a
CB
9033 case PARM_DECL:
9034 *decl = t;
770ae6cc 9035 *offset = bitsize_zero_node;
5ff904cd
JL
9036 break;
9037
c7e4ee3a
CB
9038 case ADDR_EXPR:
9039 if (TREE_CODE (TREE_OPERAND (t, 0)) == VAR_DECL)
9040 {
9041 /* A reference to COMMON. */
9042 *decl = TREE_OPERAND (t, 0);
770ae6cc 9043 *offset = bitsize_zero_node;
c7e4ee3a
CB
9044 break;
9045 }
9046 /* Fall through. */
5ff904cd 9047 default:
c7e4ee3a
CB
9048 /* Not a COMMON reference, so an unrecognized pattern. */
9049 *decl = error_mark_node;
5ff904cd
JL
9050 break;
9051 }
c7e4ee3a
CB
9052}
9053#endif
5ff904cd 9054
c7e4ee3a
CB
9055/* Given a tree that is possibly intended for use as an lvalue, return
9056 information representing a canonical view of that tree as a decl, an
9057 offset into that decl, and a size for the lvalue.
5ff904cd 9058
c7e4ee3a
CB
9059 If there's no applicable decl, NULL_TREE is returned for the decl,
9060 and the other fields are left undefined.
5ff904cd 9061
c7e4ee3a
CB
9062 If the tree doesn't fit the recognizable forms, an ERROR_MARK node
9063 is returned for the decl, and the other fields are left undefined.
5ff904cd 9064
c7e4ee3a
CB
9065 Otherwise, the decl returned currently is either a VAR_DECL or a
9066 PARM_DECL.
5ff904cd 9067
c7e4ee3a
CB
9068 The offset returned is always valid, but of course not necessarily
9069 a constant, and not necessarily converted into the appropriate
9070 type, leaving that up to the caller (so as to avoid that overhead
9071 if the decls being looked at are different anyway).
5ff904cd 9072
c7e4ee3a
CB
9073 If the size cannot be determined (e.g. an adjustable array),
9074 an ERROR_MARK node is returned for the size. Otherwise, the
9075 size returned is valid, not necessarily a constant, and not
9076 necessarily converted into the appropriate type as with the
9077 offset.
5ff904cd 9078
c7e4ee3a
CB
9079 Note that the offset and size expressions are expressed in the
9080 base storage units (usually bits) rather than in the units of
9081 the type of the decl, because two decls with different types
9082 might overlap but with apparently non-overlapping array offsets,
9083 whereas converting the array offsets to consistant offsets will
9084 reveal the overlap. */
5ff904cd
JL
9085
9086#if FFECOM_targetCURRENT == FFECOM_targetGCC
9087static void
c7e4ee3a
CB
9088ffecom_tree_canonize_ref_ (tree *decl, tree *offset,
9089 tree *size, tree t)
5ff904cd 9090{
c7e4ee3a
CB
9091 /* The default path is to report a nonexistant decl. */
9092 *decl = NULL_TREE;
5ff904cd 9093
c7e4ee3a 9094 if (t == NULL_TREE)
5ff904cd
JL
9095 return;
9096
c7e4ee3a
CB
9097 switch (TREE_CODE (t))
9098 {
9099 case ERROR_MARK:
9100 case IDENTIFIER_NODE:
9101 case INTEGER_CST:
9102 case REAL_CST:
9103 case COMPLEX_CST:
9104 case STRING_CST:
9105 case CONST_DECL:
9106 case PLUS_EXPR:
9107 case MINUS_EXPR:
9108 case MULT_EXPR:
9109 case TRUNC_DIV_EXPR:
9110 case CEIL_DIV_EXPR:
9111 case FLOOR_DIV_EXPR:
9112 case ROUND_DIV_EXPR:
9113 case TRUNC_MOD_EXPR:
9114 case CEIL_MOD_EXPR:
9115 case FLOOR_MOD_EXPR:
9116 case ROUND_MOD_EXPR:
9117 case RDIV_EXPR:
9118 case EXACT_DIV_EXPR:
9119 case FIX_TRUNC_EXPR:
9120 case FIX_CEIL_EXPR:
9121 case FIX_FLOOR_EXPR:
9122 case FIX_ROUND_EXPR:
9123 case FLOAT_EXPR:
9124 case EXPON_EXPR:
9125 case NEGATE_EXPR:
9126 case MIN_EXPR:
9127 case MAX_EXPR:
9128 case ABS_EXPR:
9129 case FFS_EXPR:
9130 case LSHIFT_EXPR:
9131 case RSHIFT_EXPR:
9132 case LROTATE_EXPR:
9133 case RROTATE_EXPR:
9134 case BIT_IOR_EXPR:
9135 case BIT_XOR_EXPR:
9136 case BIT_AND_EXPR:
9137 case BIT_ANDTC_EXPR:
9138 case BIT_NOT_EXPR:
9139 case TRUTH_ANDIF_EXPR:
9140 case TRUTH_ORIF_EXPR:
9141 case TRUTH_AND_EXPR:
9142 case TRUTH_OR_EXPR:
9143 case TRUTH_XOR_EXPR:
9144 case TRUTH_NOT_EXPR:
9145 case LT_EXPR:
9146 case LE_EXPR:
9147 case GT_EXPR:
9148 case GE_EXPR:
9149 case EQ_EXPR:
9150 case NE_EXPR:
9151 case COMPLEX_EXPR:
9152 case CONJ_EXPR:
9153 case REALPART_EXPR:
9154 case IMAGPART_EXPR:
9155 case LABEL_EXPR:
9156 case COMPONENT_REF:
9157 case COMPOUND_EXPR:
9158 case ADDR_EXPR:
9159 return;
5ff904cd 9160
c7e4ee3a
CB
9161 case VAR_DECL:
9162 case PARM_DECL:
9163 *decl = t;
770ae6cc 9164 *offset = bitsize_zero_node;
c7e4ee3a
CB
9165 *size = TYPE_SIZE (TREE_TYPE (t));
9166 return;
5ff904cd 9167
c7e4ee3a
CB
9168 case ARRAY_REF:
9169 {
9170 tree array = TREE_OPERAND (t, 0);
9171 tree element = TREE_OPERAND (t, 1);
9172 tree init_offset;
9173
9174 if ((array == NULL_TREE)
9175 || (element == NULL_TREE))
9176 {
9177 *decl = error_mark_node;
9178 return;
9179 }
9180
9181 ffecom_tree_canonize_ref_ (decl, &init_offset, size,
9182 array);
9183 if ((*decl == NULL_TREE)
9184 || (*decl == error_mark_node))
9185 return;
9186
76fa6b3b
ZW
9187 /* Calculate ((element - base) * NBBY) + init_offset. */
9188 *offset = fold (build (MINUS_EXPR, TREE_TYPE (element),
9189 element,
9190 TYPE_MIN_VALUE (TYPE_DOMAIN
9191 (TREE_TYPE (array)))));
9192
9193 *offset = size_binop (MULT_EXPR,
9194 convert (bitsizetype, *offset),
9195 TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))));
9196
9197 *offset = size_binop (PLUS_EXPR, init_offset, *offset);
c7e4ee3a
CB
9198
9199 *size = TYPE_SIZE (TREE_TYPE (t));
9200 return;
9201 }
9202
9203 case INDIRECT_REF:
9204
9205 /* Most of this code is to handle references to COMMON. And so
9206 far that is useful only for calling library functions, since
9207 external (user) functions might reference common areas. But
9208 even calling an external function, it's worthwhile to decode
9209 COMMON references because if not storing into COMMON, we don't
9210 want COMMON-based arguments to gratuitously force use of a
9211 temporary. */
9212
9213 *size = TYPE_SIZE (TREE_TYPE (t));
5ff904cd 9214
c7e4ee3a
CB
9215 ffecom_tree_canonize_ptr_ (decl, offset,
9216 TREE_OPERAND (t, 0));
5ff904cd 9217
c7e4ee3a 9218 return;
5ff904cd 9219
c7e4ee3a
CB
9220 case CONVERT_EXPR:
9221 case NOP_EXPR:
9222 case MODIFY_EXPR:
9223 case NON_LVALUE_EXPR:
9224 case RESULT_DECL:
9225 case FIELD_DECL:
9226 case COND_EXPR: /* More cases than we can handle. */
9227 case SAVE_EXPR:
9228 case REFERENCE_EXPR:
9229 case PREDECREMENT_EXPR:
9230 case PREINCREMENT_EXPR:
9231 case POSTDECREMENT_EXPR:
9232 case POSTINCREMENT_EXPR:
9233 case CALL_EXPR:
9234 default:
9235 *decl = error_mark_node;
9236 return;
9237 }
9238}
9239#endif
5ff904cd 9240
c7e4ee3a 9241/* Do divide operation appropriate to type of operands. */
5ff904cd 9242
c7e4ee3a
CB
9243#if FFECOM_targetCURRENT == FFECOM_targetGCC
9244static tree
9245ffecom_tree_divide_ (tree tree_type, tree left, tree right,
9246 tree dest_tree, ffebld dest, bool *dest_used,
9247 tree hook)
9248{
9249 if ((left == error_mark_node)
9250 || (right == error_mark_node))
9251 return error_mark_node;
a6fa6420 9252
c7e4ee3a
CB
9253 switch (TREE_CODE (tree_type))
9254 {
9255 case INTEGER_TYPE:
9256 return ffecom_2 (TRUNC_DIV_EXPR, tree_type,
9257 left,
9258 right);
a6fa6420 9259
c7e4ee3a 9260 case COMPLEX_TYPE:
c64f913e
CB
9261 if (! optimize_size)
9262 return ffecom_2 (RDIV_EXPR, tree_type,
9263 left,
9264 right);
c7e4ee3a
CB
9265 {
9266 ffecomGfrt ix;
a6fa6420 9267
c7e4ee3a
CB
9268 if (TREE_TYPE (tree_type)
9269 == ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1])
9270 ix = FFECOM_gfrtDIV_CC; /* Overlapping result okay. */
9271 else
9272 ix = FFECOM_gfrtDIV_ZZ; /* Overlapping result okay. */
a6fa6420 9273
c7e4ee3a
CB
9274 left = ffecom_1 (ADDR_EXPR,
9275 build_pointer_type (TREE_TYPE (left)),
9276 left);
9277 left = build_tree_list (NULL_TREE, left);
9278 right = ffecom_1 (ADDR_EXPR,
9279 build_pointer_type (TREE_TYPE (right)),
9280 right);
9281 right = build_tree_list (NULL_TREE, right);
9282 TREE_CHAIN (left) = right;
a6fa6420 9283
c7e4ee3a
CB
9284 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
9285 ffecom_gfrt_kindtype (ix),
9286 ffe_is_f2c_library (),
9287 tree_type,
9288 left,
9289 dest_tree, dest, dest_used,
9290 NULL_TREE, TRUE, hook);
9291 }
9292 break;
5ff904cd 9293
c7e4ee3a
CB
9294 case RECORD_TYPE:
9295 {
9296 ffecomGfrt ix;
5ff904cd 9297
c7e4ee3a
CB
9298 if (TREE_TYPE (TYPE_FIELDS (tree_type))
9299 == ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1])
9300 ix = FFECOM_gfrtDIV_CC; /* Overlapping result okay. */
9301 else
9302 ix = FFECOM_gfrtDIV_ZZ; /* Overlapping result okay. */
5ff904cd 9303
c7e4ee3a
CB
9304 left = ffecom_1 (ADDR_EXPR,
9305 build_pointer_type (TREE_TYPE (left)),
9306 left);
9307 left = build_tree_list (NULL_TREE, left);
9308 right = ffecom_1 (ADDR_EXPR,
9309 build_pointer_type (TREE_TYPE (right)),
9310 right);
9311 right = build_tree_list (NULL_TREE, right);
9312 TREE_CHAIN (left) = right;
a6fa6420 9313
c7e4ee3a
CB
9314 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
9315 ffecom_gfrt_kindtype (ix),
9316 ffe_is_f2c_library (),
9317 tree_type,
9318 left,
9319 dest_tree, dest, dest_used,
9320 NULL_TREE, TRUE, hook);
9321 }
9322 break;
5ff904cd 9323
c7e4ee3a
CB
9324 default:
9325 return ffecom_2 (RDIV_EXPR, tree_type,
9326 left,
9327 right);
5ff904cd 9328 }
c7e4ee3a 9329}
5ff904cd 9330
c7e4ee3a
CB
9331#endif
9332/* Build type info for non-dummy variable. */
5ff904cd 9333
c7e4ee3a
CB
9334#if FFECOM_targetCURRENT == FFECOM_targetGCC
9335static tree
9336ffecom_type_localvar_ (ffesymbol s, ffeinfoBasictype bt,
9337 ffeinfoKindtype kt)
9338{
9339 tree type;
9340 ffebld dl;
9341 ffebld dim;
9342 tree lowt;
9343 tree hight;
5ff904cd 9344
c7e4ee3a
CB
9345 type = ffecom_tree_type[bt][kt];
9346 if (bt == FFEINFO_basictypeCHARACTER)
9347 {
9348 hight = build_int_2 (ffesymbol_size (s), 0);
9349 TREE_TYPE (hight) = ffecom_f2c_ftnlen_type_node;
5ff904cd 9350
c7e4ee3a
CB
9351 type
9352 = build_array_type
9353 (type,
9354 build_range_type (ffecom_f2c_ftnlen_type_node,
9355 ffecom_f2c_ftnlen_one_node,
9356 hight));
9357 type = ffecom_check_size_overflow_ (s, type, FALSE);
9358 }
5ff904cd 9359
c7e4ee3a
CB
9360 for (dl = ffesymbol_dims (s); dl != NULL; dl = ffebld_trail (dl))
9361 {
9362 if (type == error_mark_node)
9363 break;
5ff904cd 9364
c7e4ee3a
CB
9365 dim = ffebld_head (dl);
9366 assert (ffebld_op (dim) == FFEBLD_opBOUNDS);
5ff904cd 9367
c7e4ee3a
CB
9368 if (ffebld_left (dim) == NULL)
9369 lowt = integer_one_node;
9370 else
9371 lowt = ffecom_expr (ffebld_left (dim));
5ff904cd 9372
c7e4ee3a
CB
9373 if (TREE_CODE (lowt) != INTEGER_CST)
9374 lowt = variable_size (lowt);
5ff904cd 9375
c7e4ee3a
CB
9376 assert (ffebld_right (dim) != NULL);
9377 hight = ffecom_expr (ffebld_right (dim));
5ff904cd 9378
c7e4ee3a
CB
9379 if (TREE_CODE (hight) != INTEGER_CST)
9380 hight = variable_size (hight);
5ff904cd 9381
c7e4ee3a
CB
9382 type = build_array_type (type,
9383 build_range_type (ffecom_integer_type_node,
9384 lowt, hight));
9385 type = ffecom_check_size_overflow_ (s, type, FALSE);
9386 }
5ff904cd 9387
c7e4ee3a 9388 return type;
5ff904cd
JL
9389}
9390
9391#endif
c7e4ee3a 9392/* Build Namelist type. */
5ff904cd 9393
c7e4ee3a
CB
9394#if FFECOM_targetCURRENT == FFECOM_targetGCC
9395static tree
9396ffecom_type_namelist_ ()
9397{
9398 static tree type = NULL_TREE;
5ff904cd 9399
c7e4ee3a
CB
9400 if (type == NULL_TREE)
9401 {
9402 static tree namefield, varsfield, nvarsfield;
9403 tree vardesctype;
5ff904cd 9404
c7e4ee3a 9405 vardesctype = ffecom_type_vardesc_ ();
5ff904cd 9406
c7e4ee3a 9407 type = make_node (RECORD_TYPE);
a6fa6420 9408
c7e4ee3a 9409 vardesctype = build_pointer_type (build_pointer_type (vardesctype));
a6fa6420 9410
c7e4ee3a
CB
9411 namefield = ffecom_decl_field (type, NULL_TREE, "name",
9412 string_type_node);
9413 varsfield = ffecom_decl_field (type, namefield, "vars", vardesctype);
9414 nvarsfield = ffecom_decl_field (type, varsfield, "nvars",
9415 integer_type_node);
a6fa6420 9416
c7e4ee3a
CB
9417 TYPE_FIELDS (type) = namefield;
9418 layout_type (type);
a6fa6420 9419
7189a4b0 9420 ggc_add_tree_root (&type, 1);
5ff904cd 9421 }
5ff904cd 9422
c7e4ee3a
CB
9423 return type;
9424}
5ff904cd 9425
c7e4ee3a 9426#endif
5ff904cd 9427
c7e4ee3a 9428/* Build Vardesc type. */
5ff904cd 9429
c7e4ee3a
CB
9430#if FFECOM_targetCURRENT == FFECOM_targetGCC
9431static tree
9432ffecom_type_vardesc_ ()
9433{
9434 static tree type = NULL_TREE;
9435 static tree namefield, addrfield, dimsfield, typefield;
5ff904cd 9436
c7e4ee3a
CB
9437 if (type == NULL_TREE)
9438 {
c7e4ee3a 9439 type = make_node (RECORD_TYPE);
5ff904cd 9440
c7e4ee3a
CB
9441 namefield = ffecom_decl_field (type, NULL_TREE, "name",
9442 string_type_node);
9443 addrfield = ffecom_decl_field (type, namefield, "addr",
9444 string_type_node);
9445 dimsfield = ffecom_decl_field (type, addrfield, "dims",
9446 ffecom_f2c_ptr_to_ftnlen_type_node);
9447 typefield = ffecom_decl_field (type, dimsfield, "type",
9448 integer_type_node);
5ff904cd 9449
c7e4ee3a
CB
9450 TYPE_FIELDS (type) = namefield;
9451 layout_type (type);
9452
7189a4b0 9453 ggc_add_tree_root (&type, 1);
c7e4ee3a
CB
9454 }
9455
9456 return type;
5ff904cd
JL
9457}
9458
9459#endif
5ff904cd
JL
9460
9461#if FFECOM_targetCURRENT == FFECOM_targetGCC
9462static tree
c7e4ee3a 9463ffecom_vardesc_ (ffebld expr)
5ff904cd 9464{
c7e4ee3a 9465 ffesymbol s;
5ff904cd 9466
c7e4ee3a
CB
9467 assert (ffebld_op (expr) == FFEBLD_opSYMTER);
9468 s = ffebld_symter (expr);
5ff904cd 9469
c7e4ee3a
CB
9470 if (ffesymbol_hook (s).vardesc_tree == NULL_TREE)
9471 {
9472 int i;
9473 tree vardesctype = ffecom_type_vardesc_ ();
9474 tree var;
9475 tree nameinit;
9476 tree dimsinit;
9477 tree addrinit;
9478 tree typeinit;
9479 tree field;
9480 tree varinits;
c7e4ee3a 9481 static int mynumber = 0;
5ff904cd 9482
c7e4ee3a
CB
9483 var = build_decl (VAR_DECL,
9484 ffecom_get_invented_identifier ("__g77_vardesc_%d",
14657de8 9485 mynumber++),
c7e4ee3a
CB
9486 vardesctype);
9487 TREE_STATIC (var) = 1;
9488 DECL_INITIAL (var) = error_mark_node;
5ff904cd 9489
c7e4ee3a 9490 var = start_decl (var, FALSE);
5ff904cd 9491
c7e4ee3a 9492 /* Process inits. */
5ff904cd 9493
c7e4ee3a
CB
9494 nameinit = ffecom_build_f2c_string_ ((i = strlen (ffesymbol_text (s)))
9495 + 1,
9496 ffesymbol_text (s));
9497 TREE_TYPE (nameinit)
9498 = build_type_variant
9499 (build_array_type
9500 (char_type_node,
9501 build_range_type (integer_type_node,
9502 integer_one_node,
9503 build_int_2 (i, 0))),
9504 1, 0);
9505 TREE_CONSTANT (nameinit) = 1;
9506 TREE_STATIC (nameinit) = 1;
9507 nameinit = ffecom_1 (ADDR_EXPR,
9508 build_pointer_type (TREE_TYPE (nameinit)),
9509 nameinit);
5ff904cd 9510
c7e4ee3a 9511 addrinit = ffecom_arg_ptr_to_expr (expr, &typeinit);
5ff904cd 9512
c7e4ee3a 9513 dimsinit = ffecom_vardesc_dims_ (s);
5ff904cd 9514
c7e4ee3a
CB
9515 if (typeinit == NULL_TREE)
9516 {
9517 ffeinfoBasictype bt = ffesymbol_basictype (s);
9518 ffeinfoKindtype kt = ffesymbol_kindtype (s);
9519 int tc = ffecom_f2c_typecode (bt, kt);
5ff904cd 9520
c7e4ee3a
CB
9521 assert (tc != -1);
9522 typeinit = build_int_2 (tc, (tc < 0) ? -1 : 0);
9523 }
9524 else
9525 typeinit = ffecom_1 (NEGATE_EXPR, TREE_TYPE (typeinit), typeinit);
5ff904cd 9526
c7e4ee3a
CB
9527 varinits = build_tree_list ((field = TYPE_FIELDS (vardesctype)),
9528 nameinit);
9529 TREE_CHAIN (varinits) = build_tree_list ((field = TREE_CHAIN (field)),
9530 addrinit);
9531 TREE_CHAIN (TREE_CHAIN (varinits))
9532 = build_tree_list ((field = TREE_CHAIN (field)), dimsinit);
9533 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (varinits)))
9534 = build_tree_list ((field = TREE_CHAIN (field)), typeinit);
5ff904cd 9535
c7e4ee3a
CB
9536 varinits = build (CONSTRUCTOR, vardesctype, NULL_TREE, varinits);
9537 TREE_CONSTANT (varinits) = 1;
9538 TREE_STATIC (varinits) = 1;
5ff904cd 9539
c7e4ee3a 9540 finish_decl (var, varinits, FALSE);
5ff904cd 9541
c7e4ee3a 9542 var = ffecom_1 (ADDR_EXPR, build_pointer_type (vardesctype), var);
5ff904cd 9543
c7e4ee3a
CB
9544 ffesymbol_hook (s).vardesc_tree = var;
9545 }
5ff904cd 9546
c7e4ee3a
CB
9547 return ffesymbol_hook (s).vardesc_tree;
9548}
5ff904cd 9549
c7e4ee3a 9550#endif
5ff904cd 9551#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
9552static tree
9553ffecom_vardesc_array_ (ffesymbol s)
5ff904cd 9554{
c7e4ee3a
CB
9555 ffebld b;
9556 tree list;
9557 tree item = NULL_TREE;
9558 tree var;
9559 int i;
c7e4ee3a 9560 static int mynumber = 0;
5ff904cd 9561
c7e4ee3a
CB
9562 for (i = 0, list = NULL_TREE, b = ffesymbol_namelist (s);
9563 b != NULL;
9564 b = ffebld_trail (b), ++i)
9565 {
9566 tree t;
5ff904cd 9567
c7e4ee3a 9568 t = ffecom_vardesc_ (ffebld_head (b));
5ff904cd 9569
c7e4ee3a
CB
9570 if (list == NULL_TREE)
9571 list = item = build_tree_list (NULL_TREE, t);
9572 else
5ff904cd 9573 {
c7e4ee3a
CB
9574 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
9575 item = TREE_CHAIN (item);
5ff904cd 9576 }
5ff904cd 9577 }
5ff904cd 9578
c7e4ee3a
CB
9579 item = build_array_type (build_pointer_type (ffecom_type_vardesc_ ()),
9580 build_range_type (integer_type_node,
9581 integer_one_node,
9582 build_int_2 (i, 0)));
9583 list = build (CONSTRUCTOR, item, NULL_TREE, list);
9584 TREE_CONSTANT (list) = 1;
9585 TREE_STATIC (list) = 1;
5ff904cd 9586
14657de8 9587 var = ffecom_get_invented_identifier ("__g77_vardesc_array_%d", mynumber++);
c7e4ee3a
CB
9588 var = build_decl (VAR_DECL, var, item);
9589 TREE_STATIC (var) = 1;
9590 DECL_INITIAL (var) = error_mark_node;
9591 var = start_decl (var, FALSE);
9592 finish_decl (var, list, FALSE);
5ff904cd 9593
c7e4ee3a
CB
9594 return var;
9595}
5ff904cd 9596
c7e4ee3a
CB
9597#endif
9598#if FFECOM_targetCURRENT == FFECOM_targetGCC
9599static tree
9600ffecom_vardesc_dims_ (ffesymbol s)
9601{
9602 if (ffesymbol_dims (s) == NULL)
9603 return convert (ffecom_f2c_ptr_to_ftnlen_type_node,
9604 integer_zero_node);
5ff904cd 9605
c7e4ee3a
CB
9606 {
9607 ffebld b;
9608 ffebld e;
9609 tree list;
9610 tree backlist;
9611 tree item = NULL_TREE;
9612 tree var;
c7e4ee3a
CB
9613 tree numdim;
9614 tree numelem;
9615 tree baseoff = NULL_TREE;
9616 static int mynumber = 0;
9617
9618 numdim = build_int_2 ((int) ffesymbol_rank (s), 0);
9619 TREE_TYPE (numdim) = ffecom_f2c_ftnlen_type_node;
9620
9621 numelem = ffecom_expr (ffesymbol_arraysize (s));
9622 TREE_TYPE (numelem) = ffecom_f2c_ftnlen_type_node;
9623
9624 list = NULL_TREE;
9625 backlist = NULL_TREE;
9626 for (b = ffesymbol_dims (s), e = ffesymbol_extents (s);
9627 b != NULL;
9628 b = ffebld_trail (b), e = ffebld_trail (e))
5ff904cd 9629 {
c7e4ee3a
CB
9630 tree t;
9631 tree low;
9632 tree back;
5ff904cd 9633
c7e4ee3a
CB
9634 if (ffebld_trail (b) == NULL)
9635 t = NULL_TREE;
9636 else
5ff904cd 9637 {
c7e4ee3a
CB
9638 t = convert (ffecom_f2c_ftnlen_type_node,
9639 ffecom_expr (ffebld_head (e)));
5ff904cd 9640
c7e4ee3a
CB
9641 if (list == NULL_TREE)
9642 list = item = build_tree_list (NULL_TREE, t);
9643 else
9644 {
9645 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
9646 item = TREE_CHAIN (item);
9647 }
9648 }
5ff904cd 9649
c7e4ee3a
CB
9650 if (ffebld_left (ffebld_head (b)) == NULL)
9651 low = ffecom_integer_one_node;
9652 else
9653 low = ffecom_expr (ffebld_left (ffebld_head (b)));
9654 low = convert (ffecom_f2c_ftnlen_type_node, low);
5ff904cd 9655
c7e4ee3a
CB
9656 back = build_tree_list (low, t);
9657 TREE_CHAIN (back) = backlist;
9658 backlist = back;
9659 }
5ff904cd 9660
c7e4ee3a
CB
9661 for (item = backlist; item != NULL_TREE; item = TREE_CHAIN (item))
9662 {
9663 if (TREE_VALUE (item) == NULL_TREE)
9664 baseoff = TREE_PURPOSE (item);
9665 else
9666 baseoff = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
9667 TREE_PURPOSE (item),
9668 ffecom_2 (MULT_EXPR,
9669 ffecom_f2c_ftnlen_type_node,
9670 TREE_VALUE (item),
9671 baseoff));
5ff904cd
JL
9672 }
9673
c7e4ee3a 9674 /* backlist now dead, along with all TREE_PURPOSEs on it. */
5ff904cd 9675
c7e4ee3a
CB
9676 baseoff = build_tree_list (NULL_TREE, baseoff);
9677 TREE_CHAIN (baseoff) = list;
5ff904cd 9678
c7e4ee3a
CB
9679 numelem = build_tree_list (NULL_TREE, numelem);
9680 TREE_CHAIN (numelem) = baseoff;
5ff904cd 9681
c7e4ee3a
CB
9682 numdim = build_tree_list (NULL_TREE, numdim);
9683 TREE_CHAIN (numdim) = numelem;
5ff904cd 9684
c7e4ee3a
CB
9685 item = build_array_type (ffecom_f2c_ftnlen_type_node,
9686 build_range_type (integer_type_node,
9687 integer_zero_node,
9688 build_int_2
9689 ((int) ffesymbol_rank (s)
9690 + 2, 0)));
9691 list = build (CONSTRUCTOR, item, NULL_TREE, numdim);
9692 TREE_CONSTANT (list) = 1;
9693 TREE_STATIC (list) = 1;
9694
14657de8 9695 var = ffecom_get_invented_identifier ("__g77_dims_%d", mynumber++);
c7e4ee3a
CB
9696 var = build_decl (VAR_DECL, var, item);
9697 TREE_STATIC (var) = 1;
9698 DECL_INITIAL (var) = error_mark_node;
9699 var = start_decl (var, FALSE);
9700 finish_decl (var, list, FALSE);
9701
9702 var = ffecom_1 (ADDR_EXPR, build_pointer_type (item), var);
9703
c7e4ee3a
CB
9704 return var;
9705 }
5ff904cd 9706}
c7e4ee3a 9707
5ff904cd 9708#endif
c7e4ee3a
CB
9709/* Essentially does a "fold (build1 (code, type, node))" while checking
9710 for certain housekeeping things.
5ff904cd 9711
c7e4ee3a
CB
9712 NOTE: for building an ADDR_EXPR around a FUNCTION_DECL, use
9713 ffecom_1_fn instead. */
5ff904cd
JL
9714
9715#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
9716tree
9717ffecom_1 (enum tree_code code, tree type, tree node)
5ff904cd 9718{
c7e4ee3a
CB
9719 tree item;
9720
9721 if ((node == error_mark_node)
9722 || (type == error_mark_node))
5ff904cd
JL
9723 return error_mark_node;
9724
c7e4ee3a 9725 if (code == ADDR_EXPR)
5ff904cd 9726 {
c7e4ee3a
CB
9727 if (!mark_addressable (node))
9728 assert ("can't mark_addressable this node!" == NULL);
9729 }
5ff904cd 9730
c7e4ee3a
CB
9731 switch (ffe_is_emulate_complex () ? code : NOP_EXPR)
9732 {
9733 tree realtype;
5ff904cd 9734
c7e4ee3a
CB
9735 case REALPART_EXPR:
9736 item = build (COMPONENT_REF, type, node, TYPE_FIELDS (TREE_TYPE (node)));
5ff904cd
JL
9737 break;
9738
c7e4ee3a
CB
9739 case IMAGPART_EXPR:
9740 item = build (COMPONENT_REF, type, node, TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (node))));
9741 break;
5ff904cd 9742
5ff904cd 9743
c7e4ee3a
CB
9744 case NEGATE_EXPR:
9745 if (TREE_CODE (type) != RECORD_TYPE)
9746 {
9747 item = build1 (code, type, node);
9748 break;
9749 }
9750 node = ffecom_stabilize_aggregate_ (node);
9751 realtype = TREE_TYPE (TYPE_FIELDS (type));
9752 item =
9753 ffecom_2 (COMPLEX_EXPR, type,
9754 ffecom_1 (NEGATE_EXPR, realtype,
9755 ffecom_1 (REALPART_EXPR, realtype,
9756 node)),
9757 ffecom_1 (NEGATE_EXPR, realtype,
9758 ffecom_1 (IMAGPART_EXPR, realtype,
9759 node)));
5ff904cd
JL
9760 break;
9761
9762 default:
c7e4ee3a
CB
9763 item = build1 (code, type, node);
9764 break;
5ff904cd 9765 }
5ff904cd 9766
c7e4ee3a
CB
9767 if (TREE_SIDE_EFFECTS (node))
9768 TREE_SIDE_EFFECTS (item) = 1;
9769 if ((code == ADDR_EXPR) && staticp (node))
9770 TREE_CONSTANT (item) = 1;
9771 return fold (item);
9772}
5ff904cd 9773#endif
5ff904cd 9774
c7e4ee3a
CB
9775/* Like ffecom_1 (ADDR_EXPR, TREE_TYPE (node), node), except
9776 handles TREE_CODE (node) == FUNCTION_DECL. In particular,
9777 does not set TREE_ADDRESSABLE (because calling an inline
9778 function does not mean the function needs to be separately
9779 compiled). */
5ff904cd
JL
9780
9781#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
9782tree
9783ffecom_1_fn (tree node)
5ff904cd 9784{
c7e4ee3a 9785 tree item;
5ff904cd 9786 tree type;
5ff904cd 9787
c7e4ee3a
CB
9788 if (node == error_mark_node)
9789 return error_mark_node;
5ff904cd 9790
c7e4ee3a
CB
9791 type = build_type_variant (TREE_TYPE (node),
9792 TREE_READONLY (node),
9793 TREE_THIS_VOLATILE (node));
9794 item = build1 (ADDR_EXPR,
9795 build_pointer_type (type), node);
9796 if (TREE_SIDE_EFFECTS (node))
9797 TREE_SIDE_EFFECTS (item) = 1;
9798 if (staticp (node))
9799 TREE_CONSTANT (item) = 1;
9800 return fold (item);
5ff904cd 9801}
5ff904cd 9802#endif
c7e4ee3a
CB
9803
9804/* Essentially does a "fold (build (code, type, node1, node2))" while
9805 checking for certain housekeeping things. */
5ff904cd
JL
9806
9807#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
9808tree
9809ffecom_2 (enum tree_code code, tree type, tree node1,
9810 tree node2)
5ff904cd 9811{
c7e4ee3a 9812 tree item;
5ff904cd 9813
c7e4ee3a
CB
9814 if ((node1 == error_mark_node)
9815 || (node2 == error_mark_node)
9816 || (type == error_mark_node))
9817 return error_mark_node;
9818
9819 switch (ffe_is_emulate_complex () ? code : NOP_EXPR)
5ff904cd 9820 {
c7e4ee3a 9821 tree a, b, c, d, realtype;
5ff904cd 9822
c7e4ee3a
CB
9823 case CONJ_EXPR:
9824 assert ("no CONJ_EXPR support yet" == NULL);
9825 return error_mark_node;
5ff904cd 9826
c7e4ee3a
CB
9827 case COMPLEX_EXPR:
9828 item = build_tree_list (TYPE_FIELDS (type), node1);
9829 TREE_CHAIN (item) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), node2);
9830 item = build (CONSTRUCTOR, type, NULL_TREE, item);
9831 break;
5ff904cd 9832
c7e4ee3a
CB
9833 case PLUS_EXPR:
9834 if (TREE_CODE (type) != RECORD_TYPE)
9835 {
9836 item = build (code, type, node1, node2);
9837 break;
9838 }
9839 node1 = ffecom_stabilize_aggregate_ (node1);
9840 node2 = ffecom_stabilize_aggregate_ (node2);
9841 realtype = TREE_TYPE (TYPE_FIELDS (type));
9842 item =
9843 ffecom_2 (COMPLEX_EXPR, type,
9844 ffecom_2 (PLUS_EXPR, realtype,
9845 ffecom_1 (REALPART_EXPR, realtype,
9846 node1),
9847 ffecom_1 (REALPART_EXPR, realtype,
9848 node2)),
9849 ffecom_2 (PLUS_EXPR, realtype,
9850 ffecom_1 (IMAGPART_EXPR, realtype,
9851 node1),
9852 ffecom_1 (IMAGPART_EXPR, realtype,
9853 node2)));
9854 break;
5ff904cd 9855
c7e4ee3a
CB
9856 case MINUS_EXPR:
9857 if (TREE_CODE (type) != RECORD_TYPE)
9858 {
9859 item = build (code, type, node1, node2);
9860 break;
9861 }
9862 node1 = ffecom_stabilize_aggregate_ (node1);
9863 node2 = ffecom_stabilize_aggregate_ (node2);
9864 realtype = TREE_TYPE (TYPE_FIELDS (type));
9865 item =
9866 ffecom_2 (COMPLEX_EXPR, type,
9867 ffecom_2 (MINUS_EXPR, realtype,
9868 ffecom_1 (REALPART_EXPR, realtype,
9869 node1),
9870 ffecom_1 (REALPART_EXPR, realtype,
9871 node2)),
9872 ffecom_2 (MINUS_EXPR, realtype,
9873 ffecom_1 (IMAGPART_EXPR, realtype,
9874 node1),
9875 ffecom_1 (IMAGPART_EXPR, realtype,
9876 node2)));
9877 break;
5ff904cd 9878
c7e4ee3a
CB
9879 case MULT_EXPR:
9880 if (TREE_CODE (type) != RECORD_TYPE)
9881 {
9882 item = build (code, type, node1, node2);
9883 break;
9884 }
9885 node1 = ffecom_stabilize_aggregate_ (node1);
9886 node2 = ffecom_stabilize_aggregate_ (node2);
9887 realtype = TREE_TYPE (TYPE_FIELDS (type));
9888 a = save_expr (ffecom_1 (REALPART_EXPR, realtype,
9889 node1));
9890 b = save_expr (ffecom_1 (IMAGPART_EXPR, realtype,
9891 node1));
9892 c = save_expr (ffecom_1 (REALPART_EXPR, realtype,
9893 node2));
9894 d = save_expr (ffecom_1 (IMAGPART_EXPR, realtype,
9895 node2));
9896 item =
9897 ffecom_2 (COMPLEX_EXPR, type,
9898 ffecom_2 (MINUS_EXPR, realtype,
9899 ffecom_2 (MULT_EXPR, realtype,
9900 a,
9901 c),
9902 ffecom_2 (MULT_EXPR, realtype,
9903 b,
9904 d)),
9905 ffecom_2 (PLUS_EXPR, realtype,
9906 ffecom_2 (MULT_EXPR, realtype,
9907 a,
9908 d),
9909 ffecom_2 (MULT_EXPR, realtype,
9910 c,
9911 b)));
9912 break;
5ff904cd 9913
c7e4ee3a
CB
9914 case EQ_EXPR:
9915 if ((TREE_CODE (node1) != RECORD_TYPE)
9916 && (TREE_CODE (node2) != RECORD_TYPE))
9917 {
9918 item = build (code, type, node1, node2);
9919 break;
9920 }
9921 assert (TREE_CODE (node1) == RECORD_TYPE);
9922 assert (TREE_CODE (node2) == RECORD_TYPE);
9923 node1 = ffecom_stabilize_aggregate_ (node1);
9924 node2 = ffecom_stabilize_aggregate_ (node2);
9925 realtype = TREE_TYPE (TYPE_FIELDS (type));
9926 item =
9927 ffecom_2 (TRUTH_ANDIF_EXPR, type,
9928 ffecom_2 (code, type,
9929 ffecom_1 (REALPART_EXPR, realtype,
9930 node1),
9931 ffecom_1 (REALPART_EXPR, realtype,
9932 node2)),
9933 ffecom_2 (code, type,
9934 ffecom_1 (IMAGPART_EXPR, realtype,
9935 node1),
9936 ffecom_1 (IMAGPART_EXPR, realtype,
9937 node2)));
9938 break;
9939
9940 case NE_EXPR:
9941 if ((TREE_CODE (node1) != RECORD_TYPE)
9942 && (TREE_CODE (node2) != RECORD_TYPE))
9943 {
9944 item = build (code, type, node1, node2);
9945 break;
9946 }
9947 assert (TREE_CODE (node1) == RECORD_TYPE);
9948 assert (TREE_CODE (node2) == RECORD_TYPE);
9949 node1 = ffecom_stabilize_aggregate_ (node1);
9950 node2 = ffecom_stabilize_aggregate_ (node2);
9951 realtype = TREE_TYPE (TYPE_FIELDS (type));
9952 item =
9953 ffecom_2 (TRUTH_ORIF_EXPR, type,
9954 ffecom_2 (code, type,
9955 ffecom_1 (REALPART_EXPR, realtype,
9956 node1),
9957 ffecom_1 (REALPART_EXPR, realtype,
9958 node2)),
9959 ffecom_2 (code, type,
9960 ffecom_1 (IMAGPART_EXPR, realtype,
9961 node1),
9962 ffecom_1 (IMAGPART_EXPR, realtype,
9963 node2)));
9964 break;
5ff904cd 9965
c7e4ee3a
CB
9966 default:
9967 item = build (code, type, node1, node2);
9968 break;
5ff904cd
JL
9969 }
9970
c7e4ee3a
CB
9971 if (TREE_SIDE_EFFECTS (node1) || TREE_SIDE_EFFECTS (node2))
9972 TREE_SIDE_EFFECTS (item) = 1;
9973 return fold (item);
5ff904cd
JL
9974}
9975
9976#endif
c7e4ee3a 9977/* ffecom_2pass_advise_entrypoint -- Advise that there's this entrypoint
5ff904cd 9978
c7e4ee3a
CB
9979 ffesymbol s; // the ENTRY point itself
9980 if (ffecom_2pass_advise_entrypoint(s))
9981 // the ENTRY point has been accepted
5ff904cd 9982
c7e4ee3a
CB
9983 Does whatever compiler needs to do when it learns about the entrypoint,
9984 like determine the return type of the master function, count the
9985 number of entrypoints, etc. Returns FALSE if the return type is
9986 not compatible with the return type(s) of other entrypoint(s).
5ff904cd 9987
c7e4ee3a
CB
9988 NOTE: for every call to this fn that returns TRUE, _do_entrypoint must
9989 later (after _finish_progunit) be called with the same entrypoint(s)
9990 as passed to this fn for which TRUE was returned.
5ff904cd 9991
c7e4ee3a
CB
9992 03-Jan-92 JCB 2.0
9993 Return FALSE if the return type conflicts with previous entrypoints. */
5ff904cd
JL
9994
9995#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
9996bool
9997ffecom_2pass_advise_entrypoint (ffesymbol entry)
5ff904cd 9998{
c7e4ee3a
CB
9999 ffebld list; /* opITEM. */
10000 ffebld mlist; /* opITEM. */
10001 ffebld plist; /* opITEM. */
10002 ffebld arg; /* ffebld_head(opITEM). */
10003 ffebld item; /* opITEM. */
10004 ffesymbol s; /* ffebld_symter(arg). */
10005 ffeinfoBasictype bt = ffesymbol_basictype (entry);
10006 ffeinfoKindtype kt = ffesymbol_kindtype (entry);
10007 ffetargetCharacterSize size = ffesymbol_size (entry);
10008 bool ok;
5ff904cd 10009
c7e4ee3a
CB
10010 if (ffecom_num_entrypoints_ == 0)
10011 { /* First entrypoint, make list of main
10012 arglist's dummies. */
10013 assert (ffecom_primary_entry_ != NULL);
5ff904cd 10014
c7e4ee3a
CB
10015 ffecom_master_bt_ = ffesymbol_basictype (ffecom_primary_entry_);
10016 ffecom_master_kt_ = ffesymbol_kindtype (ffecom_primary_entry_);
10017 ffecom_master_size_ = ffesymbol_size (ffecom_primary_entry_);
5ff904cd 10018
c7e4ee3a
CB
10019 for (plist = NULL, list = ffesymbol_dummyargs (ffecom_primary_entry_);
10020 list != NULL;
10021 list = ffebld_trail (list))
10022 {
10023 arg = ffebld_head (list);
10024 if (ffebld_op (arg) != FFEBLD_opSYMTER)
10025 continue; /* Alternate return or some such thing. */
10026 item = ffebld_new_item (arg, NULL);
10027 if (plist == NULL)
10028 ffecom_master_arglist_ = item;
10029 else
10030 ffebld_set_trail (plist, item);
10031 plist = item;
10032 }
5ff904cd
JL
10033 }
10034
c7e4ee3a
CB
10035 /* If necessary, scan entry arglist for alternate returns. Do this scan
10036 apparently redundantly (it's done below to UNIONize the arglists) so
10037 that we don't complain about RETURN 1 if an offending ENTRY is the only
10038 one with an alternate return. */
5ff904cd 10039
c7e4ee3a 10040 if (!ffecom_is_altreturning_)
5ff904cd 10041 {
c7e4ee3a
CB
10042 for (list = ffesymbol_dummyargs (entry);
10043 list != NULL;
10044 list = ffebld_trail (list))
10045 {
10046 arg = ffebld_head (list);
10047 if (ffebld_op (arg) == FFEBLD_opSTAR)
10048 {
10049 ffecom_is_altreturning_ = TRUE;
10050 break;
10051 }
10052 }
10053 }
5ff904cd 10054
c7e4ee3a 10055 /* Now check type compatibility. */
5ff904cd 10056
c7e4ee3a
CB
10057 switch (ffecom_master_bt_)
10058 {
10059 case FFEINFO_basictypeNONE:
10060 ok = (bt != FFEINFO_basictypeCHARACTER);
10061 break;
5ff904cd 10062
c7e4ee3a
CB
10063 case FFEINFO_basictypeCHARACTER:
10064 ok
10065 = (bt == FFEINFO_basictypeCHARACTER)
10066 && (kt == ffecom_master_kt_)
10067 && (size == ffecom_master_size_);
10068 break;
5ff904cd 10069
c7e4ee3a
CB
10070 case FFEINFO_basictypeANY:
10071 return FALSE; /* Just don't bother. */
5ff904cd 10072
c7e4ee3a
CB
10073 default:
10074 if (bt == FFEINFO_basictypeCHARACTER)
5ff904cd 10075 {
c7e4ee3a
CB
10076 ok = FALSE;
10077 break;
5ff904cd 10078 }
c7e4ee3a
CB
10079 ok = TRUE;
10080 if ((bt != ffecom_master_bt_) || (kt != ffecom_master_kt_))
10081 {
10082 ffecom_master_bt_ = FFEINFO_basictypeNONE;
10083 ffecom_master_kt_ = FFEINFO_kindtypeNONE;
10084 }
10085 break;
10086 }
5ff904cd 10087
c7e4ee3a
CB
10088 if (!ok)
10089 {
10090 ffebad_start (FFEBAD_ENTRY_CONFLICTS);
10091 ffest_ffebad_here_current_stmt (0);
10092 ffebad_finish ();
10093 return FALSE; /* Can't handle entrypoint. */
10094 }
5ff904cd 10095
c7e4ee3a 10096 /* Entrypoint type compatible with previous types. */
5ff904cd 10097
c7e4ee3a 10098 ++ffecom_num_entrypoints_;
5ff904cd 10099
c7e4ee3a
CB
10100 /* Master-arg-list = UNION(Master-arg-list,entry-arg-list). */
10101
10102 for (list = ffesymbol_dummyargs (entry);
10103 list != NULL;
10104 list = ffebld_trail (list))
10105 {
10106 arg = ffebld_head (list);
10107 if (ffebld_op (arg) != FFEBLD_opSYMTER)
10108 continue; /* Alternate return or some such thing. */
10109 s = ffebld_symter (arg);
10110 for (plist = NULL, mlist = ffecom_master_arglist_;
10111 mlist != NULL;
10112 plist = mlist, mlist = ffebld_trail (mlist))
10113 { /* plist points to previous item for easy
10114 appending of arg. */
10115 if (ffebld_symter (ffebld_head (mlist)) == s)
10116 break; /* Already have this arg in the master list. */
10117 }
10118 if (mlist != NULL)
10119 continue; /* Already have this arg in the master list. */
5ff904cd 10120
c7e4ee3a 10121 /* Append this arg to the master list. */
5ff904cd 10122
c7e4ee3a
CB
10123 item = ffebld_new_item (arg, NULL);
10124 if (plist == NULL)
10125 ffecom_master_arglist_ = item;
10126 else
10127 ffebld_set_trail (plist, item);
5ff904cd
JL
10128 }
10129
c7e4ee3a 10130 return TRUE;
5ff904cd
JL
10131}
10132
10133#endif
c7e4ee3a
CB
10134/* ffecom_2pass_do_entrypoint -- Do compilation of entrypoint
10135
10136 ffesymbol s; // the ENTRY point itself
10137 ffecom_2pass_do_entrypoint(s);
10138
10139 Does whatever compiler needs to do to make the entrypoint actually
10140 happen. Must be called for each entrypoint after
10141 ffecom_finish_progunit is called. */
10142
5ff904cd 10143#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
10144void
10145ffecom_2pass_do_entrypoint (ffesymbol entry)
5ff904cd 10146{
c7e4ee3a
CB
10147 static int mfn_num = 0;
10148 static int ent_num;
5ff904cd 10149
c7e4ee3a
CB
10150 if (mfn_num != ffecom_num_fns_)
10151 { /* First entrypoint for this program unit. */
10152 ent_num = 1;
10153 mfn_num = ffecom_num_fns_;
10154 ffecom_do_entry_ (ffecom_primary_entry_, 0);
10155 }
10156 else
10157 ++ent_num;
5ff904cd 10158
c7e4ee3a 10159 --ffecom_num_entrypoints_;
5ff904cd 10160
c7e4ee3a
CB
10161 ffecom_do_entry_ (entry, ent_num);
10162}
5ff904cd 10163
c7e4ee3a 10164#endif
5ff904cd 10165
c7e4ee3a
CB
10166/* Essentially does a "fold (build (code, type, node1, node2))" while
10167 checking for certain housekeeping things. Always sets
10168 TREE_SIDE_EFFECTS. */
5ff904cd 10169
c7e4ee3a
CB
10170#if FFECOM_targetCURRENT == FFECOM_targetGCC
10171tree
10172ffecom_2s (enum tree_code code, tree type, tree node1,
10173 tree node2)
10174{
10175 tree item;
5ff904cd 10176
c7e4ee3a
CB
10177 if ((node1 == error_mark_node)
10178 || (node2 == error_mark_node)
10179 || (type == error_mark_node))
10180 return error_mark_node;
5ff904cd 10181
c7e4ee3a
CB
10182 item = build (code, type, node1, node2);
10183 TREE_SIDE_EFFECTS (item) = 1;
10184 return fold (item);
5ff904cd
JL
10185}
10186
10187#endif
c7e4ee3a
CB
10188/* Essentially does a "fold (build (code, type, node1, node2, node3))" while
10189 checking for certain housekeeping things. */
10190
5ff904cd 10191#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
10192tree
10193ffecom_3 (enum tree_code code, tree type, tree node1,
10194 tree node2, tree node3)
5ff904cd 10195{
c7e4ee3a 10196 tree item;
5ff904cd 10197
c7e4ee3a
CB
10198 if ((node1 == error_mark_node)
10199 || (node2 == error_mark_node)
10200 || (node3 == error_mark_node)
10201 || (type == error_mark_node))
10202 return error_mark_node;
5ff904cd 10203
c7e4ee3a
CB
10204 item = build (code, type, node1, node2, node3);
10205 if (TREE_SIDE_EFFECTS (node1) || TREE_SIDE_EFFECTS (node2)
10206 || (node3 != NULL_TREE && TREE_SIDE_EFFECTS (node3)))
10207 TREE_SIDE_EFFECTS (item) = 1;
10208 return fold (item);
10209}
5ff904cd 10210
c7e4ee3a
CB
10211#endif
10212/* Essentially does a "fold (build (code, type, node1, node2, node3))" while
10213 checking for certain housekeeping things. Always sets
10214 TREE_SIDE_EFFECTS. */
5ff904cd 10215
c7e4ee3a
CB
10216#if FFECOM_targetCURRENT == FFECOM_targetGCC
10217tree
10218ffecom_3s (enum tree_code code, tree type, tree node1,
10219 tree node2, tree node3)
10220{
10221 tree item;
5ff904cd 10222
c7e4ee3a
CB
10223 if ((node1 == error_mark_node)
10224 || (node2 == error_mark_node)
10225 || (node3 == error_mark_node)
10226 || (type == error_mark_node))
10227 return error_mark_node;
5ff904cd 10228
c7e4ee3a
CB
10229 item = build (code, type, node1, node2, node3);
10230 TREE_SIDE_EFFECTS (item) = 1;
10231 return fold (item);
10232}
5ff904cd 10233
c7e4ee3a 10234#endif
5ff904cd 10235
c7e4ee3a 10236/* ffecom_arg_expr -- Transform argument expr into gcc tree
5ff904cd 10237
c7e4ee3a 10238 See use by ffecom_list_expr.
5ff904cd 10239
c7e4ee3a
CB
10240 If expression is NULL, returns an integer zero tree. If it is not
10241 a CHARACTER expression, returns whatever ffecom_expr
10242 returns and sets the length return value to NULL_TREE. Otherwise
10243 generates code to evaluate the character expression, returns the proper
10244 pointer to the result, but does NOT set the length return value to a tree
10245 that specifies the length of the result. (In other words, the length
10246 variable is always set to NULL_TREE, because a length is never passed.)
5ff904cd 10247
c7e4ee3a
CB
10248 21-Dec-91 JCB 1.1
10249 Don't set returned length, since nobody needs it (yet; someday if
10250 we allow CHARACTER*(*) dummies to statement functions, we'll need
10251 it). */
5ff904cd 10252
c7e4ee3a
CB
10253#if FFECOM_targetCURRENT == FFECOM_targetGCC
10254tree
10255ffecom_arg_expr (ffebld expr, tree *length)
10256{
10257 tree ign;
5ff904cd 10258
c7e4ee3a 10259 *length = NULL_TREE;
5ff904cd 10260
c7e4ee3a
CB
10261 if (expr == NULL)
10262 return integer_zero_node;
5ff904cd 10263
c7e4ee3a
CB
10264 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10265 return ffecom_expr (expr);
5ff904cd 10266
c7e4ee3a
CB
10267 return ffecom_arg_ptr_to_expr (expr, &ign);
10268}
10269
10270#endif
10271/* Transform expression into constant argument-pointer-to-expression tree.
10272
10273 If the expression can be transformed into a argument-pointer-to-expression
10274 tree that is constant, that is done, and the tree returned. Else
10275 NULL_TREE is returned.
5ff904cd 10276
c7e4ee3a
CB
10277 That way, a caller can attempt to provide compile-time initialization
10278 of a variable and, if that fails, *then* choose to start a new block
10279 and resort to using temporaries, as appropriate. */
5ff904cd 10280
c7e4ee3a
CB
10281tree
10282ffecom_arg_ptr_to_const_expr (ffebld expr, tree *length)
10283{
10284 if (! expr)
10285 return integer_zero_node;
5ff904cd 10286
c7e4ee3a
CB
10287 if (ffebld_op (expr) == FFEBLD_opANY)
10288 {
10289 if (length)
10290 *length = error_mark_node;
10291 return error_mark_node;
10292 }
10293
10294 if (ffebld_arity (expr) == 0
10295 && (ffebld_op (expr) != FFEBLD_opSYMTER
10296 || ffebld_where (expr) == FFEINFO_whereCOMMON
10297 || ffebld_where (expr) == FFEINFO_whereGLOBAL
10298 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
10299 {
10300 tree t;
10301
10302 t = ffecom_arg_ptr_to_expr (expr, length);
10303 assert (TREE_CONSTANT (t));
10304 assert (! length || TREE_CONSTANT (*length));
10305 return t;
10306 }
10307
10308 if (length
10309 && ffebld_size (expr) != FFETARGET_charactersizeNONE)
10310 *length = build_int_2 (ffebld_size (expr), 0);
10311 else if (length)
10312 *length = NULL_TREE;
10313 return NULL_TREE;
5ff904cd
JL
10314}
10315
c7e4ee3a 10316/* ffecom_arg_ptr_to_expr -- Transform argument expr into gcc tree
5ff904cd 10317
c7e4ee3a
CB
10318 See use by ffecom_list_ptr_to_expr.
10319
10320 If expression is NULL, returns an integer zero tree. If it is not
10321 a CHARACTER expression, returns whatever ffecom_ptr_to_expr
10322 returns and sets the length return value to NULL_TREE. Otherwise
10323 generates code to evaluate the character expression, returns the proper
10324 pointer to the result, AND sets the length return value to a tree that
10325 specifies the length of the result.
10326
10327 If the length argument is NULL, this is a slightly special
10328 case of building a FORMAT expression, that is, an expression that
10329 will be used at run time without regard to length. For the current
10330 implementation, which uses the libf2c library, this means it is nice
10331 to append a null byte to the end of the expression, where feasible,
10332 to make sure any diagnostic about the FORMAT string terminates at
10333 some useful point.
10334
10335 For now, treat %REF(char-expr) as the same as char-expr with a NULL
10336 length argument. This might even be seen as a feature, if a null
10337 byte can always be appended. */
5ff904cd
JL
10338
10339#if FFECOM_targetCURRENT == FFECOM_targetGCC
10340tree
c7e4ee3a 10341ffecom_arg_ptr_to_expr (ffebld expr, tree *length)
5ff904cd
JL
10342{
10343 tree item;
c7e4ee3a
CB
10344 tree ign_length;
10345 ffecomConcatList_ catlist;
5ff904cd 10346
c7e4ee3a
CB
10347 if (length != NULL)
10348 *length = NULL_TREE;
5ff904cd 10349
c7e4ee3a
CB
10350 if (expr == NULL)
10351 return integer_zero_node;
5ff904cd 10352
c7e4ee3a 10353 switch (ffebld_op (expr))
5ff904cd 10354 {
c7e4ee3a
CB
10355 case FFEBLD_opPERCENT_VAL:
10356 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10357 return ffecom_expr (ffebld_left (expr));
10358 {
10359 tree temp_exp;
10360 tree temp_length;
5ff904cd 10361
c7e4ee3a
CB
10362 temp_exp = ffecom_arg_ptr_to_expr (ffebld_left (expr), &temp_length);
10363 if (temp_exp == error_mark_node)
10364 return error_mark_node;
5ff904cd 10365
c7e4ee3a
CB
10366 return ffecom_1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (temp_exp)),
10367 temp_exp);
10368 }
5ff904cd 10369
c7e4ee3a
CB
10370 case FFEBLD_opPERCENT_REF:
10371 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10372 return ffecom_ptr_to_expr (ffebld_left (expr));
10373 if (length != NULL)
10374 {
10375 ign_length = NULL_TREE;
10376 length = &ign_length;
10377 }
10378 expr = ffebld_left (expr);
10379 break;
5ff904cd 10380
c7e4ee3a
CB
10381 case FFEBLD_opPERCENT_DESCR:
10382 switch (ffeinfo_basictype (ffebld_info (expr)))
5ff904cd 10383 {
c7e4ee3a
CB
10384#ifdef PASS_HOLLERITH_BY_DESCRIPTOR
10385 case FFEINFO_basictypeHOLLERITH:
10386#endif
10387 case FFEINFO_basictypeCHARACTER:
10388 break; /* Passed by descriptor anyway. */
10389
10390 default:
10391 item = ffecom_ptr_to_expr (expr);
10392 if (item != error_mark_node)
10393 *length = TYPE_SIZE (TREE_TYPE (TREE_TYPE (item)));
5ff904cd
JL
10394 break;
10395 }
5ff904cd
JL
10396 break;
10397
10398 default:
5ff904cd
JL
10399 break;
10400 }
10401
c7e4ee3a
CB
10402#ifdef PASS_HOLLERITH_BY_DESCRIPTOR
10403 if ((ffeinfo_basictype (ffebld_info (expr)) == FFEINFO_basictypeHOLLERITH)
10404 && (length != NULL))
10405 { /* Pass Hollerith by descriptor. */
10406 ffetargetHollerith h;
10407
10408 assert (ffebld_op (expr) == FFEBLD_opCONTER);
10409 h = ffebld_cu_val_hollerith (ffebld_constant_union
10410 (ffebld_conter (expr)));
10411 *length
10412 = build_int_2 (h.length, 0);
10413 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
10414 }
10415#endif
10416
10417 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10418 return ffecom_ptr_to_expr (expr);
10419
10420 assert (ffeinfo_kindtype (ffebld_info (expr))
10421 == FFEINFO_kindtypeCHARACTER1);
10422
47d98fa2
CB
10423 while (ffebld_op (expr) == FFEBLD_opPAREN)
10424 expr = ffebld_left (expr);
10425
c7e4ee3a
CB
10426 catlist = ffecom_concat_list_new_ (expr, FFETARGET_charactersizeNONE);
10427 switch (ffecom_concat_list_count_ (catlist))
10428 {
10429 case 0: /* Shouldn't happen, but in case it does... */
10430 if (length != NULL)
10431 {
10432 *length = ffecom_f2c_ftnlen_zero_node;
10433 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
10434 }
10435 ffecom_concat_list_kill_ (catlist);
10436 return null_pointer_node;
10437
10438 case 1: /* The (fairly) easy case. */
10439 if (length == NULL)
10440 ffecom_char_args_with_null_ (&item, &ign_length,
10441 ffecom_concat_list_expr_ (catlist, 0));
10442 else
10443 ffecom_char_args_ (&item, length,
10444 ffecom_concat_list_expr_ (catlist, 0));
10445 ffecom_concat_list_kill_ (catlist);
10446 assert (item != NULL_TREE);
10447 return item;
10448
10449 default: /* Must actually concatenate things. */
10450 break;
10451 }
10452
10453 {
10454 int count = ffecom_concat_list_count_ (catlist);
10455 int i;
10456 tree lengths;
10457 tree items;
10458 tree length_array;
10459 tree item_array;
10460 tree citem;
10461 tree clength;
10462 tree temporary;
10463 tree num;
10464 tree known_length;
10465 ffetargetCharacterSize sz;
10466
10467 sz = ffecom_concat_list_maxlen_ (catlist);
10468 /* ~~Kludge! */
10469 assert (sz != FFETARGET_charactersizeNONE);
10470
10471#ifdef HOHO
10472 length_array
10473 = lengths
10474 = ffecom_push_tempvar (ffecom_f2c_ftnlen_type_node,
10475 FFETARGET_charactersizeNONE, count, TRUE);
10476 item_array
10477 = items
10478 = ffecom_push_tempvar (ffecom_f2c_address_type_node,
10479 FFETARGET_charactersizeNONE, count, TRUE);
10480 temporary = ffecom_push_tempvar (char_type_node,
10481 sz, -1, TRUE);
10482#else
10483 {
10484 tree hook;
10485
10486 hook = ffebld_nonter_hook (expr);
10487 assert (hook);
10488 assert (TREE_CODE (hook) == TREE_VEC);
10489 assert (TREE_VEC_LENGTH (hook) == 3);
10490 length_array = lengths = TREE_VEC_ELT (hook, 0);
10491 item_array = items = TREE_VEC_ELT (hook, 1);
10492 temporary = TREE_VEC_ELT (hook, 2);
10493 }
10494#endif
10495
10496 known_length = ffecom_f2c_ftnlen_zero_node;
10497
10498 for (i = 0; i < count; ++i)
10499 {
10500 if ((i == count)
10501 && (length == NULL))
10502 ffecom_char_args_with_null_ (&citem, &clength,
10503 ffecom_concat_list_expr_ (catlist, i));
10504 else
10505 ffecom_char_args_ (&citem, &clength,
10506 ffecom_concat_list_expr_ (catlist, i));
10507 if ((citem == error_mark_node)
10508 || (clength == error_mark_node))
10509 {
10510 ffecom_concat_list_kill_ (catlist);
10511 *length = error_mark_node;
10512 return error_mark_node;
10513 }
10514
10515 items
10516 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (items),
10517 ffecom_modify (void_type_node,
10518 ffecom_2 (ARRAY_REF,
10519 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array))),
10520 item_array,
10521 build_int_2 (i, 0)),
10522 citem),
10523 items);
10524 clength = ffecom_save_tree (clength);
10525 if (length != NULL)
10526 known_length
10527 = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
10528 known_length,
10529 clength);
10530 lengths
10531 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (lengths),
10532 ffecom_modify (void_type_node,
10533 ffecom_2 (ARRAY_REF,
10534 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array))),
10535 length_array,
10536 build_int_2 (i, 0)),
10537 clength),
10538 lengths);
10539 }
10540
10541 temporary = ffecom_1 (ADDR_EXPR,
10542 build_pointer_type (TREE_TYPE (temporary)),
10543 temporary);
10544
10545 item = build_tree_list (NULL_TREE, temporary);
10546 TREE_CHAIN (item)
10547 = build_tree_list (NULL_TREE,
10548 ffecom_1 (ADDR_EXPR,
10549 build_pointer_type (TREE_TYPE (items)),
10550 items));
10551 TREE_CHAIN (TREE_CHAIN (item))
10552 = build_tree_list (NULL_TREE,
10553 ffecom_1 (ADDR_EXPR,
10554 build_pointer_type (TREE_TYPE (lengths)),
10555 lengths));
10556 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item)))
10557 = build_tree_list
10558 (NULL_TREE,
10559 ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
10560 convert (ffecom_f2c_ftnlen_type_node,
10561 build_int_2 (count, 0))));
10562 num = build_int_2 (sz, 0);
10563 TREE_TYPE (num) = ffecom_f2c_ftnlen_type_node;
10564 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item))))
10565 = build_tree_list (NULL_TREE, num);
10566
10567 item = ffecom_call_gfrt (FFECOM_gfrtCAT, item, NULL_TREE);
5ff904cd 10568 TREE_SIDE_EFFECTS (item) = 1;
c7e4ee3a
CB
10569 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (temporary),
10570 item,
10571 temporary);
10572
10573 if (length != NULL)
10574 *length = known_length;
10575 }
10576
10577 ffecom_concat_list_kill_ (catlist);
10578 assert (item != NULL_TREE);
10579 return item;
5ff904cd 10580}
c7e4ee3a 10581
5ff904cd 10582#endif
c7e4ee3a 10583/* Generate call to run-time function.
5ff904cd 10584
c7e4ee3a
CB
10585 The first arg is the GNU Fortran Run-Time function index, the second
10586 arg is the list of arguments to pass to it. Returned is the expression
10587 (WITHOUT TREE_SIDE_EFFECTS set!) that makes the call and returns the
10588 result (which may be void). */
5ff904cd
JL
10589
10590#if FFECOM_targetCURRENT == FFECOM_targetGCC
10591tree
c7e4ee3a 10592ffecom_call_gfrt (ffecomGfrt ix, tree args, tree hook)
5ff904cd 10593{
c7e4ee3a
CB
10594 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
10595 ffecom_gfrt_kindtype (ix),
10596 ffe_is_f2c_library () && ffecom_gfrt_complex_[ix],
10597 NULL_TREE, args, NULL_TREE, NULL,
10598 NULL, NULL_TREE, TRUE, hook);
5ff904cd
JL
10599}
10600#endif
10601
c7e4ee3a 10602/* Transform constant-union to tree. */
5ff904cd
JL
10603
10604#if FFECOM_targetCURRENT == FFECOM_targetGCC
10605tree
c7e4ee3a
CB
10606ffecom_constantunion (ffebldConstantUnion *cu, ffeinfoBasictype bt,
10607 ffeinfoKindtype kt, tree tree_type)
5ff904cd
JL
10608{
10609 tree item;
10610
c7e4ee3a 10611 switch (bt)
5ff904cd 10612 {
c7e4ee3a
CB
10613 case FFEINFO_basictypeINTEGER:
10614 {
10615 int val;
5ff904cd 10616
c7e4ee3a
CB
10617 switch (kt)
10618 {
10619#if FFETARGET_okINTEGER1
10620 case FFEINFO_kindtypeINTEGER1:
10621 val = ffebld_cu_val_integer1 (*cu);
10622 break;
10623#endif
5ff904cd 10624
c7e4ee3a
CB
10625#if FFETARGET_okINTEGER2
10626 case FFEINFO_kindtypeINTEGER2:
10627 val = ffebld_cu_val_integer2 (*cu);
10628 break;
10629#endif
5ff904cd 10630
c7e4ee3a
CB
10631#if FFETARGET_okINTEGER3
10632 case FFEINFO_kindtypeINTEGER3:
10633 val = ffebld_cu_val_integer3 (*cu);
10634 break;
10635#endif
5ff904cd 10636
c7e4ee3a
CB
10637#if FFETARGET_okINTEGER4
10638 case FFEINFO_kindtypeINTEGER4:
10639 val = ffebld_cu_val_integer4 (*cu);
10640 break;
10641#endif
5ff904cd 10642
c7e4ee3a
CB
10643 default:
10644 assert ("bad INTEGER constant kind type" == NULL);
10645 /* Fall through. */
10646 case FFEINFO_kindtypeANY:
10647 return error_mark_node;
10648 }
10649 item = build_int_2 (val, (val < 0) ? -1 : 0);
10650 TREE_TYPE (item) = tree_type;
10651 }
5ff904cd 10652 break;
5ff904cd 10653
c7e4ee3a
CB
10654 case FFEINFO_basictypeLOGICAL:
10655 {
10656 int val;
5ff904cd 10657
c7e4ee3a
CB
10658 switch (kt)
10659 {
10660#if FFETARGET_okLOGICAL1
10661 case FFEINFO_kindtypeLOGICAL1:
10662 val = ffebld_cu_val_logical1 (*cu);
10663 break;
5ff904cd 10664#endif
5ff904cd 10665
c7e4ee3a
CB
10666#if FFETARGET_okLOGICAL2
10667 case FFEINFO_kindtypeLOGICAL2:
10668 val = ffebld_cu_val_logical2 (*cu);
10669 break;
10670#endif
5ff904cd 10671
c7e4ee3a
CB
10672#if FFETARGET_okLOGICAL3
10673 case FFEINFO_kindtypeLOGICAL3:
10674 val = ffebld_cu_val_logical3 (*cu);
10675 break;
10676#endif
5ff904cd 10677
c7e4ee3a
CB
10678#if FFETARGET_okLOGICAL4
10679 case FFEINFO_kindtypeLOGICAL4:
10680 val = ffebld_cu_val_logical4 (*cu);
10681 break;
10682#endif
5ff904cd 10683
c7e4ee3a
CB
10684 default:
10685 assert ("bad LOGICAL constant kind type" == NULL);
10686 /* Fall through. */
10687 case FFEINFO_kindtypeANY:
10688 return error_mark_node;
10689 }
10690 item = build_int_2 (val, (val < 0) ? -1 : 0);
10691 TREE_TYPE (item) = tree_type;
10692 }
10693 break;
5ff904cd 10694
c7e4ee3a
CB
10695 case FFEINFO_basictypeREAL:
10696 {
10697 REAL_VALUE_TYPE val;
5ff904cd 10698
c7e4ee3a
CB
10699 switch (kt)
10700 {
10701#if FFETARGET_okREAL1
10702 case FFEINFO_kindtypeREAL1:
10703 val = ffetarget_value_real1 (ffebld_cu_val_real1 (*cu));
10704 break;
10705#endif
5ff904cd 10706
c7e4ee3a
CB
10707#if FFETARGET_okREAL2
10708 case FFEINFO_kindtypeREAL2:
10709 val = ffetarget_value_real2 (ffebld_cu_val_real2 (*cu));
10710 break;
10711#endif
5ff904cd 10712
c7e4ee3a
CB
10713#if FFETARGET_okREAL3
10714 case FFEINFO_kindtypeREAL3:
10715 val = ffetarget_value_real3 (ffebld_cu_val_real3 (*cu));
10716 break;
10717#endif
5ff904cd 10718
c7e4ee3a
CB
10719#if FFETARGET_okREAL4
10720 case FFEINFO_kindtypeREAL4:
10721 val = ffetarget_value_real4 (ffebld_cu_val_real4 (*cu));
10722 break;
10723#endif
5ff904cd 10724
c7e4ee3a
CB
10725 default:
10726 assert ("bad REAL constant kind type" == NULL);
10727 /* Fall through. */
10728 case FFEINFO_kindtypeANY:
10729 return error_mark_node;
10730 }
10731 item = build_real (tree_type, val);
10732 }
5ff904cd
JL
10733 break;
10734
c7e4ee3a
CB
10735 case FFEINFO_basictypeCOMPLEX:
10736 {
10737 REAL_VALUE_TYPE real;
10738 REAL_VALUE_TYPE imag;
10739 tree el_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
5ff904cd 10740
c7e4ee3a
CB
10741 switch (kt)
10742 {
10743#if FFETARGET_okCOMPLEX1
10744 case FFEINFO_kindtypeREAL1:
10745 real = ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu).real);
10746 imag = ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu).imaginary);
10747 break;
10748#endif
5ff904cd 10749
c7e4ee3a
CB
10750#if FFETARGET_okCOMPLEX2
10751 case FFEINFO_kindtypeREAL2:
10752 real = ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu).real);
10753 imag = ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu).imaginary);
10754 break;
10755#endif
5ff904cd 10756
c7e4ee3a
CB
10757#if FFETARGET_okCOMPLEX3
10758 case FFEINFO_kindtypeREAL3:
10759 real = ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu).real);
10760 imag = ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu).imaginary);
10761 break;
10762#endif
5ff904cd 10763
c7e4ee3a
CB
10764#if FFETARGET_okCOMPLEX4
10765 case FFEINFO_kindtypeREAL4:
10766 real = ffetarget_value_real4 (ffebld_cu_val_complex4 (*cu).real);
10767 imag = ffetarget_value_real4 (ffebld_cu_val_complex4 (*cu).imaginary);
10768 break;
10769#endif
5ff904cd 10770
c7e4ee3a
CB
10771 default:
10772 assert ("bad REAL constant kind type" == NULL);
10773 /* Fall through. */
10774 case FFEINFO_kindtypeANY:
10775 return error_mark_node;
10776 }
10777 item = ffecom_build_complex_constant_ (tree_type,
10778 build_real (el_type, real),
10779 build_real (el_type, imag));
10780 }
10781 break;
5ff904cd 10782
c7e4ee3a
CB
10783 case FFEINFO_basictypeCHARACTER:
10784 { /* Happens only in DATA and similar contexts. */
10785 ffetargetCharacter1 val;
5ff904cd 10786
c7e4ee3a
CB
10787 switch (kt)
10788 {
10789#if FFETARGET_okCHARACTER1
10790 case FFEINFO_kindtypeLOGICAL1:
10791 val = ffebld_cu_val_character1 (*cu);
10792 break;
10793#endif
10794
10795 default:
10796 assert ("bad CHARACTER constant kind type" == NULL);
10797 /* Fall through. */
10798 case FFEINFO_kindtypeANY:
10799 return error_mark_node;
10800 }
10801 item = build_string (ffetarget_length_character1 (val),
10802 ffetarget_text_character1 (val));
10803 TREE_TYPE (item)
10804 = build_type_variant (build_array_type (char_type_node,
10805 build_range_type
10806 (integer_type_node,
10807 integer_one_node,
10808 build_int_2
10809 (ffetarget_length_character1
10810 (val), 0))),
10811 1, 0);
10812 }
10813 break;
5ff904cd 10814
c7e4ee3a
CB
10815 case FFEINFO_basictypeHOLLERITH:
10816 {
10817 ffetargetHollerith h;
5ff904cd 10818
c7e4ee3a 10819 h = ffebld_cu_val_hollerith (*cu);
5ff904cd 10820
c7e4ee3a
CB
10821 /* If not at least as wide as default INTEGER, widen it. */
10822 if (h.length >= FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE)
10823 item = build_string (h.length, h.text);
10824 else
10825 {
10826 char str[FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE];
5ff904cd 10827
c7e4ee3a
CB
10828 memcpy (str, h.text, h.length);
10829 memset (&str[h.length], ' ',
10830 FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE
10831 - h.length);
10832 item = build_string (FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE,
10833 str);
10834 }
10835 TREE_TYPE (item)
10836 = build_type_variant (build_array_type (char_type_node,
10837 build_range_type
10838 (integer_type_node,
10839 integer_one_node,
10840 build_int_2
10841 (h.length, 0))),
10842 1, 0);
10843 }
10844 break;
5ff904cd 10845
c7e4ee3a
CB
10846 case FFEINFO_basictypeTYPELESS:
10847 {
10848 ffetargetInteger1 ival;
10849 ffetargetTypeless tless;
10850 ffebad error;
5ff904cd 10851
c7e4ee3a
CB
10852 tless = ffebld_cu_val_typeless (*cu);
10853 error = ffetarget_convert_integer1_typeless (&ival, tless);
10854 assert (error == FFEBAD);
5ff904cd 10855
c7e4ee3a
CB
10856 item = build_int_2 ((int) ival, 0);
10857 }
10858 break;
5ff904cd 10859
c7e4ee3a
CB
10860 default:
10861 assert ("not yet on constant type" == NULL);
10862 /* Fall through. */
10863 case FFEINFO_basictypeANY:
10864 return error_mark_node;
5ff904cd 10865 }
5ff904cd 10866
c7e4ee3a 10867 TREE_CONSTANT (item) = 1;
5ff904cd 10868
c7e4ee3a 10869 return item;
5ff904cd
JL
10870}
10871
10872#endif
10873
c7e4ee3a
CB
10874/* Transform expression into constant tree.
10875
10876 If the expression can be transformed into a tree that is constant,
10877 that is done, and the tree returned. Else NULL_TREE is returned.
10878
10879 That way, a caller can attempt to provide compile-time initialization
10880 of a variable and, if that fails, *then* choose to start a new block
10881 and resort to using temporaries, as appropriate. */
5ff904cd 10882
5ff904cd 10883tree
c7e4ee3a 10884ffecom_const_expr (ffebld expr)
5ff904cd 10885{
c7e4ee3a
CB
10886 if (! expr)
10887 return integer_zero_node;
5ff904cd 10888
c7e4ee3a 10889 if (ffebld_op (expr) == FFEBLD_opANY)
5ff904cd
JL
10890 return error_mark_node;
10891
c7e4ee3a
CB
10892 if (ffebld_arity (expr) == 0
10893 && (ffebld_op (expr) != FFEBLD_opSYMTER
10894#if NEWCOMMON
10895 /* ~~Enable once common/equivalence is handled properly? */
10896 || ffebld_where (expr) == FFEINFO_whereCOMMON
5ff904cd 10897#endif
c7e4ee3a
CB
10898 || ffebld_where (expr) == FFEINFO_whereGLOBAL
10899 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
10900 {
10901 tree t;
5ff904cd 10902
c7e4ee3a
CB
10903 t = ffecom_expr (expr);
10904 assert (TREE_CONSTANT (t));
10905 return t;
10906 }
5ff904cd 10907
c7e4ee3a 10908 return NULL_TREE;
5ff904cd
JL
10909}
10910
c7e4ee3a 10911/* Handy way to make a field in a struct/union. */
5ff904cd
JL
10912
10913#if FFECOM_targetCURRENT == FFECOM_targetGCC
10914tree
c7e4ee3a
CB
10915ffecom_decl_field (tree context, tree prevfield,
10916 const char *name, tree type)
5ff904cd 10917{
c7e4ee3a 10918 tree field;
5ff904cd 10919
c7e4ee3a
CB
10920 field = build_decl (FIELD_DECL, get_identifier (name), type);
10921 DECL_CONTEXT (field) = context;
8ba77681 10922 DECL_ALIGN (field) = 0;
11cf4d18 10923 DECL_USER_ALIGN (field) = 0;
c7e4ee3a
CB
10924 if (prevfield != NULL_TREE)
10925 TREE_CHAIN (prevfield) = field;
5ff904cd 10926
c7e4ee3a 10927 return field;
5ff904cd
JL
10928}
10929
10930#endif
5ff904cd 10931
c7e4ee3a
CB
10932void
10933ffecom_close_include (FILE *f)
10934{
10935#if FFECOM_GCC_INCLUDE
10936 ffecom_close_include_ (f);
10937#endif
10938}
5ff904cd 10939
c7e4ee3a
CB
10940int
10941ffecom_decode_include_option (char *spec)
10942{
10943#if FFECOM_GCC_INCLUDE
10944 return ffecom_decode_include_option_ (spec);
10945#else
10946 return 1;
10947#endif
10948}
5ff904cd 10949
c7e4ee3a 10950/* End a compound statement (block). */
5ff904cd
JL
10951
10952#if FFECOM_targetCURRENT == FFECOM_targetGCC
10953tree
c7e4ee3a 10954ffecom_end_compstmt (void)
5ff904cd 10955{
c7e4ee3a
CB
10956 return bison_rule_compstmt_ ();
10957}
10958#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
5ff904cd 10959
c7e4ee3a 10960/* ffecom_end_transition -- Perform end transition on all symbols
5ff904cd 10961
c7e4ee3a 10962 ffecom_end_transition();
5ff904cd 10963
c7e4ee3a 10964 Calls ffecom_sym_end_transition for each global and local symbol. */
5ff904cd 10965
c7e4ee3a
CB
10966void
10967ffecom_end_transition ()
10968{
10969#if FFECOM_targetCURRENT == FFECOM_targetGCC
10970 ffebld item;
5ff904cd 10971#endif
5ff904cd 10972
c7e4ee3a
CB
10973 if (ffe_is_ffedebug ())
10974 fprintf (dmpout, "; end_stmt_transition\n");
86fc7a6c 10975
c7e4ee3a
CB
10976#if FFECOM_targetCURRENT == FFECOM_targetGCC
10977 ffecom_list_blockdata_ = NULL;
10978 ffecom_list_common_ = NULL;
10979#endif
86fc7a6c 10980
c7e4ee3a
CB
10981 ffesymbol_drive (ffecom_sym_end_transition);
10982 if (ffe_is_ffedebug ())
10983 {
10984 ffestorag_report ();
10985#if FFECOM_targetCURRENT == FFECOM_targetFFE
10986 ffesymbol_report_all ();
10987#endif
10988 }
5ff904cd
JL
10989
10990#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
10991 ffecom_start_progunit_ ();
10992
10993 for (item = ffecom_list_blockdata_;
10994 item != NULL;
10995 item = ffebld_trail (item))
10996 {
10997 ffebld callee;
10998 ffesymbol s;
10999 tree dt;
11000 tree t;
11001 tree var;
c7e4ee3a
CB
11002 static int number = 0;
11003
11004 callee = ffebld_head (item);
11005 s = ffebld_symter (callee);
11006 t = ffesymbol_hook (s).decl_tree;
11007 if (t == NULL_TREE)
11008 {
11009 s = ffecom_sym_transform_ (s);
11010 t = ffesymbol_hook (s).decl_tree;
11011 }
5ff904cd 11012
c7e4ee3a 11013 dt = build_pointer_type (TREE_TYPE (t));
5ff904cd 11014
c7e4ee3a
CB
11015 var = build_decl (VAR_DECL,
11016 ffecom_get_invented_identifier ("__g77_forceload_%d",
14657de8 11017 number++),
c7e4ee3a
CB
11018 dt);
11019 DECL_EXTERNAL (var) = 0;
11020 TREE_STATIC (var) = 1;
11021 TREE_PUBLIC (var) = 0;
11022 DECL_INITIAL (var) = error_mark_node;
11023 TREE_USED (var) = 1;
5ff904cd 11024
c7e4ee3a 11025 var = start_decl (var, FALSE);
702edf1d 11026
c7e4ee3a 11027 t = ffecom_1 (ADDR_EXPR, dt, t);
5ff904cd 11028
c7e4ee3a 11029 finish_decl (var, t, FALSE);
c7e4ee3a
CB
11030 }
11031
11032 /* This handles any COMMON areas that weren't referenced but have, for
11033 example, important initial data. */
11034
11035 for (item = ffecom_list_common_;
11036 item != NULL;
11037 item = ffebld_trail (item))
11038 ffecom_transform_common_ (ffebld_symter (ffebld_head (item)));
11039
11040 ffecom_list_common_ = NULL;
5ff904cd 11041#endif
c7e4ee3a 11042}
5ff904cd 11043
c7e4ee3a 11044/* ffecom_exec_transition -- Perform exec transition on all symbols
5ff904cd 11045
c7e4ee3a 11046 ffecom_exec_transition();
5ff904cd 11047
c7e4ee3a
CB
11048 Calls ffecom_sym_exec_transition for each global and local symbol.
11049 Make sure error updating not inhibited. */
5ff904cd 11050
c7e4ee3a
CB
11051void
11052ffecom_exec_transition ()
11053{
11054 bool inhibited;
5ff904cd 11055
c7e4ee3a
CB
11056 if (ffe_is_ffedebug ())
11057 fprintf (dmpout, "; exec_stmt_transition\n");
5ff904cd 11058
c7e4ee3a
CB
11059 inhibited = ffebad_inhibit ();
11060 ffebad_set_inhibit (FALSE);
5ff904cd 11061
c7e4ee3a
CB
11062 ffesymbol_drive (ffecom_sym_exec_transition); /* Don't retract! */
11063 ffeequiv_exec_transition (); /* Handle all pending EQUIVALENCEs. */
11064 if (ffe_is_ffedebug ())
5ff904cd 11065 {
c7e4ee3a
CB
11066 ffestorag_report ();
11067#if FFECOM_targetCURRENT == FFECOM_targetFFE
11068 ffesymbol_report_all ();
11069#endif
11070 }
5ff904cd 11071
c7e4ee3a
CB
11072 if (inhibited)
11073 ffebad_set_inhibit (TRUE);
11074}
5ff904cd 11075
c7e4ee3a 11076/* Handle assignment statement.
5ff904cd 11077
c7e4ee3a
CB
11078 Convert dest and source using ffecom_expr, then join them
11079 with an ASSIGN op and pass the whole thing to expand_expr_stmt. */
5ff904cd 11080
c7e4ee3a
CB
11081#if FFECOM_targetCURRENT == FFECOM_targetGCC
11082void
11083ffecom_expand_let_stmt (ffebld dest, ffebld source)
11084{
11085 tree dest_tree;
11086 tree dest_length;
11087 tree source_tree;
11088 tree expr_tree;
5ff904cd 11089
c7e4ee3a
CB
11090 if (ffeinfo_basictype (ffebld_info (dest)) != FFEINFO_basictypeCHARACTER)
11091 {
11092 bool dest_used;
d6cd84e0 11093 tree assign_temp;
5ff904cd 11094
c7e4ee3a
CB
11095 /* This attempts to replicate the test below, but must not be
11096 true when the test below is false. (Always err on the side
11097 of creating unused temporaries, to avoid ICEs.) */
11098 if (ffebld_op (dest) != FFEBLD_opSYMTER
11099 || ((dest_tree = ffesymbol_hook (ffebld_symter (dest)).decl_tree)
11100 && (TREE_CODE (dest_tree) != VAR_DECL
11101 || TREE_ADDRESSABLE (dest_tree))))
11102 {
11103 ffecom_prepare_expr_ (source, dest);
11104 dest_used = TRUE;
11105 }
11106 else
11107 {
11108 ffecom_prepare_expr_ (source, NULL);
11109 dest_used = FALSE;
11110 }
5ff904cd 11111
c7e4ee3a 11112 ffecom_prepare_expr_w (NULL_TREE, dest);
5ff904cd 11113
d6cd84e0
CB
11114 /* For COMPLEX assignment like C1=C2, if partial overlap is possible,
11115 create a temporary through which the assignment is to take place,
11116 since MODIFY_EXPR doesn't handle partial overlap properly. */
11117 if (ffebld_basictype (dest) == FFEINFO_basictypeCOMPLEX
11118 && ffecom_possible_partial_overlap_ (dest, source))
11119 {
11120 assign_temp = ffecom_make_tempvar ("complex_let",
11121 ffecom_tree_type
11122 [ffebld_basictype (dest)]
11123 [ffebld_kindtype (dest)],
11124 FFETARGET_charactersizeNONE,
11125 -1);
11126 }
11127 else
11128 assign_temp = NULL_TREE;
11129
c7e4ee3a 11130 ffecom_prepare_end ();
5ff904cd 11131
c7e4ee3a
CB
11132 dest_tree = ffecom_expr_w (NULL_TREE, dest);
11133 if (dest_tree == error_mark_node)
11134 return;
5ff904cd 11135
c7e4ee3a
CB
11136 if ((TREE_CODE (dest_tree) != VAR_DECL)
11137 || TREE_ADDRESSABLE (dest_tree))
11138 source_tree = ffecom_expr_ (source, dest_tree, dest, &dest_used,
11139 FALSE, FALSE);
11140 else
11141 {
11142 assert (! dest_used);
11143 dest_used = FALSE;
11144 source_tree = ffecom_expr (source);
11145 }
11146 if (source_tree == error_mark_node)
11147 return;
5ff904cd 11148
c7e4ee3a
CB
11149 if (dest_used)
11150 expr_tree = source_tree;
d6cd84e0
CB
11151 else if (assign_temp)
11152 {
11153#ifdef MOVE_EXPR
11154 /* The back end understands a conceptual move (evaluate source;
11155 store into dest), so use that, in case it can determine
11156 that it is going to use, say, two registers as temporaries
11157 anyway. So don't use the temp (and someday avoid generating
11158 it, once this code starts triggering regularly). */
11159 expr_tree = ffecom_2s (MOVE_EXPR, void_type_node,
11160 dest_tree,
11161 source_tree);
11162#else
11163 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
11164 assign_temp,
11165 source_tree);
11166 expand_expr_stmt (expr_tree);
11167 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
11168 dest_tree,
11169 assign_temp);
11170#endif
11171 }
c7e4ee3a
CB
11172 else
11173 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
11174 dest_tree,
11175 source_tree);
5ff904cd 11176
c7e4ee3a
CB
11177 expand_expr_stmt (expr_tree);
11178 return;
11179 }
5ff904cd 11180
c7e4ee3a
CB
11181 ffecom_prepare_let_char_ (ffebld_size_known (dest), source);
11182 ffecom_prepare_expr_w (NULL_TREE, dest);
11183
11184 ffecom_prepare_end ();
11185
11186 ffecom_char_args_ (&dest_tree, &dest_length, dest);
11187 ffecom_let_char_ (dest_tree, dest_length, ffebld_size_known (dest),
11188 source);
5ff904cd
JL
11189}
11190
11191#endif
c7e4ee3a 11192/* ffecom_expr -- Transform expr into gcc tree
5ff904cd 11193
c7e4ee3a
CB
11194 tree t;
11195 ffebld expr; // FFE expression.
11196 tree = ffecom_expr(expr);
5ff904cd 11197
c7e4ee3a
CB
11198 Recursive descent on expr while making corresponding tree nodes and
11199 attaching type info and such. */
5ff904cd
JL
11200
11201#if FFECOM_targetCURRENT == FFECOM_targetGCC
11202tree
c7e4ee3a 11203ffecom_expr (ffebld expr)
5ff904cd 11204{
c7e4ee3a 11205 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, FALSE, FALSE);
5ff904cd 11206}
c7e4ee3a 11207
5ff904cd 11208#endif
c7e4ee3a 11209/* Like ffecom_expr, but return tree usable for assigned GOTO or FORMAT. */
5ff904cd 11210
c7e4ee3a
CB
11211#if FFECOM_targetCURRENT == FFECOM_targetGCC
11212tree
11213ffecom_expr_assign (ffebld expr)
11214{
11215 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, TRUE, FALSE);
11216}
5ff904cd 11217
c7e4ee3a
CB
11218#endif
11219/* Like ffecom_expr_rw, but return tree usable for ASSIGN. */
5ff904cd
JL
11220
11221#if FFECOM_targetCURRENT == FFECOM_targetGCC
11222tree
c7e4ee3a 11223ffecom_expr_assign_w (ffebld expr)
5ff904cd 11224{
c7e4ee3a
CB
11225 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, TRUE, FALSE);
11226}
5ff904cd 11227
5ff904cd 11228#endif
c7e4ee3a
CB
11229/* Transform expr for use as into read/write tree and stabilize the
11230 reference. Not for use on CHARACTER expressions.
5ff904cd 11231
c7e4ee3a
CB
11232 Recursive descent on expr while making corresponding tree nodes and
11233 attaching type info and such. */
5ff904cd 11234
c7e4ee3a
CB
11235#if FFECOM_targetCURRENT == FFECOM_targetGCC
11236tree
11237ffecom_expr_rw (tree type, ffebld expr)
11238{
11239 assert (expr != NULL);
11240 /* Different target types not yet supported. */
11241 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
11242
11243 return stabilize_reference (ffecom_expr (expr));
11244}
5ff904cd 11245
5ff904cd 11246#endif
c7e4ee3a
CB
11247/* Transform expr for use as into write tree and stabilize the
11248 reference. Not for use on CHARACTER expressions.
5ff904cd 11249
c7e4ee3a
CB
11250 Recursive descent on expr while making corresponding tree nodes and
11251 attaching type info and such. */
5ff904cd 11252
c7e4ee3a
CB
11253#if FFECOM_targetCURRENT == FFECOM_targetGCC
11254tree
11255ffecom_expr_w (tree type, ffebld expr)
11256{
11257 assert (expr != NULL);
11258 /* Different target types not yet supported. */
11259 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
11260
11261 return stabilize_reference (ffecom_expr (expr));
11262}
5ff904cd 11263
5ff904cd 11264#endif
c7e4ee3a
CB
11265/* Do global stuff. */
11266
11267#if FFECOM_targetCURRENT == FFECOM_targetGCC
11268void
11269ffecom_finish_compile ()
11270{
11271 assert (ffecom_outer_function_decl_ == NULL_TREE);
11272 assert (current_function_decl == NULL_TREE);
11273
11274 ffeglobal_drive (ffecom_finish_global_);
11275}
5ff904cd 11276
5ff904cd 11277#endif
c7e4ee3a
CB
11278/* Public entry point for front end to access finish_decl. */
11279
11280#if FFECOM_targetCURRENT == FFECOM_targetGCC
11281void
11282ffecom_finish_decl (tree decl, tree init, bool is_top_level)
11283{
11284 assert (!is_top_level);
11285 finish_decl (decl, init, FALSE);
11286}
5ff904cd 11287
5ff904cd 11288#endif
c7e4ee3a
CB
11289/* Finish a program unit. */
11290
11291#if FFECOM_targetCURRENT == FFECOM_targetGCC
11292void
11293ffecom_finish_progunit ()
11294{
11295 ffecom_end_compstmt ();
11296
11297 ffecom_previous_function_decl_ = current_function_decl;
11298 ffecom_which_entrypoint_decl_ = NULL_TREE;
11299
11300 finish_function (0);
11301}
5ff904cd 11302
5ff904cd 11303#endif
14657de8
KG
11304
11305/* Wrapper for get_identifier. pattern is sprintf-like. */
c7e4ee3a
CB
11306
11307#if FFECOM_targetCURRENT == FFECOM_targetGCC
11308tree
14657de8 11309ffecom_get_invented_identifier (const char *pattern, ...)
c7e4ee3a
CB
11310{
11311 tree decl;
11312 char *nam;
14657de8 11313 va_list ap;
c7e4ee3a 11314
14657de8
KG
11315 va_start (ap, pattern);
11316 if (vasprintf (&nam, pattern, ap) == 0)
11317 abort ();
11318 va_end (ap);
c7e4ee3a 11319 decl = get_identifier (nam);
14657de8 11320 free (nam);
c7e4ee3a 11321 IDENTIFIER_INVENTED (decl) = 1;
c7e4ee3a
CB
11322 return decl;
11323}
11324
11325ffeinfoBasictype
11326ffecom_gfrt_basictype (ffecomGfrt gfrt)
11327{
11328 assert (gfrt < FFECOM_gfrt);
11329
11330 switch (ffecom_gfrt_type_[gfrt])
11331 {
11332 case FFECOM_rttypeVOID_:
11333 case FFECOM_rttypeVOIDSTAR_:
11334 return FFEINFO_basictypeNONE;
11335
11336 case FFECOM_rttypeFTNINT_:
11337 return FFEINFO_basictypeINTEGER;
11338
11339 case FFECOM_rttypeINTEGER_:
11340 return FFEINFO_basictypeINTEGER;
11341
11342 case FFECOM_rttypeLONGINT_:
11343 return FFEINFO_basictypeINTEGER;
11344
11345 case FFECOM_rttypeLOGICAL_:
11346 return FFEINFO_basictypeLOGICAL;
11347
11348 case FFECOM_rttypeREAL_F2C_:
11349 case FFECOM_rttypeREAL_GNU_:
11350 return FFEINFO_basictypeREAL;
11351
11352 case FFECOM_rttypeCOMPLEX_F2C_:
11353 case FFECOM_rttypeCOMPLEX_GNU_:
11354 return FFEINFO_basictypeCOMPLEX;
11355
11356 case FFECOM_rttypeDOUBLE_:
11357 case FFECOM_rttypeDOUBLEREAL_:
11358 return FFEINFO_basictypeREAL;
11359
11360 case FFECOM_rttypeDBLCMPLX_F2C_:
11361 case FFECOM_rttypeDBLCMPLX_GNU_:
11362 return FFEINFO_basictypeCOMPLEX;
11363
11364 case FFECOM_rttypeCHARACTER_:
11365 return FFEINFO_basictypeCHARACTER;
11366
11367 default:
11368 return FFEINFO_basictypeANY;
11369 }
11370}
11371
11372ffeinfoKindtype
11373ffecom_gfrt_kindtype (ffecomGfrt gfrt)
11374{
11375 assert (gfrt < FFECOM_gfrt);
11376
11377 switch (ffecom_gfrt_type_[gfrt])
11378 {
11379 case FFECOM_rttypeVOID_:
11380 case FFECOM_rttypeVOIDSTAR_:
11381 return FFEINFO_kindtypeNONE;
5ff904cd 11382
c7e4ee3a
CB
11383 case FFECOM_rttypeFTNINT_:
11384 return FFEINFO_kindtypeINTEGER1;
5ff904cd 11385
c7e4ee3a
CB
11386 case FFECOM_rttypeINTEGER_:
11387 return FFEINFO_kindtypeINTEGER1;
5ff904cd 11388
c7e4ee3a
CB
11389 case FFECOM_rttypeLONGINT_:
11390 return FFEINFO_kindtypeINTEGER4;
5ff904cd 11391
c7e4ee3a
CB
11392 case FFECOM_rttypeLOGICAL_:
11393 return FFEINFO_kindtypeLOGICAL1;
5ff904cd 11394
c7e4ee3a
CB
11395 case FFECOM_rttypeREAL_F2C_:
11396 case FFECOM_rttypeREAL_GNU_:
11397 return FFEINFO_kindtypeREAL1;
5ff904cd 11398
c7e4ee3a
CB
11399 case FFECOM_rttypeCOMPLEX_F2C_:
11400 case FFECOM_rttypeCOMPLEX_GNU_:
11401 return FFEINFO_kindtypeREAL1;
5ff904cd 11402
c7e4ee3a
CB
11403 case FFECOM_rttypeDOUBLE_:
11404 case FFECOM_rttypeDOUBLEREAL_:
11405 return FFEINFO_kindtypeREAL2;
5ff904cd 11406
c7e4ee3a
CB
11407 case FFECOM_rttypeDBLCMPLX_F2C_:
11408 case FFECOM_rttypeDBLCMPLX_GNU_:
11409 return FFEINFO_kindtypeREAL2;
5ff904cd 11410
c7e4ee3a
CB
11411 case FFECOM_rttypeCHARACTER_:
11412 return FFEINFO_kindtypeCHARACTER1;
5ff904cd 11413
c7e4ee3a
CB
11414 default:
11415 return FFEINFO_kindtypeANY;
11416 }
11417}
5ff904cd 11418
c7e4ee3a
CB
11419void
11420ffecom_init_0 ()
11421{
11422 tree endlink;
11423 int i;
11424 int j;
11425 tree t;
11426 tree field;
11427 ffetype type;
11428 ffetype base_type;
7189a4b0
GK
11429 tree double_ftype_double;
11430 tree float_ftype_float;
11431 tree ldouble_ftype_ldouble;
11432 tree ffecom_tree_ptr_to_fun_type_void;
5ff904cd 11433
c7e4ee3a
CB
11434 /* This block of code comes from the now-obsolete cktyps.c. It checks
11435 whether the compiler environment is buggy in known ways, some of which
11436 would, if not explicitly checked here, result in subtle bugs in g77. */
5ff904cd 11437
c7e4ee3a
CB
11438 if (ffe_is_do_internal_checks ())
11439 {
11440 static char names[][12]
11441 =
11442 {"bar", "bletch", "foo", "foobar"};
11443 char *name;
11444 unsigned long ul;
11445 double fl;
5ff904cd 11446
c7e4ee3a 11447 name = bsearch ("foo", &names[0], ARRAY_SIZE (names), sizeof (names[0]),
b0791fa9 11448 (int (*)(const void *, const void *)) strcmp);
c7e4ee3a
CB
11449 if (name != (char *) &names[2])
11450 {
11451 assert ("bsearch doesn't work, #define FFEPROJ_BSEARCH 0 in proj.h"
11452 == NULL);
11453 abort ();
11454 }
5ff904cd 11455
c7e4ee3a
CB
11456 ul = strtoul ("123456789", NULL, 10);
11457 if (ul != 123456789L)
11458 {
11459 assert ("strtoul doesn't have enough range, #define FFEPROJ_STRTOUL 0\
11460 in proj.h" == NULL);
11461 abort ();
11462 }
5ff904cd 11463
c7e4ee3a
CB
11464 fl = atof ("56.789");
11465 if ((fl < 56.788) || (fl > 56.79))
11466 {
11467 assert ("atof not type double, fix your #include <stdio.h>"
11468 == NULL);
11469 abort ();
11470 }
11471 }
5ff904cd 11472
c7e4ee3a
CB
11473#if FFECOM_GCC_INCLUDE
11474 ffecom_initialize_char_syntax_ ();
11475#endif
5ff904cd 11476
c7e4ee3a
CB
11477 ffecom_outer_function_decl_ = NULL_TREE;
11478 current_function_decl = NULL_TREE;
11479 named_labels = NULL_TREE;
11480 current_binding_level = NULL_BINDING_LEVEL;
11481 free_binding_level = NULL_BINDING_LEVEL;
11482 /* Make the binding_level structure for global names. */
11483 pushlevel (0);
11484 global_binding_level = current_binding_level;
11485 current_binding_level->prep_state = 2;
5ff904cd 11486
81b3411c 11487 build_common_tree_nodes (1);
5ff904cd 11488
81b3411c 11489 /* Define `int' and `char' first so that dbx will output them first. */
c7e4ee3a
CB
11490 pushdecl (build_decl (TYPE_DECL, get_identifier ("int"),
11491 integer_type_node));
c7e4ee3a
CB
11492 pushdecl (build_decl (TYPE_DECL, get_identifier ("char"),
11493 char_type_node));
c7e4ee3a
CB
11494 pushdecl (build_decl (TYPE_DECL, get_identifier ("long int"),
11495 long_integer_type_node));
c7e4ee3a
CB
11496 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned int"),
11497 unsigned_type_node));
c7e4ee3a
CB
11498 pushdecl (build_decl (TYPE_DECL, get_identifier ("long unsigned int"),
11499 long_unsigned_type_node));
c7e4ee3a
CB
11500 pushdecl (build_decl (TYPE_DECL, get_identifier ("long long int"),
11501 long_long_integer_type_node));
c7e4ee3a
CB
11502 pushdecl (build_decl (TYPE_DECL, get_identifier ("long long unsigned int"),
11503 long_long_unsigned_type_node));
c7e4ee3a
CB
11504 pushdecl (build_decl (TYPE_DECL, get_identifier ("short int"),
11505 short_integer_type_node));
c7e4ee3a
CB
11506 pushdecl (build_decl (TYPE_DECL, get_identifier ("short unsigned int"),
11507 short_unsigned_type_node));
5ff904cd 11508
ff852b44
CB
11509 /* Set the sizetype before we make other types. This *should* be the
11510 first type we create. */
11511
11512 set_sizetype
11513 (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE))));
11514 ffecom_typesize_pointer_
11515 = TREE_INT_CST_LOW (TYPE_SIZE (sizetype)) / BITS_PER_UNIT;
11516
81b3411c 11517 build_common_tree_nodes_2 (0);
ff852b44 11518
c7e4ee3a 11519 /* Define both `signed char' and `unsigned char'. */
c7e4ee3a
CB
11520 pushdecl (build_decl (TYPE_DECL, get_identifier ("signed char"),
11521 signed_char_type_node));
5ff904cd 11522
c7e4ee3a
CB
11523 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned char"),
11524 unsigned_char_type_node));
5ff904cd 11525
c7e4ee3a
CB
11526 pushdecl (build_decl (TYPE_DECL, get_identifier ("float"),
11527 float_type_node));
c7e4ee3a
CB
11528 pushdecl (build_decl (TYPE_DECL, get_identifier ("double"),
11529 double_type_node));
c7e4ee3a
CB
11530 pushdecl (build_decl (TYPE_DECL, get_identifier ("long double"),
11531 long_double_type_node));
5ff904cd 11532
81b3411c 11533 /* For now, override what build_common_tree_nodes has done. */
c7e4ee3a 11534 complex_integer_type_node = ffecom_make_complex_type_ (integer_type_node);
81b3411c
BS
11535 complex_float_type_node = ffecom_make_complex_type_ (float_type_node);
11536 complex_double_type_node = ffecom_make_complex_type_ (double_type_node);
11537 complex_long_double_type_node
11538 = ffecom_make_complex_type_ (long_double_type_node);
11539
c7e4ee3a
CB
11540 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex int"),
11541 complex_integer_type_node));
c7e4ee3a
CB
11542 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex float"),
11543 complex_float_type_node));
c7e4ee3a
CB
11544 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex double"),
11545 complex_double_type_node));
c7e4ee3a
CB
11546 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex long double"),
11547 complex_long_double_type_node));
5ff904cd 11548
c7e4ee3a
CB
11549 pushdecl (build_decl (TYPE_DECL, get_identifier ("void"),
11550 void_type_node));
c7e4ee3a
CB
11551 /* We are not going to have real types in C with less than byte alignment,
11552 so we might as well not have any types that claim to have it. */
11553 TYPE_ALIGN (void_type_node) = BITS_PER_UNIT;
11cf4d18 11554 TYPE_USER_ALIGN (void_type_node) = 0;
5ff904cd 11555
c7e4ee3a 11556 string_type_node = build_pointer_type (char_type_node);
5ff904cd 11557
c7e4ee3a
CB
11558 ffecom_tree_fun_type_void
11559 = build_function_type (void_type_node, NULL_TREE);
5ff904cd 11560
c7e4ee3a
CB
11561 ffecom_tree_ptr_to_fun_type_void
11562 = build_pointer_type (ffecom_tree_fun_type_void);
5ff904cd 11563
c7e4ee3a 11564 endlink = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
5ff904cd 11565
c7e4ee3a
CB
11566 float_ftype_float
11567 = build_function_type (float_type_node,
11568 tree_cons (NULL_TREE, float_type_node, endlink));
5ff904cd 11569
c7e4ee3a
CB
11570 double_ftype_double
11571 = build_function_type (double_type_node,
11572 tree_cons (NULL_TREE, double_type_node, endlink));
5ff904cd 11573
c7e4ee3a
CB
11574 ldouble_ftype_ldouble
11575 = build_function_type (long_double_type_node,
11576 tree_cons (NULL_TREE, long_double_type_node,
11577 endlink));
5ff904cd 11578
c7e4ee3a
CB
11579 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11580 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11581 {
11582 ffecom_tree_type[i][j] = NULL_TREE;
11583 ffecom_tree_fun_type[i][j] = NULL_TREE;
11584 ffecom_tree_ptr_to_fun_type[i][j] = NULL_TREE;
11585 ffecom_f2c_typecode_[i][j] = -1;
11586 }
5ff904cd 11587
c7e4ee3a
CB
11588 /* Set up standard g77 types. Note that INTEGER and LOGICAL are set
11589 to size FLOAT_TYPE_SIZE because they have to be the same size as
11590 REAL, which also is FLOAT_TYPE_SIZE, according to the standard.
11591 Compiler options and other such stuff that change the ways these
11592 types are set should not affect this particular setup. */
5ff904cd 11593
c7e4ee3a
CB
11594 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER1]
11595 = t = make_signed_type (FLOAT_TYPE_SIZE);
11596 pushdecl (build_decl (TYPE_DECL, get_identifier ("integer"),
11597 t));
11598 type = ffetype_new ();
11599 base_type = type;
11600 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER1,
11601 type);
11602 ffetype_set_ams (type,
11603 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11604 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11605 ffetype_set_star (base_type,
11606 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11607 type);
11608 ffetype_set_kind (base_type, 1, type);
ff852b44 11609 ffecom_typesize_integer1_ = ffetype_size (type);
c7e4ee3a 11610 assert (ffetype_size (type) == sizeof (ffetargetInteger1));
5ff904cd 11611
c7e4ee3a
CB
11612 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER1]
11613 = t = make_unsigned_type (FLOAT_TYPE_SIZE); /* HOLLERITH means unsigned. */
11614 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned"),
11615 t));
5ff904cd 11616
c7e4ee3a
CB
11617 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER2]
11618 = t = make_signed_type (CHAR_TYPE_SIZE);
11619 pushdecl (build_decl (TYPE_DECL, get_identifier ("byte"),
11620 t));
11621 type = ffetype_new ();
11622 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER2,
11623 type);
11624 ffetype_set_ams (type,
11625 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11626 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11627 ffetype_set_star (base_type,
11628 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11629 type);
11630 ffetype_set_kind (base_type, 3, type);
11631 assert (ffetype_size (type) == sizeof (ffetargetInteger2));
5ff904cd 11632
c7e4ee3a
CB
11633 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER2]
11634 = t = make_unsigned_type (CHAR_TYPE_SIZE);
11635 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned byte"),
11636 t));
11637
11638 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER3]
11639 = t = make_signed_type (CHAR_TYPE_SIZE * 2);
11640 pushdecl (build_decl (TYPE_DECL, get_identifier ("word"),
11641 t));
11642 type = ffetype_new ();
11643 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER3,
11644 type);
11645 ffetype_set_ams (type,
11646 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11647 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11648 ffetype_set_star (base_type,
11649 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11650 type);
11651 ffetype_set_kind (base_type, 6, type);
11652 assert (ffetype_size (type) == sizeof (ffetargetInteger3));
5ff904cd 11653
c7e4ee3a
CB
11654 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER3]
11655 = t = make_unsigned_type (CHAR_TYPE_SIZE * 2);
11656 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned word"),
11657 t));
5ff904cd 11658
c7e4ee3a
CB
11659 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER4]
11660 = t = make_signed_type (FLOAT_TYPE_SIZE * 2);
11661 pushdecl (build_decl (TYPE_DECL, get_identifier ("integer4"),
11662 t));
11663 type = ffetype_new ();
11664 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER4,
11665 type);
11666 ffetype_set_ams (type,
11667 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11668 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11669 ffetype_set_star (base_type,
11670 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11671 type);
11672 ffetype_set_kind (base_type, 2, type);
11673 assert (ffetype_size (type) == sizeof (ffetargetInteger4));
5ff904cd 11674
c7e4ee3a
CB
11675 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER4]
11676 = t = make_unsigned_type (FLOAT_TYPE_SIZE * 2);
11677 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned4"),
11678 t));
5ff904cd 11679
c7e4ee3a
CB
11680#if 0
11681 if (ffe_is_do_internal_checks ()
11682 && LONG_TYPE_SIZE != FLOAT_TYPE_SIZE
11683 && LONG_TYPE_SIZE != CHAR_TYPE_SIZE
11684 && LONG_TYPE_SIZE != SHORT_TYPE_SIZE
11685 && LONG_TYPE_SIZE != LONG_LONG_TYPE_SIZE)
5ff904cd 11686 {
c7e4ee3a
CB
11687 fprintf (stderr, "Sorry, no g77 support for LONG_TYPE_SIZE (%d bits) yet.\n",
11688 LONG_TYPE_SIZE);
5ff904cd 11689 }
c7e4ee3a 11690#endif
5ff904cd 11691
c7e4ee3a
CB
11692 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL1]
11693 = t = make_signed_type (FLOAT_TYPE_SIZE);
11694 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical"),
11695 t));
11696 type = ffetype_new ();
11697 base_type = type;
11698 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL1,
11699 type);
11700 ffetype_set_ams (type,
11701 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11702 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11703 ffetype_set_star (base_type,
11704 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11705 type);
11706 ffetype_set_kind (base_type, 1, type);
11707 assert (ffetype_size (type) == sizeof (ffetargetLogical1));
5ff904cd 11708
c7e4ee3a
CB
11709 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL2]
11710 = t = make_signed_type (CHAR_TYPE_SIZE);
11711 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical2"),
11712 t));
11713 type = ffetype_new ();
11714 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL2,
11715 type);
11716 ffetype_set_ams (type,
11717 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11718 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11719 ffetype_set_star (base_type,
11720 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11721 type);
11722 ffetype_set_kind (base_type, 3, type);
11723 assert (ffetype_size (type) == sizeof (ffetargetLogical2));
5ff904cd 11724
c7e4ee3a
CB
11725 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL3]
11726 = t = make_signed_type (CHAR_TYPE_SIZE * 2);
11727 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical3"),
11728 t));
11729 type = ffetype_new ();
11730 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL3,
11731 type);
11732 ffetype_set_ams (type,
11733 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11734 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11735 ffetype_set_star (base_type,
11736 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11737 type);
11738 ffetype_set_kind (base_type, 6, type);
11739 assert (ffetype_size (type) == sizeof (ffetargetLogical3));
5ff904cd 11740
c7e4ee3a
CB
11741 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL4]
11742 = t = make_signed_type (FLOAT_TYPE_SIZE * 2);
11743 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical4"),
11744 t));
11745 type = ffetype_new ();
11746 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL4,
11747 type);
11748 ffetype_set_ams (type,
11749 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11750 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11751 ffetype_set_star (base_type,
11752 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11753 type);
11754 ffetype_set_kind (base_type, 2, type);
11755 assert (ffetype_size (type) == sizeof (ffetargetLogical4));
5ff904cd 11756
c7e4ee3a
CB
11757 ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]
11758 = t = make_node (REAL_TYPE);
11759 TYPE_PRECISION (t) = FLOAT_TYPE_SIZE;
11760 pushdecl (build_decl (TYPE_DECL, get_identifier ("real"),
11761 t));
11762 layout_type (t);
11763 type = ffetype_new ();
11764 base_type = type;
11765 ffeinfo_set_type (FFEINFO_basictypeREAL, FFEINFO_kindtypeREAL1,
11766 type);
11767 ffetype_set_ams (type,
11768 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11769 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11770 ffetype_set_star (base_type,
11771 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11772 type);
11773 ffetype_set_kind (base_type, 1, type);
11774 ffecom_f2c_typecode_[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]
11775 = FFETARGET_f2cTYREAL;
11776 assert (ffetype_size (type) == sizeof (ffetargetReal1));
5ff904cd 11777
c7e4ee3a
CB
11778 ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREALDOUBLE]
11779 = t = make_node (REAL_TYPE);
11780 TYPE_PRECISION (t) = FLOAT_TYPE_SIZE * 2; /* Always twice REAL. */
11781 pushdecl (build_decl (TYPE_DECL, get_identifier ("double precision"),
11782 t));
11783 layout_type (t);
11784 type = ffetype_new ();
11785 ffeinfo_set_type (FFEINFO_basictypeREAL, FFEINFO_kindtypeREALDOUBLE,
11786 type);
11787 ffetype_set_ams (type,
11788 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11789 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11790 ffetype_set_star (base_type,
11791 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11792 type);
11793 ffetype_set_kind (base_type, 2, type);
11794 ffecom_f2c_typecode_[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2]
11795 = FFETARGET_f2cTYDREAL;
11796 assert (ffetype_size (type) == sizeof (ffetargetReal2));
5ff904cd 11797
c7e4ee3a
CB
11798 ffecom_tree_type[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL1]
11799 = t = ffecom_make_complex_type_ (ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]);
11800 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex"),
11801 t));
11802 type = ffetype_new ();
11803 base_type = type;
11804 ffeinfo_set_type (FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREAL1,
11805 type);
11806 ffetype_set_ams (type,
11807 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11808 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11809 ffetype_set_star (base_type,
11810 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11811 type);
11812 ffetype_set_kind (base_type, 1, type);
11813 ffecom_f2c_typecode_[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL1]
11814 = FFETARGET_f2cTYCOMPLEX;
11815 assert (ffetype_size (type) == sizeof (ffetargetComplex1));
5ff904cd 11816
c7e4ee3a
CB
11817 ffecom_tree_type[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREALDOUBLE]
11818 = t = ffecom_make_complex_type_ (ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2]);
11819 pushdecl (build_decl (TYPE_DECL, get_identifier ("double complex"),
11820 t));
11821 type = ffetype_new ();
11822 ffeinfo_set_type (FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREALDOUBLE,
11823 type);
11824 ffetype_set_ams (type,
11825 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11826 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11827 ffetype_set_star (base_type,
11828 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11829 type);
11830 ffetype_set_kind (base_type, 2,
11831 type);
11832 ffecom_f2c_typecode_[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL2]
11833 = FFETARGET_f2cTYDCOMPLEX;
11834 assert (ffetype_size (type) == sizeof (ffetargetComplex2));
5ff904cd 11835
c7e4ee3a 11836 /* Make function and ptr-to-function types for non-CHARACTER types. */
5ff904cd 11837
c7e4ee3a
CB
11838 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11839 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11840 {
11841 if ((t = ffecom_tree_type[i][j]) != NULL_TREE)
11842 {
11843 if (i == FFEINFO_basictypeINTEGER)
11844 {
11845 /* Figure out the smallest INTEGER type that can hold
11846 a pointer on this machine. */
11847 if (GET_MODE_SIZE (TYPE_MODE (t))
11848 >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
11849 {
11850 if ((ffecom_pointer_kind_ == FFEINFO_kindtypeNONE)
11851 || (GET_MODE_SIZE (TYPE_MODE (ffecom_tree_type[i][ffecom_pointer_kind_]))
11852 > GET_MODE_SIZE (TYPE_MODE (t))))
11853 ffecom_pointer_kind_ = j;
11854 }
11855 }
11856 else if (i == FFEINFO_basictypeCOMPLEX)
11857 t = void_type_node;
11858 /* For f2c compatibility, REAL functions are really
11859 implemented as DOUBLE PRECISION. */
11860 else if ((i == FFEINFO_basictypeREAL)
11861 && (j == FFEINFO_kindtypeREAL1))
11862 t = ffecom_tree_type
11863 [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2];
5ff904cd 11864
c7e4ee3a
CB
11865 t = ffecom_tree_fun_type[i][j] = build_function_type (t,
11866 NULL_TREE);
11867 ffecom_tree_ptr_to_fun_type[i][j] = build_pointer_type (t);
11868 }
11869 }
5ff904cd 11870
c7e4ee3a 11871 /* Set up pointer types. */
5ff904cd 11872
c7e4ee3a
CB
11873 if (ffecom_pointer_kind_ == FFEINFO_basictypeNONE)
11874 fatal ("no INTEGER type can hold a pointer on this configuration");
11875 else if (0 && ffe_is_do_internal_checks ())
11876 fprintf (stderr, "Pointer type kt=%d\n", ffecom_pointer_kind_);
11877 ffetype_set_kind (ffeinfo_type (FFEINFO_basictypeINTEGER,
11878 FFEINFO_kindtypeINTEGERDEFAULT),
11879 7,
11880 ffeinfo_type (FFEINFO_basictypeINTEGER,
11881 ffecom_pointer_kind_));
5ff904cd 11882
c7e4ee3a
CB
11883 if (ffe_is_ugly_assign ())
11884 ffecom_label_kind_ = ffecom_pointer_kind_; /* Require ASSIGN etc to this. */
11885 else
11886 ffecom_label_kind_ = FFEINFO_kindtypeINTEGERDEFAULT;
11887 if (0 && ffe_is_do_internal_checks ())
11888 fprintf (stderr, "Label type kt=%d\n", ffecom_label_kind_);
5ff904cd 11889
c7e4ee3a
CB
11890 ffecom_integer_type_node
11891 = ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER1];
11892 ffecom_integer_zero_node = convert (ffecom_integer_type_node,
11893 integer_zero_node);
11894 ffecom_integer_one_node = convert (ffecom_integer_type_node,
11895 integer_one_node);
5ff904cd 11896
c7e4ee3a
CB
11897 /* Yes, the "FLOAT_TYPE_SIZE" references below are intentional.
11898 Turns out that by TYLONG, runtime/libI77/lio.h really means
11899 "whatever size an ftnint is". For consistency and sanity,
11900 com.h and runtime/f2c.h.in agree that flag, ftnint, and ftlen
11901 all are INTEGER, which we also make out of whatever back-end
11902 integer type is FLOAT_TYPE_SIZE bits wide. This change, from
11903 LONG_TYPE_SIZE, for TYLONG and TYLOGICAL, was necessary to
11904 accommodate machines like the Alpha. Note that this suggests
11905 f2c and libf2c are missing a distinction perhaps needed on
11906 some machines between "int" and "long int". -- burley 0.5.5 950215 */
5ff904cd 11907
c7e4ee3a
CB
11908 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, FLOAT_TYPE_SIZE,
11909 FFETARGET_f2cTYLONG);
11910 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, SHORT_TYPE_SIZE,
11911 FFETARGET_f2cTYSHORT);
11912 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, CHAR_TYPE_SIZE,
11913 FFETARGET_f2cTYINT1);
11914 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, LONG_LONG_TYPE_SIZE,
11915 FFETARGET_f2cTYQUAD);
11916 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, FLOAT_TYPE_SIZE,
11917 FFETARGET_f2cTYLOGICAL);
11918 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, SHORT_TYPE_SIZE,
11919 FFETARGET_f2cTYLOGICAL2);
11920 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, CHAR_TYPE_SIZE,
11921 FFETARGET_f2cTYLOGICAL1);
11922 /* ~~~Not really such a type in libf2c, e.g. I/O support? */
11923 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, LONG_LONG_TYPE_SIZE,
11924 FFETARGET_f2cTYQUAD);
5ff904cd 11925
c7e4ee3a
CB
11926 /* CHARACTER stuff is all special-cased, so it is not handled in the above
11927 loop. CHARACTER items are built as arrays of unsigned char. */
5ff904cd 11928
c7e4ee3a
CB
11929 ffecom_tree_type[FFEINFO_basictypeCHARACTER]
11930 [FFEINFO_kindtypeCHARACTER1] = t = char_type_node;
11931 type = ffetype_new ();
11932 base_type = type;
11933 ffeinfo_set_type (FFEINFO_basictypeCHARACTER,
11934 FFEINFO_kindtypeCHARACTER1,
11935 type);
11936 ffetype_set_ams (type,
11937 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11938 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11939 ffetype_set_kind (base_type, 1, type);
11940 assert (ffetype_size (type)
11941 == sizeof (((ffetargetCharacter1) { 0, NULL }).text[0]));
5ff904cd 11942
c7e4ee3a
CB
11943 ffecom_tree_fun_type[FFEINFO_basictypeCHARACTER]
11944 [FFEINFO_kindtypeCHARACTER1] = ffecom_tree_fun_type_void;
11945 ffecom_tree_ptr_to_fun_type[FFEINFO_basictypeCHARACTER]
11946 [FFEINFO_kindtypeCHARACTER1]
11947 = ffecom_tree_ptr_to_fun_type_void;
11948 ffecom_f2c_typecode_[FFEINFO_basictypeCHARACTER][FFEINFO_kindtypeCHARACTER1]
11949 = FFETARGET_f2cTYCHAR;
5ff904cd 11950
c7e4ee3a
CB
11951 ffecom_f2c_typecode_[FFEINFO_basictypeANY][FFEINFO_kindtypeANY]
11952 = 0;
5ff904cd 11953
c7e4ee3a 11954 /* Make multi-return-value type and fields. */
5ff904cd 11955
c7e4ee3a 11956 ffecom_multi_type_node_ = make_node (UNION_TYPE);
5ff904cd 11957
c7e4ee3a 11958 field = NULL_TREE;
5ff904cd 11959
c7e4ee3a
CB
11960 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11961 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11962 {
11963 char name[30];
5ff904cd 11964
c7e4ee3a
CB
11965 if (ffecom_tree_type[i][j] == NULL_TREE)
11966 continue; /* Not supported. */
11967 sprintf (&name[0], "bt_%s_kt_%s",
11968 ffeinfo_basictype_string ((ffeinfoBasictype) i),
11969 ffeinfo_kindtype_string ((ffeinfoKindtype) j));
11970 ffecom_multi_fields_[i][j] = build_decl (FIELD_DECL,
11971 get_identifier (name),
11972 ffecom_tree_type[i][j]);
11973 DECL_CONTEXT (ffecom_multi_fields_[i][j])
11974 = ffecom_multi_type_node_;
8ba77681 11975 DECL_ALIGN (ffecom_multi_fields_[i][j]) = 0;
11cf4d18 11976 DECL_USER_ALIGN (ffecom_multi_fields_[i][j]) = 0;
c7e4ee3a
CB
11977 TREE_CHAIN (ffecom_multi_fields_[i][j]) = field;
11978 field = ffecom_multi_fields_[i][j];
11979 }
5ff904cd 11980
c7e4ee3a
CB
11981 TYPE_FIELDS (ffecom_multi_type_node_) = field;
11982 layout_type (ffecom_multi_type_node_);
5ff904cd 11983
c7e4ee3a
CB
11984 /* Subroutines usually return integer because they might have alternate
11985 returns. */
5ff904cd 11986
c7e4ee3a
CB
11987 ffecom_tree_subr_type
11988 = build_function_type (integer_type_node, NULL_TREE);
11989 ffecom_tree_ptr_to_subr_type
11990 = build_pointer_type (ffecom_tree_subr_type);
11991 ffecom_tree_blockdata_type
11992 = build_function_type (void_type_node, NULL_TREE);
5ff904cd 11993
c7e4ee3a 11994 builtin_function ("__builtin_sqrtf", float_ftype_float,
26db82d8 11995 BUILT_IN_FSQRT, BUILT_IN_NORMAL, "sqrtf");
c7e4ee3a 11996 builtin_function ("__builtin_fsqrt", double_ftype_double,
26db82d8 11997 BUILT_IN_FSQRT, BUILT_IN_NORMAL, "sqrt");
c7e4ee3a 11998 builtin_function ("__builtin_sqrtl", ldouble_ftype_ldouble,
26db82d8 11999 BUILT_IN_FSQRT, BUILT_IN_NORMAL, "sqrtl");
c7e4ee3a 12000 builtin_function ("__builtin_sinf", float_ftype_float,
26db82d8 12001 BUILT_IN_SIN, BUILT_IN_NORMAL, "sinf");
c7e4ee3a 12002 builtin_function ("__builtin_sin", double_ftype_double,
26db82d8 12003 BUILT_IN_SIN, BUILT_IN_NORMAL, "sin");
c7e4ee3a 12004 builtin_function ("__builtin_sinl", ldouble_ftype_ldouble,
26db82d8 12005 BUILT_IN_SIN, BUILT_IN_NORMAL, "sinl");
c7e4ee3a 12006 builtin_function ("__builtin_cosf", float_ftype_float,
26db82d8 12007 BUILT_IN_COS, BUILT_IN_NORMAL, "cosf");
c7e4ee3a 12008 builtin_function ("__builtin_cos", double_ftype_double,
26db82d8 12009 BUILT_IN_COS, BUILT_IN_NORMAL, "cos");
c7e4ee3a 12010 builtin_function ("__builtin_cosl", ldouble_ftype_ldouble,
26db82d8 12011 BUILT_IN_COS, BUILT_IN_NORMAL, "cosl");
5ff904cd 12012
c7e4ee3a
CB
12013#if BUILT_FOR_270
12014 pedantic_lvalues = FALSE;
5ff904cd 12015#endif
5ff904cd 12016
c7e4ee3a
CB
12017 ffecom_f2c_make_type_ (&ffecom_f2c_integer_type_node,
12018 FFECOM_f2cINTEGER,
12019 "integer");
12020 ffecom_f2c_make_type_ (&ffecom_f2c_address_type_node,
12021 FFECOM_f2cADDRESS,
12022 "address");
12023 ffecom_f2c_make_type_ (&ffecom_f2c_real_type_node,
12024 FFECOM_f2cREAL,
12025 "real");
12026 ffecom_f2c_make_type_ (&ffecom_f2c_doublereal_type_node,
12027 FFECOM_f2cDOUBLEREAL,
12028 "doublereal");
12029 ffecom_f2c_make_type_ (&ffecom_f2c_complex_type_node,
12030 FFECOM_f2cCOMPLEX,
12031 "complex");
12032 ffecom_f2c_make_type_ (&ffecom_f2c_doublecomplex_type_node,
12033 FFECOM_f2cDOUBLECOMPLEX,
12034 "doublecomplex");
12035 ffecom_f2c_make_type_ (&ffecom_f2c_longint_type_node,
12036 FFECOM_f2cLONGINT,
12037 "longint");
12038 ffecom_f2c_make_type_ (&ffecom_f2c_logical_type_node,
12039 FFECOM_f2cLOGICAL,
12040 "logical");
12041 ffecom_f2c_make_type_ (&ffecom_f2c_flag_type_node,
12042 FFECOM_f2cFLAG,
12043 "flag");
12044 ffecom_f2c_make_type_ (&ffecom_f2c_ftnlen_type_node,
12045 FFECOM_f2cFTNLEN,
12046 "ftnlen");
12047 ffecom_f2c_make_type_ (&ffecom_f2c_ftnint_type_node,
12048 FFECOM_f2cFTNINT,
12049 "ftnint");
5ff904cd 12050
c7e4ee3a
CB
12051 ffecom_f2c_ftnlen_zero_node
12052 = convert (ffecom_f2c_ftnlen_type_node, integer_zero_node);
5ff904cd 12053
c7e4ee3a
CB
12054 ffecom_f2c_ftnlen_one_node
12055 = convert (ffecom_f2c_ftnlen_type_node, integer_one_node);
5ff904cd 12056
c7e4ee3a
CB
12057 ffecom_f2c_ftnlen_two_node = build_int_2 (2, 0);
12058 TREE_TYPE (ffecom_f2c_ftnlen_two_node) = ffecom_integer_type_node;
5ff904cd 12059
c7e4ee3a
CB
12060 ffecom_f2c_ptr_to_ftnlen_type_node
12061 = build_pointer_type (ffecom_f2c_ftnlen_type_node);
5ff904cd 12062
c7e4ee3a
CB
12063 ffecom_f2c_ptr_to_ftnint_type_node
12064 = build_pointer_type (ffecom_f2c_ftnint_type_node);
5ff904cd 12065
c7e4ee3a
CB
12066 ffecom_f2c_ptr_to_integer_type_node
12067 = build_pointer_type (ffecom_f2c_integer_type_node);
5ff904cd 12068
c7e4ee3a
CB
12069 ffecom_f2c_ptr_to_real_type_node
12070 = build_pointer_type (ffecom_f2c_real_type_node);
5ff904cd 12071
c7e4ee3a
CB
12072 ffecom_float_zero_ = build_real (float_type_node, dconst0);
12073 ffecom_double_zero_ = build_real (double_type_node, dconst0);
12074 {
12075 REAL_VALUE_TYPE point_5;
5ff904cd 12076
c7e4ee3a
CB
12077#ifdef REAL_ARITHMETIC
12078 REAL_ARITHMETIC (point_5, RDIV_EXPR, dconst1, dconst2);
12079#else
12080 point_5 = .5;
12081#endif
12082 ffecom_float_half_ = build_real (float_type_node, point_5);
12083 ffecom_double_half_ = build_real (double_type_node, point_5);
12084 }
5ff904cd 12085
c7e4ee3a 12086 /* Do "extern int xargc;". */
5ff904cd 12087
c7e4ee3a
CB
12088 ffecom_tree_xargc_ = build_decl (VAR_DECL,
12089 get_identifier ("f__xargc"),
12090 integer_type_node);
12091 DECL_EXTERNAL (ffecom_tree_xargc_) = 1;
12092 TREE_STATIC (ffecom_tree_xargc_) = 1;
12093 TREE_PUBLIC (ffecom_tree_xargc_) = 1;
12094 ffecom_tree_xargc_ = start_decl (ffecom_tree_xargc_, FALSE);
12095 finish_decl (ffecom_tree_xargc_, NULL_TREE, FALSE);
5ff904cd 12096
c7e4ee3a
CB
12097#if 0 /* This is being fixed, and seems to be working now. */
12098 if ((FLOAT_TYPE_SIZE != 32)
12099 || (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node))) != 32))
5ff904cd 12100 {
c7e4ee3a
CB
12101 warning ("configuration: REAL, INTEGER, and LOGICAL are %d bits wide,",
12102 (int) FLOAT_TYPE_SIZE);
12103 warning ("and pointers are %d bits wide, but g77 doesn't yet work",
12104 (int) TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node))));
12105 warning ("properly unless they all are 32 bits wide.");
12106 warning ("Please keep this in mind before you report bugs. g77 should");
12107 warning ("support non-32-bit machines better as of version 0.6.");
12108 }
12109#endif
5ff904cd 12110
c7e4ee3a
CB
12111#if 0 /* Code in ste.c that would crash has been commented out. */
12112 if (TYPE_PRECISION (ffecom_f2c_ftnlen_type_node)
12113 < TYPE_PRECISION (string_type_node))
12114 /* I/O will probably crash. */
12115 warning ("configuration: char * holds %d bits, but ftnlen only %d",
12116 TYPE_PRECISION (string_type_node),
12117 TYPE_PRECISION (ffecom_f2c_ftnlen_type_node));
12118#endif
5ff904cd 12119
c7e4ee3a
CB
12120#if 0 /* ASSIGN-related stuff has been changed to accommodate this. */
12121 if (TYPE_PRECISION (ffecom_integer_type_node)
12122 < TYPE_PRECISION (string_type_node))
12123 /* ASSIGN 10 TO I will crash. */
12124 warning ("configuration: char * holds %d bits, but INTEGER only %d --\n\
12125 ASSIGN statement might fail",
12126 TYPE_PRECISION (string_type_node),
12127 TYPE_PRECISION (ffecom_integer_type_node));
12128#endif
12129}
5ff904cd 12130
c7e4ee3a
CB
12131#endif
12132/* ffecom_init_2 -- Initialize
5ff904cd 12133
c7e4ee3a 12134 ffecom_init_2(); */
5ff904cd 12135
c7e4ee3a
CB
12136#if FFECOM_targetCURRENT == FFECOM_targetGCC
12137void
12138ffecom_init_2 ()
12139{
12140 assert (ffecom_outer_function_decl_ == NULL_TREE);
12141 assert (current_function_decl == NULL_TREE);
12142 assert (ffecom_which_entrypoint_decl_ == NULL_TREE);
5ff904cd 12143
c7e4ee3a
CB
12144 ffecom_master_arglist_ = NULL;
12145 ++ffecom_num_fns_;
12146 ffecom_primary_entry_ = NULL;
12147 ffecom_is_altreturning_ = FALSE;
12148 ffecom_func_result_ = NULL_TREE;
12149 ffecom_multi_retval_ = NULL_TREE;
12150}
5ff904cd 12151
c7e4ee3a
CB
12152#endif
12153/* ffecom_list_expr -- Transform list of exprs into gcc tree
5ff904cd 12154
c7e4ee3a
CB
12155 tree t;
12156 ffebld expr; // FFE opITEM list.
12157 tree = ffecom_list_expr(expr);
5ff904cd 12158
c7e4ee3a 12159 List of actual args is transformed into corresponding gcc backend list. */
5ff904cd 12160
c7e4ee3a
CB
12161#if FFECOM_targetCURRENT == FFECOM_targetGCC
12162tree
12163ffecom_list_expr (ffebld expr)
5ff904cd 12164{
c7e4ee3a
CB
12165 tree list;
12166 tree *plist = &list;
12167 tree trail = NULL_TREE; /* Append char length args here. */
12168 tree *ptrail = &trail;
12169 tree length;
5ff904cd 12170
c7e4ee3a 12171 while (expr != NULL)
5ff904cd 12172 {
c7e4ee3a 12173 tree texpr = ffecom_arg_expr (ffebld_head (expr), &length);
5ff904cd 12174
c7e4ee3a
CB
12175 if (texpr == error_mark_node)
12176 return error_mark_node;
5ff904cd 12177
c7e4ee3a
CB
12178 *plist = build_tree_list (NULL_TREE, texpr);
12179 plist = &TREE_CHAIN (*plist);
12180 expr = ffebld_trail (expr);
12181 if (length != NULL_TREE)
5ff904cd 12182 {
c7e4ee3a
CB
12183 *ptrail = build_tree_list (NULL_TREE, length);
12184 ptrail = &TREE_CHAIN (*ptrail);
5ff904cd
JL
12185 }
12186 }
12187
c7e4ee3a 12188 *plist = trail;
5ff904cd 12189
c7e4ee3a
CB
12190 return list;
12191}
5ff904cd 12192
c7e4ee3a
CB
12193#endif
12194/* ffecom_list_ptr_to_expr -- Transform list of exprs into gcc tree
5ff904cd 12195
c7e4ee3a
CB
12196 tree t;
12197 ffebld expr; // FFE opITEM list.
12198 tree = ffecom_list_ptr_to_expr(expr);
5ff904cd 12199
c7e4ee3a
CB
12200 List of actual args is transformed into corresponding gcc backend list for
12201 use in calling an external procedure (vs. a statement function). */
5ff904cd 12202
c7e4ee3a
CB
12203#if FFECOM_targetCURRENT == FFECOM_targetGCC
12204tree
12205ffecom_list_ptr_to_expr (ffebld expr)
12206{
12207 tree list;
12208 tree *plist = &list;
12209 tree trail = NULL_TREE; /* Append char length args here. */
12210 tree *ptrail = &trail;
12211 tree length;
5ff904cd 12212
c7e4ee3a
CB
12213 while (expr != NULL)
12214 {
12215 tree texpr = ffecom_arg_ptr_to_expr (ffebld_head (expr), &length);
5ff904cd 12216
c7e4ee3a
CB
12217 if (texpr == error_mark_node)
12218 return error_mark_node;
5ff904cd 12219
c7e4ee3a
CB
12220 *plist = build_tree_list (NULL_TREE, texpr);
12221 plist = &TREE_CHAIN (*plist);
12222 expr = ffebld_trail (expr);
12223 if (length != NULL_TREE)
12224 {
12225 *ptrail = build_tree_list (NULL_TREE, length);
12226 ptrail = &TREE_CHAIN (*ptrail);
12227 }
12228 }
5ff904cd 12229
c7e4ee3a 12230 *plist = trail;
5ff904cd 12231
c7e4ee3a
CB
12232 return list;
12233}
5ff904cd 12234
c7e4ee3a
CB
12235#endif
12236/* Obtain gcc's LABEL_DECL tree for label. */
5ff904cd 12237
c7e4ee3a
CB
12238#if FFECOM_targetCURRENT == FFECOM_targetGCC
12239tree
12240ffecom_lookup_label (ffelab label)
12241{
12242 tree glabel;
5ff904cd 12243
c7e4ee3a
CB
12244 if (ffelab_hook (label) == NULL_TREE)
12245 {
12246 char labelname[16];
5ff904cd 12247
c7e4ee3a
CB
12248 switch (ffelab_type (label))
12249 {
12250 case FFELAB_typeLOOPEND:
12251 case FFELAB_typeNOTLOOP:
12252 case FFELAB_typeENDIF:
12253 sprintf (labelname, "%" ffelabValue_f "u", ffelab_value (label));
12254 glabel = build_decl (LABEL_DECL, get_identifier (labelname),
12255 void_type_node);
12256 DECL_CONTEXT (glabel) = current_function_decl;
12257 DECL_MODE (glabel) = VOIDmode;
12258 break;
5ff904cd 12259
c7e4ee3a 12260 case FFELAB_typeFORMAT:
c7e4ee3a
CB
12261 glabel = build_decl (VAR_DECL,
12262 ffecom_get_invented_identifier
14657de8 12263 ("__g77_format_%d", (int) ffelab_value (label)),
c7e4ee3a
CB
12264 build_type_variant (build_array_type
12265 (char_type_node,
12266 NULL_TREE),
12267 1, 0));
12268 TREE_CONSTANT (glabel) = 1;
12269 TREE_STATIC (glabel) = 1;
12270 DECL_CONTEXT (glabel) = 0;
12271 DECL_INITIAL (glabel) = NULL;
12272 make_decl_rtl (glabel, NULL, 0);
12273 expand_decl (glabel);
5ff904cd 12274
7189a4b0 12275 ffecom_save_tree_forever (glabel);
5ff904cd 12276
c7e4ee3a 12277 break;
5ff904cd 12278
c7e4ee3a
CB
12279 case FFELAB_typeANY:
12280 glabel = error_mark_node;
12281 break;
5ff904cd 12282
c7e4ee3a
CB
12283 default:
12284 assert ("bad label type" == NULL);
12285 glabel = NULL;
12286 break;
12287 }
12288 ffelab_set_hook (label, glabel);
12289 }
12290 else
12291 {
12292 glabel = ffelab_hook (label);
12293 }
5ff904cd 12294
c7e4ee3a
CB
12295 return glabel;
12296}
5ff904cd 12297
c7e4ee3a
CB
12298#endif
12299/* Stabilizes the arguments. Don't use this if the lhs and rhs come from
12300 a single source specification (as in the fourth argument of MVBITS).
12301 If the type is NULL_TREE, the type of lhs is used to make the type of
12302 the MODIFY_EXPR. */
5ff904cd 12303
c7e4ee3a
CB
12304#if FFECOM_targetCURRENT == FFECOM_targetGCC
12305tree
12306ffecom_modify (tree newtype, tree lhs,
12307 tree rhs)
12308{
12309 if (lhs == error_mark_node || rhs == error_mark_node)
12310 return error_mark_node;
5ff904cd 12311
c7e4ee3a
CB
12312 if (newtype == NULL_TREE)
12313 newtype = TREE_TYPE (lhs);
5ff904cd 12314
c7e4ee3a
CB
12315 if (TREE_SIDE_EFFECTS (lhs))
12316 lhs = stabilize_reference (lhs);
5ff904cd 12317
c7e4ee3a
CB
12318 return ffecom_2s (MODIFY_EXPR, newtype, lhs, rhs);
12319}
5ff904cd 12320
c7e4ee3a 12321#endif
5ff904cd 12322
c7e4ee3a 12323/* Register source file name. */
5ff904cd 12324
c7e4ee3a 12325void
b0791fa9 12326ffecom_file (const char *name)
c7e4ee3a
CB
12327{
12328#if FFECOM_GCC_INCLUDE
12329 ffecom_file_ (name);
12330#endif
12331}
5ff904cd 12332
c7e4ee3a 12333/* ffecom_notify_init_storage -- An aggregate storage is now fully init'ed
5ff904cd 12334
c7e4ee3a
CB
12335 ffestorag st;
12336 ffecom_notify_init_storage(st);
5ff904cd 12337
c7e4ee3a
CB
12338 Gets called when all possible units in an aggregate storage area (a LOCAL
12339 with equivalences or a COMMON) have been initialized. The initialization
12340 info either is in ffestorag_init or, if that is NULL,
12341 ffestorag_accretion:
5ff904cd 12342
c7e4ee3a
CB
12343 ffestorag_init may contain an opCONTER or opARRTER. opCONTER may occur
12344 even for an array if the array is one element in length!
5ff904cd 12345
c7e4ee3a
CB
12346 ffestorag_accretion will contain an opACCTER. It is much like an
12347 opARRTER except it has an ffebit object in it instead of just a size.
12348 The back end can use the info in the ffebit object, if it wants, to
12349 reduce the amount of actual initialization, but in any case it should
12350 kill the ffebit object when done. Also, set accretion to NULL but
12351 init to a non-NULL value.
5ff904cd 12352
c7e4ee3a
CB
12353 After performing initialization, DO NOT set init to NULL, because that'll
12354 tell the front end it is ok for more initialization to happen. Instead,
12355 set init to an opANY expression or some such thing that you can use to
12356 tell that you've already initialized the object.
5ff904cd 12357
c7e4ee3a
CB
12358 27-Oct-91 JCB 1.1
12359 Support two-pass FFE. */
5ff904cd 12360
c7e4ee3a
CB
12361void
12362ffecom_notify_init_storage (ffestorag st)
12363{
12364 ffebld init; /* The initialization expression. */
12365#if 0 && FFECOM_targetCURRENT == FFECOM_targetGCC
12366 ffetargetOffset size; /* The size of the entity. */
12367 ffetargetAlign pad; /* Its initial padding. */
12368#endif
12369
12370 if (ffestorag_init (st) == NULL)
5ff904cd 12371 {
c7e4ee3a
CB
12372 init = ffestorag_accretion (st);
12373 assert (init != NULL);
12374 ffestorag_set_accretion (st, NULL);
12375 ffestorag_set_accretes (st, 0);
12376
12377#if 0 && FFECOM_targetCURRENT == FFECOM_targetGCC
12378 /* For GNU backend, just turn ACCTER into ARRTER and proceed. */
12379 size = ffebld_accter_size (init);
12380 pad = ffebld_accter_pad (init);
12381 ffebit_kill (ffebld_accter_bits (init));
12382 ffebld_set_op (init, FFEBLD_opARRTER);
12383 ffebld_set_arrter (init, ffebld_accter (init));
12384 ffebld_arrter_set_size (init, size);
12385 ffebld_arrter_set_pad (init, size);
12386#endif
12387
12388#if FFECOM_TWOPASS
12389 ffestorag_set_init (st, init);
12390#endif
5ff904cd 12391 }
c7e4ee3a
CB
12392#if FFECOM_ONEPASS
12393 else
12394 init = ffestorag_init (st);
5ff904cd
JL
12395#endif
12396
c7e4ee3a
CB
12397#if FFECOM_ONEPASS /* Process the inits, wipe 'em out. */
12398 ffestorag_set_init (st, ffebld_new_any ());
5ff904cd 12399
c7e4ee3a
CB
12400 if (ffebld_op (init) == FFEBLD_opANY)
12401 return; /* Oh, we already did this! */
5ff904cd 12402
c7e4ee3a
CB
12403#if FFECOM_targetCURRENT == FFECOM_targetFFE
12404 {
12405 ffesymbol s;
5ff904cd 12406
c7e4ee3a
CB
12407 if (ffestorag_symbol (st) != NULL)
12408 s = ffestorag_symbol (st);
12409 else
12410 s = ffestorag_typesymbol (st);
5ff904cd 12411
c7e4ee3a
CB
12412 fprintf (dmpout, "= initialize_storage \"%s\" ",
12413 (s != NULL) ? ffesymbol_text (s) : "(unnamed)");
12414 ffebld_dump (init);
12415 fputc ('\n', dmpout);
12416 }
12417#endif
5ff904cd 12418
c7e4ee3a
CB
12419#endif /* if FFECOM_ONEPASS */
12420}
5ff904cd 12421
c7e4ee3a 12422/* ffecom_notify_init_symbol -- A symbol is now fully init'ed
5ff904cd 12423
c7e4ee3a
CB
12424 ffesymbol s;
12425 ffecom_notify_init_symbol(s);
5ff904cd 12426
c7e4ee3a
CB
12427 Gets called when all possible units in a symbol (not placed in COMMON
12428 or involved in EQUIVALENCE, unless it as yet has no ffestorag object)
12429 have been initialized. The initialization info either is in
12430 ffesymbol_init or, if that is NULL, ffesymbol_accretion:
5ff904cd 12431
c7e4ee3a
CB
12432 ffesymbol_init may contain an opCONTER or opARRTER. opCONTER may occur
12433 even for an array if the array is one element in length!
5ff904cd 12434
c7e4ee3a
CB
12435 ffesymbol_accretion will contain an opACCTER. It is much like an
12436 opARRTER except it has an ffebit object in it instead of just a size.
12437 The back end can use the info in the ffebit object, if it wants, to
12438 reduce the amount of actual initialization, but in any case it should
12439 kill the ffebit object when done. Also, set accretion to NULL but
12440 init to a non-NULL value.
5ff904cd 12441
c7e4ee3a
CB
12442 After performing initialization, DO NOT set init to NULL, because that'll
12443 tell the front end it is ok for more initialization to happen. Instead,
12444 set init to an opANY expression or some such thing that you can use to
12445 tell that you've already initialized the object.
5ff904cd 12446
c7e4ee3a
CB
12447 27-Oct-91 JCB 1.1
12448 Support two-pass FFE. */
5ff904cd 12449
c7e4ee3a
CB
12450void
12451ffecom_notify_init_symbol (ffesymbol s)
12452{
12453 ffebld init; /* The initialization expression. */
12454#if 0 && FFECOM_targetCURRENT == FFECOM_targetGCC
12455 ffetargetOffset size; /* The size of the entity. */
12456 ffetargetAlign pad; /* Its initial padding. */
12457#endif
5ff904cd 12458
c7e4ee3a
CB
12459 if (ffesymbol_storage (s) == NULL)
12460 return; /* Do nothing until COMMON/EQUIVALENCE
12461 possibilities checked. */
5ff904cd 12462
c7e4ee3a
CB
12463 if ((ffesymbol_init (s) == NULL)
12464 && ((init = ffesymbol_accretion (s)) != NULL))
12465 {
12466 ffesymbol_set_accretion (s, NULL);
12467 ffesymbol_set_accretes (s, 0);
5ff904cd 12468
c7e4ee3a
CB
12469#if 0 && FFECOM_targetCURRENT == FFECOM_targetGCC
12470 /* For GNU backend, just turn ACCTER into ARRTER and proceed. */
12471 size = ffebld_accter_size (init);
12472 pad = ffebld_accter_pad (init);
12473 ffebit_kill (ffebld_accter_bits (init));
12474 ffebld_set_op (init, FFEBLD_opARRTER);
12475 ffebld_set_arrter (init, ffebld_accter (init));
12476 ffebld_arrter_set_size (init, size);
12477 ffebld_arrter_set_pad (init, size);
12478#endif
5ff904cd 12479
c7e4ee3a
CB
12480#if FFECOM_TWOPASS
12481 ffesymbol_set_init (s, init);
12482#endif
12483 }
12484#if FFECOM_ONEPASS
12485 else
12486 init = ffesymbol_init (s);
12487#endif
5ff904cd 12488
c7e4ee3a
CB
12489#if FFECOM_ONEPASS
12490 ffesymbol_set_init (s, ffebld_new_any ());
5ff904cd 12491
c7e4ee3a
CB
12492 if (ffebld_op (init) == FFEBLD_opANY)
12493 return; /* Oh, we already did this! */
5ff904cd 12494
c7e4ee3a
CB
12495#if FFECOM_targetCURRENT == FFECOM_targetFFE
12496 fprintf (dmpout, "= initialize_symbol \"%s\" ", ffesymbol_text (s));
12497 ffebld_dump (init);
12498 fputc ('\n', dmpout);
12499#endif
5ff904cd 12500
c7e4ee3a
CB
12501#endif /* if FFECOM_ONEPASS */
12502}
5ff904cd 12503
c7e4ee3a 12504/* ffecom_notify_primary_entry -- Learn which is the primary entry point
5ff904cd 12505
c7e4ee3a
CB
12506 ffesymbol s;
12507 ffecom_notify_primary_entry(s);
5ff904cd 12508
c7e4ee3a
CB
12509 Gets called when implicit or explicit PROGRAM statement seen or when
12510 FUNCTION, SUBROUTINE, or BLOCK DATA statement seen, with the primary
12511 global symbol that serves as the entry point. */
5ff904cd 12512
c7e4ee3a
CB
12513void
12514ffecom_notify_primary_entry (ffesymbol s)
12515{
12516 ffecom_primary_entry_ = s;
12517 ffecom_primary_entry_kind_ = ffesymbol_kind (s);
5ff904cd 12518
c7e4ee3a
CB
12519 if ((ffecom_primary_entry_kind_ == FFEINFO_kindFUNCTION)
12520 || (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE))
12521 ffecom_primary_entry_is_proc_ = TRUE;
12522 else
12523 ffecom_primary_entry_is_proc_ = FALSE;
5ff904cd 12524
c7e4ee3a
CB
12525 if (!ffe_is_silent ())
12526 {
12527 if (ffecom_primary_entry_kind_ == FFEINFO_kindPROGRAM)
12528 fprintf (stderr, "%s:\n", ffesymbol_text (s));
12529 else
12530 fprintf (stderr, " %s:\n", ffesymbol_text (s));
12531 }
5ff904cd 12532
c7e4ee3a
CB
12533#if FFECOM_targetCURRENT == FFECOM_targetGCC
12534 if (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE)
12535 {
12536 ffebld list;
12537 ffebld arg;
5ff904cd 12538
c7e4ee3a
CB
12539 for (list = ffesymbol_dummyargs (s);
12540 list != NULL;
12541 list = ffebld_trail (list))
12542 {
12543 arg = ffebld_head (list);
12544 if (ffebld_op (arg) == FFEBLD_opSTAR)
12545 {
12546 ffecom_is_altreturning_ = TRUE;
12547 break;
12548 }
12549 }
12550 }
12551#endif
12552}
5ff904cd 12553
c7e4ee3a
CB
12554FILE *
12555ffecom_open_include (char *name, ffewhereLine l, ffewhereColumn c)
12556{
12557#if FFECOM_GCC_INCLUDE
12558 return ffecom_open_include_ (name, l, c);
12559#else
12560 return fopen (name, "r");
5ff904cd 12561#endif
c7e4ee3a 12562}
5ff904cd 12563
c7e4ee3a 12564/* ffecom_ptr_to_expr -- Transform expr into gcc tree with & in front
5ff904cd 12565
c7e4ee3a
CB
12566 tree t;
12567 ffebld expr; // FFE expression.
12568 tree = ffecom_ptr_to_expr(expr);
5ff904cd 12569
c7e4ee3a 12570 Like ffecom_expr, but sticks address-of in front of most things. */
5ff904cd 12571
c7e4ee3a
CB
12572#if FFECOM_targetCURRENT == FFECOM_targetGCC
12573tree
12574ffecom_ptr_to_expr (ffebld expr)
12575{
12576 tree item;
12577 ffeinfoBasictype bt;
12578 ffeinfoKindtype kt;
12579 ffesymbol s;
5ff904cd 12580
c7e4ee3a 12581 assert (expr != NULL);
5ff904cd 12582
c7e4ee3a
CB
12583 switch (ffebld_op (expr))
12584 {
12585 case FFEBLD_opSYMTER:
12586 s = ffebld_symter (expr);
12587 if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC)
12588 {
12589 ffecomGfrt ix;
5ff904cd 12590
c7e4ee3a
CB
12591 ix = ffeintrin_gfrt_indirect (ffebld_symter_implementation (expr));
12592 assert (ix != FFECOM_gfrt);
12593 if ((item = ffecom_gfrt_[ix]) == NULL_TREE)
12594 {
12595 ffecom_make_gfrt_ (ix);
12596 item = ffecom_gfrt_[ix];
12597 }
12598 }
12599 else
12600 {
12601 item = ffesymbol_hook (s).decl_tree;
12602 if (item == NULL_TREE)
12603 {
12604 s = ffecom_sym_transform_ (s);
12605 item = ffesymbol_hook (s).decl_tree;
12606 }
12607 }
12608 assert (item != NULL);
12609 if (item == error_mark_node)
12610 return item;
12611 if (!ffesymbol_hook (s).addr)
12612 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12613 item);
12614 return item;
5ff904cd 12615
c7e4ee3a 12616 case FFEBLD_opARRAYREF:
ff852b44 12617 return ffecom_arrayref_ (NULL_TREE, expr, 1);
5ff904cd 12618
c7e4ee3a 12619 case FFEBLD_opCONTER:
5ff904cd 12620
c7e4ee3a
CB
12621 bt = ffeinfo_basictype (ffebld_info (expr));
12622 kt = ffeinfo_kindtype (ffebld_info (expr));
5ff904cd 12623
c7e4ee3a
CB
12624 item = ffecom_constantunion (&ffebld_constant_union
12625 (ffebld_conter (expr)), bt, kt,
12626 ffecom_tree_type[bt][kt]);
12627 if (item == error_mark_node)
12628 return error_mark_node;
12629 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12630 item);
12631 return item;
5ff904cd 12632
c7e4ee3a
CB
12633 case FFEBLD_opANY:
12634 return error_mark_node;
5ff904cd 12635
c7e4ee3a
CB
12636 default:
12637 bt = ffeinfo_basictype (ffebld_info (expr));
12638 kt = ffeinfo_kindtype (ffebld_info (expr));
12639
12640 item = ffecom_expr (expr);
12641 if (item == error_mark_node)
12642 return error_mark_node;
12643
12644 /* The back end currently optimizes a bit too zealously for us, in that
12645 we fail JCB001 if the following block of code is omitted. It checks
12646 to see if the transformed expression is a symbol or array reference,
12647 and encloses it in a SAVE_EXPR if that is the case. */
12648
12649 STRIP_NOPS (item);
12650 if ((TREE_CODE (item) == VAR_DECL)
12651 || (TREE_CODE (item) == PARM_DECL)
12652 || (TREE_CODE (item) == RESULT_DECL)
12653 || (TREE_CODE (item) == INDIRECT_REF)
12654 || (TREE_CODE (item) == ARRAY_REF)
12655 || (TREE_CODE (item) == COMPONENT_REF)
12656#ifdef OFFSET_REF
12657 || (TREE_CODE (item) == OFFSET_REF)
12658#endif
12659 || (TREE_CODE (item) == BUFFER_REF)
12660 || (TREE_CODE (item) == REALPART_EXPR)
12661 || (TREE_CODE (item) == IMAGPART_EXPR))
12662 {
12663 item = ffecom_save_tree (item);
12664 }
12665
12666 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12667 item);
12668 return item;
12669 }
12670
12671 assert ("fall-through error" == NULL);
12672 return error_mark_node;
5ff904cd
JL
12673}
12674
12675#endif
c7e4ee3a 12676/* Obtain a temp var with given data type.
5ff904cd 12677
c7e4ee3a
CB
12678 size is FFETARGET_charactersizeNONE for a non-CHARACTER type
12679 or >= 0 for a CHARACTER type.
5ff904cd 12680
c7e4ee3a 12681 elements is -1 for a scalar or > 0 for an array of type. */
5ff904cd
JL
12682
12683#if FFECOM_targetCURRENT == FFECOM_targetGCC
12684tree
c7e4ee3a
CB
12685ffecom_make_tempvar (const char *commentary, tree type,
12686 ffetargetCharacterSize size, int elements)
5ff904cd 12687{
c7e4ee3a
CB
12688 tree t;
12689 static int mynumber;
5ff904cd 12690
c7e4ee3a 12691 assert (current_binding_level->prep_state < 2);
702edf1d 12692
c7e4ee3a
CB
12693 if (type == error_mark_node)
12694 return error_mark_node;
702edf1d 12695
c7e4ee3a
CB
12696 if (size != FFETARGET_charactersizeNONE)
12697 type = build_array_type (type,
12698 build_range_type (ffecom_f2c_ftnlen_type_node,
12699 ffecom_f2c_ftnlen_one_node,
12700 build_int_2 (size, 0)));
12701 if (elements != -1)
12702 type = build_array_type (type,
12703 build_range_type (integer_type_node,
12704 integer_zero_node,
12705 build_int_2 (elements - 1,
12706 0)));
12707 t = build_decl (VAR_DECL,
12708 ffecom_get_invented_identifier ("__g77_%s_%d",
12709 commentary,
12710 mynumber++),
12711 type);
5ff904cd 12712
c7e4ee3a
CB
12713 t = start_decl (t, FALSE);
12714 finish_decl (t, NULL_TREE, FALSE);
12715
c7e4ee3a
CB
12716 return t;
12717}
5ff904cd 12718#endif
5ff904cd 12719
c7e4ee3a 12720/* Prepare argument pointer to expression.
5ff904cd 12721
c7e4ee3a
CB
12722 Like ffecom_prepare_expr, except for expressions to be evaluated
12723 via ffecom_arg_ptr_to_expr. */
5ff904cd 12724
c7e4ee3a
CB
12725void
12726ffecom_prepare_arg_ptr_to_expr (ffebld expr)
5ff904cd 12727{
c7e4ee3a
CB
12728 /* ~~For now, it seems to be the same thing. */
12729 ffecom_prepare_expr (expr);
12730 return;
12731}
702edf1d 12732
c7e4ee3a 12733/* End of preparations. */
702edf1d 12734
c7e4ee3a
CB
12735bool
12736ffecom_prepare_end (void)
12737{
12738 int prep_state = current_binding_level->prep_state;
5ff904cd 12739
c7e4ee3a
CB
12740 assert (prep_state < 2);
12741 current_binding_level->prep_state = 2;
5ff904cd 12742
c7e4ee3a 12743 return (prep_state == 1) ? TRUE : FALSE;
5ff904cd
JL
12744}
12745
c7e4ee3a 12746/* Prepare expression.
5ff904cd 12747
c7e4ee3a
CB
12748 This is called before any code is generated for the current block.
12749 It scans the expression, declares any temporaries that might be needed
12750 during evaluation of the expression, and stores those temporaries in
12751 the appropriate "hook" fields of the expression. `dest', if not NULL,
12752 specifies the destination that ffecom_expr_ will see, in case that
12753 helps avoid generating unused temporaries.
12754
12755 ~~Improve to avoid allocating unused temporaries by taking `dest'
12756 into account vis-a-vis aliasing requirements of complex/character
12757 functions. */
12758
12759void
12760ffecom_prepare_expr_ (ffebld expr, ffebld dest UNUSED)
5ff904cd 12761{
c7e4ee3a
CB
12762 ffeinfoBasictype bt;
12763 ffeinfoKindtype kt;
12764 ffetargetCharacterSize sz;
12765 tree tempvar = NULL_TREE;
5ff904cd 12766
c7e4ee3a
CB
12767 assert (current_binding_level->prep_state < 2);
12768
12769 if (! expr)
12770 return;
12771
12772 bt = ffeinfo_basictype (ffebld_info (expr));
12773 kt = ffeinfo_kindtype (ffebld_info (expr));
12774 sz = ffeinfo_size (ffebld_info (expr));
12775
12776 /* Generate whatever temporaries are needed to represent the result
12777 of the expression. */
12778
47d98fa2
CB
12779 if (bt == FFEINFO_basictypeCHARACTER)
12780 {
12781 while (ffebld_op (expr) == FFEBLD_opPAREN)
12782 expr = ffebld_left (expr);
12783 }
12784
c7e4ee3a 12785 switch (ffebld_op (expr))
5ff904cd 12786 {
c7e4ee3a
CB
12787 default:
12788 /* Don't make temps for SYMTER, CONTER, etc. */
12789 if (ffebld_arity (expr) == 0)
12790 break;
5ff904cd 12791
c7e4ee3a 12792 switch (bt)
5ff904cd 12793 {
c7e4ee3a
CB
12794 case FFEINFO_basictypeCOMPLEX:
12795 if (ffebld_op (expr) == FFEBLD_opFUNCREF)
12796 {
12797 ffesymbol s;
5ff904cd 12798
c7e4ee3a
CB
12799 if (ffebld_op (ffebld_left (expr)) != FFEBLD_opSYMTER)
12800 break;
5ff904cd 12801
c7e4ee3a
CB
12802 s = ffebld_symter (ffebld_left (expr));
12803 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT
68779408
CB
12804 || (ffesymbol_where (s) != FFEINFO_whereINTRINSIC
12805 && ! ffesymbol_is_f2c (s))
12806 || (ffesymbol_where (s) == FFEINFO_whereINTRINSIC
12807 && ! ffe_is_f2c_library ()))
c7e4ee3a
CB
12808 break;
12809 }
12810 else if (ffebld_op (expr) == FFEBLD_opPOWER)
12811 {
12812 /* Requires special treatment. There's no POW_CC function
12813 in libg2c, so POW_ZZ is used, which means we always
12814 need a double-complex temp, not a single-complex. */
12815 kt = FFEINFO_kindtypeREAL2;
12816 }
12817 else if (ffebld_op (expr) != FFEBLD_opDIVIDE)
12818 /* The other ops don't need temps for complex operands. */
12819 break;
5ff904cd 12820
c7e4ee3a
CB
12821 /* ~~~Avoid making temps for some intrinsics, such as AIMAG(C),
12822 REAL(C). See 19990325-0.f, routine `check', for cases. */
12823 tempvar = ffecom_make_tempvar ("complex",
12824 ffecom_tree_type
12825 [FFEINFO_basictypeCOMPLEX][kt],
12826 FFETARGET_charactersizeNONE,
12827 -1);
5ff904cd
JL
12828 break;
12829
c7e4ee3a
CB
12830 case FFEINFO_basictypeCHARACTER:
12831 if (ffebld_op (expr) != FFEBLD_opFUNCREF)
12832 break;
12833
12834 if (sz == FFETARGET_charactersizeNONE)
12835 /* ~~Kludge alert! This should someday be fixed. */
12836 sz = 24;
12837
12838 tempvar = ffecom_make_tempvar ("char", char_type_node, sz, -1);
5ff904cd
JL
12839 break;
12840
12841 default:
5ff904cd
JL
12842 break;
12843 }
c7e4ee3a 12844 break;
5ff904cd 12845
c7e4ee3a
CB
12846#ifdef HAHA
12847 case FFEBLD_opPOWER:
12848 {
12849 tree rtype, ltype;
12850 tree rtmp, ltmp, result;
5ff904cd 12851
c7e4ee3a
CB
12852 ltype = ffecom_type_expr (ffebld_left (expr));
12853 rtype = ffecom_type_expr (ffebld_right (expr));
5ff904cd 12854
c7e4ee3a
CB
12855 rtmp = ffecom_make_tempvar (rtype, FFETARGET_charactersizeNONE, -1);
12856 ltmp = ffecom_make_tempvar (ltype, FFETARGET_charactersizeNONE, -1);
12857 result = ffecom_make_tempvar (ltype, FFETARGET_charactersizeNONE, -1);
5ff904cd 12858
c7e4ee3a
CB
12859 tempvar = make_tree_vec (3);
12860 TREE_VEC_ELT (tempvar, 0) = rtmp;
12861 TREE_VEC_ELT (tempvar, 1) = ltmp;
12862 TREE_VEC_ELT (tempvar, 2) = result;
12863 }
12864 break;
12865#endif /* HAHA */
5ff904cd 12866
c7e4ee3a
CB
12867 case FFEBLD_opCONCATENATE:
12868 {
12869 /* This gets special handling, because only one set of temps
12870 is needed for a tree of these -- the tree is treated as
12871 a flattened list of concatenations when generating code. */
5ff904cd 12872
c7e4ee3a
CB
12873 ffecomConcatList_ catlist;
12874 tree ltmp, itmp, result;
12875 int count;
12876 int i;
5ff904cd 12877
c7e4ee3a
CB
12878 catlist = ffecom_concat_list_new_ (expr, FFETARGET_charactersizeNONE);
12879 count = ffecom_concat_list_count_ (catlist);
5ff904cd 12880
c7e4ee3a
CB
12881 if (count >= 2)
12882 {
12883 ltmp
12884 = ffecom_make_tempvar ("concat_len",
12885 ffecom_f2c_ftnlen_type_node,
12886 FFETARGET_charactersizeNONE, count);
12887 itmp
12888 = ffecom_make_tempvar ("concat_item",
12889 ffecom_f2c_address_type_node,
12890 FFETARGET_charactersizeNONE, count);
12891 result
12892 = ffecom_make_tempvar ("concat_res",
12893 char_type_node,
12894 ffecom_concat_list_maxlen_ (catlist),
12895 -1);
12896
12897 tempvar = make_tree_vec (3);
12898 TREE_VEC_ELT (tempvar, 0) = ltmp;
12899 TREE_VEC_ELT (tempvar, 1) = itmp;
12900 TREE_VEC_ELT (tempvar, 2) = result;
12901 }
5ff904cd 12902
c7e4ee3a
CB
12903 for (i = 0; i < count; ++i)
12904 ffecom_prepare_arg_ptr_to_expr (ffecom_concat_list_expr_ (catlist,
12905 i));
5ff904cd 12906
c7e4ee3a 12907 ffecom_concat_list_kill_ (catlist);
5ff904cd 12908
c7e4ee3a
CB
12909 if (tempvar)
12910 {
12911 ffebld_nonter_set_hook (expr, tempvar);
12912 current_binding_level->prep_state = 1;
12913 }
12914 }
12915 return;
5ff904cd 12916
c7e4ee3a
CB
12917 case FFEBLD_opCONVERT:
12918 if (bt == FFEINFO_basictypeCHARACTER
12919 && ((ffebld_size_known (ffebld_left (expr))
12920 == FFETARGET_charactersizeNONE)
12921 || (ffebld_size_known (ffebld_left (expr)) >= sz)))
12922 tempvar = ffecom_make_tempvar ("convert", char_type_node, sz, -1);
12923 break;
12924 }
5ff904cd 12925
c7e4ee3a
CB
12926 if (tempvar)
12927 {
12928 ffebld_nonter_set_hook (expr, tempvar);
12929 current_binding_level->prep_state = 1;
12930 }
5ff904cd 12931
c7e4ee3a 12932 /* Prepare subexpressions for this expr. */
5ff904cd 12933
c7e4ee3a 12934 switch (ffebld_op (expr))
5ff904cd 12935 {
c7e4ee3a
CB
12936 case FFEBLD_opPERCENT_LOC:
12937 ffecom_prepare_ptr_to_expr (ffebld_left (expr));
12938 break;
5ff904cd 12939
c7e4ee3a
CB
12940 case FFEBLD_opPERCENT_VAL:
12941 case FFEBLD_opPERCENT_REF:
12942 ffecom_prepare_expr (ffebld_left (expr));
12943 break;
5ff904cd 12944
c7e4ee3a
CB
12945 case FFEBLD_opPERCENT_DESCR:
12946 ffecom_prepare_arg_ptr_to_expr (ffebld_left (expr));
12947 break;
5ff904cd 12948
c7e4ee3a
CB
12949 case FFEBLD_opITEM:
12950 {
12951 ffebld item;
5ff904cd 12952
c7e4ee3a
CB
12953 for (item = expr;
12954 item != NULL;
12955 item = ffebld_trail (item))
12956 if (ffebld_head (item) != NULL)
12957 ffecom_prepare_expr (ffebld_head (item));
12958 }
12959 break;
5ff904cd 12960
c7e4ee3a
CB
12961 default:
12962 /* Need to handle character conversion specially. */
12963 switch (ffebld_arity (expr))
12964 {
12965 case 2:
12966 ffecom_prepare_expr (ffebld_left (expr));
12967 ffecom_prepare_expr (ffebld_right (expr));
12968 break;
5ff904cd 12969
c7e4ee3a
CB
12970 case 1:
12971 ffecom_prepare_expr (ffebld_left (expr));
12972 break;
5ff904cd 12973
c7e4ee3a
CB
12974 default:
12975 break;
12976 }
12977 }
5ff904cd 12978
c7e4ee3a 12979 return;
5ff904cd
JL
12980}
12981
c7e4ee3a 12982/* Prepare expression for reading and writing.
5ff904cd 12983
c7e4ee3a
CB
12984 Like ffecom_prepare_expr, except for expressions to be evaluated
12985 via ffecom_expr_rw. */
5ff904cd 12986
c7e4ee3a
CB
12987void
12988ffecom_prepare_expr_rw (tree type, ffebld expr)
12989{
12990 /* This is all we support for now. */
12991 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
5ff904cd 12992
c7e4ee3a
CB
12993 /* ~~For now, it seems to be the same thing. */
12994 ffecom_prepare_expr (expr);
12995 return;
12996}
5ff904cd 12997
c7e4ee3a 12998/* Prepare expression for writing.
5ff904cd 12999
c7e4ee3a
CB
13000 Like ffecom_prepare_expr, except for expressions to be evaluated
13001 via ffecom_expr_w. */
5ff904cd
JL
13002
13003void
c7e4ee3a 13004ffecom_prepare_expr_w (tree type, ffebld expr)
5ff904cd 13005{
c7e4ee3a
CB
13006 /* This is all we support for now. */
13007 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
5ff904cd 13008
c7e4ee3a
CB
13009 /* ~~For now, it seems to be the same thing. */
13010 ffecom_prepare_expr (expr);
13011 return;
13012}
5ff904cd 13013
c7e4ee3a 13014/* Prepare expression for returning.
5ff904cd 13015
c7e4ee3a
CB
13016 Like ffecom_prepare_expr, except for expressions to be evaluated
13017 via ffecom_return_expr. */
5ff904cd 13018
c7e4ee3a
CB
13019void
13020ffecom_prepare_return_expr (ffebld expr)
13021{
13022 assert (current_binding_level->prep_state < 2);
5ff904cd 13023
c7e4ee3a
CB
13024 if (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE
13025 && ffecom_is_altreturning_
13026 && expr != NULL)
13027 ffecom_prepare_expr (expr);
13028}
5ff904cd 13029
c7e4ee3a 13030/* Prepare pointer to expression.
5ff904cd 13031
c7e4ee3a
CB
13032 Like ffecom_prepare_expr, except for expressions to be evaluated
13033 via ffecom_ptr_to_expr. */
5ff904cd 13034
c7e4ee3a
CB
13035void
13036ffecom_prepare_ptr_to_expr (ffebld expr)
13037{
13038 /* ~~For now, it seems to be the same thing. */
13039 ffecom_prepare_expr (expr);
13040 return;
5ff904cd
JL
13041}
13042
c7e4ee3a 13043/* Transform expression into constant pointer-to-expression tree.
5ff904cd 13044
c7e4ee3a
CB
13045 If the expression can be transformed into a pointer-to-expression tree
13046 that is constant, that is done, and the tree returned. Else NULL_TREE
13047 is returned.
5ff904cd 13048
c7e4ee3a
CB
13049 That way, a caller can attempt to provide compile-time initialization
13050 of a variable and, if that fails, *then* choose to start a new block
13051 and resort to using temporaries, as appropriate. */
5ff904cd 13052
c7e4ee3a
CB
13053tree
13054ffecom_ptr_to_const_expr (ffebld expr)
5ff904cd 13055{
c7e4ee3a
CB
13056 if (! expr)
13057 return integer_zero_node;
5ff904cd 13058
c7e4ee3a
CB
13059 if (ffebld_op (expr) == FFEBLD_opANY)
13060 return error_mark_node;
5ff904cd 13061
c7e4ee3a
CB
13062 if (ffebld_arity (expr) == 0
13063 && (ffebld_op (expr) != FFEBLD_opSYMTER
13064 || ffebld_where (expr) == FFEINFO_whereCOMMON
13065 || ffebld_where (expr) == FFEINFO_whereGLOBAL
13066 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
5ff904cd 13067 {
c7e4ee3a
CB
13068 tree t;
13069
13070 t = ffecom_ptr_to_expr (expr);
13071 assert (TREE_CONSTANT (t));
13072 return t;
5ff904cd
JL
13073 }
13074
c7e4ee3a
CB
13075 return NULL_TREE;
13076}
13077
13078/* ffecom_return_expr -- Returns return-value expr given alt return expr
13079
13080 tree rtn; // NULL_TREE means use expand_null_return()
13081 ffebld expr; // NULL if no alt return expr to RETURN stmt
13082 rtn = ffecom_return_expr(expr);
13083
13084 Based on the program unit type and other info (like return function
13085 type, return master function type when alternate ENTRY points,
13086 whether subroutine has any alternate RETURN points, etc), returns the
13087 appropriate expression to be returned to the caller, or NULL_TREE
13088 meaning no return value or the caller expects it to be returned somewhere
13089 else (which is handled by other parts of this module). */
13090
5ff904cd 13091#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
13092tree
13093ffecom_return_expr (ffebld expr)
13094{
13095 tree rtn;
13096
13097 switch (ffecom_primary_entry_kind_)
5ff904cd 13098 {
c7e4ee3a
CB
13099 case FFEINFO_kindPROGRAM:
13100 case FFEINFO_kindBLOCKDATA:
13101 rtn = NULL_TREE;
13102 break;
5ff904cd 13103
c7e4ee3a
CB
13104 case FFEINFO_kindSUBROUTINE:
13105 if (!ffecom_is_altreturning_)
13106 rtn = NULL_TREE; /* No alt returns, never an expr. */
13107 else if (expr == NULL)
13108 rtn = integer_zero_node;
13109 else
13110 rtn = ffecom_expr (expr);
13111 break;
13112
13113 case FFEINFO_kindFUNCTION:
13114 if ((ffecom_multi_retval_ != NULL_TREE)
13115 || (ffesymbol_basictype (ffecom_primary_entry_)
13116 == FFEINFO_basictypeCHARACTER)
13117 || ((ffesymbol_basictype (ffecom_primary_entry_)
13118 == FFEINFO_basictypeCOMPLEX)
13119 && (ffecom_num_entrypoints_ == 0)
13120 && ffesymbol_is_f2c (ffecom_primary_entry_)))
13121 { /* Value is returned by direct assignment
13122 into (implicit) dummy. */
13123 rtn = NULL_TREE;
13124 break;
5ff904cd 13125 }
c7e4ee3a
CB
13126 rtn = ffecom_func_result_;
13127#if 0
13128 /* Spurious error if RETURN happens before first reference! So elide
13129 this code. In particular, for debugging registry, rtn should always
13130 be non-null after all, but TREE_USED won't be set until we encounter
13131 a reference in the code. Perfectly okay (but weird) code that,
13132 e.g., has "GOTO 20;10 RETURN;20 RTN=0;GOTO 10", would result in
13133 this diagnostic for no reason. Have people use -O -Wuninitialized
13134 and leave it to the back end to find obviously weird cases. */
5ff904cd 13135
c7e4ee3a
CB
13136 /* Used to "assert(rtn != NULL_TREE);" here, but it's kind of a valid
13137 situation; if the return value has never been referenced, it won't
13138 have a tree under 2pass mode. */
13139 if ((rtn == NULL_TREE)
13140 || !TREE_USED (rtn))
13141 {
13142 ffebad_start (FFEBAD_RETURN_VALUE_UNSET);
13143 ffebad_here (0, ffesymbol_where_line (ffecom_primary_entry_),
13144 ffesymbol_where_column (ffecom_primary_entry_));
13145 ffebad_string (ffesymbol_text (ffesymbol_funcresult
13146 (ffecom_primary_entry_)));
13147 ffebad_finish ();
13148 }
5ff904cd 13149#endif
c7e4ee3a 13150 break;
5ff904cd 13151
c7e4ee3a
CB
13152 default:
13153 assert ("bad unit kind" == NULL);
13154 case FFEINFO_kindANY:
13155 rtn = error_mark_node;
13156 break;
13157 }
5ff904cd 13158
c7e4ee3a
CB
13159 return rtn;
13160}
5ff904cd 13161
c7e4ee3a
CB
13162#endif
13163/* Do save_expr only if tree is not error_mark_node. */
5ff904cd
JL
13164
13165#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
13166tree
13167ffecom_save_tree (tree t)
5ff904cd 13168{
c7e4ee3a 13169 return save_expr (t);
5ff904cd 13170}
5ff904cd 13171#endif
c7e4ee3a
CB
13172
13173/* Start a compound statement (block). */
5ff904cd
JL
13174
13175#if FFECOM_targetCURRENT == FFECOM_targetGCC
13176void
c7e4ee3a 13177ffecom_start_compstmt (void)
5ff904cd 13178{
c7e4ee3a 13179 bison_rule_pushlevel_ ();
5ff904cd 13180}
c7e4ee3a 13181#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
5ff904cd 13182
c7e4ee3a 13183/* Public entry point for front end to access start_decl. */
5ff904cd
JL
13184
13185#if FFECOM_targetCURRENT == FFECOM_targetGCC
13186tree
c7e4ee3a 13187ffecom_start_decl (tree decl, bool is_initialized)
5ff904cd 13188{
c7e4ee3a
CB
13189 DECL_INITIAL (decl) = is_initialized ? error_mark_node : NULL_TREE;
13190 return start_decl (decl, FALSE);
13191}
5ff904cd 13192
c7e4ee3a
CB
13193#endif
13194/* ffecom_sym_commit -- Symbol's state being committed to reality
5ff904cd 13195
c7e4ee3a
CB
13196 ffesymbol s;
13197 ffecom_sym_commit(s);
5ff904cd 13198
c7e4ee3a
CB
13199 Does whatever the backend needs when a symbol is committed after having
13200 been backtrackable for a period of time. */
5ff904cd 13201
c7e4ee3a
CB
13202#if FFECOM_targetCURRENT == FFECOM_targetGCC
13203void
13204ffecom_sym_commit (ffesymbol s UNUSED)
13205{
13206 assert (!ffesymbol_retractable ());
13207}
5ff904cd 13208
c7e4ee3a
CB
13209#endif
13210/* ffecom_sym_end_transition -- Perform end transition on all symbols
5ff904cd 13211
c7e4ee3a 13212 ffecom_sym_end_transition();
5ff904cd 13213
c7e4ee3a
CB
13214 Does backend-specific stuff and also calls ffest_sym_end_transition
13215 to do the necessary FFE stuff.
5ff904cd 13216
c7e4ee3a
CB
13217 Backtracking is never enabled when this fn is called, so don't worry
13218 about it. */
5ff904cd 13219
c7e4ee3a
CB
13220ffesymbol
13221ffecom_sym_end_transition (ffesymbol s)
13222{
13223 ffestorag st;
5ff904cd 13224
c7e4ee3a 13225 assert (!ffesymbol_retractable ());
5ff904cd 13226
c7e4ee3a 13227 s = ffest_sym_end_transition (s);
5ff904cd 13228
c7e4ee3a
CB
13229#if FFECOM_targetCURRENT == FFECOM_targetGCC
13230 if ((ffesymbol_kind (s) == FFEINFO_kindBLOCKDATA)
13231 && (ffesymbol_where (s) == FFEINFO_whereGLOBAL))
13232 {
13233 ffecom_list_blockdata_
13234 = ffebld_new_item (ffebld_new_symter (s, FFEINTRIN_genNONE,
13235 FFEINTRIN_specNONE,
13236 FFEINTRIN_impNONE),
13237 ffecom_list_blockdata_);
5ff904cd 13238 }
5ff904cd 13239#endif
5ff904cd 13240
c7e4ee3a
CB
13241 /* This is where we finally notice that a symbol has partial initialization
13242 and finalize it. */
5ff904cd 13243
c7e4ee3a
CB
13244 if (ffesymbol_accretion (s) != NULL)
13245 {
13246 assert (ffesymbol_init (s) == NULL);
13247 ffecom_notify_init_symbol (s);
13248 }
13249 else if (((st = ffesymbol_storage (s)) != NULL)
13250 && ((st = ffestorag_parent (st)) != NULL)
13251 && (ffestorag_accretion (st) != NULL))
13252 {
13253 assert (ffestorag_init (st) == NULL);
13254 ffecom_notify_init_storage (st);
13255 }
5ff904cd
JL
13256
13257#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
13258 if ((ffesymbol_kind (s) == FFEINFO_kindCOMMON)
13259 && (ffesymbol_where (s) == FFEINFO_whereLOCAL)
13260 && (ffesymbol_storage (s) != NULL))
13261 {
13262 ffecom_list_common_
13263 = ffebld_new_item (ffebld_new_symter (s, FFEINTRIN_genNONE,
13264 FFEINTRIN_specNONE,
13265 FFEINTRIN_impNONE),
13266 ffecom_list_common_);
13267 }
13268#endif
5ff904cd 13269
c7e4ee3a
CB
13270 return s;
13271}
5ff904cd 13272
c7e4ee3a 13273/* ffecom_sym_exec_transition -- Perform exec transition on all symbols
5ff904cd 13274
c7e4ee3a 13275 ffecom_sym_exec_transition();
5ff904cd 13276
c7e4ee3a
CB
13277 Does backend-specific stuff and also calls ffest_sym_exec_transition
13278 to do the necessary FFE stuff.
5ff904cd 13279
c7e4ee3a
CB
13280 See the long-winded description in ffecom_sym_learned for info
13281 on handling the situation where backtracking is inhibited. */
5ff904cd 13282
c7e4ee3a
CB
13283ffesymbol
13284ffecom_sym_exec_transition (ffesymbol s)
13285{
13286 s = ffest_sym_exec_transition (s);
5ff904cd 13287
c7e4ee3a
CB
13288 return s;
13289}
5ff904cd 13290
c7e4ee3a 13291/* ffecom_sym_learned -- Initial or more info gained on symbol after exec
5ff904cd 13292
c7e4ee3a
CB
13293 ffesymbol s;
13294 s = ffecom_sym_learned(s);
5ff904cd 13295
c7e4ee3a
CB
13296 Called when a new symbol is seen after the exec transition or when more
13297 info (perhaps) is gained for an UNCERTAIN symbol. The symbol state when
13298 it arrives here is that all its latest info is updated already, so its
13299 state may be UNCERTAIN or UNDERSTOOD, it might already have the hook
13300 field filled in if its gone through here or exec_transition first, and
13301 so on.
5ff904cd 13302
c7e4ee3a
CB
13303 The backend probably wants to check ffesymbol_retractable() to see if
13304 backtracking is in effect. If so, the FFE's changes to the symbol may
13305 be retracted (undone) or committed (ratified), at which time the
13306 appropriate ffecom_sym_retract or _commit function will be called
13307 for that function.
5ff904cd 13308
c7e4ee3a
CB
13309 If the backend has its own backtracking mechanism, great, use it so that
13310 committal is a simple operation. Though it doesn't make much difference,
13311 I suppose: the reason for tentative symbol evolution in the FFE is to
13312 enable error detection in weird incorrect statements early and to disable
13313 incorrect error detection on a correct statement. The backend is not
13314 likely to introduce any information that'll get involved in these
13315 considerations, so it is probably just fine that the implementation
13316 model for this fn and for _exec_transition is to not do anything
13317 (besides the required FFE stuff) if ffesymbol_retractable() returns TRUE
13318 and instead wait until ffecom_sym_commit is called (which it never
13319 will be as long as we're using ambiguity-detecting statement analysis in
13320 the FFE, which we are initially to shake out the code, but don't depend
13321 on this), otherwise go ahead and do whatever is needed.
5ff904cd 13322
c7e4ee3a
CB
13323 In essence, then, when this fn and _exec_transition get called while
13324 backtracking is enabled, a general mechanism would be to flag which (or
13325 both) of these were called (and in what order? neat question as to what
13326 might happen that I'm too lame to think through right now) and then when
13327 _commit is called reproduce the original calling sequence, if any, for
13328 the two fns (at which point backtracking will, of course, be disabled). */
5ff904cd 13329
c7e4ee3a
CB
13330ffesymbol
13331ffecom_sym_learned (ffesymbol s)
13332{
13333 ffestorag_exec_layout (s);
5ff904cd 13334
c7e4ee3a 13335 return s;
5ff904cd
JL
13336}
13337
c7e4ee3a 13338/* ffecom_sym_retract -- Symbol's state being retracted from reality
5ff904cd 13339
c7e4ee3a
CB
13340 ffesymbol s;
13341 ffecom_sym_retract(s);
5ff904cd 13342
c7e4ee3a
CB
13343 Does whatever the backend needs when a symbol is retracted after having
13344 been backtrackable for a period of time. */
5ff904cd
JL
13345
13346#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
13347void
13348ffecom_sym_retract (ffesymbol s UNUSED)
5ff904cd 13349{
c7e4ee3a 13350 assert (!ffesymbol_retractable ());
5ff904cd 13351
c7e4ee3a
CB
13352#if 0 /* GCC doesn't commit any backtrackable sins,
13353 so nothing needed here. */
13354 switch (ffesymbol_hook (s).state)
5ff904cd 13355 {
c7e4ee3a 13356 case 0: /* nothing happened yet. */
5ff904cd
JL
13357 break;
13358
c7e4ee3a 13359 case 1: /* exec transition happened. */
5ff904cd
JL
13360 break;
13361
c7e4ee3a
CB
13362 case 2: /* learned happened. */
13363 break;
5ff904cd 13364
c7e4ee3a
CB
13365 case 3: /* learned then exec. */
13366 break;
13367
13368 case 4: /* exec then learned. */
5ff904cd
JL
13369 break;
13370
13371 default:
c7e4ee3a 13372 assert ("bad hook state" == NULL);
5ff904cd
JL
13373 break;
13374 }
c7e4ee3a
CB
13375#endif
13376}
5ff904cd 13377
c7e4ee3a
CB
13378#endif
13379/* Create temporary gcc label. */
13380
13381#if FFECOM_targetCURRENT == FFECOM_targetGCC
13382tree
13383ffecom_temp_label ()
13384{
13385 tree glabel;
13386 static int mynumber = 0;
13387
13388 glabel = build_decl (LABEL_DECL,
13389 ffecom_get_invented_identifier ("__g77_label_%d",
c7e4ee3a
CB
13390 mynumber++),
13391 void_type_node);
13392 DECL_CONTEXT (glabel) = current_function_decl;
13393 DECL_MODE (glabel) = VOIDmode;
13394
13395 return glabel;
5ff904cd
JL
13396}
13397
13398#endif
c7e4ee3a
CB
13399/* Return an expression that is usable as an arg in a conditional context
13400 (IF, DO WHILE, .NOT., and so on).
13401
13402 Use the one provided for the back end as of >2.6.0. */
5ff904cd
JL
13403
13404#if FFECOM_targetCURRENT == FFECOM_targetGCC
a2977d2d 13405tree
c7e4ee3a 13406ffecom_truth_value (tree expr)
5ff904cd 13407{
c7e4ee3a 13408 return truthvalue_conversion (expr);
5ff904cd 13409}
c7e4ee3a 13410
5ff904cd 13411#endif
c7e4ee3a
CB
13412/* Return the inversion of a truth value (the inversion of what
13413 ffecom_truth_value builds).
5ff904cd 13414
c7e4ee3a
CB
13415 Apparently invert_truthvalue, which is properly in the back end, is
13416 enough for now, so just use it. */
5ff904cd
JL
13417
13418#if FFECOM_targetCURRENT == FFECOM_targetGCC
13419tree
c7e4ee3a 13420ffecom_truth_value_invert (tree expr)
5ff904cd 13421{
c7e4ee3a 13422 return invert_truthvalue (ffecom_truth_value (expr));
5ff904cd
JL
13423}
13424
13425#endif
5ff904cd 13426
c7e4ee3a
CB
13427/* Return the tree that is the type of the expression, as would be
13428 returned in TREE_TYPE(ffecom_expr(expr)), without otherwise
13429 transforming the expression, generating temporaries, etc. */
5ff904cd 13430
c7e4ee3a
CB
13431tree
13432ffecom_type_expr (ffebld expr)
13433{
13434 ffeinfoBasictype bt;
13435 ffeinfoKindtype kt;
13436 tree tree_type;
13437
13438 assert (expr != NULL);
13439
13440 bt = ffeinfo_basictype (ffebld_info (expr));
13441 kt = ffeinfo_kindtype (ffebld_info (expr));
13442 tree_type = ffecom_tree_type[bt][kt];
13443
13444 switch (ffebld_op (expr))
13445 {
13446 case FFEBLD_opCONTER:
13447 case FFEBLD_opSYMTER:
13448 case FFEBLD_opARRAYREF:
13449 case FFEBLD_opUPLUS:
13450 case FFEBLD_opPAREN:
13451 case FFEBLD_opUMINUS:
13452 case FFEBLD_opADD:
13453 case FFEBLD_opSUBTRACT:
13454 case FFEBLD_opMULTIPLY:
13455 case FFEBLD_opDIVIDE:
13456 case FFEBLD_opPOWER:
13457 case FFEBLD_opNOT:
13458 case FFEBLD_opFUNCREF:
13459 case FFEBLD_opSUBRREF:
13460 case FFEBLD_opAND:
13461 case FFEBLD_opOR:
13462 case FFEBLD_opXOR:
13463 case FFEBLD_opNEQV:
13464 case FFEBLD_opEQV:
13465 case FFEBLD_opCONVERT:
13466 case FFEBLD_opLT:
13467 case FFEBLD_opLE:
13468 case FFEBLD_opEQ:
13469 case FFEBLD_opNE:
13470 case FFEBLD_opGT:
13471 case FFEBLD_opGE:
13472 case FFEBLD_opPERCENT_LOC:
13473 return tree_type;
13474
13475 case FFEBLD_opACCTER:
13476 case FFEBLD_opARRTER:
13477 case FFEBLD_opITEM:
13478 case FFEBLD_opSTAR:
13479 case FFEBLD_opBOUNDS:
13480 case FFEBLD_opREPEAT:
13481 case FFEBLD_opLABTER:
13482 case FFEBLD_opLABTOK:
13483 case FFEBLD_opIMPDO:
13484 case FFEBLD_opCONCATENATE:
13485 case FFEBLD_opSUBSTR:
13486 default:
13487 assert ("bad op for ffecom_type_expr" == NULL);
13488 /* Fall through. */
13489 case FFEBLD_opANY:
13490 return error_mark_node;
13491 }
13492}
13493
13494/* Return PARM_DECL for arg#1 of master fn containing alternate ENTRY points
13495
13496 If the PARM_DECL already exists, return it, else create it. It's an
13497 integer_type_node argument for the master function that implements a
13498 subroutine or function with more than one entrypoint and is bound at
13499 run time with the entrypoint number (0 for SUBROUTINE/FUNCTION, 1 for
13500 first ENTRY statement, and so on). */
5ff904cd
JL
13501
13502#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
13503tree
13504ffecom_which_entrypoint_decl ()
5ff904cd 13505{
c7e4ee3a
CB
13506 assert (ffecom_which_entrypoint_decl_ != NULL_TREE);
13507
13508 return ffecom_which_entrypoint_decl_;
5ff904cd
JL
13509}
13510
13511#endif
c7e4ee3a
CB
13512\f
13513/* The following sections consists of private and public functions
13514 that have the same names and perform roughly the same functions
13515 as counterparts in the C front end. Changes in the C front end
13516 might affect how things should be done here. Only functions
13517 needed by the back end should be public here; the rest should
13518 be private (static in the C sense). Functions needed by other
13519 g77 front-end modules should be accessed by them via public
13520 ffecom_* names, which should themselves call private versions
13521 in this section so the private versions are easy to recognize
13522 when upgrading to a new gcc and finding interesting changes
13523 in the front end.
5ff904cd 13524
c7e4ee3a
CB
13525 Functions named after rule "foo:" in c-parse.y are named
13526 "bison_rule_foo_" so they are easy to find. */
5ff904cd 13527
c7e4ee3a 13528#if FFECOM_targetCURRENT == FFECOM_targetGCC
5ff904cd 13529
c7e4ee3a
CB
13530static void
13531bison_rule_pushlevel_ ()
13532{
13533 emit_line_note (input_filename, lineno);
13534 pushlevel (0);
13535 clear_last_expr ();
c7e4ee3a
CB
13536 expand_start_bindings (0);
13537}
5ff904cd 13538
c7e4ee3a
CB
13539static tree
13540bison_rule_compstmt_ ()
5ff904cd 13541{
c7e4ee3a
CB
13542 tree t;
13543 int keep = kept_level_p ();
5ff904cd 13544
c7e4ee3a
CB
13545 /* Make the temps go away. */
13546 if (! keep)
13547 current_binding_level->names = NULL_TREE;
5ff904cd 13548
c7e4ee3a
CB
13549 emit_line_note (input_filename, lineno);
13550 expand_end_bindings (getdecls (), keep, 0);
13551 t = poplevel (keep, 1, 0);
5ff904cd 13552
c7e4ee3a
CB
13553 return t;
13554}
5ff904cd 13555
c7e4ee3a
CB
13556/* Return a definition for a builtin function named NAME and whose data type
13557 is TYPE. TYPE should be a function type with argument types.
13558 FUNCTION_CODE tells later passes how to compile calls to this function.
13559 See tree.h for its possible values.
5ff904cd 13560
c7e4ee3a
CB
13561 If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME,
13562 the name to be called if we can't opencode the function. */
5ff904cd 13563
26db82d8
BS
13564tree
13565builtin_function (const char *name, tree type, int function_code,
13566 enum built_in_class class,
c7e4ee3a
CB
13567 const char *library_name)
13568{
13569 tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
13570 DECL_EXTERNAL (decl) = 1;
13571 TREE_PUBLIC (decl) = 1;
13572 if (library_name)
13573 DECL_ASSEMBLER_NAME (decl) = get_identifier (library_name);
13574 make_decl_rtl (decl, NULL_PTR, 1);
13575 pushdecl (decl);
26db82d8
BS
13576 DECL_BUILT_IN_CLASS (decl) = class;
13577 DECL_FUNCTION_CODE (decl) = function_code;
5ff904cd 13578
c7e4ee3a 13579 return decl;
5ff904cd
JL
13580}
13581
c7e4ee3a
CB
13582/* Handle when a new declaration NEWDECL
13583 has the same name as an old one OLDDECL
13584 in the same binding contour.
13585 Prints an error message if appropriate.
5ff904cd 13586
c7e4ee3a
CB
13587 If safely possible, alter OLDDECL to look like NEWDECL, and return 1.
13588 Otherwise, return 0. */
5ff904cd 13589
c7e4ee3a
CB
13590static int
13591duplicate_decls (tree newdecl, tree olddecl)
5ff904cd 13592{
c7e4ee3a
CB
13593 int types_match = 1;
13594 int new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL
13595 && DECL_INITIAL (newdecl) != 0);
13596 tree oldtype = TREE_TYPE (olddecl);
13597 tree newtype = TREE_TYPE (newdecl);
5ff904cd 13598
c7e4ee3a
CB
13599 if (olddecl == newdecl)
13600 return 1;
5ff904cd 13601
c7e4ee3a
CB
13602 if (TREE_CODE (newtype) == ERROR_MARK
13603 || TREE_CODE (oldtype) == ERROR_MARK)
13604 types_match = 0;
5ff904cd 13605
c7e4ee3a
CB
13606 /* New decl is completely inconsistent with the old one =>
13607 tell caller to replace the old one.
13608 This is always an error except in the case of shadowing a builtin. */
13609 if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
13610 return 0;
5ff904cd 13611
c7e4ee3a
CB
13612 /* For real parm decl following a forward decl,
13613 return 1 so old decl will be reused. */
13614 if (types_match && TREE_CODE (newdecl) == PARM_DECL
13615 && TREE_ASM_WRITTEN (olddecl) && ! TREE_ASM_WRITTEN (newdecl))
13616 return 1;
5ff904cd 13617
c7e4ee3a
CB
13618 /* The new declaration is the same kind of object as the old one.
13619 The declarations may partially match. Print warnings if they don't
13620 match enough. Ultimately, copy most of the information from the new
13621 decl to the old one, and keep using the old one. */
5ff904cd 13622
c7e4ee3a
CB
13623 if (TREE_CODE (olddecl) == FUNCTION_DECL
13624 && DECL_BUILT_IN (olddecl))
13625 {
13626 /* A function declaration for a built-in function. */
13627 if (!TREE_PUBLIC (newdecl))
13628 return 0;
13629 else if (!types_match)
13630 {
13631 /* Accept the return type of the new declaration if same modes. */
13632 tree oldreturntype = TREE_TYPE (TREE_TYPE (olddecl));
13633 tree newreturntype = TREE_TYPE (TREE_TYPE (newdecl));
5ff904cd 13634
c7e4ee3a
CB
13635 if (TYPE_MODE (oldreturntype) == TYPE_MODE (newreturntype))
13636 {
13637 /* Function types may be shared, so we can't just modify
13638 the return type of olddecl's function type. */
13639 tree newtype
13640 = build_function_type (newreturntype,
13641 TYPE_ARG_TYPES (TREE_TYPE (olddecl)));
5ff904cd 13642
c7e4ee3a
CB
13643 types_match = 1;
13644 if (types_match)
13645 TREE_TYPE (olddecl) = newtype;
13646 }
c7e4ee3a
CB
13647 }
13648 if (!types_match)
13649 return 0;
13650 }
13651 else if (TREE_CODE (olddecl) == FUNCTION_DECL
13652 && DECL_SOURCE_LINE (olddecl) == 0)
5ff904cd 13653 {
c7e4ee3a
CB
13654 /* A function declaration for a predeclared function
13655 that isn't actually built in. */
13656 if (!TREE_PUBLIC (newdecl))
13657 return 0;
13658 else if (!types_match)
13659 {
13660 /* If the types don't match, preserve volatility indication.
13661 Later on, we will discard everything else about the
13662 default declaration. */
13663 TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
13664 }
13665 }
5ff904cd 13666
c7e4ee3a
CB
13667 /* Copy all the DECL_... slots specified in the new decl
13668 except for any that we copy here from the old type.
5ff904cd 13669
c7e4ee3a
CB
13670 Past this point, we don't change OLDTYPE and NEWTYPE
13671 even if we change the types of NEWDECL and OLDDECL. */
5ff904cd 13672
c7e4ee3a
CB
13673 if (types_match)
13674 {
c7e4ee3a
CB
13675 /* Merge the data types specified in the two decls. */
13676 if (TREE_CODE (newdecl) != FUNCTION_DECL || !DECL_BUILT_IN (olddecl))
13677 TREE_TYPE (newdecl)
13678 = TREE_TYPE (olddecl)
13679 = TREE_TYPE (newdecl);
5ff904cd 13680
c7e4ee3a
CB
13681 /* Lay the type out, unless already done. */
13682 if (oldtype != TREE_TYPE (newdecl))
13683 {
13684 if (TREE_TYPE (newdecl) != error_mark_node)
13685 layout_type (TREE_TYPE (newdecl));
13686 if (TREE_CODE (newdecl) != FUNCTION_DECL
13687 && TREE_CODE (newdecl) != TYPE_DECL
13688 && TREE_CODE (newdecl) != CONST_DECL)
13689 layout_decl (newdecl, 0);
13690 }
13691 else
13692 {
13693 /* Since the type is OLDDECL's, make OLDDECL's size go with. */
13694 DECL_SIZE (newdecl) = DECL_SIZE (olddecl);
06ceef4e 13695 DECL_SIZE_UNIT (newdecl) = DECL_SIZE_UNIT (olddecl);
c7e4ee3a
CB
13696 if (TREE_CODE (olddecl) != FUNCTION_DECL)
13697 if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl))
11cf4d18
JJ
13698 {
13699 DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl);
13700 DECL_USER_ALIGN (newdecl) |= DECL_USER_ALIGN (olddecl);
13701 }
c7e4ee3a 13702 }
5ff904cd 13703
c7e4ee3a
CB
13704 /* Keep the old rtl since we can safely use it. */
13705 DECL_RTL (newdecl) = DECL_RTL (olddecl);
5ff904cd 13706
c7e4ee3a
CB
13707 /* Merge the type qualifiers. */
13708 if (DECL_BUILT_IN_NONANSI (olddecl) && TREE_THIS_VOLATILE (olddecl)
13709 && !TREE_THIS_VOLATILE (newdecl))
13710 TREE_THIS_VOLATILE (olddecl) = 0;
13711 if (TREE_READONLY (newdecl))
13712 TREE_READONLY (olddecl) = 1;
13713 if (TREE_THIS_VOLATILE (newdecl))
13714 {
13715 TREE_THIS_VOLATILE (olddecl) = 1;
13716 if (TREE_CODE (newdecl) == VAR_DECL)
13717 make_var_volatile (newdecl);
13718 }
5ff904cd 13719
c7e4ee3a
CB
13720 /* Keep source location of definition rather than declaration.
13721 Likewise, keep decl at outer scope. */
13722 if ((DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0)
13723 || (DECL_CONTEXT (newdecl) != 0 && DECL_CONTEXT (olddecl) == 0))
13724 {
13725 DECL_SOURCE_LINE (newdecl) = DECL_SOURCE_LINE (olddecl);
13726 DECL_SOURCE_FILE (newdecl) = DECL_SOURCE_FILE (olddecl);
5ff904cd 13727
c7e4ee3a
CB
13728 if (DECL_CONTEXT (olddecl) == 0
13729 && TREE_CODE (newdecl) != FUNCTION_DECL)
13730 DECL_CONTEXT (newdecl) = 0;
13731 }
5ff904cd 13732
c7e4ee3a
CB
13733 /* Merge the unused-warning information. */
13734 if (DECL_IN_SYSTEM_HEADER (olddecl))
13735 DECL_IN_SYSTEM_HEADER (newdecl) = 1;
13736 else if (DECL_IN_SYSTEM_HEADER (newdecl))
13737 DECL_IN_SYSTEM_HEADER (olddecl) = 1;
5ff904cd 13738
c7e4ee3a
CB
13739 /* Merge the initialization information. */
13740 if (DECL_INITIAL (newdecl) == 0)
13741 DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
5ff904cd 13742
c7e4ee3a
CB
13743 /* Merge the section attribute.
13744 We want to issue an error if the sections conflict but that must be
13745 done later in decl_attributes since we are called before attributes
13746 are assigned. */
13747 if (DECL_SECTION_NAME (newdecl) == NULL_TREE)
13748 DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl);
5ff904cd 13749
c7e4ee3a
CB
13750#if BUILT_FOR_270
13751 if (TREE_CODE (newdecl) == FUNCTION_DECL)
13752 {
13753 DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl);
13754 DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
13755 }
5ff904cd 13756#endif
c7e4ee3a
CB
13757 }
13758 /* If cannot merge, then use the new type and qualifiers,
13759 and don't preserve the old rtl. */
13760 else
13761 {
13762 TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
13763 TREE_READONLY (olddecl) = TREE_READONLY (newdecl);
13764 TREE_THIS_VOLATILE (olddecl) = TREE_THIS_VOLATILE (newdecl);
13765 TREE_SIDE_EFFECTS (olddecl) = TREE_SIDE_EFFECTS (newdecl);
13766 }
5ff904cd 13767
c7e4ee3a
CB
13768 /* Merge the storage class information. */
13769 /* For functions, static overrides non-static. */
13770 if (TREE_CODE (newdecl) == FUNCTION_DECL)
13771 {
13772 TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl);
13773 /* This is since we don't automatically
13774 copy the attributes of NEWDECL into OLDDECL. */
13775 TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
13776 /* If this clears `static', clear it in the identifier too. */
13777 if (! TREE_PUBLIC (olddecl))
13778 TREE_PUBLIC (DECL_NAME (olddecl)) = 0;
13779 }
13780 if (DECL_EXTERNAL (newdecl))
13781 {
13782 TREE_STATIC (newdecl) = TREE_STATIC (olddecl);
13783 DECL_EXTERNAL (newdecl) = DECL_EXTERNAL (olddecl);
13784 /* An extern decl does not override previous storage class. */
13785 TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
13786 }
13787 else
13788 {
13789 TREE_STATIC (olddecl) = TREE_STATIC (newdecl);
13790 TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
13791 }
5ff904cd 13792
c7e4ee3a
CB
13793 /* If either decl says `inline', this fn is inline,
13794 unless its definition was passed already. */
13795 if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == 0)
13796 DECL_INLINE (olddecl) = 1;
13797 DECL_INLINE (newdecl) = DECL_INLINE (olddecl);
5ff904cd 13798
c7e4ee3a
CB
13799 /* Get rid of any built-in function if new arg types don't match it
13800 or if we have a function definition. */
13801 if (TREE_CODE (newdecl) == FUNCTION_DECL
13802 && DECL_BUILT_IN (olddecl)
13803 && (!types_match || new_is_definition))
13804 {
13805 TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
26db82d8 13806 DECL_BUILT_IN_CLASS (olddecl) = NOT_BUILT_IN;
c7e4ee3a 13807 }
5ff904cd 13808
c7e4ee3a
CB
13809 /* If redeclaring a builtin function, and not a definition,
13810 it stays built in.
13811 Also preserve various other info from the definition. */
13812 if (TREE_CODE (newdecl) == FUNCTION_DECL && !new_is_definition)
13813 {
13814 if (DECL_BUILT_IN (olddecl))
13815 {
26db82d8 13816 DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl);
c7e4ee3a
CB
13817 DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
13818 }
13819 else
13820 DECL_FRAME_SIZE (newdecl) = DECL_FRAME_SIZE (olddecl);
5ff904cd 13821
c7e4ee3a
CB
13822 DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
13823 DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
13824 DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl);
13825 DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
13826 }
5ff904cd 13827
c7e4ee3a
CB
13828 /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
13829 But preserve olddecl's DECL_UID. */
13830 {
13831 register unsigned olddecl_uid = DECL_UID (olddecl);
5ff904cd 13832
c7e4ee3a
CB
13833 memcpy ((char *) olddecl + sizeof (struct tree_common),
13834 (char *) newdecl + sizeof (struct tree_common),
13835 sizeof (struct tree_decl) - sizeof (struct tree_common));
13836 DECL_UID (olddecl) = olddecl_uid;
13837 }
5ff904cd 13838
c7e4ee3a 13839 return 1;
5ff904cd
JL
13840}
13841
c7e4ee3a
CB
13842/* Finish processing of a declaration;
13843 install its initial value.
13844 If the length of an array type is not known before,
13845 it must be determined now, from the initial value, or it is an error. */
13846
5ff904cd 13847static void
c7e4ee3a 13848finish_decl (tree decl, tree init, bool is_top_level)
5ff904cd 13849{
c7e4ee3a
CB
13850 register tree type = TREE_TYPE (decl);
13851 int was_incomplete = (DECL_SIZE (decl) == 0);
c7e4ee3a
CB
13852 bool at_top_level = (current_binding_level == global_binding_level);
13853 bool top_level = is_top_level || at_top_level;
5ff904cd 13854
c7e4ee3a
CB
13855 /* Caller should pass TRUE for is_top_level only if we wouldn't be at top
13856 level anyway. */
13857 assert (!is_top_level || !at_top_level);
5ff904cd 13858
c7e4ee3a
CB
13859 if (TREE_CODE (decl) == PARM_DECL)
13860 assert (init == NULL_TREE);
13861 /* Remember that PARM_DECL doesn't have a DECL_INITIAL field per se -- it
13862 overlaps DECL_ARG_TYPE. */
13863 else if (init == NULL_TREE)
13864 assert (DECL_INITIAL (decl) == NULL_TREE);
13865 else
13866 assert (DECL_INITIAL (decl) == error_mark_node);
5ff904cd 13867
c7e4ee3a 13868 if (init != NULL_TREE)
5ff904cd 13869 {
c7e4ee3a
CB
13870 if (TREE_CODE (decl) != TYPE_DECL)
13871 DECL_INITIAL (decl) = init;
13872 else
13873 {
13874 /* typedef foo = bar; store the type of bar as the type of foo. */
13875 TREE_TYPE (decl) = TREE_TYPE (init);
13876 DECL_INITIAL (decl) = init = 0;
13877 }
5ff904cd
JL
13878 }
13879
c7e4ee3a 13880 /* Deduce size of array from initialization, if not already known */
5ff904cd 13881
c7e4ee3a
CB
13882 if (TREE_CODE (type) == ARRAY_TYPE
13883 && TYPE_DOMAIN (type) == 0
13884 && TREE_CODE (decl) != TYPE_DECL)
13885 {
13886 assert (top_level);
13887 assert (was_incomplete);
5ff904cd 13888
c7e4ee3a
CB
13889 layout_decl (decl, 0);
13890 }
5ff904cd 13891
c7e4ee3a
CB
13892 if (TREE_CODE (decl) == VAR_DECL)
13893 {
13894 if (DECL_SIZE (decl) == NULL_TREE
13895 && TYPE_SIZE (TREE_TYPE (decl)) != NULL_TREE)
13896 layout_decl (decl, 0);
5ff904cd 13897
c7e4ee3a
CB
13898 if (DECL_SIZE (decl) == NULL_TREE
13899 && (TREE_STATIC (decl)
13900 ?
13901 /* A static variable with an incomplete type is an error if it is
13902 initialized. Also if it is not file scope. Otherwise, let it
13903 through, but if it is not `extern' then it may cause an error
13904 message later. */
13905 (DECL_INITIAL (decl) != 0 || DECL_CONTEXT (decl) != 0)
13906 :
13907 /* An automatic variable with an incomplete type is an error. */
13908 !DECL_EXTERNAL (decl)))
13909 {
13910 assert ("storage size not known" == NULL);
13911 abort ();
13912 }
5ff904cd 13913
c7e4ee3a
CB
13914 if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl))
13915 && (DECL_SIZE (decl) != 0)
13916 && (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST))
13917 {
13918 assert ("storage size not constant" == NULL);
13919 abort ();
13920 }
13921 }
5ff904cd 13922
c7e4ee3a
CB
13923 /* Output the assembler code and/or RTL code for variables and functions,
13924 unless the type is an undefined structure or union. If not, it will get
13925 done when the type is completed. */
5ff904cd 13926
c7e4ee3a 13927 if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)
5ff904cd 13928 {
c7e4ee3a
CB
13929 rest_of_decl_compilation (decl, NULL,
13930 DECL_CONTEXT (decl) == 0,
13931 0);
5ff904cd 13932
c7e4ee3a
CB
13933 if (DECL_CONTEXT (decl) != 0)
13934 {
13935 /* Recompute the RTL of a local array now if it used to be an
13936 incomplete type. */
13937 if (was_incomplete
13938 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
5ff904cd 13939 {
c7e4ee3a
CB
13940 /* If we used it already as memory, it must stay in memory. */
13941 TREE_ADDRESSABLE (decl) = TREE_USED (decl);
13942 /* If it's still incomplete now, no init will save it. */
13943 if (DECL_SIZE (decl) == 0)
13944 DECL_INITIAL (decl) = 0;
13945 expand_decl (decl);
5ff904cd 13946 }
c7e4ee3a
CB
13947 /* Compute and store the initial value. */
13948 if (TREE_CODE (decl) != FUNCTION_DECL)
13949 expand_decl_init (decl);
13950 }
13951 }
13952 else if (TREE_CODE (decl) == TYPE_DECL)
13953 {
13954 rest_of_decl_compilation (decl, NULL_PTR,
13955 DECL_CONTEXT (decl) == 0,
13956 0);
13957 }
5ff904cd 13958
c7e4ee3a
CB
13959 /* At the end of a declaration, throw away any variable type sizes of types
13960 defined inside that declaration. There is no use computing them in the
13961 following function definition. */
13962 if (current_binding_level == global_binding_level)
13963 get_pending_sizes ();
13964}
5ff904cd 13965
c7e4ee3a
CB
13966/* Finish up a function declaration and compile that function
13967 all the way to assembler language output. The free the storage
13968 for the function definition.
5ff904cd 13969
c7e4ee3a 13970 This is called after parsing the body of the function definition.
5ff904cd 13971
c7e4ee3a
CB
13972 NESTED is nonzero if the function being finished is nested in another. */
13973
13974static void
13975finish_function (int nested)
13976{
13977 register tree fndecl = current_function_decl;
13978
13979 assert (fndecl != NULL_TREE);
13980 if (TREE_CODE (fndecl) != ERROR_MARK)
13981 {
13982 if (nested)
13983 assert (DECL_CONTEXT (fndecl) != NULL_TREE);
5ff904cd 13984 else
c7e4ee3a
CB
13985 assert (DECL_CONTEXT (fndecl) == NULL_TREE);
13986 }
5ff904cd 13987
c7e4ee3a
CB
13988/* TREE_READONLY (fndecl) = 1;
13989 This caused &foo to be of type ptr-to-const-function
13990 which then got a warning when stored in a ptr-to-function variable. */
5ff904cd 13991
c7e4ee3a 13992 poplevel (1, 0, 1);
5ff904cd 13993
c7e4ee3a
CB
13994 if (TREE_CODE (fndecl) != ERROR_MARK)
13995 {
13996 BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
5ff904cd 13997
c7e4ee3a 13998 /* Must mark the RESULT_DECL as being in this function. */
5ff904cd 13999
c7e4ee3a 14000 DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;
5ff904cd 14001
c7e4ee3a
CB
14002 /* Obey `register' declarations if `setjmp' is called in this fn. */
14003 /* Generate rtl for function exit. */
14004 expand_function_end (input_filename, lineno, 0);
5ff904cd 14005
7189a4b0
GK
14006 /* If this is a nested function, protect the local variables in the stack
14007 above us from being collected while we're compiling this function. */
1f8f4a0b 14008 if (nested)
7189a4b0
GK
14009 ggc_push_context ();
14010
c7e4ee3a
CB
14011 /* Run the optimizers and output the assembler code for this function. */
14012 rest_of_compilation (fndecl);
7189a4b0
GK
14013
14014 /* Undo the GC context switch. */
1f8f4a0b 14015 if (nested)
7189a4b0 14016 ggc_pop_context ();
c7e4ee3a 14017 }
5ff904cd 14018
c7e4ee3a
CB
14019 if (TREE_CODE (fndecl) != ERROR_MARK
14020 && !nested
14021 && DECL_SAVED_INSNS (fndecl) == 0)
14022 {
14023 /* Stop pointing to the local nodes about to be freed. */
14024 /* But DECL_INITIAL must remain nonzero so we know this was an actual
14025 function definition. */
14026 /* For a nested function, this is done in pop_f_function_context. */
14027 /* If rest_of_compilation set this to 0, leave it 0. */
14028 if (DECL_INITIAL (fndecl) != 0)
14029 DECL_INITIAL (fndecl) = error_mark_node;
14030 DECL_ARGUMENTS (fndecl) = 0;
5ff904cd 14031 }
c7e4ee3a
CB
14032
14033 if (!nested)
5ff904cd 14034 {
c7e4ee3a
CB
14035 /* Let the error reporting routines know that we're outside a function.
14036 For a nested function, this value is used in pop_c_function_context
14037 and then reset via pop_function_context. */
14038 ffecom_outer_function_decl_ = current_function_decl = NULL;
5ff904cd 14039 }
c7e4ee3a 14040}
5ff904cd 14041
c7e4ee3a
CB
14042/* Plug-in replacement for identifying the name of a decl and, for a
14043 function, what we call it in diagnostics. For now, "program unit"
14044 should suffice, since it's a bit of a hassle to figure out which
14045 of several kinds of things it is. Note that it could conceivably
14046 be a statement function, which probably isn't really a program unit
14047 per se, but if that comes up, it should be easy to check (being a
14048 nested function and all). */
14049
4b731ffa 14050static const char *
c7e4ee3a
CB
14051lang_printable_name (tree decl, int v)
14052{
14053 /* Just to keep GCC quiet about the unused variable.
14054 In theory, differing values of V should produce different
14055 output. */
14056 switch (v)
5ff904cd 14057 {
c7e4ee3a
CB
14058 default:
14059 if (TREE_CODE (decl) == ERROR_MARK)
14060 return "erroneous code";
14061 return IDENTIFIER_POINTER (DECL_NAME (decl));
5ff904cd 14062 }
c7e4ee3a
CB
14063}
14064
14065/* g77's function to print out name of current function that caused
14066 an error. */
14067
14068#if BUILT_FOR_270
b0791fa9
KG
14069static void
14070lang_print_error_function (const char *file)
c7e4ee3a
CB
14071{
14072 static ffeglobal last_g = NULL;
14073 static ffesymbol last_s = NULL;
14074 ffeglobal g;
14075 ffesymbol s;
14076 const char *kind;
14077
14078 if ((ffecom_primary_entry_ == NULL)
14079 || (ffesymbol_global (ffecom_primary_entry_) == NULL))
5ff904cd 14080 {
c7e4ee3a
CB
14081 g = NULL;
14082 s = NULL;
14083 kind = NULL;
5ff904cd
JL
14084 }
14085 else
14086 {
c7e4ee3a
CB
14087 g = ffesymbol_global (ffecom_primary_entry_);
14088 if (ffecom_nested_entry_ == NULL)
14089 {
14090 s = ffecom_primary_entry_;
14091 switch (ffesymbol_kind (s))
14092 {
14093 case FFEINFO_kindFUNCTION:
14094 kind = "function";
14095 break;
5ff904cd 14096
c7e4ee3a
CB
14097 case FFEINFO_kindSUBROUTINE:
14098 kind = "subroutine";
14099 break;
5ff904cd 14100
c7e4ee3a
CB
14101 case FFEINFO_kindPROGRAM:
14102 kind = "program";
14103 break;
14104
14105 case FFEINFO_kindBLOCKDATA:
14106 kind = "block-data";
14107 break;
14108
14109 default:
14110 kind = ffeinfo_kind_message (ffesymbol_kind (s));
14111 break;
14112 }
14113 }
14114 else
14115 {
14116 s = ffecom_nested_entry_;
14117 kind = "statement function";
14118 }
5ff904cd
JL
14119 }
14120
c7e4ee3a 14121 if ((last_g != g) || (last_s != s))
5ff904cd 14122 {
c7e4ee3a
CB
14123 if (file)
14124 fprintf (stderr, "%s: ", file);
14125
14126 if (s == NULL)
14127 fprintf (stderr, "Outside of any program unit:\n");
14128 else
5ff904cd 14129 {
c7e4ee3a
CB
14130 const char *name = ffesymbol_text (s);
14131
14132 fprintf (stderr, "In %s `%s':\n", kind, name);
5ff904cd 14133 }
5ff904cd 14134
c7e4ee3a
CB
14135 last_g = g;
14136 last_s = s;
5ff904cd 14137 }
c7e4ee3a
CB
14138}
14139#endif
5ff904cd 14140
c7e4ee3a 14141/* Similar to `lookup_name' but look only at current binding level. */
5ff904cd 14142
c7e4ee3a
CB
14143static tree
14144lookup_name_current_level (tree name)
14145{
14146 register tree t;
5ff904cd 14147
c7e4ee3a
CB
14148 if (current_binding_level == global_binding_level)
14149 return IDENTIFIER_GLOBAL_VALUE (name);
14150
14151 if (IDENTIFIER_LOCAL_VALUE (name) == 0)
14152 return 0;
14153
14154 for (t = current_binding_level->names; t; t = TREE_CHAIN (t))
14155 if (DECL_NAME (t) == name)
14156 break;
14157
14158 return t;
5ff904cd
JL
14159}
14160
c7e4ee3a 14161/* Create a new `struct binding_level'. */
5ff904cd 14162
c7e4ee3a
CB
14163static struct binding_level *
14164make_binding_level ()
5ff904cd 14165{
c7e4ee3a
CB
14166 /* NOSTRICT */
14167 return (struct binding_level *) xmalloc (sizeof (struct binding_level));
14168}
5ff904cd 14169
c7e4ee3a
CB
14170/* Save and restore the variables in this file and elsewhere
14171 that keep track of the progress of compilation of the current function.
14172 Used for nested functions. */
5ff904cd 14173
c7e4ee3a
CB
14174struct f_function
14175{
14176 struct f_function *next;
14177 tree named_labels;
14178 tree shadowed_labels;
14179 struct binding_level *binding_level;
14180};
5ff904cd 14181
c7e4ee3a 14182struct f_function *f_function_chain;
5ff904cd 14183
c7e4ee3a 14184/* Restore the variables used during compilation of a C function. */
5ff904cd 14185
c7e4ee3a
CB
14186static void
14187pop_f_function_context ()
14188{
14189 struct f_function *p = f_function_chain;
14190 tree link;
5ff904cd 14191
c7e4ee3a
CB
14192 /* Bring back all the labels that were shadowed. */
14193 for (link = shadowed_labels; link; link = TREE_CHAIN (link))
14194 if (DECL_NAME (TREE_VALUE (link)) != 0)
14195 IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link)))
14196 = TREE_VALUE (link);
5ff904cd 14197
c7e4ee3a
CB
14198 if (current_function_decl != error_mark_node
14199 && DECL_SAVED_INSNS (current_function_decl) == 0)
14200 {
14201 /* Stop pointing to the local nodes about to be freed. */
14202 /* But DECL_INITIAL must remain nonzero so we know this was an actual
14203 function definition. */
14204 DECL_INITIAL (current_function_decl) = error_mark_node;
14205 DECL_ARGUMENTS (current_function_decl) = 0;
5ff904cd
JL
14206 }
14207
c7e4ee3a 14208 pop_function_context ();
5ff904cd 14209
c7e4ee3a 14210 f_function_chain = p->next;
5ff904cd 14211
c7e4ee3a
CB
14212 named_labels = p->named_labels;
14213 shadowed_labels = p->shadowed_labels;
14214 current_binding_level = p->binding_level;
5ff904cd 14215
c7e4ee3a
CB
14216 free (p);
14217}
5ff904cd 14218
c7e4ee3a
CB
14219/* Save and reinitialize the variables
14220 used during compilation of a C function. */
5ff904cd 14221
c7e4ee3a
CB
14222static void
14223push_f_function_context ()
14224{
14225 struct f_function *p
14226 = (struct f_function *) xmalloc (sizeof (struct f_function));
5ff904cd 14227
c7e4ee3a
CB
14228 push_function_context ();
14229
14230 p->next = f_function_chain;
14231 f_function_chain = p;
14232
14233 p->named_labels = named_labels;
14234 p->shadowed_labels = shadowed_labels;
14235 p->binding_level = current_binding_level;
14236}
5ff904cd 14237
c7e4ee3a
CB
14238static void
14239push_parm_decl (tree parm)
14240{
14241 int old_immediate_size_expand = immediate_size_expand;
5ff904cd 14242
c7e4ee3a 14243 /* Don't try computing parm sizes now -- wait till fn is called. */
5ff904cd 14244
c7e4ee3a 14245 immediate_size_expand = 0;
5ff904cd 14246
c7e4ee3a 14247 /* Fill in arg stuff. */
5ff904cd 14248
c7e4ee3a
CB
14249 DECL_ARG_TYPE (parm) = TREE_TYPE (parm);
14250 DECL_ARG_TYPE_AS_WRITTEN (parm) = TREE_TYPE (parm);
14251 TREE_READONLY (parm) = 1; /* All implementation args are read-only. */
5ff904cd 14252
c7e4ee3a
CB
14253 parm = pushdecl (parm);
14254
14255 immediate_size_expand = old_immediate_size_expand;
14256
14257 finish_decl (parm, NULL_TREE, FALSE);
5ff904cd
JL
14258}
14259
c7e4ee3a 14260/* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL, if appropriate. */
5ff904cd 14261
c7e4ee3a
CB
14262static tree
14263pushdecl_top_level (x)
14264 tree x;
14265{
14266 register tree t;
14267 register struct binding_level *b = current_binding_level;
14268 register tree f = current_function_decl;
5ff904cd 14269
c7e4ee3a
CB
14270 current_binding_level = global_binding_level;
14271 current_function_decl = NULL_TREE;
14272 t = pushdecl (x);
14273 current_binding_level = b;
14274 current_function_decl = f;
14275 return t;
14276}
14277
14278/* Store the list of declarations of the current level.
14279 This is done for the parameter declarations of a function being defined,
14280 after they are modified in the light of any missing parameters. */
14281
14282static tree
14283storedecls (decls)
14284 tree decls;
14285{
14286 return current_binding_level->names = decls;
14287}
14288
14289/* Store the parameter declarations into the current function declaration.
14290 This is called after parsing the parameter declarations, before
14291 digesting the body of the function.
14292
14293 For an old-style definition, modify the function's type
14294 to specify at least the number of arguments. */
5ff904cd
JL
14295
14296static void
c7e4ee3a 14297store_parm_decls (int is_main_program UNUSED)
5ff904cd
JL
14298{
14299 register tree fndecl = current_function_decl;
14300
c7e4ee3a
CB
14301 if (fndecl == error_mark_node)
14302 return;
5ff904cd 14303
c7e4ee3a
CB
14304 /* This is a chain of PARM_DECLs from old-style parm declarations. */
14305 DECL_ARGUMENTS (fndecl) = storedecls (nreverse (getdecls ()));
5ff904cd 14306
c7e4ee3a 14307 /* Initialize the RTL code for the function. */
5ff904cd 14308
c7e4ee3a 14309 init_function_start (fndecl, input_filename, lineno);
56a0044b 14310
c7e4ee3a 14311 /* Set up parameters and prepare for return, for the function. */
5ff904cd 14312
c7e4ee3a
CB
14313 expand_function_start (fndecl, 0);
14314}
5ff904cd 14315
c7e4ee3a
CB
14316static tree
14317start_decl (tree decl, bool is_top_level)
14318{
14319 register tree tem;
14320 bool at_top_level = (current_binding_level == global_binding_level);
14321 bool top_level = is_top_level || at_top_level;
5ff904cd 14322
c7e4ee3a
CB
14323 /* Caller should pass TRUE for is_top_level only if we wouldn't be at top
14324 level anyway. */
14325 assert (!is_top_level || !at_top_level);
5ff904cd 14326
c7e4ee3a
CB
14327 if (DECL_INITIAL (decl) != NULL_TREE)
14328 {
14329 assert (DECL_INITIAL (decl) == error_mark_node);
14330 assert (!DECL_EXTERNAL (decl));
56a0044b 14331 }
c7e4ee3a
CB
14332 else if (top_level)
14333 assert ((TREE_STATIC (decl) == 1) || DECL_EXTERNAL (decl) == 1);
5ff904cd 14334
c7e4ee3a
CB
14335 /* For Fortran, we by default put things in .common when possible. */
14336 DECL_COMMON (decl) = 1;
5ff904cd 14337
c7e4ee3a
CB
14338 /* Add this decl to the current binding level. TEM may equal DECL or it may
14339 be a previous decl of the same name. */
14340 if (is_top_level)
14341 tem = pushdecl_top_level (decl);
14342 else
14343 tem = pushdecl (decl);
14344
14345 /* For a local variable, define the RTL now. */
14346 if (!top_level
14347 /* But not if this is a duplicate decl and we preserved the rtl from the
14348 previous one (which may or may not happen). */
14349 && DECL_RTL (tem) == 0)
5ff904cd 14350 {
c7e4ee3a
CB
14351 if (TYPE_SIZE (TREE_TYPE (tem)) != 0)
14352 expand_decl (tem);
14353 else if (TREE_CODE (TREE_TYPE (tem)) == ARRAY_TYPE
14354 && DECL_INITIAL (tem) != 0)
14355 expand_decl (tem);
5ff904cd
JL
14356 }
14357
c7e4ee3a 14358 return tem;
5ff904cd
JL
14359}
14360
c7e4ee3a
CB
14361/* Create the FUNCTION_DECL for a function definition.
14362 DECLSPECS and DECLARATOR are the parts of the declaration;
14363 they describe the function's name and the type it returns,
14364 but twisted together in a fashion that parallels the syntax of C.
5ff904cd 14365
c7e4ee3a
CB
14366 This function creates a binding context for the function body
14367 as well as setting up the FUNCTION_DECL in current_function_decl.
5ff904cd 14368
c7e4ee3a
CB
14369 Returns 1 on success. If the DECLARATOR is not suitable for a function
14370 (it defines a datum instead), we return 0, which tells
14371 yyparse to report a parse error.
5ff904cd 14372
c7e4ee3a
CB
14373 NESTED is nonzero for a function nested within another function. */
14374
14375static void
14376start_function (tree name, tree type, int nested, int public)
5ff904cd 14377{
c7e4ee3a
CB
14378 tree decl1;
14379 tree restype;
14380 int old_immediate_size_expand = immediate_size_expand;
5ff904cd 14381
c7e4ee3a
CB
14382 named_labels = 0;
14383 shadowed_labels = 0;
14384
14385 /* Don't expand any sizes in the return type of the function. */
14386 immediate_size_expand = 0;
14387
14388 if (nested)
5ff904cd 14389 {
c7e4ee3a
CB
14390 assert (!public);
14391 assert (current_function_decl != NULL_TREE);
14392 assert (DECL_CONTEXT (current_function_decl) == NULL_TREE);
14393 }
14394 else
14395 {
14396 assert (current_function_decl == NULL_TREE);
5ff904cd 14397 }
c7e4ee3a
CB
14398
14399 if (TREE_CODE (type) == ERROR_MARK)
14400 decl1 = current_function_decl = error_mark_node;
56a0044b 14401 else
5ff904cd 14402 {
c7e4ee3a
CB
14403 decl1 = build_decl (FUNCTION_DECL,
14404 name,
14405 type);
14406 TREE_PUBLIC (decl1) = public ? 1 : 0;
14407 if (nested)
14408 DECL_INLINE (decl1) = 1;
14409 TREE_STATIC (decl1) = 1;
14410 DECL_EXTERNAL (decl1) = 0;
5ff904cd 14411
c7e4ee3a 14412 announce_function (decl1);
5ff904cd 14413
c7e4ee3a
CB
14414 /* Make the init_value nonzero so pushdecl knows this is not tentative.
14415 error_mark_node is replaced below (in poplevel) with the BLOCK. */
14416 DECL_INITIAL (decl1) = error_mark_node;
5ff904cd 14417
c7e4ee3a
CB
14418 /* Record the decl so that the function name is defined. If we already have
14419 a decl for this name, and it is a FUNCTION_DECL, use the old decl. */
5ff904cd 14420
c7e4ee3a 14421 current_function_decl = pushdecl (decl1);
5ff904cd
JL
14422 }
14423
c7e4ee3a
CB
14424 if (!nested)
14425 ffecom_outer_function_decl_ = current_function_decl;
5ff904cd 14426
c7e4ee3a
CB
14427 pushlevel (0);
14428 current_binding_level->prep_state = 2;
5ff904cd 14429
c7e4ee3a
CB
14430 if (TREE_CODE (current_function_decl) != ERROR_MARK)
14431 {
14432 make_function_rtl (current_function_decl);
5ff904cd 14433
c7e4ee3a
CB
14434 restype = TREE_TYPE (TREE_TYPE (current_function_decl));
14435 DECL_RESULT (current_function_decl)
14436 = build_decl (RESULT_DECL, NULL_TREE, restype);
5ff904cd 14437 }
5ff904cd 14438
c7e4ee3a
CB
14439 if (!nested && (TREE_CODE (current_function_decl) != ERROR_MARK))
14440 TREE_ADDRESSABLE (current_function_decl) = 1;
14441
14442 immediate_size_expand = old_immediate_size_expand;
14443}
14444\f
14445/* Here are the public functions the GNU back end needs. */
14446
14447tree
14448convert (type, expr)
14449 tree type, expr;
5ff904cd 14450{
c7e4ee3a
CB
14451 register tree e = expr;
14452 register enum tree_code code = TREE_CODE (type);
5ff904cd 14453
c7e4ee3a
CB
14454 if (type == TREE_TYPE (e)
14455 || TREE_CODE (e) == ERROR_MARK)
14456 return e;
14457 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
14458 return fold (build1 (NOP_EXPR, type, e));
14459 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
14460 || code == ERROR_MARK)
14461 return error_mark_node;
14462 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
14463 {
14464 assert ("void value not ignored as it ought to be" == NULL);
14465 return error_mark_node;
14466 }
14467 if (code == VOID_TYPE)
14468 return build1 (CONVERT_EXPR, type, e);
14469 if ((code != RECORD_TYPE)
14470 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
14471 e = ffecom_1 (REALPART_EXPR, TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e))),
14472 e);
14473 if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)
14474 return fold (convert_to_integer (type, e));
14475 if (code == POINTER_TYPE)
14476 return fold (convert_to_pointer (type, e));
14477 if (code == REAL_TYPE)
14478 return fold (convert_to_real (type, e));
14479 if (code == COMPLEX_TYPE)
14480 return fold (convert_to_complex (type, e));
14481 if (code == RECORD_TYPE)
14482 return fold (ffecom_convert_to_complex_ (type, e));
5ff904cd 14483
c7e4ee3a
CB
14484 assert ("conversion to non-scalar type requested" == NULL);
14485 return error_mark_node;
14486}
5ff904cd 14487
c7e4ee3a
CB
14488/* integrate_decl_tree calls this function, but since we don't use the
14489 DECL_LANG_SPECIFIC field, this is a no-op. */
5ff904cd 14490
c7e4ee3a
CB
14491void
14492copy_lang_decl (node)
14493 tree node UNUSED;
14494{
5ff904cd
JL
14495}
14496
c7e4ee3a
CB
14497/* Return the list of declarations of the current level.
14498 Note that this list is in reverse order unless/until
14499 you nreverse it; and when you do nreverse it, you must
14500 store the result back using `storedecls' or you will lose. */
5ff904cd 14501
c7e4ee3a
CB
14502tree
14503getdecls ()
5ff904cd 14504{
c7e4ee3a 14505 return current_binding_level->names;
5ff904cd
JL
14506}
14507
c7e4ee3a 14508/* Nonzero if we are currently in the global binding level. */
5ff904cd 14509
c7e4ee3a
CB
14510int
14511global_bindings_p ()
5ff904cd 14512{
c7e4ee3a
CB
14513 return current_binding_level == global_binding_level;
14514}
5ff904cd 14515
c7e4ee3a
CB
14516/* Print an error message for invalid use of an incomplete type.
14517 VALUE is the expression that was used (or 0 if that isn't known)
14518 and TYPE is the type that was invalid. */
5ff904cd 14519
c7e4ee3a
CB
14520void
14521incomplete_type_error (value, type)
14522 tree value UNUSED;
14523 tree type;
14524{
14525 if (TREE_CODE (type) == ERROR_MARK)
14526 return;
5ff904cd 14527
c7e4ee3a
CB
14528 assert ("incomplete type?!?" == NULL);
14529}
14530
7189a4b0
GK
14531/* Mark ARG for GC. */
14532static void
54551044 14533mark_binding_level (void *arg)
7189a4b0
GK
14534{
14535 struct binding_level *level = *(struct binding_level **) arg;
14536
14537 while (level)
14538 {
14539 ggc_mark_tree (level->names);
14540 ggc_mark_tree (level->blocks);
14541 ggc_mark_tree (level->this_block);
14542 level = level->level_chain;
14543 }
14544}
14545
c7e4ee3a
CB
14546void
14547init_decl_processing ()
5ff904cd 14548{
7189a4b0
GK
14549 static tree *const tree_roots[] = {
14550 &current_function_decl,
14551 &string_type_node,
14552 &ffecom_tree_fun_type_void,
14553 &ffecom_integer_zero_node,
14554 &ffecom_integer_one_node,
14555 &ffecom_tree_subr_type,
14556 &ffecom_tree_ptr_to_subr_type,
14557 &ffecom_tree_blockdata_type,
14558 &ffecom_tree_xargc_,
14559 &ffecom_f2c_integer_type_node,
14560 &ffecom_f2c_ptr_to_integer_type_node,
14561 &ffecom_f2c_address_type_node,
14562 &ffecom_f2c_real_type_node,
14563 &ffecom_f2c_ptr_to_real_type_node,
14564 &ffecom_f2c_doublereal_type_node,
14565 &ffecom_f2c_complex_type_node,
14566 &ffecom_f2c_doublecomplex_type_node,
14567 &ffecom_f2c_longint_type_node,
14568 &ffecom_f2c_logical_type_node,
14569 &ffecom_f2c_flag_type_node,
14570 &ffecom_f2c_ftnlen_type_node,
14571 &ffecom_f2c_ftnlen_zero_node,
14572 &ffecom_f2c_ftnlen_one_node,
14573 &ffecom_f2c_ftnlen_two_node,
14574 &ffecom_f2c_ptr_to_ftnlen_type_node,
14575 &ffecom_f2c_ftnint_type_node,
14576 &ffecom_f2c_ptr_to_ftnint_type_node,
14577 &ffecom_outer_function_decl_,
14578 &ffecom_previous_function_decl_,
14579 &ffecom_which_entrypoint_decl_,
14580 &ffecom_float_zero_,
14581 &ffecom_float_half_,
14582 &ffecom_double_zero_,
14583 &ffecom_double_half_,
14584 &ffecom_func_result_,
14585 &ffecom_func_length_,
14586 &ffecom_multi_type_node_,
14587 &ffecom_multi_retval_,
14588 &named_labels,
14589 &shadowed_labels
14590 };
14591 size_t i;
14592
c7e4ee3a 14593 malloc_init ();
7189a4b0
GK
14594
14595 /* Record our roots. */
75ff2ca7 14596 for (i = 0; i < ARRAY_SIZE (tree_roots); i++)
7189a4b0
GK
14597 ggc_add_tree_root (tree_roots[i], 1);
14598 ggc_add_tree_root (&ffecom_tree_type[0][0],
14599 FFEINFO_basictype*FFEINFO_kindtype);
14600 ggc_add_tree_root (&ffecom_tree_fun_type[0][0],
14601 FFEINFO_basictype*FFEINFO_kindtype);
14602 ggc_add_tree_root (&ffecom_tree_ptr_to_fun_type[0][0],
14603 FFEINFO_basictype*FFEINFO_kindtype);
14604 ggc_add_tree_root (ffecom_gfrt_, FFECOM_gfrt);
14605 ggc_add_root (&current_binding_level, 1, sizeof current_binding_level,
14606 mark_binding_level);
14607 ggc_add_root (&free_binding_level, 1, sizeof current_binding_level,
14608 mark_binding_level);
14609 ggc_add_root (&tracker_head, 1, sizeof tracker_head, mark_tracker_head);
14610
c7e4ee3a
CB
14611 ffe_init_0 ();
14612}
5ff904cd 14613
3b304f5b 14614const char *
c7e4ee3a 14615init_parse (filename)
3b304f5b 14616 const char *filename;
c7e4ee3a 14617{
c7e4ee3a
CB
14618 /* Open input file. */
14619 if (filename == 0 || !strcmp (filename, "-"))
5ff904cd 14620 {
c7e4ee3a
CB
14621 finput = stdin;
14622 filename = "stdin";
5ff904cd 14623 }
c7e4ee3a
CB
14624 else
14625 finput = fopen (filename, "r");
14626 if (finput == 0)
14627 pfatal_with_name (filename);
5ff904cd 14628
c7e4ee3a
CB
14629#ifdef IO_BUFFER_SIZE
14630 setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
14631#endif
5ff904cd 14632
c7e4ee3a
CB
14633 /* Make identifier nodes long enough for the language-specific slots. */
14634 set_identifier_size (sizeof (struct lang_identifier));
14635 decl_printable_name = lang_printable_name;
14636#if BUILT_FOR_270
14637 print_error_function = lang_print_error_function;
14638#endif
5ff904cd 14639
c7e4ee3a
CB
14640 return filename;
14641}
5ff904cd 14642
c7e4ee3a
CB
14643void
14644finish_parse ()
14645{
14646 fclose (finput);
14647}
14648
14649/* Delete the node BLOCK from the current binding level.
14650 This is used for the block inside a stmt expr ({...})
14651 so that the block can be reinserted where appropriate. */
14652
14653static void
14654delete_block (block)
14655 tree block;
14656{
14657 tree t;
14658 if (current_binding_level->blocks == block)
14659 current_binding_level->blocks = TREE_CHAIN (block);
14660 for (t = current_binding_level->blocks; t;)
14661 {
14662 if (TREE_CHAIN (t) == block)
14663 TREE_CHAIN (t) = TREE_CHAIN (block);
14664 else
14665 t = TREE_CHAIN (t);
14666 }
14667 TREE_CHAIN (block) = NULL;
14668 /* Clear TREE_USED which is always set by poplevel.
14669 The flag is set again if insert_block is called. */
14670 TREE_USED (block) = 0;
14671}
14672
14673void
14674insert_block (block)
14675 tree block;
14676{
14677 TREE_USED (block) = 1;
14678 current_binding_level->blocks
14679 = chainon (current_binding_level->blocks, block);
14680}
14681
14682int
14683lang_decode_option (argc, argv)
14684 int argc;
14685 char **argv;
14686{
14687 return ffe_decode_option (argc, argv);
5ff904cd
JL
14688}
14689
c7e4ee3a 14690/* used by print-tree.c */
5ff904cd 14691
c7e4ee3a
CB
14692void
14693lang_print_xnode (file, node, indent)
14694 FILE *file UNUSED;
14695 tree node UNUSED;
14696 int indent UNUSED;
5ff904cd 14697{
c7e4ee3a 14698}
5ff904cd 14699
c7e4ee3a
CB
14700void
14701lang_finish ()
14702{
14703 ffe_terminate_0 ();
5ff904cd 14704
c7e4ee3a
CB
14705 if (ffe_is_ffedebug ())
14706 malloc_pool_display (malloc_pool_image ());
5ff904cd
JL
14707}
14708
dafbd854 14709const char *
c7e4ee3a 14710lang_identify ()
5ff904cd 14711{
c7e4ee3a
CB
14712 return "f77";
14713}
5ff904cd 14714
2e761e49
RH
14715/* Return the typed-based alias set for T, which may be an expression
14716 or a type. Return -1 if we don't do anything special. */
14717
14718HOST_WIDE_INT
14719lang_get_alias_set (t)
5ac9118e 14720 tree t ATTRIBUTE_UNUSED;
2e761e49
RH
14721{
14722 /* We do not wish to use alias-set based aliasing at all. Used in the
14723 extreme (every object with its own set, with equivalences recorded)
14724 it might be helpful, but there are problems when it comes to inlining.
14725 We get on ok with flag_argument_noalias, and alias-set aliasing does
14726 currently limit how stack slots can be reused, which is a lose. */
14727 return 0;
14728}
14729
c7e4ee3a
CB
14730void
14731lang_init_options ()
14732{
14733 /* Set default options for Fortran. */
14734 flag_move_all_movables = 1;
14735 flag_reduce_all_givs = 1;
14736 flag_argument_noalias = 2;
41af162c 14737 flag_errno_math = 0;
c64f913e 14738 flag_complex_divide_method = 1;
c7e4ee3a 14739}
5ff904cd 14740
c7e4ee3a
CB
14741void
14742lang_init ()
14743{
14744 /* If the file is output from cpp, it should contain a first line
14745 `# 1 "real-filename"', and the current design of gcc (toplev.c
14746 in particular and the way it sets up information relied on by
14747 INCLUDE) requires that we read this now, and store the
14748 "real-filename" info in master_input_filename. Ask the lexer
14749 to try doing this. */
14750 ffelex_hash_kludge (finput);
14751}
5ff904cd 14752
c7e4ee3a
CB
14753int
14754mark_addressable (exp)
14755 tree exp;
14756{
14757 register tree x = exp;
14758 while (1)
14759 switch (TREE_CODE (x))
14760 {
14761 case ADDR_EXPR:
14762 case COMPONENT_REF:
14763 case ARRAY_REF:
14764 x = TREE_OPERAND (x, 0);
14765 break;
5ff904cd 14766
c7e4ee3a
CB
14767 case CONSTRUCTOR:
14768 TREE_ADDRESSABLE (x) = 1;
14769 return 1;
5ff904cd 14770
c7e4ee3a
CB
14771 case VAR_DECL:
14772 case CONST_DECL:
14773 case PARM_DECL:
14774 case RESULT_DECL:
14775 if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
14776 && DECL_NONLOCAL (x))
14777 {
14778 if (TREE_PUBLIC (x))
14779 {
14780 assert ("address of global register var requested" == NULL);
14781 return 0;
14782 }
14783 assert ("address of register variable requested" == NULL);
14784 }
14785 else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x))
14786 {
14787 if (TREE_PUBLIC (x))
14788 {
14789 assert ("address of global register var requested" == NULL);
14790 return 0;
14791 }
14792 assert ("address of register var requested" == NULL);
14793 }
14794 put_var_into_stack (x);
5ff904cd 14795
c7e4ee3a
CB
14796 /* drops in */
14797 case FUNCTION_DECL:
14798 TREE_ADDRESSABLE (x) = 1;
14799#if 0 /* poplevel deals with this now. */
14800 if (DECL_CONTEXT (x) == 0)
14801 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (x)) = 1;
14802#endif
5ff904cd 14803
c7e4ee3a
CB
14804 default:
14805 return 1;
14806 }
5ff904cd
JL
14807}
14808
c7e4ee3a
CB
14809/* If DECL has a cleanup, build and return that cleanup here.
14810 This is a callback called by expand_expr. */
5ff904cd 14811
c7e4ee3a
CB
14812tree
14813maybe_build_cleanup (decl)
14814 tree decl UNUSED;
5ff904cd 14815{
c7e4ee3a
CB
14816 /* There are no cleanups in Fortran. */
14817 return NULL_TREE;
5ff904cd
JL
14818}
14819
c7e4ee3a
CB
14820/* Exit a binding level.
14821 Pop the level off, and restore the state of the identifier-decl mappings
14822 that were in effect when this level was entered.
5ff904cd 14823
c7e4ee3a
CB
14824 If KEEP is nonzero, this level had explicit declarations, so
14825 and create a "block" (a BLOCK node) for the level
14826 to record its declarations and subblocks for symbol table output.
5ff904cd 14827
c7e4ee3a
CB
14828 If FUNCTIONBODY is nonzero, this level is the body of a function,
14829 so create a block as if KEEP were set and also clear out all
14830 label names.
5ff904cd 14831
c7e4ee3a
CB
14832 If REVERSE is nonzero, reverse the order of decls before putting
14833 them into the BLOCK. */
5ff904cd 14834
c7e4ee3a
CB
14835tree
14836poplevel (keep, reverse, functionbody)
14837 int keep;
14838 int reverse;
14839 int functionbody;
5ff904cd 14840{
c7e4ee3a
CB
14841 register tree link;
14842 /* The chain of decls was accumulated in reverse order.
14843 Put it into forward order, just for cleanliness. */
14844 tree decls;
14845 tree subblocks = current_binding_level->blocks;
14846 tree block = 0;
14847 tree decl;
14848 int block_previously_created;
5ff904cd 14849
c7e4ee3a
CB
14850 /* Get the decls in the order they were written.
14851 Usually current_binding_level->names is in reverse order.
14852 But parameter decls were previously put in forward order. */
702edf1d 14853
c7e4ee3a
CB
14854 if (reverse)
14855 current_binding_level->names
14856 = decls = nreverse (current_binding_level->names);
14857 else
14858 decls = current_binding_level->names;
5ff904cd 14859
c7e4ee3a
CB
14860 /* Output any nested inline functions within this block
14861 if they weren't already output. */
5ff904cd 14862
c7e4ee3a
CB
14863 for (decl = decls; decl; decl = TREE_CHAIN (decl))
14864 if (TREE_CODE (decl) == FUNCTION_DECL
14865 && ! TREE_ASM_WRITTEN (decl)
14866 && DECL_INITIAL (decl) != 0
14867 && TREE_ADDRESSABLE (decl))
14868 {
14869 /* If this decl was copied from a file-scope decl
14870 on account of a block-scope extern decl,
14871 propagate TREE_ADDRESSABLE to the file-scope decl.
14872
14873 DECL_ABSTRACT_ORIGIN can be set to itself if warn_return_type is
14874 true, since then the decl goes through save_for_inline_copying. */
14875 if (DECL_ABSTRACT_ORIGIN (decl) != 0
14876 && DECL_ABSTRACT_ORIGIN (decl) != decl)
14877 TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1;
14878 else if (DECL_SAVED_INSNS (decl) != 0)
14879 {
14880 push_function_context ();
14881 output_inline_function (decl);
14882 pop_function_context ();
14883 }
14884 }
5ff904cd 14885
c7e4ee3a
CB
14886 /* If there were any declarations or structure tags in that level,
14887 or if this level is a function body,
14888 create a BLOCK to record them for the life of this function. */
5ff904cd 14889
c7e4ee3a
CB
14890 block = 0;
14891 block_previously_created = (current_binding_level->this_block != 0);
14892 if (block_previously_created)
14893 block = current_binding_level->this_block;
14894 else if (keep || functionbody)
14895 block = make_node (BLOCK);
14896 if (block != 0)
14897 {
14898 BLOCK_VARS (block) = decls;
14899 BLOCK_SUBBLOCKS (block) = subblocks;
c7e4ee3a 14900 }
5ff904cd 14901
c7e4ee3a 14902 /* In each subblock, record that this is its superior. */
5ff904cd 14903
c7e4ee3a
CB
14904 for (link = subblocks; link; link = TREE_CHAIN (link))
14905 BLOCK_SUPERCONTEXT (link) = block;
5ff904cd 14906
c7e4ee3a 14907 /* Clear out the meanings of the local variables of this level. */
5ff904cd 14908
c7e4ee3a 14909 for (link = decls; link; link = TREE_CHAIN (link))
5ff904cd 14910 {
c7e4ee3a
CB
14911 if (DECL_NAME (link) != 0)
14912 {
14913 /* If the ident. was used or addressed via a local extern decl,
14914 don't forget that fact. */
14915 if (DECL_EXTERNAL (link))
14916 {
14917 if (TREE_USED (link))
14918 TREE_USED (DECL_NAME (link)) = 1;
14919 if (TREE_ADDRESSABLE (link))
14920 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (link)) = 1;
14921 }
14922 IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = 0;
14923 }
5ff904cd 14924 }
5ff904cd 14925
c7e4ee3a
CB
14926 /* If the level being exited is the top level of a function,
14927 check over all the labels, and clear out the current
14928 (function local) meanings of their names. */
5ff904cd 14929
c7e4ee3a 14930 if (functionbody)
5ff904cd 14931 {
c7e4ee3a
CB
14932 /* If this is the top level block of a function,
14933 the vars are the function's parameters.
14934 Don't leave them in the BLOCK because they are
14935 found in the FUNCTION_DECL instead. */
14936
14937 BLOCK_VARS (block) = 0;
5ff904cd
JL
14938 }
14939
c7e4ee3a
CB
14940 /* Pop the current level, and free the structure for reuse. */
14941
14942 {
14943 register struct binding_level *level = current_binding_level;
14944 current_binding_level = current_binding_level->level_chain;
14945
14946 level->level_chain = free_binding_level;
14947 free_binding_level = level;
14948 }
14949
14950 /* Dispose of the block that we just made inside some higher level. */
14951 if (functionbody
14952 && current_function_decl != error_mark_node)
14953 DECL_INITIAL (current_function_decl) = block;
14954 else if (block)
5ff904cd 14955 {
c7e4ee3a
CB
14956 if (!block_previously_created)
14957 current_binding_level->blocks
14958 = chainon (current_binding_level->blocks, block);
5ff904cd 14959 }
c7e4ee3a
CB
14960 /* If we did not make a block for the level just exited,
14961 any blocks made for inner levels
14962 (since they cannot be recorded as subblocks in that level)
14963 must be carried forward so they will later become subblocks
14964 of something else. */
14965 else if (subblocks)
14966 current_binding_level->blocks
14967 = chainon (current_binding_level->blocks, subblocks);
5ff904cd 14968
c7e4ee3a
CB
14969 if (block)
14970 TREE_USED (block) = 1;
14971 return block;
5ff904cd
JL
14972}
14973
c7e4ee3a
CB
14974void
14975print_lang_decl (file, node, indent)
14976 FILE *file UNUSED;
14977 tree node UNUSED;
14978 int indent UNUSED;
14979{
14980}
5ff904cd 14981
c7e4ee3a
CB
14982void
14983print_lang_identifier (file, node, indent)
14984 FILE *file;
14985 tree node;
14986 int indent;
14987{
14988 print_node (file, "global", IDENTIFIER_GLOBAL_VALUE (node), indent + 4);
14989 print_node (file, "local", IDENTIFIER_LOCAL_VALUE (node), indent + 4);
14990}
5ff904cd 14991
c7e4ee3a
CB
14992void
14993print_lang_statistics ()
14994{
14995}
5ff904cd 14996
c7e4ee3a
CB
14997void
14998print_lang_type (file, node, indent)
14999 FILE *file UNUSED;
15000 tree node UNUSED;
15001 int indent UNUSED;
5ff904cd 15002{
c7e4ee3a 15003}
5ff904cd 15004
c7e4ee3a
CB
15005/* Record a decl-node X as belonging to the current lexical scope.
15006 Check for errors (such as an incompatible declaration for the same
15007 name already seen in the same scope).
5ff904cd 15008
c7e4ee3a
CB
15009 Returns either X or an old decl for the same name.
15010 If an old decl is returned, it may have been smashed
15011 to agree with what X says. */
5ff904cd 15012
c7e4ee3a
CB
15013tree
15014pushdecl (x)
15015 tree x;
15016{
15017 register tree t;
15018 register tree name = DECL_NAME (x);
15019 register struct binding_level *b = current_binding_level;
5ff904cd 15020
c7e4ee3a
CB
15021 if ((TREE_CODE (x) == FUNCTION_DECL)
15022 && (DECL_INITIAL (x) == 0)
15023 && DECL_EXTERNAL (x))
15024 DECL_CONTEXT (x) = NULL_TREE;
56a0044b 15025 else
c7e4ee3a
CB
15026 DECL_CONTEXT (x) = current_function_decl;
15027
15028 if (name)
56a0044b 15029 {
c7e4ee3a
CB
15030 if (IDENTIFIER_INVENTED (name))
15031 {
15032#if BUILT_FOR_270
15033 DECL_ARTIFICIAL (x) = 1;
15034#endif
15035 DECL_IN_SYSTEM_HEADER (x) = 1;
15036 }
5ff904cd 15037
c7e4ee3a 15038 t = lookup_name_current_level (name);
5ff904cd 15039
c7e4ee3a 15040 assert ((t == NULL_TREE) || (DECL_CONTEXT (x) == NULL_TREE));
5ff904cd 15041
c7e4ee3a
CB
15042 /* Don't push non-parms onto list for parms until we understand
15043 why we're doing this and whether it works. */
56a0044b 15044
c7e4ee3a
CB
15045 assert ((b == global_binding_level)
15046 || !ffecom_transform_only_dummies_
15047 || TREE_CODE (x) == PARM_DECL);
5ff904cd 15048
c7e4ee3a
CB
15049 if ((t != NULL_TREE) && duplicate_decls (x, t))
15050 return t;
5ff904cd 15051
c7e4ee3a
CB
15052 /* If we are processing a typedef statement, generate a whole new
15053 ..._TYPE node (which will be just an variant of the existing
15054 ..._TYPE node with identical properties) and then install the
15055 TYPE_DECL node generated to represent the typedef name as the
15056 TYPE_NAME of this brand new (duplicate) ..._TYPE node.
5ff904cd 15057
c7e4ee3a
CB
15058 The whole point here is to end up with a situation where each and every
15059 ..._TYPE node the compiler creates will be uniquely associated with
15060 AT MOST one node representing a typedef name. This way, even though
15061 the compiler substitutes corresponding ..._TYPE nodes for TYPE_DECL
15062 (i.e. "typedef name") nodes very early on, later parts of the
15063 compiler can always do the reverse translation and get back the
15064 corresponding typedef name. For example, given:
5ff904cd 15065
c7e4ee3a 15066 typedef struct S MY_TYPE; MY_TYPE object;
5ff904cd 15067
c7e4ee3a
CB
15068 Later parts of the compiler might only know that `object' was of type
15069 `struct S' if it were not for code just below. With this code
15070 however, later parts of the compiler see something like:
5ff904cd 15071
c7e4ee3a 15072 struct S' == struct S typedef struct S' MY_TYPE; struct S' object;
5ff904cd 15073
c7e4ee3a
CB
15074 And they can then deduce (from the node for type struct S') that the
15075 original object declaration was:
5ff904cd 15076
c7e4ee3a 15077 MY_TYPE object;
5ff904cd 15078
c7e4ee3a
CB
15079 Being able to do this is important for proper support of protoize, and
15080 also for generating precise symbolic debugging information which
15081 takes full account of the programmer's (typedef) vocabulary.
5ff904cd 15082
c7e4ee3a
CB
15083 Obviously, we don't want to generate a duplicate ..._TYPE node if the
15084 TYPE_DECL node that we are now processing really represents a
15085 standard built-in type.
5ff904cd 15086
c7e4ee3a
CB
15087 Since all standard types are effectively declared at line zero in the
15088 source file, we can easily check to see if we are working on a
15089 standard type by checking the current value of lineno. */
15090
15091 if (TREE_CODE (x) == TYPE_DECL)
15092 {
15093 if (DECL_SOURCE_LINE (x) == 0)
15094 {
15095 if (TYPE_NAME (TREE_TYPE (x)) == 0)
15096 TYPE_NAME (TREE_TYPE (x)) = x;
15097 }
15098 else if (TREE_TYPE (x) != error_mark_node)
15099 {
15100 tree tt = TREE_TYPE (x);
15101
15102 tt = build_type_copy (tt);
15103 TYPE_NAME (tt) = x;
15104 TREE_TYPE (x) = tt;
15105 }
15106 }
5ff904cd 15107
c7e4ee3a
CB
15108 /* This name is new in its binding level. Install the new declaration
15109 and return it. */
15110 if (b == global_binding_level)
15111 IDENTIFIER_GLOBAL_VALUE (name) = x;
15112 else
15113 IDENTIFIER_LOCAL_VALUE (name) = x;
15114 }
5ff904cd 15115
c7e4ee3a
CB
15116 /* Put decls on list in reverse order. We will reverse them later if
15117 necessary. */
15118 TREE_CHAIN (x) = b->names;
15119 b->names = x;
5ff904cd 15120
c7e4ee3a 15121 return x;
5ff904cd
JL
15122}
15123
c7e4ee3a 15124/* Nonzero if the current level needs to have a BLOCK made. */
5ff904cd 15125
c7e4ee3a
CB
15126static int
15127kept_level_p ()
5ff904cd 15128{
c7e4ee3a
CB
15129 tree decl;
15130
15131 for (decl = current_binding_level->names;
15132 decl;
15133 decl = TREE_CHAIN (decl))
15134 {
15135 if (TREE_USED (decl) || TREE_CODE (decl) != VAR_DECL
15136 || (DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl)))
15137 /* Currently, there aren't supposed to be non-artificial names
15138 at other than the top block for a function -- they're
15139 believed to always be temps. But it's wise to check anyway. */
15140 return 1;
15141 }
15142 return 0;
5ff904cd
JL
15143}
15144
c7e4ee3a
CB
15145/* Enter a new binding level.
15146 If TAG_TRANSPARENT is nonzero, do so only for the name space of variables,
15147 not for that of tags. */
5ff904cd
JL
15148
15149void
c7e4ee3a
CB
15150pushlevel (tag_transparent)
15151 int tag_transparent;
5ff904cd 15152{
c7e4ee3a 15153 register struct binding_level *newlevel = NULL_BINDING_LEVEL;
5ff904cd 15154
c7e4ee3a 15155 assert (! tag_transparent);
5ff904cd 15156
c7e4ee3a
CB
15157 if (current_binding_level == global_binding_level)
15158 {
15159 named_labels = 0;
15160 }
5ff904cd 15161
c7e4ee3a 15162 /* Reuse or create a struct for this binding level. */
5ff904cd 15163
c7e4ee3a 15164 if (free_binding_level)
77f77701 15165 {
c7e4ee3a
CB
15166 newlevel = free_binding_level;
15167 free_binding_level = free_binding_level->level_chain;
77f77701
DB
15168 }
15169 else
c7e4ee3a
CB
15170 {
15171 newlevel = make_binding_level ();
15172 }
77f77701 15173
c7e4ee3a
CB
15174 /* Add this level to the front of the chain (stack) of levels that
15175 are active. */
71b5e532 15176
c7e4ee3a
CB
15177 *newlevel = clear_binding_level;
15178 newlevel->level_chain = current_binding_level;
15179 current_binding_level = newlevel;
5ff904cd
JL
15180}
15181
c7e4ee3a
CB
15182/* Set the BLOCK node for the innermost scope
15183 (the one we are currently in). */
77f77701 15184
5ff904cd 15185void
c7e4ee3a
CB
15186set_block (block)
15187 register tree block;
5ff904cd 15188{
c7e4ee3a 15189 current_binding_level->this_block = block;
5ff904cd
JL
15190}
15191
c7e4ee3a 15192/* ~~gcc/tree.h *should* declare this, because toplev.c references it. */
5ff904cd 15193
c7e4ee3a 15194/* Can't 'yydebug' a front end not generated by yacc/bison! */
bc289659
ML
15195
15196void
c7e4ee3a
CB
15197set_yydebug (value)
15198 int value;
bc289659 15199{
c7e4ee3a
CB
15200 if (value)
15201 fprintf (stderr, "warning: no yacc/bison-generated output to debug!\n");
bc289659
ML
15202}
15203
c7e4ee3a
CB
15204tree
15205signed_or_unsigned_type (unsignedp, type)
15206 int unsignedp;
15207 tree type;
5ff904cd 15208{
c7e4ee3a 15209 tree type2;
5ff904cd 15210
c7e4ee3a
CB
15211 if (! INTEGRAL_TYPE_P (type))
15212 return type;
15213 if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node))
15214 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
15215 if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
15216 return unsignedp ? unsigned_type_node : integer_type_node;
15217 if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node))
15218 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
15219 if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node))
15220 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
15221 if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node))
15222 return (unsignedp ? long_long_unsigned_type_node
15223 : long_long_integer_type_node);
5ff904cd 15224
c7e4ee3a
CB
15225 type2 = type_for_size (TYPE_PRECISION (type), unsignedp);
15226 if (type2 == NULL_TREE)
15227 return type;
f84639ba 15228
c7e4ee3a 15229 return type2;
5ff904cd
JL
15230}
15231
c7e4ee3a
CB
15232tree
15233signed_type (type)
15234 tree type;
5ff904cd 15235{
c7e4ee3a
CB
15236 tree type1 = TYPE_MAIN_VARIANT (type);
15237 ffeinfoKindtype kt;
15238 tree type2;
5ff904cd 15239
c7e4ee3a
CB
15240 if (type1 == unsigned_char_type_node || type1 == char_type_node)
15241 return signed_char_type_node;
15242 if (type1 == unsigned_type_node)
15243 return integer_type_node;
15244 if (type1 == short_unsigned_type_node)
15245 return short_integer_type_node;
15246 if (type1 == long_unsigned_type_node)
15247 return long_integer_type_node;
15248 if (type1 == long_long_unsigned_type_node)
15249 return long_long_integer_type_node;
15250#if 0 /* gcc/c-* files only */
15251 if (type1 == unsigned_intDI_type_node)
15252 return intDI_type_node;
15253 if (type1 == unsigned_intSI_type_node)
15254 return intSI_type_node;
15255 if (type1 == unsigned_intHI_type_node)
15256 return intHI_type_node;
15257 if (type1 == unsigned_intQI_type_node)
15258 return intQI_type_node;
15259#endif
5ff904cd 15260
c7e4ee3a
CB
15261 type2 = type_for_size (TYPE_PRECISION (type1), 0);
15262 if (type2 != NULL_TREE)
15263 return type2;
5ff904cd 15264
c7e4ee3a
CB
15265 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
15266 {
15267 type2 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
5ff904cd 15268
c7e4ee3a
CB
15269 if (type1 == type2)
15270 return ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
15271 }
15272
15273 return type;
5ff904cd
JL
15274}
15275
c7e4ee3a
CB
15276/* Prepare expr to be an argument of a TRUTH_NOT_EXPR,
15277 or validate its data type for an `if' or `while' statement or ?..: exp.
15278
15279 This preparation consists of taking the ordinary
15280 representation of an expression expr and producing a valid tree
15281 boolean expression describing whether expr is nonzero. We could
15282 simply always do build_binary_op (NE_EXPR, expr, integer_zero_node, 1),
15283 but we optimize comparisons, &&, ||, and !.
15284
15285 The resulting type should always be `integer_type_node'. */
5ff904cd
JL
15286
15287tree
c7e4ee3a
CB
15288truthvalue_conversion (expr)
15289 tree expr;
5ff904cd 15290{
c7e4ee3a
CB
15291 if (TREE_CODE (expr) == ERROR_MARK)
15292 return expr;
5ff904cd 15293
c7e4ee3a
CB
15294#if 0 /* This appears to be wrong for C++. */
15295 /* These really should return error_mark_node after 2.4 is stable.
15296 But not all callers handle ERROR_MARK properly. */
15297 switch (TREE_CODE (TREE_TYPE (expr)))
15298 {
15299 case RECORD_TYPE:
15300 error ("struct type value used where scalar is required");
15301 return integer_zero_node;
5ff904cd 15302
c7e4ee3a
CB
15303 case UNION_TYPE:
15304 error ("union type value used where scalar is required");
15305 return integer_zero_node;
5ff904cd 15306
c7e4ee3a
CB
15307 case ARRAY_TYPE:
15308 error ("array type value used where scalar is required");
15309 return integer_zero_node;
5ff904cd 15310
c7e4ee3a
CB
15311 default:
15312 break;
15313 }
15314#endif /* 0 */
5ff904cd 15315
c7e4ee3a
CB
15316 switch (TREE_CODE (expr))
15317 {
15318 /* It is simpler and generates better code to have only TRUTH_*_EXPR
15319 or comparison expressions as truth values at this level. */
15320#if 0
15321 case COMPONENT_REF:
15322 /* A one-bit unsigned bit-field is already acceptable. */
15323 if (1 == TREE_INT_CST_LOW (DECL_SIZE (TREE_OPERAND (expr, 1)))
15324 && TREE_UNSIGNED (TREE_OPERAND (expr, 1)))
15325 return expr;
15326 break;
15327#endif
15328
15329 case EQ_EXPR:
15330 /* It is simpler and generates better code to have only TRUTH_*_EXPR
15331 or comparison expressions as truth values at this level. */
15332#if 0
15333 if (integer_zerop (TREE_OPERAND (expr, 1)))
15334 return build_unary_op (TRUTH_NOT_EXPR, TREE_OPERAND (expr, 0), 0);
15335#endif
15336 case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
15337 case TRUTH_ANDIF_EXPR:
15338 case TRUTH_ORIF_EXPR:
15339 case TRUTH_AND_EXPR:
15340 case TRUTH_OR_EXPR:
15341 case TRUTH_XOR_EXPR:
15342 TREE_TYPE (expr) = integer_type_node;
15343 return expr;
5ff904cd 15344
c7e4ee3a
CB
15345 case ERROR_MARK:
15346 return expr;
5ff904cd 15347
c7e4ee3a
CB
15348 case INTEGER_CST:
15349 return integer_zerop (expr) ? integer_zero_node : integer_one_node;
5ff904cd 15350
c7e4ee3a
CB
15351 case REAL_CST:
15352 return real_zerop (expr) ? integer_zero_node : integer_one_node;
5ff904cd 15353
c7e4ee3a
CB
15354 case ADDR_EXPR:
15355 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 0)))
15356 return build (COMPOUND_EXPR, integer_type_node,
15357 TREE_OPERAND (expr, 0), integer_one_node);
15358 else
15359 return integer_one_node;
5ff904cd 15360
c7e4ee3a
CB
15361 case COMPLEX_EXPR:
15362 return ffecom_2 ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))
15363 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
15364 integer_type_node,
15365 truthvalue_conversion (TREE_OPERAND (expr, 0)),
15366 truthvalue_conversion (TREE_OPERAND (expr, 1)));
5ff904cd 15367
c7e4ee3a
CB
15368 case NEGATE_EXPR:
15369 case ABS_EXPR:
15370 case FLOAT_EXPR:
15371 case FFS_EXPR:
15372 /* These don't change whether an object is non-zero or zero. */
15373 return truthvalue_conversion (TREE_OPERAND (expr, 0));
5ff904cd 15374
c7e4ee3a
CB
15375 case LROTATE_EXPR:
15376 case RROTATE_EXPR:
15377 /* These don't change whether an object is zero or non-zero, but
15378 we can't ignore them if their second arg has side-effects. */
15379 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)))
15380 return build (COMPOUND_EXPR, integer_type_node, TREE_OPERAND (expr, 1),
15381 truthvalue_conversion (TREE_OPERAND (expr, 0)));
15382 else
15383 return truthvalue_conversion (TREE_OPERAND (expr, 0));
5ff904cd 15384
c7e4ee3a
CB
15385 case COND_EXPR:
15386 /* Distribute the conversion into the arms of a COND_EXPR. */
15387 return fold (build (COND_EXPR, integer_type_node, TREE_OPERAND (expr, 0),
15388 truthvalue_conversion (TREE_OPERAND (expr, 1)),
15389 truthvalue_conversion (TREE_OPERAND (expr, 2))));
5ff904cd 15390
c7e4ee3a
CB
15391 case CONVERT_EXPR:
15392 /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
15393 since that affects how `default_conversion' will behave. */
15394 if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE
15395 || TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)
15396 break;
15397 /* fall through... */
15398 case NOP_EXPR:
15399 /* If this is widening the argument, we can ignore it. */
15400 if (TYPE_PRECISION (TREE_TYPE (expr))
15401 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
15402 return truthvalue_conversion (TREE_OPERAND (expr, 0));
15403 break;
5ff904cd 15404
c7e4ee3a
CB
15405 case MINUS_EXPR:
15406 /* With IEEE arithmetic, x - x may not equal 0, so we can't optimize
15407 this case. */
15408 if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
15409 && TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE)
15410 break;
15411 /* fall through... */
15412 case BIT_XOR_EXPR:
15413 /* This and MINUS_EXPR can be changed into a comparison of the
15414 two objects. */
15415 if (TREE_TYPE (TREE_OPERAND (expr, 0))
15416 == TREE_TYPE (TREE_OPERAND (expr, 1)))
15417 return ffecom_2 (NE_EXPR, integer_type_node,
15418 TREE_OPERAND (expr, 0),
15419 TREE_OPERAND (expr, 1));
15420 return ffecom_2 (NE_EXPR, integer_type_node,
15421 TREE_OPERAND (expr, 0),
15422 fold (build1 (NOP_EXPR,
15423 TREE_TYPE (TREE_OPERAND (expr, 0)),
15424 TREE_OPERAND (expr, 1))));
15425
15426 case BIT_AND_EXPR:
15427 if (integer_onep (TREE_OPERAND (expr, 1)))
15428 return expr;
15429 break;
15430
15431 case MODIFY_EXPR:
15432#if 0 /* No such thing in Fortran. */
15433 if (warn_parentheses && C_EXP_ORIGINAL_CODE (expr) == MODIFY_EXPR)
15434 warning ("suggest parentheses around assignment used as truth value");
15435#endif
15436 break;
15437
15438 default:
15439 break;
5ff904cd
JL
15440 }
15441
c7e4ee3a
CB
15442 if (TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE)
15443 return (ffecom_2
15444 ((TREE_SIDE_EFFECTS (expr)
15445 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
15446 integer_type_node,
15447 truthvalue_conversion (ffecom_1 (REALPART_EXPR,
15448 TREE_TYPE (TREE_TYPE (expr)),
15449 expr)),
15450 truthvalue_conversion (ffecom_1 (IMAGPART_EXPR,
15451 TREE_TYPE (TREE_TYPE (expr)),
15452 expr))));
15453
15454 return ffecom_2 (NE_EXPR, integer_type_node,
15455 expr,
15456 convert (TREE_TYPE (expr), integer_zero_node));
15457}
15458
15459tree
15460type_for_mode (mode, unsignedp)
15461 enum machine_mode mode;
15462 int unsignedp;
15463{
15464 int i;
15465 int j;
15466 tree t;
5ff904cd 15467
c7e4ee3a
CB
15468 if (mode == TYPE_MODE (integer_type_node))
15469 return unsignedp ? unsigned_type_node : integer_type_node;
5ff904cd 15470
c7e4ee3a
CB
15471 if (mode == TYPE_MODE (signed_char_type_node))
15472 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
5ff904cd 15473
c7e4ee3a
CB
15474 if (mode == TYPE_MODE (short_integer_type_node))
15475 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
5ff904cd 15476
c7e4ee3a
CB
15477 if (mode == TYPE_MODE (long_integer_type_node))
15478 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
5ff904cd 15479
c7e4ee3a
CB
15480 if (mode == TYPE_MODE (long_long_integer_type_node))
15481 return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node;
5ff904cd 15482
fed3cef0
RK
15483#if HOST_BITS_PER_WIDE_INT >= 64
15484 if (mode == TYPE_MODE (intTI_type_node))
15485 return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
15486#endif
15487
c7e4ee3a
CB
15488 if (mode == TYPE_MODE (float_type_node))
15489 return float_type_node;
5ff904cd 15490
c7e4ee3a
CB
15491 if (mode == TYPE_MODE (double_type_node))
15492 return double_type_node;
5ff904cd 15493
c7e4ee3a
CB
15494 if (mode == TYPE_MODE (build_pointer_type (char_type_node)))
15495 return build_pointer_type (char_type_node);
5ff904cd 15496
c7e4ee3a
CB
15497 if (mode == TYPE_MODE (build_pointer_type (integer_type_node)))
15498 return build_pointer_type (integer_type_node);
5ff904cd 15499
c7e4ee3a
CB
15500 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
15501 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
15502 {
15503 if (((t = ffecom_tree_type[i][j]) != NULL_TREE)
15504 && (mode == TYPE_MODE (t)))
15505 {
15506 if ((i == FFEINFO_basictypeINTEGER) && unsignedp)
15507 return ffecom_tree_type[FFEINFO_basictypeHOLLERITH][j];
15508 else
15509 return t;
15510 }
15511 }
5ff904cd 15512
c7e4ee3a 15513 return 0;
5ff904cd
JL
15514}
15515
c7e4ee3a
CB
15516tree
15517type_for_size (bits, unsignedp)
15518 unsigned bits;
15519 int unsignedp;
5ff904cd 15520{
c7e4ee3a
CB
15521 ffeinfoKindtype kt;
15522 tree type_node;
5ff904cd 15523
c7e4ee3a
CB
15524 if (bits == TYPE_PRECISION (integer_type_node))
15525 return unsignedp ? unsigned_type_node : integer_type_node;
5ff904cd 15526
c7e4ee3a
CB
15527 if (bits == TYPE_PRECISION (signed_char_type_node))
15528 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
5ff904cd 15529
c7e4ee3a
CB
15530 if (bits == TYPE_PRECISION (short_integer_type_node))
15531 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
5ff904cd 15532
c7e4ee3a
CB
15533 if (bits == TYPE_PRECISION (long_integer_type_node))
15534 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
5ff904cd 15535
c7e4ee3a
CB
15536 if (bits == TYPE_PRECISION (long_long_integer_type_node))
15537 return (unsignedp ? long_long_unsigned_type_node
15538 : long_long_integer_type_node);
5ff904cd 15539
c7e4ee3a 15540 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
5ff904cd 15541 {
c7e4ee3a 15542 type_node = ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
5ff904cd 15543
c7e4ee3a
CB
15544 if ((type_node != NULL_TREE) && (bits == TYPE_PRECISION (type_node)))
15545 return unsignedp ? ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt]
15546 : type_node;
15547 }
5ff904cd 15548
c7e4ee3a
CB
15549 return 0;
15550}
5ff904cd 15551
c7e4ee3a
CB
15552tree
15553unsigned_type (type)
15554 tree type;
15555{
15556 tree type1 = TYPE_MAIN_VARIANT (type);
15557 ffeinfoKindtype kt;
15558 tree type2;
5ff904cd 15559
c7e4ee3a
CB
15560 if (type1 == signed_char_type_node || type1 == char_type_node)
15561 return unsigned_char_type_node;
15562 if (type1 == integer_type_node)
15563 return unsigned_type_node;
15564 if (type1 == short_integer_type_node)
15565 return short_unsigned_type_node;
15566 if (type1 == long_integer_type_node)
15567 return long_unsigned_type_node;
15568 if (type1 == long_long_integer_type_node)
15569 return long_long_unsigned_type_node;
15570#if 0 /* gcc/c-* files only */
15571 if (type1 == intDI_type_node)
15572 return unsigned_intDI_type_node;
15573 if (type1 == intSI_type_node)
15574 return unsigned_intSI_type_node;
15575 if (type1 == intHI_type_node)
15576 return unsigned_intHI_type_node;
15577 if (type1 == intQI_type_node)
15578 return unsigned_intQI_type_node;
15579#endif
5ff904cd 15580
c7e4ee3a
CB
15581 type2 = type_for_size (TYPE_PRECISION (type1), 1);
15582 if (type2 != NULL_TREE)
15583 return type2;
5ff904cd 15584
c7e4ee3a
CB
15585 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
15586 {
15587 type2 = ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
5ff904cd 15588
c7e4ee3a
CB
15589 if (type1 == type2)
15590 return ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
15591 }
5ff904cd 15592
c7e4ee3a
CB
15593 return type;
15594}
5ff904cd 15595
7189a4b0
GK
15596void
15597lang_mark_tree (t)
15598 union tree_node *t ATTRIBUTE_UNUSED;
15599{
15600 if (TREE_CODE (t) == IDENTIFIER_NODE)
15601 {
15602 struct lang_identifier *i = (struct lang_identifier *) t;
15603 ggc_mark_tree (IDENTIFIER_GLOBAL_VALUE (i));
15604 ggc_mark_tree (IDENTIFIER_LOCAL_VALUE (i));
15605 ggc_mark_tree (IDENTIFIER_LABEL_VALUE (i));
15606 }
15607 else if (TYPE_P (t) && TYPE_LANG_SPECIFIC (t))
15608 ggc_mark (TYPE_LANG_SPECIFIC (t));
15609}
15610
c7e4ee3a
CB
15611#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
15612\f
15613#if FFECOM_GCC_INCLUDE
5ff904cd 15614
c7e4ee3a 15615/* From gcc/cccp.c, the code to handle -I. */
5ff904cd 15616
c7e4ee3a
CB
15617/* Skip leading "./" from a directory name.
15618 This may yield the empty string, which represents the current directory. */
5ff904cd 15619
c7e4ee3a
CB
15620static const char *
15621skip_redundant_dir_prefix (const char *dir)
15622{
15623 while (dir[0] == '.' && dir[1] == '/')
15624 for (dir += 2; *dir == '/'; dir++)
15625 continue;
15626 if (dir[0] == '.' && !dir[1])
15627 dir++;
15628 return dir;
15629}
5ff904cd 15630
c7e4ee3a
CB
15631/* The file_name_map structure holds a mapping of file names for a
15632 particular directory. This mapping is read from the file named
15633 FILE_NAME_MAP_FILE in that directory. Such a file can be used to
15634 map filenames on a file system with severe filename restrictions,
15635 such as DOS. The format of the file name map file is just a series
15636 of lines with two tokens on each line. The first token is the name
15637 to map, and the second token is the actual name to use. */
5ff904cd 15638
c7e4ee3a
CB
15639struct file_name_map
15640{
15641 struct file_name_map *map_next;
15642 char *map_from;
15643 char *map_to;
15644};
5ff904cd 15645
c7e4ee3a 15646#define FILE_NAME_MAP_FILE "header.gcc"
5ff904cd 15647
c7e4ee3a
CB
15648/* Current maximum length of directory names in the search path
15649 for include files. (Altered as we get more of them.) */
5ff904cd 15650
c7e4ee3a 15651static int max_include_len = 0;
5ff904cd 15652
c7e4ee3a
CB
15653struct file_name_list
15654 {
15655 struct file_name_list *next;
15656 char *fname;
15657 /* Mapping of file names for this directory. */
15658 struct file_name_map *name_map;
15659 /* Non-zero if name_map is valid. */
15660 int got_name_map;
15661 };
5ff904cd 15662
c7e4ee3a
CB
15663static struct file_name_list *include = NULL; /* First dir to search */
15664static struct file_name_list *last_include = NULL; /* Last in chain */
5ff904cd 15665
c7e4ee3a
CB
15666/* I/O buffer structure.
15667 The `fname' field is nonzero for source files and #include files
15668 and for the dummy text used for -D and -U.
15669 It is zero for rescanning results of macro expansion
15670 and for expanding macro arguments. */
15671#define INPUT_STACK_MAX 400
15672static struct file_buf {
b0791fa9 15673 const char *fname;
c7e4ee3a 15674 /* Filename specified with #line command. */
b0791fa9 15675 const char *nominal_fname;
c7e4ee3a
CB
15676 /* Record where in the search path this file was found.
15677 For #include_next. */
15678 struct file_name_list *dir;
15679 ffewhereLine line;
15680 ffewhereColumn column;
15681} instack[INPUT_STACK_MAX];
5ff904cd 15682
c7e4ee3a
CB
15683static int last_error_tick = 0; /* Incremented each time we print it. */
15684static int input_file_stack_tick = 0; /* Incremented when status changes. */
5ff904cd 15685
c7e4ee3a
CB
15686/* Current nesting level of input sources.
15687 `instack[indepth]' is the level currently being read. */
15688static int indepth = -1;
5ff904cd 15689
c7e4ee3a 15690typedef struct file_buf FILE_BUF;
5ff904cd 15691
c7e4ee3a 15692typedef unsigned char U_CHAR;
5ff904cd 15693
c7e4ee3a
CB
15694/* table to tell if char can be part of a C identifier. */
15695U_CHAR is_idchar[256];
15696/* table to tell if char can be first char of a c identifier. */
15697U_CHAR is_idstart[256];
15698/* table to tell if c is horizontal space. */
15699U_CHAR is_hor_space[256];
15700/* table to tell if c is horizontal or vertical space. */
15701static U_CHAR is_space[256];
5ff904cd 15702
c7e4ee3a
CB
15703#define SKIP_WHITE_SPACE(p) do { while (is_hor_space[*p]) p++; } while (0)
15704#define SKIP_ALL_WHITE_SPACE(p) do { while (is_space[*p]) p++; } while (0)
5ff904cd 15705
c7e4ee3a
CB
15706/* Nonzero means -I- has been seen,
15707 so don't look for #include "foo" the source-file directory. */
15708static int ignore_srcdir;
5ff904cd 15709
c7e4ee3a
CB
15710#ifndef INCLUDE_LEN_FUDGE
15711#define INCLUDE_LEN_FUDGE 0
15712#endif
5ff904cd 15713
c7e4ee3a
CB
15714static void append_include_chain (struct file_name_list *first,
15715 struct file_name_list *last);
15716static FILE *open_include_file (char *filename,
15717 struct file_name_list *searchptr);
15718static void print_containing_files (ffebadSeverity sev);
15719static const char *skip_redundant_dir_prefix (const char *);
15720static char *read_filename_string (int ch, FILE *f);
15721static struct file_name_map *read_name_map (const char *dirname);
5ff904cd 15722
c7e4ee3a
CB
15723/* Append a chain of `struct file_name_list's
15724 to the end of the main include chain.
15725 FIRST is the beginning of the chain to append, and LAST is the end. */
5ff904cd 15726
c7e4ee3a
CB
15727static void
15728append_include_chain (first, last)
15729 struct file_name_list *first, *last;
5ff904cd 15730{
c7e4ee3a 15731 struct file_name_list *dir;
5ff904cd 15732
c7e4ee3a
CB
15733 if (!first || !last)
15734 return;
5ff904cd 15735
c7e4ee3a
CB
15736 if (include == 0)
15737 include = first;
15738 else
15739 last_include->next = first;
5ff904cd 15740
c7e4ee3a
CB
15741 for (dir = first; ; dir = dir->next) {
15742 int len = strlen (dir->fname) + INCLUDE_LEN_FUDGE;
15743 if (len > max_include_len)
15744 max_include_len = len;
15745 if (dir == last)
15746 break;
15747 }
15748
15749 last->next = NULL;
15750 last_include = last;
5ff904cd
JL
15751}
15752
c7e4ee3a
CB
15753/* Try to open include file FILENAME. SEARCHPTR is the directory
15754 being tried from the include file search path. This function maps
15755 filenames on file systems based on information read by
15756 read_name_map. */
15757
15758static FILE *
15759open_include_file (filename, searchptr)
15760 char *filename;
15761 struct file_name_list *searchptr;
5ff904cd 15762{
c7e4ee3a
CB
15763 register struct file_name_map *map;
15764 register char *from;
15765 char *p, *dir;
5ff904cd 15766
c7e4ee3a
CB
15767 if (searchptr && ! searchptr->got_name_map)
15768 {
15769 searchptr->name_map = read_name_map (searchptr->fname
15770 ? searchptr->fname : ".");
15771 searchptr->got_name_map = 1;
15772 }
5ff904cd 15773
c7e4ee3a
CB
15774 /* First check the mapping for the directory we are using. */
15775 if (searchptr && searchptr->name_map)
15776 {
15777 from = filename;
15778 if (searchptr->fname)
15779 from += strlen (searchptr->fname) + 1;
15780 for (map = searchptr->name_map; map; map = map->map_next)
15781 {
15782 if (! strcmp (map->map_from, from))
15783 {
15784 /* Found a match. */
15785 return fopen (map->map_to, "r");
15786 }
15787 }
15788 }
5ff904cd 15789
c7e4ee3a
CB
15790 /* Try to find a mapping file for the particular directory we are
15791 looking in. Thus #include <sys/types.h> will look up sys/types.h
15792 in /usr/include/header.gcc and look up types.h in
15793 /usr/include/sys/header.gcc. */
9473c522 15794 p = strrchr (filename, '/');
c7e4ee3a 15795#ifdef DIR_SEPARATOR
9473c522 15796 if (! p) p = strrchr (filename, DIR_SEPARATOR);
c7e4ee3a 15797 else {
9473c522 15798 char *tmp = strrchr (filename, DIR_SEPARATOR);
c7e4ee3a
CB
15799 if (tmp != NULL && tmp > p) p = tmp;
15800 }
15801#endif
15802 if (! p)
15803 p = filename;
15804 if (searchptr
15805 && searchptr->fname
15806 && strlen (searchptr->fname) == (size_t) (p - filename)
15807 && ! strncmp (searchptr->fname, filename, (int) (p - filename)))
15808 {
15809 /* FILENAME is in SEARCHPTR, which we've already checked. */
15810 return fopen (filename, "r");
15811 }
15812
15813 if (p == filename)
15814 {
15815 from = filename;
15816 map = read_name_map (".");
15817 }
15818 else
5ff904cd 15819 {
c7e4ee3a
CB
15820 dir = (char *) xmalloc (p - filename + 1);
15821 memcpy (dir, filename, p - filename);
15822 dir[p - filename] = '\0';
15823 from = p + 1;
15824 map = read_name_map (dir);
15825 free (dir);
5ff904cd 15826 }
c7e4ee3a
CB
15827 for (; map; map = map->map_next)
15828 if (! strcmp (map->map_from, from))
15829 return fopen (map->map_to, "r");
5ff904cd 15830
c7e4ee3a 15831 return fopen (filename, "r");
5ff904cd
JL
15832}
15833
c7e4ee3a
CB
15834/* Print the file names and line numbers of the #include
15835 commands which led to the current file. */
5ff904cd 15836
c7e4ee3a
CB
15837static void
15838print_containing_files (ffebadSeverity sev)
15839{
15840 FILE_BUF *ip = NULL;
15841 int i;
15842 int first = 1;
15843 const char *str1;
15844 const char *str2;
5ff904cd 15845
c7e4ee3a
CB
15846 /* If stack of files hasn't changed since we last printed
15847 this info, don't repeat it. */
15848 if (last_error_tick == input_file_stack_tick)
15849 return;
5ff904cd 15850
c7e4ee3a
CB
15851 for (i = indepth; i >= 0; i--)
15852 if (instack[i].fname != NULL) {
15853 ip = &instack[i];
15854 break;
15855 }
5ff904cd 15856
c7e4ee3a
CB
15857 /* Give up if we don't find a source file. */
15858 if (ip == NULL)
15859 return;
5ff904cd 15860
c7e4ee3a
CB
15861 /* Find the other, outer source files. */
15862 for (i--; i >= 0; i--)
15863 if (instack[i].fname != NULL)
15864 {
15865 ip = &instack[i];
15866 if (first)
15867 {
15868 first = 0;
15869 str1 = "In file included";
15870 }
15871 else
15872 {
15873 str1 = "... ...";
15874 }
5ff904cd 15875
c7e4ee3a
CB
15876 if (i == 1)
15877 str2 = ":";
15878 else
15879 str2 = "";
5ff904cd 15880
c7e4ee3a
CB
15881 ffebad_start_msg ("%A from %B at %0%C", sev);
15882 ffebad_here (0, ip->line, ip->column);
15883 ffebad_string (str1);
15884 ffebad_string (ip->nominal_fname);
15885 ffebad_string (str2);
15886 ffebad_finish ();
15887 }
5ff904cd 15888
c7e4ee3a
CB
15889 /* Record we have printed the status as of this time. */
15890 last_error_tick = input_file_stack_tick;
15891}
5ff904cd 15892
c7e4ee3a
CB
15893/* Read a space delimited string of unlimited length from a stdio
15894 file. */
5ff904cd 15895
c7e4ee3a
CB
15896static char *
15897read_filename_string (ch, f)
15898 int ch;
15899 FILE *f;
15900{
15901 char *alloc, *set;
15902 int len;
5ff904cd 15903
c7e4ee3a
CB
15904 len = 20;
15905 set = alloc = xmalloc (len + 1);
15906 if (! is_space[ch])
15907 {
15908 *set++ = ch;
15909 while ((ch = getc (f)) != EOF && ! is_space[ch])
15910 {
15911 if (set - alloc == len)
15912 {
15913 len *= 2;
15914 alloc = xrealloc (alloc, len + 1);
15915 set = alloc + len / 2;
15916 }
15917 *set++ = ch;
15918 }
15919 }
15920 *set = '\0';
15921 ungetc (ch, f);
15922 return alloc;
15923}
5ff904cd 15924
c7e4ee3a 15925/* Read the file name map file for DIRNAME. */
5ff904cd 15926
c7e4ee3a
CB
15927static struct file_name_map *
15928read_name_map (dirname)
15929 const char *dirname;
15930{
15931 /* This structure holds a linked list of file name maps, one per
15932 directory. */
15933 struct file_name_map_list
15934 {
15935 struct file_name_map_list *map_list_next;
15936 char *map_list_name;
15937 struct file_name_map *map_list_map;
15938 };
15939 static struct file_name_map_list *map_list;
15940 register struct file_name_map_list *map_list_ptr;
15941 char *name;
15942 FILE *f;
15943 size_t dirlen;
15944 int separator_needed;
5ff904cd 15945
c7e4ee3a 15946 dirname = skip_redundant_dir_prefix (dirname);
5ff904cd 15947
c7e4ee3a
CB
15948 for (map_list_ptr = map_list; map_list_ptr;
15949 map_list_ptr = map_list_ptr->map_list_next)
15950 if (! strcmp (map_list_ptr->map_list_name, dirname))
15951 return map_list_ptr->map_list_map;
5ff904cd 15952
c7e4ee3a
CB
15953 map_list_ptr = ((struct file_name_map_list *)
15954 xmalloc (sizeof (struct file_name_map_list)));
15955 map_list_ptr->map_list_name = xstrdup (dirname);
15956 map_list_ptr->map_list_map = NULL;
5ff904cd 15957
c7e4ee3a
CB
15958 dirlen = strlen (dirname);
15959 separator_needed = dirlen != 0 && dirname[dirlen - 1] != '/';
15960 name = (char *) xmalloc (dirlen + strlen (FILE_NAME_MAP_FILE) + 2);
15961 strcpy (name, dirname);
15962 name[dirlen] = '/';
15963 strcpy (name + dirlen + separator_needed, FILE_NAME_MAP_FILE);
15964 f = fopen (name, "r");
15965 free (name);
15966 if (!f)
15967 map_list_ptr->map_list_map = NULL;
15968 else
15969 {
15970 int ch;
5ff904cd 15971
c7e4ee3a
CB
15972 while ((ch = getc (f)) != EOF)
15973 {
15974 char *from, *to;
15975 struct file_name_map *ptr;
15976
15977 if (is_space[ch])
15978 continue;
15979 from = read_filename_string (ch, f);
15980 while ((ch = getc (f)) != EOF && is_hor_space[ch])
15981 ;
15982 to = read_filename_string (ch, f);
5ff904cd 15983
c7e4ee3a
CB
15984 ptr = ((struct file_name_map *)
15985 xmalloc (sizeof (struct file_name_map)));
15986 ptr->map_from = from;
5ff904cd 15987
c7e4ee3a
CB
15988 /* Make the real filename absolute. */
15989 if (*to == '/')
15990 ptr->map_to = to;
15991 else
15992 {
15993 ptr->map_to = xmalloc (dirlen + strlen (to) + 2);
15994 strcpy (ptr->map_to, dirname);
15995 ptr->map_to[dirlen] = '/';
15996 strcpy (ptr->map_to + dirlen + separator_needed, to);
15997 free (to);
15998 }
5ff904cd 15999
c7e4ee3a
CB
16000 ptr->map_next = map_list_ptr->map_list_map;
16001 map_list_ptr->map_list_map = ptr;
5ff904cd 16002
c7e4ee3a
CB
16003 while ((ch = getc (f)) != '\n')
16004 if (ch == EOF)
16005 break;
16006 }
16007 fclose (f);
5ff904cd
JL
16008 }
16009
c7e4ee3a
CB
16010 map_list_ptr->map_list_next = map_list;
16011 map_list = map_list_ptr;
5ff904cd 16012
c7e4ee3a 16013 return map_list_ptr->map_list_map;
5ff904cd
JL
16014}
16015
c7e4ee3a 16016static void
b0791fa9 16017ffecom_file_ (const char *name)
5ff904cd 16018{
c7e4ee3a 16019 FILE_BUF *fp;
5ff904cd 16020
c7e4ee3a
CB
16021 /* Do partial setup of input buffer for the sake of generating
16022 early #line directives (when -g is in effect). */
5ff904cd 16023
c7e4ee3a
CB
16024 fp = &instack[++indepth];
16025 memset ((char *) fp, 0, sizeof (FILE_BUF));
16026 if (name == NULL)
16027 name = "";
16028 fp->nominal_fname = fp->fname = name;
16029}
5ff904cd 16030
c7e4ee3a 16031/* Initialize syntactic classifications of characters. */
5ff904cd 16032
c7e4ee3a
CB
16033static void
16034ffecom_initialize_char_syntax_ ()
16035{
16036 register int i;
5ff904cd 16037
c7e4ee3a
CB
16038 /*
16039 * Set up is_idchar and is_idstart tables. These should be
16040 * faster than saying (is_alpha (c) || c == '_'), etc.
16041 * Set up these things before calling any routines tthat
16042 * refer to them.
16043 */
16044 for (i = 'a'; i <= 'z'; i++) {
16045 is_idchar[i - 'a' + 'A'] = 1;
16046 is_idchar[i] = 1;
16047 is_idstart[i - 'a' + 'A'] = 1;
16048 is_idstart[i] = 1;
16049 }
16050 for (i = '0'; i <= '9'; i++)
16051 is_idchar[i] = 1;
16052 is_idchar['_'] = 1;
16053 is_idstart['_'] = 1;
5ff904cd 16054
c7e4ee3a
CB
16055 /* horizontal space table */
16056 is_hor_space[' '] = 1;
16057 is_hor_space['\t'] = 1;
16058 is_hor_space['\v'] = 1;
16059 is_hor_space['\f'] = 1;
16060 is_hor_space['\r'] = 1;
5ff904cd 16061
c7e4ee3a
CB
16062 is_space[' '] = 1;
16063 is_space['\t'] = 1;
16064 is_space['\v'] = 1;
16065 is_space['\f'] = 1;
16066 is_space['\n'] = 1;
16067 is_space['\r'] = 1;
16068}
5ff904cd 16069
c7e4ee3a
CB
16070static void
16071ffecom_close_include_ (FILE *f)
16072{
16073 fclose (f);
5ff904cd 16074
c7e4ee3a
CB
16075 indepth--;
16076 input_file_stack_tick++;
5ff904cd 16077
c7e4ee3a
CB
16078 ffewhere_line_kill (instack[indepth].line);
16079 ffewhere_column_kill (instack[indepth].column);
16080}
5ff904cd 16081
c7e4ee3a
CB
16082static int
16083ffecom_decode_include_option_ (char *spec)
16084{
16085 struct file_name_list *dirtmp;
16086
16087 if (! ignore_srcdir && !strcmp (spec, "-"))
16088 ignore_srcdir = 1;
16089 else
16090 {
16091 dirtmp = (struct file_name_list *)
16092 xmalloc (sizeof (struct file_name_list));
16093 dirtmp->next = 0; /* New one goes on the end */
16094 if (spec[0] != 0)
16095 dirtmp->fname = spec;
16096 else
16097 fatal ("Directory name must immediately follow -I option with no intervening spaces, as in `-Idir', not `-I dir'");
16098 dirtmp->got_name_map = 0;
16099 append_include_chain (dirtmp, dirtmp);
16100 }
16101 return 1;
5ff904cd
JL
16102}
16103
c7e4ee3a
CB
16104/* Open INCLUDEd file. */
16105
16106static FILE *
16107ffecom_open_include_ (char *name, ffewhereLine l, ffewhereColumn c)
5ff904cd 16108{
c7e4ee3a
CB
16109 char *fbeg = name;
16110 size_t flen = strlen (fbeg);
16111 struct file_name_list *search_start = include; /* Chain of dirs to search */
16112 struct file_name_list dsp[1]; /* First in chain, if #include "..." */
16113 struct file_name_list *searchptr = 0;
16114 char *fname; /* Dynamically allocated fname buffer */
16115 FILE *f;
16116 FILE_BUF *fp;
5ff904cd 16117
c7e4ee3a
CB
16118 if (flen == 0)
16119 return NULL;
5ff904cd 16120
c7e4ee3a 16121 dsp[0].fname = NULL;
5ff904cd 16122
c7e4ee3a
CB
16123 /* If -I- was specified, don't search current dir, only spec'd ones. */
16124 if (!ignore_srcdir)
16125 {
16126 for (fp = &instack[indepth]; fp >= instack; fp--)
16127 {
16128 int n;
16129 char *ep;
b0791fa9 16130 const char *nam;
5ff904cd 16131
c7e4ee3a
CB
16132 if ((nam = fp->nominal_fname) != NULL)
16133 {
16134 /* Found a named file. Figure out dir of the file,
16135 and put it in front of the search list. */
16136 dsp[0].next = search_start;
16137 search_start = dsp;
16138#ifndef VMS
9473c522 16139 ep = strrchr (nam, '/');
c7e4ee3a 16140#ifdef DIR_SEPARATOR
9473c522 16141 if (ep == NULL) ep = strrchr (nam, DIR_SEPARATOR);
c7e4ee3a 16142 else {
9473c522 16143 char *tmp = strrchr (nam, DIR_SEPARATOR);
c7e4ee3a
CB
16144 if (tmp != NULL && tmp > ep) ep = tmp;
16145 }
16146#endif
16147#else /* VMS */
9473c522
JM
16148 ep = strrchr (nam, ']');
16149 if (ep == NULL) ep = strrchr (nam, '>');
16150 if (ep == NULL) ep = strrchr (nam, ':');
c7e4ee3a
CB
16151 if (ep != NULL) ep++;
16152#endif /* VMS */
16153 if (ep != NULL)
16154 {
16155 n = ep - nam;
16156 dsp[0].fname = (char *) xmalloc (n + 1);
16157 strncpy (dsp[0].fname, nam, n);
16158 dsp[0].fname[n] = '\0';
16159 if (n + INCLUDE_LEN_FUDGE > max_include_len)
16160 max_include_len = n + INCLUDE_LEN_FUDGE;
16161 }
16162 else
16163 dsp[0].fname = NULL; /* Current directory */
16164 dsp[0].got_name_map = 0;
16165 break;
16166 }
16167 }
16168 }
5ff904cd 16169
c7e4ee3a
CB
16170 /* Allocate this permanently, because it gets stored in the definitions
16171 of macros. */
16172 fname = xmalloc (max_include_len + flen + 4);
16173 /* + 2 above for slash and terminating null. */
16174 /* + 2 added for '.h' on VMS (to support '#include filename') (NOT USED
16175 for g77 yet). */
5ff904cd 16176
c7e4ee3a 16177 /* If specified file name is absolute, just open it. */
5ff904cd 16178
c7e4ee3a
CB
16179 if (*fbeg == '/'
16180#ifdef DIR_SEPARATOR
16181 || *fbeg == DIR_SEPARATOR
16182#endif
16183 )
16184 {
16185 strncpy (fname, (char *) fbeg, flen);
16186 fname[flen] = 0;
16187 f = open_include_file (fname, NULL_PTR);
5ff904cd 16188 }
c7e4ee3a
CB
16189 else
16190 {
16191 f = NULL;
5ff904cd 16192
c7e4ee3a
CB
16193 /* Search directory path, trying to open the file.
16194 Copy each filename tried into FNAME. */
5ff904cd 16195
c7e4ee3a
CB
16196 for (searchptr = search_start; searchptr; searchptr = searchptr->next)
16197 {
16198 if (searchptr->fname)
16199 {
16200 /* The empty string in a search path is ignored.
16201 This makes it possible to turn off entirely
16202 a standard piece of the list. */
16203 if (searchptr->fname[0] == 0)
16204 continue;
16205 strcpy (fname, skip_redundant_dir_prefix (searchptr->fname));
16206 if (fname[0] && fname[strlen (fname) - 1] != '/')
16207 strcat (fname, "/");
16208 fname[strlen (fname) + flen] = 0;
16209 }
16210 else
16211 fname[0] = 0;
5ff904cd 16212
c7e4ee3a
CB
16213 strncat (fname, fbeg, flen);
16214#ifdef VMS
16215 /* Change this 1/2 Unix 1/2 VMS file specification into a
16216 full VMS file specification */
16217 if (searchptr->fname && (searchptr->fname[0] != 0))
16218 {
16219 /* Fix up the filename */
16220 hack_vms_include_specification (fname);
16221 }
16222 else
16223 {
16224 /* This is a normal VMS filespec, so use it unchanged. */
16225 strncpy (fname, (char *) fbeg, flen);
16226 fname[flen] = 0;
16227#if 0 /* Not for g77. */
16228 /* if it's '#include filename', add the missing .h */
9473c522 16229 if (strchr (fname, '.') == NULL)
c7e4ee3a 16230 strcat (fname, ".h");
5ff904cd 16231#endif
c7e4ee3a
CB
16232 }
16233#endif /* VMS */
16234 f = open_include_file (fname, searchptr);
16235#ifdef EACCES
16236 if (f == NULL && errno == EACCES)
16237 {
16238 print_containing_files (FFEBAD_severityWARNING);
16239 ffebad_start_msg ("At %0, INCLUDE file %A exists, but is not readable",
16240 FFEBAD_severityWARNING);
16241 ffebad_string (fname);
16242 ffebad_here (0, l, c);
16243 ffebad_finish ();
16244 }
16245#endif
16246 if (f != NULL)
16247 break;
16248 }
16249 }
5ff904cd 16250
c7e4ee3a 16251 if (f == NULL)
5ff904cd 16252 {
c7e4ee3a 16253 /* A file that was not found. */
5ff904cd 16254
c7e4ee3a
CB
16255 strncpy (fname, (char *) fbeg, flen);
16256 fname[flen] = 0;
16257 print_containing_files (ffebad_severity (FFEBAD_OPEN_INCLUDE));
16258 ffebad_start (FFEBAD_OPEN_INCLUDE);
16259 ffebad_here (0, l, c);
16260 ffebad_string (fname);
16261 ffebad_finish ();
5ff904cd
JL
16262 }
16263
c7e4ee3a
CB
16264 if (dsp[0].fname != NULL)
16265 free (dsp[0].fname);
5ff904cd 16266
c7e4ee3a
CB
16267 if (f == NULL)
16268 return NULL;
5ff904cd 16269
c7e4ee3a
CB
16270 if (indepth >= (INPUT_STACK_MAX - 1))
16271 {
16272 print_containing_files (FFEBAD_severityFATAL);
16273 ffebad_start_msg ("At %0, INCLUDE nesting too deep",
16274 FFEBAD_severityFATAL);
16275 ffebad_string (fname);
16276 ffebad_here (0, l, c);
16277 ffebad_finish ();
16278 return NULL;
16279 }
5ff904cd 16280
c7e4ee3a
CB
16281 instack[indepth].line = ffewhere_line_use (l);
16282 instack[indepth].column = ffewhere_column_use (c);
5ff904cd 16283
c7e4ee3a
CB
16284 fp = &instack[indepth + 1];
16285 memset ((char *) fp, 0, sizeof (FILE_BUF));
16286 fp->nominal_fname = fp->fname = fname;
16287 fp->dir = searchptr;
5ff904cd 16288
c7e4ee3a
CB
16289 indepth++;
16290 input_file_stack_tick++;
5ff904cd 16291
c7e4ee3a
CB
16292 return f;
16293}
16294#endif /* FFECOM_GCC_INCLUDE */
5ff904cd 16295
c7e4ee3a
CB
16296/**INDENT* (Do not reformat this comment even with -fca option.)
16297 Data-gathering files: Given the source file listed below, compiled with
16298 f2c I obtained the output file listed after that, and from the output
16299 file I derived the above code.
5ff904cd 16300
c7e4ee3a
CB
16301-------- (begin input file to f2c)
16302 implicit none
16303 character*10 A1,A2
16304 complex C1,C2
16305 integer I1,I2
16306 real R1,R2
16307 double precision D1,D2
16308C
16309 call getem(A1,A2,C1,C2,I1,I2,R1,R2,D1,D2)
16310c /
16311 call fooI(I1/I2)
16312 call fooR(R1/I1)
16313 call fooD(D1/I1)
16314 call fooC(C1/I1)
16315 call fooR(R1/R2)
16316 call fooD(R1/D1)
16317 call fooD(D1/D2)
16318 call fooD(D1/R1)
16319 call fooC(C1/C2)
16320 call fooC(C1/R1)
16321 call fooZ(C1/D1)
16322c **
16323 call fooI(I1**I2)
16324 call fooR(R1**I1)
16325 call fooD(D1**I1)
16326 call fooC(C1**I1)
16327 call fooR(R1**R2)
16328 call fooD(R1**D1)
16329 call fooD(D1**D2)
16330 call fooD(D1**R1)
16331 call fooC(C1**C2)
16332 call fooC(C1**R1)
16333 call fooZ(C1**D1)
16334c FFEINTRIN_impABS
16335 call fooR(ABS(R1))
16336c FFEINTRIN_impACOS
16337 call fooR(ACOS(R1))
16338c FFEINTRIN_impAIMAG
16339 call fooR(AIMAG(C1))
16340c FFEINTRIN_impAINT
16341 call fooR(AINT(R1))
16342c FFEINTRIN_impALOG
16343 call fooR(ALOG(R1))
16344c FFEINTRIN_impALOG10
16345 call fooR(ALOG10(R1))
16346c FFEINTRIN_impAMAX0
16347 call fooR(AMAX0(I1,I2))
16348c FFEINTRIN_impAMAX1
16349 call fooR(AMAX1(R1,R2))
16350c FFEINTRIN_impAMIN0
16351 call fooR(AMIN0(I1,I2))
16352c FFEINTRIN_impAMIN1
16353 call fooR(AMIN1(R1,R2))
16354c FFEINTRIN_impAMOD
16355 call fooR(AMOD(R1,R2))
16356c FFEINTRIN_impANINT
16357 call fooR(ANINT(R1))
16358c FFEINTRIN_impASIN
16359 call fooR(ASIN(R1))
16360c FFEINTRIN_impATAN
16361 call fooR(ATAN(R1))
16362c FFEINTRIN_impATAN2
16363 call fooR(ATAN2(R1,R2))
16364c FFEINTRIN_impCABS
16365 call fooR(CABS(C1))
16366c FFEINTRIN_impCCOS
16367 call fooC(CCOS(C1))
16368c FFEINTRIN_impCEXP
16369 call fooC(CEXP(C1))
16370c FFEINTRIN_impCHAR
16371 call fooA(CHAR(I1))
16372c FFEINTRIN_impCLOG
16373 call fooC(CLOG(C1))
16374c FFEINTRIN_impCONJG
16375 call fooC(CONJG(C1))
16376c FFEINTRIN_impCOS
16377 call fooR(COS(R1))
16378c FFEINTRIN_impCOSH
16379 call fooR(COSH(R1))
16380c FFEINTRIN_impCSIN
16381 call fooC(CSIN(C1))
16382c FFEINTRIN_impCSQRT
16383 call fooC(CSQRT(C1))
16384c FFEINTRIN_impDABS
16385 call fooD(DABS(D1))
16386c FFEINTRIN_impDACOS
16387 call fooD(DACOS(D1))
16388c FFEINTRIN_impDASIN
16389 call fooD(DASIN(D1))
16390c FFEINTRIN_impDATAN
16391 call fooD(DATAN(D1))
16392c FFEINTRIN_impDATAN2
16393 call fooD(DATAN2(D1,D2))
16394c FFEINTRIN_impDCOS
16395 call fooD(DCOS(D1))
16396c FFEINTRIN_impDCOSH
16397 call fooD(DCOSH(D1))
16398c FFEINTRIN_impDDIM
16399 call fooD(DDIM(D1,D2))
16400c FFEINTRIN_impDEXP
16401 call fooD(DEXP(D1))
16402c FFEINTRIN_impDIM
16403 call fooR(DIM(R1,R2))
16404c FFEINTRIN_impDINT
16405 call fooD(DINT(D1))
16406c FFEINTRIN_impDLOG
16407 call fooD(DLOG(D1))
16408c FFEINTRIN_impDLOG10
16409 call fooD(DLOG10(D1))
16410c FFEINTRIN_impDMAX1
16411 call fooD(DMAX1(D1,D2))
16412c FFEINTRIN_impDMIN1
16413 call fooD(DMIN1(D1,D2))
16414c FFEINTRIN_impDMOD
16415 call fooD(DMOD(D1,D2))
16416c FFEINTRIN_impDNINT
16417 call fooD(DNINT(D1))
16418c FFEINTRIN_impDPROD
16419 call fooD(DPROD(R1,R2))
16420c FFEINTRIN_impDSIGN
16421 call fooD(DSIGN(D1,D2))
16422c FFEINTRIN_impDSIN
16423 call fooD(DSIN(D1))
16424c FFEINTRIN_impDSINH
16425 call fooD(DSINH(D1))
16426c FFEINTRIN_impDSQRT
16427 call fooD(DSQRT(D1))
16428c FFEINTRIN_impDTAN
16429 call fooD(DTAN(D1))
16430c FFEINTRIN_impDTANH
16431 call fooD(DTANH(D1))
16432c FFEINTRIN_impEXP
16433 call fooR(EXP(R1))
16434c FFEINTRIN_impIABS
16435 call fooI(IABS(I1))
16436c FFEINTRIN_impICHAR
16437 call fooI(ICHAR(A1))
16438c FFEINTRIN_impIDIM
16439 call fooI(IDIM(I1,I2))
16440c FFEINTRIN_impIDNINT
16441 call fooI(IDNINT(D1))
16442c FFEINTRIN_impINDEX
16443 call fooI(INDEX(A1,A2))
16444c FFEINTRIN_impISIGN
16445 call fooI(ISIGN(I1,I2))
16446c FFEINTRIN_impLEN
16447 call fooI(LEN(A1))
16448c FFEINTRIN_impLGE
16449 call fooL(LGE(A1,A2))
16450c FFEINTRIN_impLGT
16451 call fooL(LGT(A1,A2))
16452c FFEINTRIN_impLLE
16453 call fooL(LLE(A1,A2))
16454c FFEINTRIN_impLLT
16455 call fooL(LLT(A1,A2))
16456c FFEINTRIN_impMAX0
16457 call fooI(MAX0(I1,I2))
16458c FFEINTRIN_impMAX1
16459 call fooI(MAX1(R1,R2))
16460c FFEINTRIN_impMIN0
16461 call fooI(MIN0(I1,I2))
16462c FFEINTRIN_impMIN1
16463 call fooI(MIN1(R1,R2))
16464c FFEINTRIN_impMOD
16465 call fooI(MOD(I1,I2))
16466c FFEINTRIN_impNINT
16467 call fooI(NINT(R1))
16468c FFEINTRIN_impSIGN
16469 call fooR(SIGN(R1,R2))
16470c FFEINTRIN_impSIN
16471 call fooR(SIN(R1))
16472c FFEINTRIN_impSINH
16473 call fooR(SINH(R1))
16474c FFEINTRIN_impSQRT
16475 call fooR(SQRT(R1))
16476c FFEINTRIN_impTAN
16477 call fooR(TAN(R1))
16478c FFEINTRIN_impTANH
16479 call fooR(TANH(R1))
16480c FFEINTRIN_imp_CMPLX_C
16481 call fooC(cmplx(C1,C2))
16482c FFEINTRIN_imp_CMPLX_D
16483 call fooZ(cmplx(D1,D2))
16484c FFEINTRIN_imp_CMPLX_I
16485 call fooC(cmplx(I1,I2))
16486c FFEINTRIN_imp_CMPLX_R
16487 call fooC(cmplx(R1,R2))
16488c FFEINTRIN_imp_DBLE_C
16489 call fooD(dble(C1))
16490c FFEINTRIN_imp_DBLE_D
16491 call fooD(dble(D1))
16492c FFEINTRIN_imp_DBLE_I
16493 call fooD(dble(I1))
16494c FFEINTRIN_imp_DBLE_R
16495 call fooD(dble(R1))
16496c FFEINTRIN_imp_INT_C
16497 call fooI(int(C1))
16498c FFEINTRIN_imp_INT_D
16499 call fooI(int(D1))
16500c FFEINTRIN_imp_INT_I
16501 call fooI(int(I1))
16502c FFEINTRIN_imp_INT_R
16503 call fooI(int(R1))
16504c FFEINTRIN_imp_REAL_C
16505 call fooR(real(C1))
16506c FFEINTRIN_imp_REAL_D
16507 call fooR(real(D1))
16508c FFEINTRIN_imp_REAL_I
16509 call fooR(real(I1))
16510c FFEINTRIN_imp_REAL_R
16511 call fooR(real(R1))
16512c
16513c FFEINTRIN_imp_INT_D:
16514c
16515c FFEINTRIN_specIDINT
16516 call fooI(IDINT(D1))
16517c
16518c FFEINTRIN_imp_INT_R:
16519c
16520c FFEINTRIN_specIFIX
16521 call fooI(IFIX(R1))
16522c FFEINTRIN_specINT
16523 call fooI(INT(R1))
16524c
16525c FFEINTRIN_imp_REAL_D:
16526c
16527c FFEINTRIN_specSNGL
16528 call fooR(SNGL(D1))
16529c
16530c FFEINTRIN_imp_REAL_I:
16531c
16532c FFEINTRIN_specFLOAT
16533 call fooR(FLOAT(I1))
16534c FFEINTRIN_specREAL
16535 call fooR(REAL(I1))
16536c
16537 end
16538-------- (end input file to f2c)
5ff904cd 16539
c7e4ee3a
CB
16540-------- (begin output from providing above input file as input to:
16541-------- `f2c | gcc -E -C - | sed -e "s:/[*]*://:g" -e "s:[*]*[/]://:g" \
16542-------- -e "s:^#.*$::g"')
5ff904cd 16543
c7e4ee3a
CB
16544// -- translated by f2c (version 19950223).
16545 You must link the resulting object file with the libraries:
16546 -lf2c -lm (in that order)
16547//
5ff904cd 16548
5ff904cd 16549
c7e4ee3a 16550// f2c.h -- Standard Fortran to C header file //
5ff904cd 16551
c7e4ee3a 16552/// barf [ba:rf] 2. "He suggested using FORTRAN, and everybody barfed."
5ff904cd 16553
c7e4ee3a 16554 - From The Shogakukan DICTIONARY OF NEW ENGLISH (Second edition) //
5ff904cd 16555
5ff904cd 16556
5ff904cd 16557
5ff904cd 16558
c7e4ee3a
CB
16559// F2C_INTEGER will normally be `int' but would be `long' on 16-bit systems //
16560// we assume short, float are OK //
16561typedef long int // long int // integer;
16562typedef char *address;
16563typedef short int shortint;
16564typedef float real;
16565typedef double doublereal;
16566typedef struct { real r, i; } complex;
16567typedef struct { doublereal r, i; } doublecomplex;
16568typedef long int // long int // logical;
16569typedef short int shortlogical;
16570typedef char logical1;
16571typedef char integer1;
16572// typedef long long longint; // // system-dependent //
5ff904cd 16573
5ff904cd 16574
5ff904cd 16575
5ff904cd 16576
c7e4ee3a 16577// Extern is for use with -E //
5ff904cd 16578
5ff904cd 16579
5ff904cd 16580
5ff904cd 16581
c7e4ee3a 16582// I/O stuff //
5ff904cd 16583
5ff904cd 16584
5ff904cd 16585
5ff904cd 16586
5ff904cd 16587
5ff904cd 16588
5ff904cd 16589
5ff904cd 16590
c7e4ee3a
CB
16591typedef long int // int or long int // flag;
16592typedef long int // int or long int // ftnlen;
16593typedef long int // int or long int // ftnint;
5ff904cd 16594
5ff904cd 16595
c7e4ee3a
CB
16596//external read, write//
16597typedef struct
16598{ flag cierr;
16599 ftnint ciunit;
16600 flag ciend;
16601 char *cifmt;
16602 ftnint cirec;
16603} cilist;
5ff904cd 16604
c7e4ee3a
CB
16605//internal read, write//
16606typedef struct
16607{ flag icierr;
16608 char *iciunit;
16609 flag iciend;
16610 char *icifmt;
16611 ftnint icirlen;
16612 ftnint icirnum;
16613} icilist;
5ff904cd 16614
c7e4ee3a
CB
16615//open//
16616typedef struct
16617{ flag oerr;
16618 ftnint ounit;
16619 char *ofnm;
16620 ftnlen ofnmlen;
16621 char *osta;
16622 char *oacc;
16623 char *ofm;
16624 ftnint orl;
16625 char *oblnk;
16626} olist;
5ff904cd 16627
c7e4ee3a
CB
16628//close//
16629typedef struct
16630{ flag cerr;
16631 ftnint cunit;
16632 char *csta;
16633} cllist;
5ff904cd 16634
c7e4ee3a
CB
16635//rewind, backspace, endfile//
16636typedef struct
16637{ flag aerr;
16638 ftnint aunit;
16639} alist;
5ff904cd 16640
c7e4ee3a
CB
16641// inquire //
16642typedef struct
16643{ flag inerr;
16644 ftnint inunit;
16645 char *infile;
16646 ftnlen infilen;
16647 ftnint *inex; //parameters in standard's order//
16648 ftnint *inopen;
16649 ftnint *innum;
16650 ftnint *innamed;
16651 char *inname;
16652 ftnlen innamlen;
16653 char *inacc;
16654 ftnlen inacclen;
16655 char *inseq;
16656 ftnlen inseqlen;
16657 char *indir;
16658 ftnlen indirlen;
16659 char *infmt;
16660 ftnlen infmtlen;
16661 char *inform;
16662 ftnint informlen;
16663 char *inunf;
16664 ftnlen inunflen;
16665 ftnint *inrecl;
16666 ftnint *innrec;
16667 char *inblank;
16668 ftnlen inblanklen;
16669} inlist;
5ff904cd 16670
5ff904cd 16671
5ff904cd 16672
c7e4ee3a
CB
16673union Multitype { // for multiple entry points //
16674 integer1 g;
16675 shortint h;
16676 integer i;
16677 // longint j; //
16678 real r;
16679 doublereal d;
16680 complex c;
16681 doublecomplex z;
16682 };
16683
16684typedef union Multitype Multitype;
5ff904cd 16685
c7e4ee3a 16686typedef long Long; // No longer used; formerly in Namelist //
5ff904cd 16687
c7e4ee3a
CB
16688struct Vardesc { // for Namelist //
16689 char *name;
16690 char *addr;
16691 ftnlen *dims;
16692 int type;
16693 };
16694typedef struct Vardesc Vardesc;
5ff904cd 16695
c7e4ee3a
CB
16696struct Namelist {
16697 char *name;
16698 Vardesc **vars;
16699 int nvars;
16700 };
16701typedef struct Namelist Namelist;
5ff904cd 16702
5ff904cd 16703
5ff904cd 16704
5ff904cd 16705
5ff904cd 16706
5ff904cd 16707
5ff904cd 16708
5ff904cd 16709
c7e4ee3a 16710// procedure parameter types for -A and -C++ //
5ff904cd 16711
5ff904cd 16712
5ff904cd 16713
5ff904cd 16714
c7e4ee3a
CB
16715typedef int // Unknown procedure type // (*U_fp)();
16716typedef shortint (*J_fp)();
16717typedef integer (*I_fp)();
16718typedef real (*R_fp)();
16719typedef doublereal (*D_fp)(), (*E_fp)();
16720typedef // Complex // void (*C_fp)();
16721typedef // Double Complex // void (*Z_fp)();
16722typedef logical (*L_fp)();
16723typedef shortlogical (*K_fp)();
16724typedef // Character // void (*H_fp)();
16725typedef // Subroutine // int (*S_fp)();
5ff904cd 16726
c7e4ee3a
CB
16727// E_fp is for real functions when -R is not specified //
16728typedef void C_f; // complex function //
16729typedef void H_f; // character function //
16730typedef void Z_f; // double complex function //
16731typedef doublereal E_f; // real function with -R not specified //
5ff904cd 16732
c7e4ee3a 16733// undef any lower-case symbols that your C compiler predefines, e.g.: //
5ff904cd 16734
5ff904cd 16735
c7e4ee3a
CB
16736// (No such symbols should be defined in a strict ANSI C compiler.
16737 We can avoid trouble with f2c-translated code by using
16738 gcc -ansi [-traditional].) //
16739
5ff904cd 16740
5ff904cd 16741
5ff904cd 16742
5ff904cd 16743
5ff904cd 16744
5ff904cd 16745
5ff904cd 16746
5ff904cd 16747
5ff904cd 16748
5ff904cd 16749
5ff904cd 16750
5ff904cd 16751
5ff904cd 16752
5ff904cd 16753
5ff904cd 16754
5ff904cd 16755
5ff904cd 16756
5ff904cd 16757
5ff904cd 16758
5ff904cd 16759
5ff904cd 16760
5ff904cd 16761
c7e4ee3a
CB
16762// Main program // MAIN__()
16763{
16764 // System generated locals //
16765 integer i__1;
16766 real r__1, r__2;
16767 doublereal d__1, d__2;
16768 complex q__1;
16769 doublecomplex z__1, z__2, z__3;
16770 logical L__1;
16771 char ch__1[1];
16772
16773 // Builtin functions //
16774 void c_div();
16775 integer pow_ii();
16776 double pow_ri(), pow_di();
16777 void pow_ci();
16778 double pow_dd();
16779 void pow_zz();
16780 double acos(), r_imag(), r_int(), log(), r_lg10(), r_mod(), r_nint(),
16781 asin(), atan(), atan2(), c_abs();
16782 void c_cos(), c_exp(), c_log(), r_cnjg();
16783 double cos(), cosh();
16784 void c_sin(), c_sqrt();
16785 double d_dim(), exp(), r_dim(), d_int(), d_lg10(), d_mod(), d_nint(),
16786 d_sign(), sin(), sinh(), sqrt(), tan(), tanh();
16787 integer i_dim(), i_dnnt(), i_indx(), i_sign(), i_len();
16788 logical l_ge(), l_gt(), l_le(), l_lt();
16789 integer i_nint();
16790 double r_sign();
16791
16792 // Local variables //
16793 extern // Subroutine // int fooa_(), fooc_(), food_(), fooi_(), foor_(),
16794 fool_(), fooz_(), getem_();
16795 static char a1[10], a2[10];
16796 static complex c1, c2;
16797 static doublereal d1, d2;
16798 static integer i1, i2;
16799 static real r1, r2;
16800
16801
16802 getem_(a1, a2, &c1, &c2, &i1, &i2, &r1, &r2, &d1, &d2, 10L, 10L);
16803// / //
16804 i__1 = i1 / i2;
16805 fooi_(&i__1);
16806 r__1 = r1 / i1;
16807 foor_(&r__1);
16808 d__1 = d1 / i1;
16809 food_(&d__1);
16810 d__1 = (doublereal) i1;
16811 q__1.r = c1.r / d__1, q__1.i = c1.i / d__1;
16812 fooc_(&q__1);
16813 r__1 = r1 / r2;
16814 foor_(&r__1);
16815 d__1 = r1 / d1;
16816 food_(&d__1);
16817 d__1 = d1 / d2;
16818 food_(&d__1);
16819 d__1 = d1 / r1;
16820 food_(&d__1);
16821 c_div(&q__1, &c1, &c2);
16822 fooc_(&q__1);
16823 q__1.r = c1.r / r1, q__1.i = c1.i / r1;
16824 fooc_(&q__1);
16825 z__1.r = c1.r / d1, z__1.i = c1.i / d1;
16826 fooz_(&z__1);
16827// ** //
16828 i__1 = pow_ii(&i1, &i2);
16829 fooi_(&i__1);
16830 r__1 = pow_ri(&r1, &i1);
16831 foor_(&r__1);
16832 d__1 = pow_di(&d1, &i1);
16833 food_(&d__1);
16834 pow_ci(&q__1, &c1, &i1);
16835 fooc_(&q__1);
16836 d__1 = (doublereal) r1;
16837 d__2 = (doublereal) r2;
16838 r__1 = pow_dd(&d__1, &d__2);
16839 foor_(&r__1);
16840 d__2 = (doublereal) r1;
16841 d__1 = pow_dd(&d__2, &d1);
16842 food_(&d__1);
16843 d__1 = pow_dd(&d1, &d2);
16844 food_(&d__1);
16845 d__2 = (doublereal) r1;
16846 d__1 = pow_dd(&d1, &d__2);
16847 food_(&d__1);
16848 z__2.r = c1.r, z__2.i = c1.i;
16849 z__3.r = c2.r, z__3.i = c2.i;
16850 pow_zz(&z__1, &z__2, &z__3);
16851 q__1.r = z__1.r, q__1.i = z__1.i;
16852 fooc_(&q__1);
16853 z__2.r = c1.r, z__2.i = c1.i;
16854 z__3.r = r1, z__3.i = 0.;
16855 pow_zz(&z__1, &z__2, &z__3);
16856 q__1.r = z__1.r, q__1.i = z__1.i;
16857 fooc_(&q__1);
16858 z__2.r = c1.r, z__2.i = c1.i;
16859 z__3.r = d1, z__3.i = 0.;
16860 pow_zz(&z__1, &z__2, &z__3);
16861 fooz_(&z__1);
16862// FFEINTRIN_impABS //
16863 r__1 = (doublereal)(( r1 ) >= 0 ? ( r1 ) : -( r1 )) ;
16864 foor_(&r__1);
16865// FFEINTRIN_impACOS //
16866 r__1 = acos(r1);
16867 foor_(&r__1);
16868// FFEINTRIN_impAIMAG //
16869 r__1 = r_imag(&c1);
16870 foor_(&r__1);
16871// FFEINTRIN_impAINT //
16872 r__1 = r_int(&r1);
16873 foor_(&r__1);
16874// FFEINTRIN_impALOG //
16875 r__1 = log(r1);
16876 foor_(&r__1);
16877// FFEINTRIN_impALOG10 //
16878 r__1 = r_lg10(&r1);
16879 foor_(&r__1);
16880// FFEINTRIN_impAMAX0 //
16881 r__1 = (real) (( i1 ) >= ( i2 ) ? ( i1 ) : ( i2 )) ;
16882 foor_(&r__1);
16883// FFEINTRIN_impAMAX1 //
16884 r__1 = (doublereal)(( r1 ) >= ( r2 ) ? ( r1 ) : ( r2 )) ;
16885 foor_(&r__1);
16886// FFEINTRIN_impAMIN0 //
16887 r__1 = (real) (( i1 ) <= ( i2 ) ? ( i1 ) : ( i2 )) ;
16888 foor_(&r__1);
16889// FFEINTRIN_impAMIN1 //
16890 r__1 = (doublereal)(( r1 ) <= ( r2 ) ? ( r1 ) : ( r2 )) ;
16891 foor_(&r__1);
16892// FFEINTRIN_impAMOD //
16893 r__1 = r_mod(&r1, &r2);
16894 foor_(&r__1);
16895// FFEINTRIN_impANINT //
16896 r__1 = r_nint(&r1);
16897 foor_(&r__1);
16898// FFEINTRIN_impASIN //
16899 r__1 = asin(r1);
16900 foor_(&r__1);
16901// FFEINTRIN_impATAN //
16902 r__1 = atan(r1);
16903 foor_(&r__1);
16904// FFEINTRIN_impATAN2 //
16905 r__1 = atan2(r1, r2);
16906 foor_(&r__1);
16907// FFEINTRIN_impCABS //
16908 r__1 = c_abs(&c1);
16909 foor_(&r__1);
16910// FFEINTRIN_impCCOS //
16911 c_cos(&q__1, &c1);
16912 fooc_(&q__1);
16913// FFEINTRIN_impCEXP //
16914 c_exp(&q__1, &c1);
16915 fooc_(&q__1);
16916// FFEINTRIN_impCHAR //
16917 *(unsigned char *)&ch__1[0] = i1;
16918 fooa_(ch__1, 1L);
16919// FFEINTRIN_impCLOG //
16920 c_log(&q__1, &c1);
16921 fooc_(&q__1);
16922// FFEINTRIN_impCONJG //
16923 r_cnjg(&q__1, &c1);
16924 fooc_(&q__1);
16925// FFEINTRIN_impCOS //
16926 r__1 = cos(r1);
16927 foor_(&r__1);
16928// FFEINTRIN_impCOSH //
16929 r__1 = cosh(r1);
16930 foor_(&r__1);
16931// FFEINTRIN_impCSIN //
16932 c_sin(&q__1, &c1);
16933 fooc_(&q__1);
16934// FFEINTRIN_impCSQRT //
16935 c_sqrt(&q__1, &c1);
16936 fooc_(&q__1);
16937// FFEINTRIN_impDABS //
16938 d__1 = (( d1 ) >= 0 ? ( d1 ) : -( d1 )) ;
16939 food_(&d__1);
16940// FFEINTRIN_impDACOS //
16941 d__1 = acos(d1);
16942 food_(&d__1);
16943// FFEINTRIN_impDASIN //
16944 d__1 = asin(d1);
16945 food_(&d__1);
16946// FFEINTRIN_impDATAN //
16947 d__1 = atan(d1);
16948 food_(&d__1);
16949// FFEINTRIN_impDATAN2 //
16950 d__1 = atan2(d1, d2);
16951 food_(&d__1);
16952// FFEINTRIN_impDCOS //
16953 d__1 = cos(d1);
16954 food_(&d__1);
16955// FFEINTRIN_impDCOSH //
16956 d__1 = cosh(d1);
16957 food_(&d__1);
16958// FFEINTRIN_impDDIM //
16959 d__1 = d_dim(&d1, &d2);
16960 food_(&d__1);
16961// FFEINTRIN_impDEXP //
16962 d__1 = exp(d1);
16963 food_(&d__1);
16964// FFEINTRIN_impDIM //
16965 r__1 = r_dim(&r1, &r2);
16966 foor_(&r__1);
16967// FFEINTRIN_impDINT //
16968 d__1 = d_int(&d1);
16969 food_(&d__1);
16970// FFEINTRIN_impDLOG //
16971 d__1 = log(d1);
16972 food_(&d__1);
16973// FFEINTRIN_impDLOG10 //
16974 d__1 = d_lg10(&d1);
16975 food_(&d__1);
16976// FFEINTRIN_impDMAX1 //
16977 d__1 = (( d1 ) >= ( d2 ) ? ( d1 ) : ( d2 )) ;
16978 food_(&d__1);
16979// FFEINTRIN_impDMIN1 //
16980 d__1 = (( d1 ) <= ( d2 ) ? ( d1 ) : ( d2 )) ;
16981 food_(&d__1);
16982// FFEINTRIN_impDMOD //
16983 d__1 = d_mod(&d1, &d2);
16984 food_(&d__1);
16985// FFEINTRIN_impDNINT //
16986 d__1 = d_nint(&d1);
16987 food_(&d__1);
16988// FFEINTRIN_impDPROD //
16989 d__1 = (doublereal) r1 * r2;
16990 food_(&d__1);
16991// FFEINTRIN_impDSIGN //
16992 d__1 = d_sign(&d1, &d2);
16993 food_(&d__1);
16994// FFEINTRIN_impDSIN //
16995 d__1 = sin(d1);
16996 food_(&d__1);
16997// FFEINTRIN_impDSINH //
16998 d__1 = sinh(d1);
16999 food_(&d__1);
17000// FFEINTRIN_impDSQRT //
17001 d__1 = sqrt(d1);
17002 food_(&d__1);
17003// FFEINTRIN_impDTAN //
17004 d__1 = tan(d1);
17005 food_(&d__1);
17006// FFEINTRIN_impDTANH //
17007 d__1 = tanh(d1);
17008 food_(&d__1);
17009// FFEINTRIN_impEXP //
17010 r__1 = exp(r1);
17011 foor_(&r__1);
17012// FFEINTRIN_impIABS //
17013 i__1 = (( i1 ) >= 0 ? ( i1 ) : -( i1 )) ;
17014 fooi_(&i__1);
17015// FFEINTRIN_impICHAR //
17016 i__1 = *(unsigned char *)a1;
17017 fooi_(&i__1);
17018// FFEINTRIN_impIDIM //
17019 i__1 = i_dim(&i1, &i2);
17020 fooi_(&i__1);
17021// FFEINTRIN_impIDNINT //
17022 i__1 = i_dnnt(&d1);
17023 fooi_(&i__1);
17024// FFEINTRIN_impINDEX //
17025 i__1 = i_indx(a1, a2, 10L, 10L);
17026 fooi_(&i__1);
17027// FFEINTRIN_impISIGN //
17028 i__1 = i_sign(&i1, &i2);
17029 fooi_(&i__1);
17030// FFEINTRIN_impLEN //
17031 i__1 = i_len(a1, 10L);
17032 fooi_(&i__1);
17033// FFEINTRIN_impLGE //
17034 L__1 = l_ge(a1, a2, 10L, 10L);
17035 fool_(&L__1);
17036// FFEINTRIN_impLGT //
17037 L__1 = l_gt(a1, a2, 10L, 10L);
17038 fool_(&L__1);
17039// FFEINTRIN_impLLE //
17040 L__1 = l_le(a1, a2, 10L, 10L);
17041 fool_(&L__1);
17042// FFEINTRIN_impLLT //
17043 L__1 = l_lt(a1, a2, 10L, 10L);
17044 fool_(&L__1);
17045// FFEINTRIN_impMAX0 //
17046 i__1 = (( i1 ) >= ( i2 ) ? ( i1 ) : ( i2 )) ;
17047 fooi_(&i__1);
17048// FFEINTRIN_impMAX1 //
17049 i__1 = (integer) (doublereal)(( r1 ) >= ( r2 ) ? ( r1 ) : ( r2 )) ;
17050 fooi_(&i__1);
17051// FFEINTRIN_impMIN0 //
17052 i__1 = (( i1 ) <= ( i2 ) ? ( i1 ) : ( i2 )) ;
17053 fooi_(&i__1);
17054// FFEINTRIN_impMIN1 //
17055 i__1 = (integer) (doublereal)(( r1 ) <= ( r2 ) ? ( r1 ) : ( r2 )) ;
17056 fooi_(&i__1);
17057// FFEINTRIN_impMOD //
17058 i__1 = i1 % i2;
17059 fooi_(&i__1);
17060// FFEINTRIN_impNINT //
17061 i__1 = i_nint(&r1);
17062 fooi_(&i__1);
17063// FFEINTRIN_impSIGN //
17064 r__1 = r_sign(&r1, &r2);
17065 foor_(&r__1);
17066// FFEINTRIN_impSIN //
17067 r__1 = sin(r1);
17068 foor_(&r__1);
17069// FFEINTRIN_impSINH //
17070 r__1 = sinh(r1);
17071 foor_(&r__1);
17072// FFEINTRIN_impSQRT //
17073 r__1 = sqrt(r1);
17074 foor_(&r__1);
17075// FFEINTRIN_impTAN //
17076 r__1 = tan(r1);
17077 foor_(&r__1);
17078// FFEINTRIN_impTANH //
17079 r__1 = tanh(r1);
17080 foor_(&r__1);
17081// FFEINTRIN_imp_CMPLX_C //
17082 r__1 = c1.r;
17083 r__2 = c2.r;
17084 q__1.r = r__1, q__1.i = r__2;
17085 fooc_(&q__1);
17086// FFEINTRIN_imp_CMPLX_D //
17087 z__1.r = d1, z__1.i = d2;
17088 fooz_(&z__1);
17089// FFEINTRIN_imp_CMPLX_I //
17090 r__1 = (real) i1;
17091 r__2 = (real) i2;
17092 q__1.r = r__1, q__1.i = r__2;
17093 fooc_(&q__1);
17094// FFEINTRIN_imp_CMPLX_R //
17095 q__1.r = r1, q__1.i = r2;
17096 fooc_(&q__1);
17097// FFEINTRIN_imp_DBLE_C //
17098 d__1 = (doublereal) c1.r;
17099 food_(&d__1);
17100// FFEINTRIN_imp_DBLE_D //
17101 d__1 = d1;
17102 food_(&d__1);
17103// FFEINTRIN_imp_DBLE_I //
17104 d__1 = (doublereal) i1;
17105 food_(&d__1);
17106// FFEINTRIN_imp_DBLE_R //
17107 d__1 = (doublereal) r1;
17108 food_(&d__1);
17109// FFEINTRIN_imp_INT_C //
17110 i__1 = (integer) c1.r;
17111 fooi_(&i__1);
17112// FFEINTRIN_imp_INT_D //
17113 i__1 = (integer) d1;
17114 fooi_(&i__1);
17115// FFEINTRIN_imp_INT_I //
17116 i__1 = i1;
17117 fooi_(&i__1);
17118// FFEINTRIN_imp_INT_R //
17119 i__1 = (integer) r1;
17120 fooi_(&i__1);
17121// FFEINTRIN_imp_REAL_C //
17122 r__1 = c1.r;
17123 foor_(&r__1);
17124// FFEINTRIN_imp_REAL_D //
17125 r__1 = (real) d1;
17126 foor_(&r__1);
17127// FFEINTRIN_imp_REAL_I //
17128 r__1 = (real) i1;
17129 foor_(&r__1);
17130// FFEINTRIN_imp_REAL_R //
17131 r__1 = r1;
17132 foor_(&r__1);
17133
17134// FFEINTRIN_imp_INT_D: //
17135
17136// FFEINTRIN_specIDINT //
17137 i__1 = (integer) d1;
17138 fooi_(&i__1);
17139
17140// FFEINTRIN_imp_INT_R: //
17141
17142// FFEINTRIN_specIFIX //
17143 i__1 = (integer) r1;
17144 fooi_(&i__1);
17145// FFEINTRIN_specINT //
17146 i__1 = (integer) r1;
17147 fooi_(&i__1);
17148
17149// FFEINTRIN_imp_REAL_D: //
5ff904cd 17150
c7e4ee3a
CB
17151// FFEINTRIN_specSNGL //
17152 r__1 = (real) d1;
17153 foor_(&r__1);
5ff904cd 17154
c7e4ee3a 17155// FFEINTRIN_imp_REAL_I: //
5ff904cd 17156
c7e4ee3a
CB
17157// FFEINTRIN_specFLOAT //
17158 r__1 = (real) i1;
17159 foor_(&r__1);
17160// FFEINTRIN_specREAL //
17161 r__1 = (real) i1;
17162 foor_(&r__1);
5ff904cd 17163
c7e4ee3a 17164} // MAIN__ //
5ff904cd 17165
c7e4ee3a 17166-------- (end output file from f2c)
5ff904cd 17167
c7e4ee3a 17168*/
This page took 2.748914 seconds and 5 git commands to generate.