]> gcc.gnu.org Git - gcc.git/blame - gcc/f/com.c
c-decl.c (grokdeclarator): Update.
[gcc.git] / gcc / f / com.c
CommitLineData
5ff904cd 1/* com.c -- Implementation File (module.c template V1.0)
9bc02796 2 Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
06ceef4e 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"
15a40ced
ZW
84#include "flags.h"
85#include "rtl.h"
86#include "toplev.h"
87#include "tree.h"
88#include "output.h" /* Must follow tree.h so TREE_CODE is defined! */
89#include "convert.h"
90#include "ggc.h"
46f018e1 91#include "diagnostic.h"
f1685b7c 92#include "intl.h"
17ed6335 93#include "langhooks.h"
d23c55c2 94#include "langhooks-def.h"
5ff904cd 95
5ff904cd
JL
96/* VMS-specific definitions */
97#ifdef VMS
98#include <descrip.h>
99#define O_RDONLY 0 /* Open arg for Read/Only */
100#define O_WRONLY 1 /* Open arg for Write/Only */
101#define read(fd,buf,size) VMS_read (fd,buf,size)
102#define write(fd,buf,size) VMS_write (fd,buf,size)
103#define open(fname,mode,prot) VMS_open (fname,mode,prot)
104#define fopen(fname,mode) VMS_fopen (fname,mode)
105#define freopen(fname,mode,ofile) VMS_freopen (fname,mode,ofile)
106#define strncat(dst,src,cnt) VMS_strncat (dst,src,cnt)
107#define fstat(fd,stbuf) VMS_fstat (fd,stbuf)
108static int VMS_fstat (), VMS_stat ();
109static char * VMS_strncat ();
110static int VMS_read ();
111static int VMS_write ();
112static int VMS_open ();
113static FILE * VMS_fopen ();
114static FILE * VMS_freopen ();
115static void hack_vms_include_specification ();
116typedef struct { unsigned :16, :16, :16; } vms_ino_t;
117#define ino_t vms_ino_t
118#define INCLUDE_LEN_FUDGE 10 /* leave room for VMS syntax conversion */
5ff904cd
JL
119#endif /* VMS */
120
5ff904cd
JL
121#define FFECOM_DETERMINE_TYPES 1 /* for com.h */
122#include "com.h"
123#include "bad.h"
124#include "bld.h"
125#include "equiv.h"
126#include "expr.h"
127#include "implic.h"
128#include "info.h"
129#include "malloc.h"
130#include "src.h"
131#include "st.h"
132#include "storag.h"
133#include "symbol.h"
134#include "target.h"
135#include "top.h"
136#include "type.h"
137
138/* Externals defined here. */
139
77f77701
DB
140/* Stream for reading from the input file. */
141FILE *finput;
142
5ff904cd
JL
143/* These definitions parallel those in c-decl.c so that code from that
144 module can be used pretty much as is. Much of these defs aren't
145 otherwise used, i.e. by g77 code per se, except some of them are used
146 to build some of them that are. The ones that are global (i.e. not
147 "static") are those that ste.c and such might use (directly
148 or by using com macros that reference them in their definitions). */
149
5ff904cd
JL
150tree string_type_node;
151
5ff904cd
JL
152/* The rest of these are inventions for g77, though there might be
153 similar things in the C front end. As they are found, these
154 inventions should be renamed to be canonical. Note that only
155 the ones currently required to be global are so. */
156
157static tree ffecom_tree_fun_type_void;
5ff904cd
JL
158
159tree ffecom_integer_type_node; /* Abbrev for _tree_type[blah][blah]. */
160tree ffecom_integer_zero_node; /* Like *_*_* with g77's integer type. */
161tree ffecom_integer_one_node; /* " */
162tree ffecom_tree_type[FFEINFO_basictype][FFEINFO_kindtype];
163
164/* _fun_type things are the f2c-specific versions. For -fno-f2c,
165 just use build_function_type and build_pointer_type on the
166 appropriate _tree_type array element. */
167
168static tree ffecom_tree_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
169static tree ffecom_tree_ptr_to_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
170static tree ffecom_tree_subr_type;
171static tree ffecom_tree_ptr_to_subr_type;
172static tree ffecom_tree_blockdata_type;
173
174static tree ffecom_tree_xargc_;
175
176ffecomSymbol ffecom_symbol_null_
177=
178{
179 NULL_TREE,
180 NULL_TREE,
181 NULL_TREE,
0816ebdd
KG
182 NULL_TREE,
183 false
5ff904cd
JL
184};
185ffeinfoKindtype ffecom_pointer_kind_ = FFEINFO_basictypeNONE;
186ffeinfoKindtype ffecom_label_kind_ = FFEINFO_basictypeNONE;
187
188int ffecom_f2c_typecode_[FFEINFO_basictype][FFEINFO_kindtype];
189tree ffecom_f2c_integer_type_node;
190tree ffecom_f2c_ptr_to_integer_type_node;
191tree ffecom_f2c_address_type_node;
192tree ffecom_f2c_real_type_node;
193tree ffecom_f2c_ptr_to_real_type_node;
194tree ffecom_f2c_doublereal_type_node;
195tree ffecom_f2c_complex_type_node;
196tree ffecom_f2c_doublecomplex_type_node;
197tree ffecom_f2c_longint_type_node;
198tree ffecom_f2c_logical_type_node;
199tree ffecom_f2c_flag_type_node;
200tree ffecom_f2c_ftnlen_type_node;
201tree ffecom_f2c_ftnlen_zero_node;
202tree ffecom_f2c_ftnlen_one_node;
203tree ffecom_f2c_ftnlen_two_node;
204tree ffecom_f2c_ptr_to_ftnlen_type_node;
205tree ffecom_f2c_ftnint_type_node;
206tree ffecom_f2c_ptr_to_ftnint_type_node;
5ff904cd
JL
207
208/* Simple definitions and enumerations. */
209
210#ifndef FFECOM_sizeMAXSTACKITEM
211#define FFECOM_sizeMAXSTACKITEM 32*1024 /* Keep user-declared things
212 larger than this # bytes
213 off stack if possible. */
214#endif
215
216/* For systems that have large enough stacks, they should define
217 this to 0, and here, for ease of use later on, we just undefine
218 it if it is 0. */
219
220#if FFECOM_sizeMAXSTACKITEM == 0
221#undef FFECOM_sizeMAXSTACKITEM
222#endif
223
224typedef enum
225 {
226 FFECOM_rttypeVOID_,
6d433196 227 FFECOM_rttypeVOIDSTAR_, /* C's `void *' type. */
795232f7
JL
228 FFECOM_rttypeFTNINT_, /* f2c's `ftnint' type. */
229 FFECOM_rttypeINTEGER_, /* f2c's `integer' type. */
230 FFECOM_rttypeLONGINT_, /* f2c's `longint' type. */
231 FFECOM_rttypeLOGICAL_, /* f2c's `logical' type. */
232 FFECOM_rttypeREAL_F2C_, /* f2c's `real' returned as `double'. */
233 FFECOM_rttypeREAL_GNU_, /* `real' returned as such. */
5ff904cd 234 FFECOM_rttypeCOMPLEX_F2C_, /* f2c's `complex' returned via 1st arg. */
795232f7 235 FFECOM_rttypeCOMPLEX_GNU_, /* f2c's `complex' returned directly. */
5ff904cd 236 FFECOM_rttypeDOUBLE_, /* C's `double' type. */
795232f7 237 FFECOM_rttypeDOUBLEREAL_, /* f2c's `doublereal' type. */
5ff904cd 238 FFECOM_rttypeDBLCMPLX_F2C_, /* f2c's `doublecomplex' returned via 1st arg. */
795232f7 239 FFECOM_rttypeDBLCMPLX_GNU_, /* f2c's `doublecomplex' returned directly. */
5ff904cd
JL
240 FFECOM_rttypeCHARACTER_, /* f2c `char *'/`ftnlen' pair. */
241 FFECOM_rttype_
242 } ffecomRttype_;
243
244/* Internal typedefs. */
245
5ff904cd 246typedef struct _ffecom_concat_list_ ffecomConcatList_;
5ff904cd
JL
247
248/* Private include files. */
249
250
251/* Internal structure definitions. */
252
5ff904cd
JL
253struct _ffecom_concat_list_
254 {
255 ffebld *exprs;
256 int count;
257 int max;
258 ffetargetCharacterSize minlen;
259 ffetargetCharacterSize maxlen;
260 };
5ff904cd
JL
261
262/* Static functions (internal). */
263
b0c48229
NB
264static tree ffe_type_for_mode PARAMS ((enum machine_mode, int));
265static tree ffe_type_for_size PARAMS ((unsigned int, int));
ceef8ce4
NB
266static tree ffe_unsigned_type PARAMS ((tree));
267static tree ffe_signed_type PARAMS ((tree));
268static tree ffe_signed_or_unsigned_type PARAMS ((int, tree));
dffd7eb6 269static bool ffe_mark_addressable PARAMS ((tree));
f5e99456 270static void ffecom_init_decl_processing PARAMS ((void));
26f096f9 271static tree ffecom_arglist_expr_ (const char *argstring, ffebld args);
5ff904cd
JL
272static tree ffecom_widest_expr_type_ (ffebld list);
273static bool ffecom_overlap_ (tree dest_decl, tree dest_offset,
274 tree dest_size, tree source_tree,
275 ffebld source, bool scalar_arg);
276static bool ffecom_args_overlapping_ (tree dest_tree, ffebld dest,
277 tree args, tree callee_commons,
278 bool scalar_args);
26f096f9 279static tree ffecom_build_f2c_string_ (int i, const char *s);
5ff904cd
JL
280static tree ffecom_call_ (tree fn, ffeinfoKindtype kt,
281 bool is_f2c_complex, tree type,
282 tree args, tree dest_tree,
283 ffebld dest, bool *dest_used,
c7e4ee3a 284 tree callee_commons, bool scalar_args, tree hook);
5ff904cd
JL
285static tree ffecom_call_binop_ (tree fn, ffeinfoKindtype kt,
286 bool is_f2c_complex, tree type,
287 ffebld left, ffebld right,
288 tree dest_tree, ffebld dest,
289 bool *dest_used, tree callee_commons,
95eb4fd9 290 bool scalar_args, bool ref, tree hook);
86fc7a6c
CB
291static void ffecom_char_args_x_ (tree *xitem, tree *length,
292 ffebld expr, bool with_null);
5ff904cd
JL
293static tree ffecom_check_size_overflow_ (ffesymbol s, tree type, bool dummy);
294static tree ffecom_char_enhance_arg_ (tree *xtype, ffesymbol s);
295static ffecomConcatList_
296 ffecom_concat_list_gather_ (ffecomConcatList_ catlist,
297 ffebld expr,
298 ffetargetCharacterSize max);
299static void ffecom_concat_list_kill_ (ffecomConcatList_ catlist);
300static ffecomConcatList_ ffecom_concat_list_new_ (ffebld expr,
301 ffetargetCharacterSize max);
26f096f9
KG
302static void ffecom_debug_kludge_ (tree aggr, const char *aggr_type,
303 ffesymbol member, tree member_type,
304 ffetargetOffset offset);
5ff904cd 305static void ffecom_do_entry_ (ffesymbol fn, int entrynum);
092a4ef8
RH
306static tree ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest,
307 bool *dest_used, bool assignp, bool widenp);
5ff904cd
JL
308static tree ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree,
309 ffebld dest, bool *dest_used);
c7e4ee3a 310static tree ffecom_expr_power_integer_ (ffebld expr);
5ff904cd 311static void ffecom_expr_transform_ (ffebld expr);
26f096f9 312static void ffecom_f2c_make_type_ (tree *type, int tcode, const char *name);
5ff904cd
JL
313static void ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size,
314 int code);
315static ffeglobal ffecom_finish_global_ (ffeglobal global);
316static ffesymbol ffecom_finish_symbol_transform_ (ffesymbol s);
26f096f9 317static tree ffecom_get_appended_identifier_ (char us, const char *text);
5ff904cd 318static tree ffecom_get_external_identifier_ (ffesymbol s);
26f096f9 319static tree ffecom_get_identifier_ (const char *text);
5ff904cd
JL
320static tree ffecom_gen_sfuncdef_ (ffesymbol s,
321 ffeinfoBasictype bt,
322 ffeinfoKindtype kt);
26f096f9 323static const char *ffecom_gfrt_args_ (ffecomGfrt ix);
5ff904cd
JL
324static tree ffecom_gfrt_tree_ (ffecomGfrt ix);
325static tree ffecom_init_zero_ (tree decl);
326static tree ffecom_intrinsic_ichar_ (tree tree_type, ffebld arg,
327 tree *maybe_tree);
328static tree ffecom_intrinsic_len_ (ffebld expr);
329static void ffecom_let_char_ (tree dest_tree,
330 tree dest_length,
331 ffetargetCharacterSize dest_size,
332 ffebld source);
333static void ffecom_make_gfrt_ (ffecomGfrt ix);
334static void ffecom_member_phase1_ (ffestorag mst, ffestorag st);
5ff904cd 335static void ffecom_member_phase2_ (ffestorag mst, ffestorag st);
c7e4ee3a
CB
336static void ffecom_prepare_let_char_ (ffetargetCharacterSize dest_size,
337 ffebld source);
5ff904cd
JL
338static void ffecom_push_dummy_decls_ (ffebld dumlist,
339 bool stmtfunc);
340static void ffecom_start_progunit_ (void);
341static ffesymbol ffecom_sym_transform_ (ffesymbol s);
342static ffesymbol ffecom_sym_transform_assign_ (ffesymbol s);
343static void ffecom_transform_common_ (ffesymbol s);
344static void ffecom_transform_equiv_ (ffestorag st);
345static tree ffecom_transform_namelist_ (ffesymbol s);
346static void ffecom_tree_canonize_ptr_ (tree *decl, tree *offset,
347 tree t);
348static void ffecom_tree_canonize_ref_ (tree *decl, tree *offset,
349 tree *size, tree tree);
350static tree ffecom_tree_divide_ (tree tree_type, tree left, tree right,
351 tree dest_tree, ffebld dest,
c7e4ee3a 352 bool *dest_used, tree hook);
5ff904cd
JL
353static tree ffecom_type_localvar_ (ffesymbol s,
354 ffeinfoBasictype bt,
355 ffeinfoKindtype kt);
356static tree ffecom_type_namelist_ (void);
5ff904cd
JL
357static tree ffecom_type_vardesc_ (void);
358static tree ffecom_vardesc_ (ffebld expr);
359static tree ffecom_vardesc_array_ (ffesymbol s);
360static tree ffecom_vardesc_dims_ (ffesymbol s);
26f096f9
KG
361static tree ffecom_convert_narrow_ (tree type, tree expr);
362static tree ffecom_convert_widen_ (tree type, tree expr);
5ff904cd
JL
363
364/* These are static functions that parallel those found in the C front
365 end and thus have the same names. */
366
c7e4ee3a 367static tree bison_rule_compstmt_ (void);
5ff904cd 368static void bison_rule_pushlevel_ (void);
c7e4ee3a 369static void delete_block (tree block);
5ff904cd
JL
370static int duplicate_decls (tree newdecl, tree olddecl);
371static void finish_decl (tree decl, tree init, bool is_top_level);
372static void finish_function (int nested);
7afff7cf 373static const char *ffe_printable_name (tree decl, int v);
7cb32822 374static void ffe_print_error_function (diagnostic_context *, const char *);
5ff904cd
JL
375static tree lookup_name_current_level (tree name);
376static struct binding_level *make_binding_level (void);
377static void pop_f_function_context (void);
378static void push_f_function_context (void);
379static void push_parm_decl (tree parm);
380static tree pushdecl_top_level (tree decl);
c7e4ee3a 381static int kept_level_p (void);
5ff904cd
JL
382static tree storedecls (tree decls);
383static void store_parm_decls (int is_main_program);
384static tree start_decl (tree decl, bool is_top_level);
385static void start_function (tree name, tree type, int nested, int public);
b0791fa9 386static void ffecom_file_ (const char *name);
5ff904cd
JL
387static void ffecom_close_include_ (FILE *f);
388static int ffecom_decode_include_option_ (char *spec);
389static FILE *ffecom_open_include_ (char *name, ffewhereLine l,
390 ffewhereColumn c);
5ff904cd
JL
391
392/* Static objects accessed by functions in this module. */
393
394static ffesymbol ffecom_primary_entry_ = NULL;
395static ffesymbol ffecom_nested_entry_ = NULL;
396static ffeinfoKind ffecom_primary_entry_kind_;
397static bool ffecom_primary_entry_is_proc_;
5ff904cd
JL
398static tree ffecom_outer_function_decl_;
399static tree ffecom_previous_function_decl_;
400static tree ffecom_which_entrypoint_decl_;
5ff904cd
JL
401static tree ffecom_float_zero_ = NULL_TREE;
402static tree ffecom_float_half_ = NULL_TREE;
403static tree ffecom_double_zero_ = NULL_TREE;
404static tree ffecom_double_half_ = NULL_TREE;
405static tree ffecom_func_result_;/* For functions. */
406static tree ffecom_func_length_;/* For CHARACTER fns. */
407static ffebld ffecom_list_blockdata_;
408static ffebld ffecom_list_common_;
409static ffebld ffecom_master_arglist_;
410static ffeinfoBasictype ffecom_master_bt_;
411static ffeinfoKindtype ffecom_master_kt_;
412static ffetargetCharacterSize ffecom_master_size_;
413static int ffecom_num_fns_ = 0;
414static int ffecom_num_entrypoints_ = 0;
415static bool ffecom_is_altreturning_ = FALSE;
416static tree ffecom_multi_type_node_;
417static tree ffecom_multi_retval_;
418static tree
419 ffecom_multi_fields_[FFEINFO_basictype][FFEINFO_kindtype];
420static bool ffecom_member_namelisted_; /* _member_phase1_ namelisted? */
421static bool ffecom_doing_entry_ = FALSE;
422static bool ffecom_transform_only_dummies_ = FALSE;
ff852b44
CB
423static int ffecom_typesize_pointer_;
424static int ffecom_typesize_integer1_;
5ff904cd
JL
425
426/* Holds pointer-to-function expressions. */
427
428static tree ffecom_gfrt_[FFECOM_gfrt]
429=
430{
95eb4fd9 431#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) NULL_TREE,
5ff904cd
JL
432#include "com-rt.def"
433#undef DEFGFRT
434};
435
436/* Holds the external names of the functions. */
437
19dab795 438static const char *const ffecom_gfrt_name_[FFECOM_gfrt]
5ff904cd
JL
439=
440{
95eb4fd9 441#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) NAME,
5ff904cd
JL
442#include "com-rt.def"
443#undef DEFGFRT
444};
445
446/* Whether the function returns. */
447
0b5826ac 448static const bool ffecom_gfrt_volatile_[FFECOM_gfrt]
5ff904cd
JL
449=
450{
95eb4fd9 451#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) VOLATILE,
5ff904cd
JL
452#include "com-rt.def"
453#undef DEFGFRT
454};
455
456/* Whether the function returns type complex. */
457
0b5826ac 458static const bool ffecom_gfrt_complex_[FFECOM_gfrt]
5ff904cd
JL
459=
460{
95eb4fd9
TM
461#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) COMPLEX,
462#include "com-rt.def"
463#undef DEFGFRT
464};
465
466/* Whether the function is const
467 (i.e., has no side effects and only depends on its arguments). */
468
0b5826ac 469static const bool ffecom_gfrt_const_[FFECOM_gfrt]
95eb4fd9
TM
470=
471{
472#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) CONST,
5ff904cd
JL
473#include "com-rt.def"
474#undef DEFGFRT
475};
476
477/* Type code for the function return value. */
478
0b5826ac 479static const ffecomRttype_ ffecom_gfrt_type_[FFECOM_gfrt]
5ff904cd
JL
480=
481{
95eb4fd9 482#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) TYPE,
5ff904cd
JL
483#include "com-rt.def"
484#undef DEFGFRT
485};
486
487/* String of codes for the function's arguments. */
488
19dab795 489static const char *const ffecom_gfrt_argstring_[FFECOM_gfrt]
5ff904cd
JL
490=
491{
95eb4fd9 492#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) ARGS,
5ff904cd
JL
493#include "com-rt.def"
494#undef DEFGFRT
495};
5ff904cd
JL
496
497/* Internal macros. */
498
5ff904cd
JL
499/* We let tm.h override the types used here, to handle trivial differences
500 such as the choice of unsigned int or long unsigned int for size_t.
501 When machines start needing nontrivial differences in the size type,
502 it would be best to do something here to figure out automatically
503 from other information what type to use. */
504
ff852b44
CB
505#ifndef SIZE_TYPE
506#define SIZE_TYPE "long unsigned int"
507#endif
5ff904cd 508
5ff904cd
JL
509#define ffecom_concat_list_count_(catlist) ((catlist).count)
510#define ffecom_concat_list_expr_(catlist,i) ((catlist).exprs[(i)])
511#define ffecom_concat_list_maxlen_(catlist) ((catlist).maxlen)
512#define ffecom_concat_list_minlen_(catlist) ((catlist).minlen)
513
86fc7a6c
CB
514#define ffecom_char_args_(i,l,e) ffecom_char_args_x_((i),(l),(e),FALSE)
515#define ffecom_char_args_with_null_(i,l,e) ffecom_char_args_x_((i),(l),(e),TRUE)
516
5ff904cd
JL
517/* For each binding contour we allocate a binding_level structure
518 * which records the names defined in that contour.
519 * Contours include:
520 * 0) the global one
521 * 1) one for each function definition,
522 * where internal declarations of the parameters appear.
523 *
524 * The current meaning of a name can be found by searching the levels from
525 * the current one out to the global one.
526 */
527
528/* Note that the information in the `names' component of the global contour
529 is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */
530
531struct binding_level
532 {
c7e4ee3a
CB
533 /* A chain of _DECL nodes for all variables, constants, functions,
534 and typedef types. These are in the reverse of the order supplied.
535 */
5ff904cd
JL
536 tree names;
537
c7e4ee3a
CB
538 /* For each level (except not the global one),
539 a chain of BLOCK nodes for all the levels
540 that were entered and exited one level down. */
5ff904cd
JL
541 tree blocks;
542
c7e4ee3a
CB
543 /* The BLOCK node for this level, if one has been preallocated.
544 If 0, the BLOCK is allocated (if needed) when the level is popped. */
5ff904cd
JL
545 tree this_block;
546
547 /* The binding level which this one is contained in (inherits from). */
548 struct binding_level *level_chain;
c7e4ee3a
CB
549
550 /* 0: no ffecom_prepare_* functions called at this level yet;
551 1: ffecom_prepare* functions called, except not ffecom_prepare_end;
552 2: ffecom_prepare_end called. */
553 int prep_state;
5ff904cd
JL
554 };
555
556#define NULL_BINDING_LEVEL (struct binding_level *) NULL
557
558/* The binding level currently in effect. */
559
560static struct binding_level *current_binding_level;
561
562/* A chain of binding_level structures awaiting reuse. */
563
564static struct binding_level *free_binding_level;
565
566/* The outermost binding level, for names of file scope.
567 This is created when the compiler is started and exists
568 through the entire run. */
569
570static struct binding_level *global_binding_level;
571
572/* Binding level structures are initialized by copying this one. */
573
5e65297b 574static const struct binding_level clear_binding_level
5ff904cd 575=
c7e4ee3a 576{NULL, NULL, NULL, NULL_BINDING_LEVEL, 0};
5ff904cd
JL
577
578/* Language-dependent contents of an identifier. */
579
580struct lang_identifier
581 {
582 struct tree_identifier ignore;
583 tree global_value, local_value, label_value;
584 bool invented;
585 };
586
587/* Macros for access to language-specific slots in an identifier. */
588/* Each of these slots contains a DECL node or null. */
589
590/* This represents the value which the identifier has in the
591 file-scope namespace. */
592#define IDENTIFIER_GLOBAL_VALUE(NODE) \
593 (((struct lang_identifier *)(NODE))->global_value)
594/* This represents the value which the identifier has in the current
595 scope. */
596#define IDENTIFIER_LOCAL_VALUE(NODE) \
597 (((struct lang_identifier *)(NODE))->local_value)
598/* This represents the value which the identifier has as a label in
599 the current label scope. */
600#define IDENTIFIER_LABEL_VALUE(NODE) \
601 (((struct lang_identifier *)(NODE))->label_value)
602/* This is nonzero if the identifier was "made up" by g77 code. */
603#define IDENTIFIER_INVENTED(NODE) \
604 (((struct lang_identifier *)(NODE))->invented)
605
606/* In identifiers, C uses the following fields in a special way:
607 TREE_PUBLIC to record that there was a previous local extern decl.
608 TREE_USED to record that such a decl was used.
609 TREE_ADDRESSABLE to record that the address of such a decl was used. */
610
611/* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function
612 that have names. Here so we can clear out their names' definitions
613 at the end of the function. */
614
615static tree named_labels;
616
617/* A list of LABEL_DECLs from outer contexts that are currently shadowed. */
618
619static tree shadowed_labels;
5ff904cd 620\f
6b55276e
CB
621/* Return the subscript expression, modified to do range-checking.
622
623 `array' is the array to be checked against.
624 `element' is the subscript expression to check.
625 `dim' is the dimension number (starting at 0).
626 `total_dims' is the total number of dimensions (0 for CHARACTER substring).
627*/
628
629static tree
630ffecom_subscript_check_ (tree array, tree element, int dim, int total_dims,
3b304f5b 631 const char *array_name)
6b55276e
CB
632{
633 tree low = TYPE_MIN_VALUE (TYPE_DOMAIN (array));
634 tree high = TYPE_MAX_VALUE (TYPE_DOMAIN (array));
635 tree cond;
636 tree die;
637 tree args;
638
639 if (element == error_mark_node)
640 return element;
641
ff852b44
CB
642 if (TREE_TYPE (low) != TREE_TYPE (element))
643 {
644 if (TYPE_PRECISION (TREE_TYPE (low))
645 > TYPE_PRECISION (TREE_TYPE (element)))
646 element = convert (TREE_TYPE (low), element);
647 else
648 {
649 low = convert (TREE_TYPE (element), low);
650 if (high)
651 high = convert (TREE_TYPE (element), high);
652 }
653 }
654
6b55276e 655 element = ffecom_save_tree (element);
2bc21ba5 656 if (total_dims == 0)
6b55276e 657 {
2bc21ba5
GH
658 /* Special handling for substring range checks. Fortran allows the
659 end subscript < begin subscript, which means that expressions like
660 string(1:0) are valid (and yield a null string). In view of this,
661 enforce two simpler conditions:
662 1) element<=high for end-substring;
663 2) element>=low for start-substring.
664 Run-time character movement will enforce remaining conditions.
665
666 More complicated checks would be better, but present structure only
667 provides one index element at a time, so it is not possible to
668 enforce a check of both i and j in string(i:j). If it were, the
669 complete set of rules would read,
670 if ( ((j<i) && ((low<=i<=high) || (low<=j<=high))) ||
671 ((low<=i<=high) && (low<=j<=high)) )
672 ok ;
673 else
674 range error ;
675 */
676 if (dim)
677 cond = ffecom_2 (LE_EXPR, integer_type_node, element, high);
678 else
679 cond = ffecom_2 (LE_EXPR, integer_type_node, low, element);
680 }
681 else
682 {
683 /* Array reference substring range checking. */
516b69ff 684
2bc21ba5
GH
685 cond = ffecom_2 (LE_EXPR, integer_type_node,
686 low,
687 element);
688 if (high)
689 {
690 cond = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
691 cond,
692 ffecom_2 (LE_EXPR, integer_type_node,
693 element,
694 high));
695 }
6b55276e
CB
696 }
697
698 {
699 int len;
700 char *proc;
701 char *var;
702 tree arg3;
703 tree arg2;
704 tree arg1;
705 tree arg4;
706
707 switch (total_dims)
708 {
709 case 0:
d4c3ec27
KG
710 var = concat (array_name, "[", (dim ? "end" : "start"),
711 "-substring]", NULL);
6b55276e 712 len = strlen (var) + 1;
3b304f5b
ZW
713 arg1 = build_string (len, var);
714 free (var);
6b55276e
CB
715 break;
716
717 case 1:
718 len = strlen (array_name) + 1;
3b304f5b 719 arg1 = build_string (len, array_name);
6b55276e
CB
720 break;
721
722 default:
723 var = xmalloc (strlen (array_name) + 40);
3b304f5b 724 sprintf (var, "%s[subscript-%d-of-%d]",
6b55276e
CB
725 array_name,
726 dim + 1, total_dims);
727 len = strlen (var) + 1;
3b304f5b
ZW
728 arg1 = build_string (len, var);
729 free (var);
6b55276e
CB
730 break;
731 }
732
6b55276e
CB
733 TREE_TYPE (arg1)
734 = build_type_variant (build_array_type (char_type_node,
735 build_range_type
736 (integer_type_node,
737 integer_one_node,
738 build_int_2 (len, 0))),
739 1, 0);
740 TREE_CONSTANT (arg1) = 1;
741 TREE_STATIC (arg1) = 1;
742 arg1 = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg1)),
743 arg1);
744
745 /* s_rnge adds one to the element to print it, so bias against
746 that -- want to print a faithful *subscript* value. */
747 arg2 = convert (ffecom_f2c_ftnint_type_node,
748 ffecom_2 (MINUS_EXPR,
749 TREE_TYPE (element),
750 element,
751 convert (TREE_TYPE (element),
752 integer_one_node)));
753
d4c3ec27
KG
754 proc = concat (input_filename, "/",
755 IDENTIFIER_POINTER (DECL_NAME (current_function_decl)),
756 NULL);
757 len = strlen (proc) + 1;
6b55276e
CB
758 arg3 = build_string (len, proc);
759
760 free (proc);
761
762 TREE_TYPE (arg3)
763 = build_type_variant (build_array_type (char_type_node,
764 build_range_type
765 (integer_type_node,
766 integer_one_node,
767 build_int_2 (len, 0))),
768 1, 0);
769 TREE_CONSTANT (arg3) = 1;
770 TREE_STATIC (arg3) = 1;
771 arg3 = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg3)),
772 arg3);
773
774 arg4 = convert (ffecom_f2c_ftnint_type_node,
775 build_int_2 (lineno, 0));
776
777 arg1 = build_tree_list (NULL_TREE, arg1);
778 arg2 = build_tree_list (NULL_TREE, arg2);
779 arg3 = build_tree_list (NULL_TREE, arg3);
780 arg4 = build_tree_list (NULL_TREE, arg4);
781 TREE_CHAIN (arg3) = arg4;
782 TREE_CHAIN (arg2) = arg3;
783 TREE_CHAIN (arg1) = arg2;
784
785 args = arg1;
786 }
787 die = ffecom_call_gfrt (FFECOM_gfrtRANGE,
788 args, NULL_TREE);
789 TREE_SIDE_EFFECTS (die) = 1;
790
791 element = ffecom_3 (COND_EXPR,
792 TREE_TYPE (element),
793 cond,
794 element,
795 die);
796
797 return element;
798}
799
800/* Return the computed element of an array reference.
801
ff852b44
CB
802 `item' is NULL_TREE, or the transformed pointer to the array.
803 `expr' is the original opARRAYREF expression, which is transformed
804 if `item' is NULL_TREE.
805 `want_ptr' is non-zero if a pointer to the element, instead of
6b55276e
CB
806 the element itself, is to be returned. */
807
808static tree
809ffecom_arrayref_ (tree item, ffebld expr, int want_ptr)
810{
811 ffebld dims[FFECOM_dimensionsMAX];
812 int i;
813 int total_dims;
ff852b44
CB
814 int flatten = ffe_is_flatten_arrays ();
815 int need_ptr;
6b55276e
CB
816 tree array;
817 tree element;
ff852b44
CB
818 tree tree_type;
819 tree tree_type_x;
3b304f5b 820 const char *array_name;
ff852b44
CB
821 ffetype type;
822 ffebld list;
6b55276e
CB
823
824 if (ffebld_op (ffebld_left (expr)) == FFEBLD_opSYMTER)
825 array_name = ffesymbol_text (ffebld_symter (ffebld_left (expr)));
826 else
827 array_name = "[expr?]";
828
829 /* Build up ARRAY_REFs in reverse order (since we're column major
830 here in Fortran land). */
831
ff852b44
CB
832 for (i = 0, list = ffebld_right (expr);
833 list != NULL;
834 ++i, list = ffebld_trail (list))
835 {
836 dims[i] = ffebld_head (list);
837 type = ffeinfo_type (ffebld_basictype (dims[i]),
838 ffebld_kindtype (dims[i]));
839 if (! flatten
840 && ffecom_typesize_pointer_ > ffecom_typesize_integer1_
841 && ffetype_size (type) > ffecom_typesize_integer1_)
842 /* E.g. ARRAY(INDEX), given INTEGER*8 INDEX, on a system with 64-bit
843 pointers and 32-bit integers. Do the full 64-bit pointer
844 arithmetic, for codes using arrays for nonstandard heap-like
845 work. */
846 flatten = 1;
847 }
6b55276e
CB
848
849 total_dims = i;
850
ff852b44
CB
851 need_ptr = want_ptr || flatten;
852
853 if (! item)
854 {
855 if (need_ptr)
856 item = ffecom_ptr_to_expr (ffebld_left (expr));
857 else
858 item = ffecom_expr (ffebld_left (expr));
859
860 if (item == error_mark_node)
861 return item;
862
863 if (ffeinfo_where (ffebld_info (expr)) == FFEINFO_whereFLEETING
dffd7eb6 864 && ! ffe_mark_addressable (item))
ff852b44
CB
865 return error_mark_node;
866 }
867
868 if (item == error_mark_node)
869 return item;
870
6b55276e
CB
871 if (need_ptr)
872 {
ff852b44
CB
873 tree min;
874
6b55276e
CB
875 for (--i, array = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item)));
876 i >= 0;
877 --i, array = TYPE_MAIN_VARIANT (TREE_TYPE (array)))
878 {
ff852b44
CB
879 min = TYPE_MIN_VALUE (TYPE_DOMAIN (array));
880 element = ffecom_expr_ (dims[i], NULL, NULL, NULL, FALSE, TRUE);
02f06e64 881 if (flag_bounds_check)
6b55276e
CB
882 element = ffecom_subscript_check_ (array, element, i, total_dims,
883 array_name);
ff852b44
CB
884 if (element == error_mark_node)
885 return element;
886
887 /* Widen integral arithmetic as desired while preserving
888 signedness. */
889 tree_type = TREE_TYPE (element);
890 tree_type_x = tree_type;
891 if (tree_type
892 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
893 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
894 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
895
896 if (TREE_TYPE (min) != tree_type_x)
897 min = convert (tree_type_x, min);
898 if (TREE_TYPE (element) != tree_type_x)
899 element = convert (tree_type_x, element);
900
6b55276e
CB
901 item = ffecom_2 (PLUS_EXPR,
902 build_pointer_type (TREE_TYPE (array)),
903 item,
904 size_binop (MULT_EXPR,
905 size_in_bytes (TREE_TYPE (array)),
fed3cef0
RK
906 convert (sizetype,
907 fold (build (MINUS_EXPR,
908 tree_type_x,
909 element, min)))));
6b55276e
CB
910 }
911 if (! want_ptr)
912 {
913 item = ffecom_1 (INDIRECT_REF,
914 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item))),
915 item);
916 }
917 }
918 else
919 {
920 for (--i;
921 i >= 0;
922 --i)
923 {
924 array = TYPE_MAIN_VARIANT (TREE_TYPE (item));
925
926 element = ffecom_expr_ (dims[i], NULL, NULL, NULL, FALSE, TRUE);
02f06e64 927 if (flag_bounds_check)
6b55276e
CB
928 element = ffecom_subscript_check_ (array, element, i, total_dims,
929 array_name);
ff852b44
CB
930 if (element == error_mark_node)
931 return element;
932
933 /* Widen integral arithmetic as desired while preserving
934 signedness. */
935 tree_type = TREE_TYPE (element);
936 tree_type_x = tree_type;
937 if (tree_type
938 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
939 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
940 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
941
942 element = convert (tree_type_x, element);
943
6b55276e
CB
944 item = ffecom_2 (ARRAY_REF,
945 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item))),
946 item,
947 element);
948 }
949 }
950
951 return item;
952}
953
5ff904cd
JL
954/* This is like gcc's stabilize_reference -- in fact, most of the code
955 comes from that -- but it handles the situation where the reference
956 is going to have its subparts picked at, and it shouldn't change
957 (or trigger extra invocations of functions in the subtrees) due to
958 this. save_expr is a bit overzealous, because we don't need the
959 entire thing calculated and saved like a temp. So, for DECLs, no
960 change is needed, because these are stable aggregates, and ARRAY_REF
961 and such might well be stable too, but for things like calculations,
962 we do need to calculate a snapshot of a value before picking at it. */
963
5ff904cd
JL
964static tree
965ffecom_stabilize_aggregate_ (tree ref)
966{
967 tree result;
968 enum tree_code code = TREE_CODE (ref);
969
970 switch (code)
971 {
972 case VAR_DECL:
973 case PARM_DECL:
974 case RESULT_DECL:
975 /* No action is needed in this case. */
976 return ref;
977
978 case NOP_EXPR:
979 case CONVERT_EXPR:
980 case FLOAT_EXPR:
981 case FIX_TRUNC_EXPR:
982 case FIX_FLOOR_EXPR:
983 case FIX_ROUND_EXPR:
984 case FIX_CEIL_EXPR:
985 result = build_nt (code, stabilize_reference (TREE_OPERAND (ref, 0)));
986 break;
987
988 case INDIRECT_REF:
989 result = build_nt (INDIRECT_REF,
990 stabilize_reference_1 (TREE_OPERAND (ref, 0)));
991 break;
992
993 case COMPONENT_REF:
994 result = build_nt (COMPONENT_REF,
995 stabilize_reference (TREE_OPERAND (ref, 0)),
996 TREE_OPERAND (ref, 1));
997 break;
998
999 case BIT_FIELD_REF:
1000 result = build_nt (BIT_FIELD_REF,
1001 stabilize_reference (TREE_OPERAND (ref, 0)),
1002 stabilize_reference_1 (TREE_OPERAND (ref, 1)),
1003 stabilize_reference_1 (TREE_OPERAND (ref, 2)));
1004 break;
1005
1006 case ARRAY_REF:
1007 result = build_nt (ARRAY_REF,
1008 stabilize_reference (TREE_OPERAND (ref, 0)),
1009 stabilize_reference_1 (TREE_OPERAND (ref, 1)));
1010 break;
1011
1012 case COMPOUND_EXPR:
1013 result = build_nt (COMPOUND_EXPR,
1014 stabilize_reference_1 (TREE_OPERAND (ref, 0)),
1015 stabilize_reference (TREE_OPERAND (ref, 1)));
1016 break;
1017
1018 case RTL_EXPR:
a8d0a42e 1019 abort ();
5ff904cd
JL
1020
1021
1022 default:
1023 return save_expr (ref);
1024
1025 case ERROR_MARK:
1026 return error_mark_node;
1027 }
1028
1029 TREE_TYPE (result) = TREE_TYPE (ref);
1030 TREE_READONLY (result) = TREE_READONLY (ref);
1031 TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (ref);
1032 TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (ref);
5ff904cd
JL
1033
1034 return result;
1035}
5ff904cd
JL
1036
1037/* A rip-off of gcc's convert.c convert_to_complex function,
1038 reworked to handle complex implemented as C structures
1039 (RECORD_TYPE with two fields, real and imaginary `r' and `i'). */
1040
5ff904cd
JL
1041static tree
1042ffecom_convert_to_complex_ (tree type, tree expr)
1043{
1044 register enum tree_code form = TREE_CODE (TREE_TYPE (expr));
1045 tree subtype;
1046
1047 assert (TREE_CODE (type) == RECORD_TYPE);
1048
1049 subtype = TREE_TYPE (TYPE_FIELDS (type));
516b69ff 1050
5ff904cd
JL
1051 if (form == REAL_TYPE || form == INTEGER_TYPE || form == ENUMERAL_TYPE)
1052 {
1053 expr = convert (subtype, expr);
1054 return ffecom_2 (COMPLEX_EXPR, type, expr,
1055 convert (subtype, integer_zero_node));
1056 }
1057
1058 if (form == RECORD_TYPE)
1059 {
1060 tree elt_type = TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr)));
1061 if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype))
1062 return expr;
1063 else
1064 {
1065 expr = save_expr (expr);
1066 return ffecom_2 (COMPLEX_EXPR,
1067 type,
1068 convert (subtype,
1069 ffecom_1 (REALPART_EXPR,
1070 TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))),
1071 expr)),
1072 convert (subtype,
1073 ffecom_1 (IMAGPART_EXPR,
1074 TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))),
1075 expr)));
1076 }
1077 }
1078
1079 if (form == POINTER_TYPE || form == REFERENCE_TYPE)
1080 error ("pointer value used where a complex was expected");
1081 else
1082 error ("aggregate value used where a complex was expected");
516b69ff 1083
5ff904cd
JL
1084 return ffecom_2 (COMPLEX_EXPR, type,
1085 convert (subtype, integer_zero_node),
1086 convert (subtype, integer_zero_node));
1087}
5ff904cd
JL
1088
1089/* Like gcc's convert(), but crashes if widening might happen. */
1090
5ff904cd
JL
1091static tree
1092ffecom_convert_narrow_ (type, expr)
1093 tree type, expr;
1094{
1095 register tree e = expr;
1096 register enum tree_code code = TREE_CODE (type);
1097
1098 if (type == TREE_TYPE (e)
1099 || TREE_CODE (e) == ERROR_MARK)
1100 return e;
1101 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
1102 return fold (build1 (NOP_EXPR, type, e));
1103 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
1104 || code == ERROR_MARK)
1105 return error_mark_node;
1106 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
1107 {
1108 assert ("void value not ignored as it ought to be" == NULL);
1109 return error_mark_node;
1110 }
1111 assert (code != VOID_TYPE);
1112 if ((code != RECORD_TYPE)
1113 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
1114 assert ("converting COMPLEX to REAL" == NULL);
1115 assert (code != ENUMERAL_TYPE);
1116 if (code == INTEGER_TYPE)
1117 {
a74de6ea
CB
1118 assert ((TREE_CODE (TREE_TYPE (e)) == INTEGER_TYPE
1119 && TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (e)))
1120 || (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE
1121 && (TYPE_PRECISION (type)
1122 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e))))));
5ff904cd
JL
1123 return fold (convert_to_integer (type, e));
1124 }
1125 if (code == POINTER_TYPE)
1126 {
1127 assert (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE);
1128 return fold (convert_to_pointer (type, e));
1129 }
1130 if (code == REAL_TYPE)
1131 {
1132 assert (TREE_CODE (TREE_TYPE (e)) == REAL_TYPE);
1133 assert (TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (e)));
1134 return fold (convert_to_real (type, e));
1135 }
1136 if (code == COMPLEX_TYPE)
1137 {
1138 assert (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE);
1139 assert (TYPE_PRECISION (TREE_TYPE (type)) <= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e))));
1140 return fold (convert_to_complex (type, e));
1141 }
1142 if (code == RECORD_TYPE)
1143 {
1144 assert (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE);
270fc4e8
CB
1145 /* Check that at least the first field name agrees. */
1146 assert (DECL_NAME (TYPE_FIELDS (type))
1147 == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e))));
5ff904cd
JL
1148 assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1149 <= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))));
270fc4e8
CB
1150 if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1151 == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))))
1152 return e;
5ff904cd
JL
1153 return fold (ffecom_convert_to_complex_ (type, e));
1154 }
1155
1156 assert ("conversion to non-scalar type requested" == NULL);
1157 return error_mark_node;
1158}
5ff904cd
JL
1159
1160/* Like gcc's convert(), but crashes if narrowing might happen. */
1161
5ff904cd
JL
1162static tree
1163ffecom_convert_widen_ (type, expr)
1164 tree type, expr;
1165{
1166 register tree e = expr;
1167 register enum tree_code code = TREE_CODE (type);
1168
1169 if (type == TREE_TYPE (e)
1170 || TREE_CODE (e) == ERROR_MARK)
1171 return e;
1172 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
1173 return fold (build1 (NOP_EXPR, type, e));
1174 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
1175 || code == ERROR_MARK)
1176 return error_mark_node;
1177 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
1178 {
1179 assert ("void value not ignored as it ought to be" == NULL);
1180 return error_mark_node;
1181 }
1182 assert (code != VOID_TYPE);
1183 if ((code != RECORD_TYPE)
1184 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
1185 assert ("narrowing COMPLEX to REAL" == NULL);
1186 assert (code != ENUMERAL_TYPE);
1187 if (code == INTEGER_TYPE)
1188 {
a74de6ea
CB
1189 assert ((TREE_CODE (TREE_TYPE (e)) == INTEGER_TYPE
1190 && TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (e)))
1191 || (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE
1192 && (TYPE_PRECISION (type)
1193 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e))))));
5ff904cd
JL
1194 return fold (convert_to_integer (type, e));
1195 }
1196 if (code == POINTER_TYPE)
1197 {
1198 assert (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE);
1199 return fold (convert_to_pointer (type, e));
1200 }
1201 if (code == REAL_TYPE)
1202 {
1203 assert (TREE_CODE (TREE_TYPE (e)) == REAL_TYPE);
1204 assert (TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (e)));
1205 return fold (convert_to_real (type, e));
1206 }
1207 if (code == COMPLEX_TYPE)
1208 {
1209 assert (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE);
1210 assert (TYPE_PRECISION (TREE_TYPE (type)) >= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e))));
1211 return fold (convert_to_complex (type, e));
1212 }
1213 if (code == RECORD_TYPE)
1214 {
1215 assert (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE);
270fc4e8
CB
1216 /* Check that at least the first field name agrees. */
1217 assert (DECL_NAME (TYPE_FIELDS (type))
1218 == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e))));
5ff904cd
JL
1219 assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1220 >= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))));
270fc4e8
CB
1221 if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1222 == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))))
1223 return e;
5ff904cd
JL
1224 return fold (ffecom_convert_to_complex_ (type, e));
1225 }
1226
1227 assert ("conversion to non-scalar type requested" == NULL);
1228 return error_mark_node;
1229}
5ff904cd
JL
1230
1231/* Handles making a COMPLEX type, either the standard
1232 (but buggy?) gbe way, or the safer (but less elegant?)
1233 f2c way. */
1234
5ff904cd
JL
1235static tree
1236ffecom_make_complex_type_ (tree subtype)
1237{
1238 tree type;
1239 tree realfield;
1240 tree imagfield;
1241
1242 if (ffe_is_emulate_complex ())
1243 {
1244 type = make_node (RECORD_TYPE);
1245 realfield = ffecom_decl_field (type, NULL_TREE, "r", subtype);
1246 imagfield = ffecom_decl_field (type, realfield, "i", subtype);
1247 TYPE_FIELDS (type) = realfield;
1248 layout_type (type);
1249 }
1250 else
1251 {
1252 type = make_node (COMPLEX_TYPE);
1253 TREE_TYPE (type) = subtype;
1254 layout_type (type);
1255 }
1256
1257 return type;
1258}
5ff904cd
JL
1259
1260/* Chooses either the gbe or the f2c way to build a
1261 complex constant. */
1262
5ff904cd
JL
1263static tree
1264ffecom_build_complex_constant_ (tree type, tree realpart, tree imagpart)
1265{
1266 tree bothparts;
1267
1268 if (ffe_is_emulate_complex ())
1269 {
1270 bothparts = build_tree_list (TYPE_FIELDS (type), realpart);
1271 TREE_CHAIN (bothparts) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), imagpart);
1272 bothparts = build (CONSTRUCTOR, type, NULL_TREE, bothparts);
1273 }
1274 else
1275 {
1276 bothparts = build_complex (type, realpart, imagpart);
1277 }
1278
1279 return bothparts;
1280}
5ff904cd 1281
5ff904cd 1282static tree
26f096f9 1283ffecom_arglist_expr_ (const char *c, ffebld expr)
5ff904cd
JL
1284{
1285 tree list;
1286 tree *plist = &list;
1287 tree trail = NULL_TREE; /* Append char length args here. */
1288 tree *ptrail = &trail;
1289 tree length;
1290 ffebld exprh;
1291 tree item;
1292 bool ptr = FALSE;
1293 tree wanted = NULL_TREE;
5e65297b 1294 static const char zed[] = "0";
e2fa159e
JL
1295
1296 if (c == NULL)
1297 c = &zed[0];
5ff904cd
JL
1298
1299 while (expr != NULL)
1300 {
1301 if (*c != '\0')
1302 {
1303 ptr = FALSE;
1304 if (*c == '&')
1305 {
1306 ptr = TRUE;
1307 ++c;
1308 }
1309 switch (*(c++))
1310 {
1311 case '\0':
1312 ptr = TRUE;
1313 wanted = NULL_TREE;
1314 break;
1315
1316 case 'a':
1317 assert (ptr);
1318 wanted = NULL_TREE;
1319 break;
1320
1321 case 'c':
1322 wanted = ffecom_f2c_complex_type_node;
1323 break;
1324
1325 case 'd':
1326 wanted = ffecom_f2c_doublereal_type_node;
1327 break;
1328
1329 case 'e':
1330 wanted = ffecom_f2c_doublecomplex_type_node;
1331 break;
1332
1333 case 'f':
1334 wanted = ffecom_f2c_real_type_node;
1335 break;
1336
1337 case 'i':
1338 wanted = ffecom_f2c_integer_type_node;
1339 break;
1340
1341 case 'j':
1342 wanted = ffecom_f2c_longint_type_node;
1343 break;
1344
1345 default:
1346 assert ("bad argstring code" == NULL);
1347 wanted = NULL_TREE;
1348 break;
1349 }
1350 }
1351
1352 exprh = ffebld_head (expr);
1353 if (exprh == NULL)
1354 wanted = NULL_TREE;
1355
1356 if ((wanted == NULL_TREE)
1357 || (ptr
1358 && (TYPE_MODE
1359 (ffecom_tree_type[ffeinfo_basictype (ffebld_info (exprh))]
1360 [ffeinfo_kindtype (ffebld_info (exprh))])
1361 == TYPE_MODE (wanted))))
1362 *plist
1363 = build_tree_list (NULL_TREE,
1364 ffecom_arg_ptr_to_expr (exprh,
1365 &length));
1366 else
1367 {
1368 item = ffecom_arg_expr (exprh, &length);
1369 item = ffecom_convert_widen_ (wanted, item);
1370 if (ptr)
1371 {
1372 item = ffecom_1 (ADDR_EXPR,
1373 build_pointer_type (TREE_TYPE (item)),
1374 item);
1375 }
1376 *plist
1377 = build_tree_list (NULL_TREE,
1378 item);
1379 }
1380
1381 plist = &TREE_CHAIN (*plist);
1382 expr = ffebld_trail (expr);
1383 if (length != NULL_TREE)
1384 {
1385 *ptrail = build_tree_list (NULL_TREE, length);
1386 ptrail = &TREE_CHAIN (*ptrail);
1387 }
1388 }
1389
e2fa159e
JL
1390 /* We've run out of args in the call; if the implementation expects
1391 more, supply null pointers for them, which the implementation can
1392 check to see if an arg was omitted. */
1393
1394 while (*c != '\0' && *c != '0')
1395 {
1396 if (*c == '&')
1397 ++c;
1398 else
1399 assert ("missing arg to run-time routine!" == NULL);
1400
1401 switch (*(c++))
1402 {
1403 case '\0':
1404 case 'a':
1405 case 'c':
1406 case 'd':
1407 case 'e':
1408 case 'f':
1409 case 'i':
1410 case 'j':
1411 break;
1412
1413 default:
1414 assert ("bad arg string code" == NULL);
1415 break;
1416 }
1417 *plist
1418 = build_tree_list (NULL_TREE,
1419 null_pointer_node);
1420 plist = &TREE_CHAIN (*plist);
1421 }
1422
5ff904cd
JL
1423 *plist = trail;
1424
1425 return list;
1426}
5ff904cd 1427
5ff904cd
JL
1428static tree
1429ffecom_widest_expr_type_ (ffebld list)
1430{
1431 ffebld item;
1432 ffebld widest = NULL;
1433 ffetype type;
1434 ffetype widest_type = NULL;
1435 tree t;
1436
1437 for (; list != NULL; list = ffebld_trail (list))
1438 {
1439 item = ffebld_head (list);
1440 if (item == NULL)
1441 continue;
1442 if ((widest != NULL)
1443 && (ffeinfo_basictype (ffebld_info (item))
1444 != ffeinfo_basictype (ffebld_info (widest))))
1445 continue;
1446 type = ffeinfo_type (ffeinfo_basictype (ffebld_info (item)),
1447 ffeinfo_kindtype (ffebld_info (item)));
1448 if ((widest == FFEINFO_kindtypeNONE)
1449 || (ffetype_size (type)
1450 > ffetype_size (widest_type)))
1451 {
1452 widest = item;
1453 widest_type = type;
1454 }
1455 }
1456
1457 assert (widest != NULL);
1458 t = ffecom_tree_type[ffeinfo_basictype (ffebld_info (widest))]
1459 [ffeinfo_kindtype (ffebld_info (widest))];
1460 assert (t != NULL_TREE);
1461 return t;
1462}
5ff904cd 1463
d6cd84e0
CB
1464/* Check whether a partial overlap between two expressions is possible.
1465
1466 Can *starting* to write a portion of expr1 change the value
1467 computed (perhaps already, *partially*) by expr2?
1468
1469 Currently, this is a concern only for a COMPLEX expr1. But if it
1470 isn't in COMMON or local EQUIVALENCE, since we don't support
1471 aliasing of arguments, it isn't a concern. */
1472
1473static bool
b0791fa9 1474ffecom_possible_partial_overlap_ (ffebld expr1, ffebld expr2 ATTRIBUTE_UNUSED)
d6cd84e0
CB
1475{
1476 ffesymbol sym;
1477 ffestorag st;
1478
1479 switch (ffebld_op (expr1))
1480 {
1481 case FFEBLD_opSYMTER:
1482 sym = ffebld_symter (expr1);
1483 break;
1484
1485 case FFEBLD_opARRAYREF:
1486 if (ffebld_op (ffebld_left (expr1)) != FFEBLD_opSYMTER)
1487 return FALSE;
1488 sym = ffebld_symter (ffebld_left (expr1));
1489 break;
1490
1491 default:
1492 return FALSE;
1493 }
1494
1495 if (ffesymbol_where (sym) != FFEINFO_whereCOMMON
1496 && (ffesymbol_where (sym) != FFEINFO_whereLOCAL
1497 || ! (st = ffesymbol_storage (sym))
1498 || ! ffestorag_parent (st)))
1499 return FALSE;
1500
1501 /* It's in COMMON or local EQUIVALENCE. */
1502
1503 return TRUE;
1504}
1505
5ff904cd
JL
1506/* Check whether dest and source might overlap. ffebld versions of these
1507 might or might not be passed, will be NULL if not.
1508
1509 The test is really whether source_tree is modifiable and, if modified,
1510 might overlap destination such that the value(s) in the destination might
1511 change before it is finally modified. dest_* are the canonized
1512 destination itself. */
1513
5ff904cd
JL
1514static bool
1515ffecom_overlap_ (tree dest_decl, tree dest_offset, tree dest_size,
1516 tree source_tree, ffebld source UNUSED,
1517 bool scalar_arg)
1518{
1519 tree source_decl;
1520 tree source_offset;
1521 tree source_size;
1522 tree t;
1523
1524 if (source_tree == NULL_TREE)
1525 return FALSE;
1526
1527 switch (TREE_CODE (source_tree))
1528 {
1529 case ERROR_MARK:
1530 case IDENTIFIER_NODE:
1531 case INTEGER_CST:
1532 case REAL_CST:
1533 case COMPLEX_CST:
1534 case STRING_CST:
1535 case CONST_DECL:
1536 case VAR_DECL:
1537 case RESULT_DECL:
1538 case FIELD_DECL:
1539 case MINUS_EXPR:
1540 case MULT_EXPR:
1541 case TRUNC_DIV_EXPR:
1542 case CEIL_DIV_EXPR:
1543 case FLOOR_DIV_EXPR:
1544 case ROUND_DIV_EXPR:
1545 case TRUNC_MOD_EXPR:
1546 case CEIL_MOD_EXPR:
1547 case FLOOR_MOD_EXPR:
1548 case ROUND_MOD_EXPR:
1549 case RDIV_EXPR:
1550 case EXACT_DIV_EXPR:
1551 case FIX_TRUNC_EXPR:
1552 case FIX_CEIL_EXPR:
1553 case FIX_FLOOR_EXPR:
1554 case FIX_ROUND_EXPR:
1555 case FLOAT_EXPR:
5ff904cd
JL
1556 case NEGATE_EXPR:
1557 case MIN_EXPR:
1558 case MAX_EXPR:
1559 case ABS_EXPR:
1560 case FFS_EXPR:
1561 case LSHIFT_EXPR:
1562 case RSHIFT_EXPR:
1563 case LROTATE_EXPR:
1564 case RROTATE_EXPR:
1565 case BIT_IOR_EXPR:
1566 case BIT_XOR_EXPR:
1567 case BIT_AND_EXPR:
1568 case BIT_ANDTC_EXPR:
1569 case BIT_NOT_EXPR:
1570 case TRUTH_ANDIF_EXPR:
1571 case TRUTH_ORIF_EXPR:
1572 case TRUTH_AND_EXPR:
1573 case TRUTH_OR_EXPR:
1574 case TRUTH_XOR_EXPR:
1575 case TRUTH_NOT_EXPR:
1576 case LT_EXPR:
1577 case LE_EXPR:
1578 case GT_EXPR:
1579 case GE_EXPR:
1580 case EQ_EXPR:
1581 case NE_EXPR:
1582 case COMPLEX_EXPR:
1583 case CONJ_EXPR:
1584 case REALPART_EXPR:
1585 case IMAGPART_EXPR:
1586 case LABEL_EXPR:
1587 case COMPONENT_REF:
1588 return FALSE;
1589
1590 case COMPOUND_EXPR:
1591 return ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1592 TREE_OPERAND (source_tree, 1), NULL,
1593 scalar_arg);
1594
1595 case MODIFY_EXPR:
1596 return ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1597 TREE_OPERAND (source_tree, 0), NULL,
1598 scalar_arg);
1599
1600 case CONVERT_EXPR:
1601 case NOP_EXPR:
1602 case NON_LVALUE_EXPR:
1603 case PLUS_EXPR:
1604 if (TREE_CODE (TREE_TYPE (source_tree)) != POINTER_TYPE)
1605 return TRUE;
1606
1607 ffecom_tree_canonize_ptr_ (&source_decl, &source_offset,
1608 source_tree);
1609 source_size = TYPE_SIZE (TREE_TYPE (TREE_TYPE (source_tree)));
1610 break;
1611
1612 case COND_EXPR:
1613 return
1614 ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1615 TREE_OPERAND (source_tree, 1), NULL,
1616 scalar_arg)
1617 || ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1618 TREE_OPERAND (source_tree, 2), NULL,
1619 scalar_arg);
1620
1621
1622 case ADDR_EXPR:
1623 ffecom_tree_canonize_ref_ (&source_decl, &source_offset,
1624 &source_size,
1625 TREE_OPERAND (source_tree, 0));
1626 break;
1627
1628 case PARM_DECL:
1629 if (TREE_CODE (TREE_TYPE (source_tree)) != POINTER_TYPE)
1630 return TRUE;
1631
1632 source_decl = source_tree;
76fa6b3b 1633 source_offset = bitsize_zero_node;
5ff904cd
JL
1634 source_size = TYPE_SIZE (TREE_TYPE (TREE_TYPE (source_tree)));
1635 break;
1636
1637 case SAVE_EXPR:
1638 case REFERENCE_EXPR:
1639 case PREDECREMENT_EXPR:
1640 case PREINCREMENT_EXPR:
1641 case POSTDECREMENT_EXPR:
1642 case POSTINCREMENT_EXPR:
1643 case INDIRECT_REF:
1644 case ARRAY_REF:
1645 case CALL_EXPR:
1646 default:
1647 return TRUE;
1648 }
1649
1650 /* Come here when source_decl, source_offset, and source_size filled
1651 in appropriately. */
1652
1653 if (source_decl == NULL_TREE)
1654 return FALSE; /* No decl involved, so no overlap. */
1655
1656 if (source_decl != dest_decl)
1657 return FALSE; /* Different decl, no overlap. */
1658
1659 if (TREE_CODE (dest_size) == ERROR_MARK)
1660 return TRUE; /* Assignment into entire assumed-size
1661 array? Shouldn't happen.... */
1662
1663 t = ffecom_2 (LE_EXPR, integer_type_node,
1664 ffecom_2 (PLUS_EXPR, TREE_TYPE (dest_offset),
1665 dest_offset,
1666 convert (TREE_TYPE (dest_offset),
1667 dest_size)),
1668 convert (TREE_TYPE (dest_offset),
1669 source_offset));
1670
1671 if (integer_onep (t))
1672 return FALSE; /* Destination precedes source. */
1673
1674 if (!scalar_arg
1675 || (source_size == NULL_TREE)
1676 || (TREE_CODE (source_size) == ERROR_MARK)
1677 || integer_zerop (source_size))
1678 return TRUE; /* No way to tell if dest follows source. */
1679
1680 t = ffecom_2 (LE_EXPR, integer_type_node,
1681 ffecom_2 (PLUS_EXPR, TREE_TYPE (source_offset),
1682 source_offset,
1683 convert (TREE_TYPE (source_offset),
1684 source_size)),
1685 convert (TREE_TYPE (source_offset),
1686 dest_offset));
1687
1688 if (integer_onep (t))
1689 return FALSE; /* Destination follows source. */
1690
1691 return TRUE; /* Destination and source overlap. */
1692}
5ff904cd
JL
1693
1694/* Check whether dest might overlap any of a list of arguments or is
1695 in a COMMON area the callee might know about (and thus modify). */
1696
5ff904cd
JL
1697static bool
1698ffecom_args_overlapping_ (tree dest_tree, ffebld dest UNUSED,
1699 tree args, tree callee_commons,
1700 bool scalar_args)
1701{
1702 tree arg;
1703 tree dest_decl;
1704 tree dest_offset;
1705 tree dest_size;
1706
1707 ffecom_tree_canonize_ref_ (&dest_decl, &dest_offset, &dest_size,
1708 dest_tree);
1709
1710 if (dest_decl == NULL_TREE)
1711 return FALSE; /* Seems unlikely! */
1712
1713 /* If the decl cannot be determined reliably, or if its in COMMON
1714 and the callee isn't known to not futz with COMMON via other
1715 means, overlap might happen. */
1716
1717 if ((TREE_CODE (dest_decl) == ERROR_MARK)
1718 || ((callee_commons != NULL_TREE)
1719 && TREE_PUBLIC (dest_decl)))
1720 return TRUE;
1721
1722 for (; args != NULL_TREE; args = TREE_CHAIN (args))
1723 {
1724 if (((arg = TREE_VALUE (args)) != NULL_TREE)
1725 && ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1726 arg, NULL, scalar_args))
1727 return TRUE;
1728 }
1729
1730 return FALSE;
1731}
5ff904cd
JL
1732
1733/* Build a string for a variable name as used by NAMELIST. This means that
1734 if we're using the f2c library, we build an uppercase string, since
1735 f2c does this. */
1736
5ff904cd 1737static tree
26f096f9 1738ffecom_build_f2c_string_ (int i, const char *s)
5ff904cd
JL
1739{
1740 if (!ffe_is_f2c_library ())
1741 return build_string (i, s);
1742
1743 {
1744 char *tmp;
26f096f9 1745 const char *p;
5ff904cd
JL
1746 char *q;
1747 char space[34];
1748 tree t;
1749
1750 if (((size_t) i) > ARRAY_SIZE (space))
1751 tmp = malloc_new_ks (malloc_pool_image (), "f2c_string", i);
1752 else
1753 tmp = &space[0];
1754
1755 for (p = s, q = tmp; *p != '\0'; ++p, ++q)
f6bbde28 1756 *q = TOUPPER (*p);
5ff904cd
JL
1757 *q = '\0';
1758
1759 t = build_string (i, tmp);
1760
1761 if (((size_t) i) > ARRAY_SIZE (space))
1762 malloc_kill_ks (malloc_pool_image (), tmp, i);
1763
1764 return t;
1765 }
1766}
1767
5ff904cd
JL
1768/* Returns CALL_EXPR or equivalent with given type (pass NULL_TREE for
1769 type to just get whatever the function returns), handling the
1770 f2c value-returning convention, if required, by prepending
1771 to the arglist a pointer to a temporary to receive the return value. */
1772
5ff904cd
JL
1773static tree
1774ffecom_call_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex,
1775 tree type, tree args, tree dest_tree,
1776 ffebld dest, bool *dest_used, tree callee_commons,
c7e4ee3a 1777 bool scalar_args, tree hook)
5ff904cd
JL
1778{
1779 tree item;
1780 tree tempvar;
1781
1782 if (dest_used != NULL)
1783 *dest_used = FALSE;
1784
1785 if (is_f2c_complex)
1786 {
1787 if ((dest_used == NULL)
1788 || (dest == NULL)
1789 || (ffeinfo_basictype (ffebld_info (dest))
1790 != FFEINFO_basictypeCOMPLEX)
1791 || (ffeinfo_kindtype (ffebld_info (dest)) != kt)
1792 || ((type != NULL_TREE) && (TREE_TYPE (dest_tree) != type))
1793 || ffecom_args_overlapping_ (dest_tree, dest, args,
1794 callee_commons,
1795 scalar_args))
1796 {
c7e4ee3a
CB
1797#ifdef HOHO
1798 tempvar = ffecom_make_tempvar (ffecom_tree_type
5ff904cd
JL
1799 [FFEINFO_basictypeCOMPLEX][kt],
1800 FFETARGET_charactersizeNONE,
c7e4ee3a
CB
1801 -1);
1802#else
1803 tempvar = hook;
1804 assert (tempvar);
1805#endif
5ff904cd
JL
1806 }
1807 else
1808 {
1809 *dest_used = TRUE;
1810 tempvar = dest_tree;
1811 type = NULL_TREE;
1812 }
1813
1814 item
1815 = build_tree_list (NULL_TREE,
1816 ffecom_1 (ADDR_EXPR,
c7e4ee3a 1817 build_pointer_type (TREE_TYPE (tempvar)),
5ff904cd
JL
1818 tempvar));
1819 TREE_CHAIN (item) = args;
1820
1821 item = ffecom_3s (CALL_EXPR, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), fn,
1822 item, NULL_TREE);
1823
1824 if (tempvar != dest_tree)
1825 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), item, tempvar);
1826 }
1827 else
1828 item = ffecom_3s (CALL_EXPR, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), fn,
1829 args, NULL_TREE);
1830
1831 if ((type != NULL_TREE) && (TREE_TYPE (item) != type))
1832 item = ffecom_convert_narrow_ (type, item);
1833
1834 return item;
1835}
5ff904cd
JL
1836
1837/* Given two arguments, transform them and make a call to the given
1838 function via ffecom_call_. */
1839
5ff904cd
JL
1840static tree
1841ffecom_call_binop_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex,
1842 tree type, ffebld left, ffebld right,
1843 tree dest_tree, ffebld dest, bool *dest_used,
95eb4fd9 1844 tree callee_commons, bool scalar_args, bool ref, tree hook)
5ff904cd
JL
1845{
1846 tree left_tree;
1847 tree right_tree;
1848 tree left_length;
1849 tree right_length;
1850
95eb4fd9
TM
1851 if (ref)
1852 {
1853 /* Pass arguments by reference. */
1854 left_tree = ffecom_arg_ptr_to_expr (left, &left_length);
1855 right_tree = ffecom_arg_ptr_to_expr (right, &right_length);
1856 }
1857 else
1858 {
1859 /* Pass arguments by value. */
1860 left_tree = ffecom_arg_expr (left, &left_length);
1861 right_tree = ffecom_arg_expr (right, &right_length);
1862 }
1863
5ff904cd
JL
1864
1865 left_tree = build_tree_list (NULL_TREE, left_tree);
1866 right_tree = build_tree_list (NULL_TREE, right_tree);
1867 TREE_CHAIN (left_tree) = right_tree;
1868
1869 if (left_length != NULL_TREE)
1870 {
1871 left_length = build_tree_list (NULL_TREE, left_length);
1872 TREE_CHAIN (right_tree) = left_length;
1873 }
1874
1875 if (right_length != NULL_TREE)
1876 {
1877 right_length = build_tree_list (NULL_TREE, right_length);
1878 if (left_length != NULL_TREE)
1879 TREE_CHAIN (left_length) = right_length;
1880 else
1881 TREE_CHAIN (right_tree) = right_length;
1882 }
1883
1884 return ffecom_call_ (fn, kt, is_f2c_complex, type, left_tree,
1885 dest_tree, dest, dest_used, callee_commons,
c7e4ee3a 1886 scalar_args, hook);
5ff904cd 1887}
5ff904cd 1888
c7e4ee3a 1889/* Return ptr/length args for char subexpression
5ff904cd
JL
1890
1891 Handles CHARACTER-type CONTER, SYMTER, SUBSTR, ARRAYREF, and FUNCREF
1892 subexpressions by constructing the appropriate trees for the ptr-to-
1893 character-text and length-of-character-text arguments in a calling
86fc7a6c
CB
1894 sequence.
1895
1896 Note that if with_null is TRUE, and the expression is an opCONTER,
1897 a null byte is appended to the string. */
5ff904cd 1898
5ff904cd 1899static void
86fc7a6c 1900ffecom_char_args_x_ (tree *xitem, tree *length, ffebld expr, bool with_null)
5ff904cd
JL
1901{
1902 tree item;
1903 tree high;
1904 ffetargetCharacter1 val;
86fc7a6c 1905 ffetargetCharacterSize newlen;
5ff904cd
JL
1906
1907 switch (ffebld_op (expr))
1908 {
1909 case FFEBLD_opCONTER:
1910 val = ffebld_constant_character1 (ffebld_conter (expr));
86fc7a6c
CB
1911 newlen = ffetarget_length_character1 (val);
1912 if (with_null)
1913 {
c7e4ee3a 1914 /* Begin FFETARGET-NULL-KLUDGE. */
86fc7a6c 1915 if (newlen != 0)
c7e4ee3a 1916 ++newlen;
86fc7a6c
CB
1917 }
1918 *length = build_int_2 (newlen, 0);
5ff904cd 1919 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
86fc7a6c 1920 high = build_int_2 (newlen, 0);
5ff904cd 1921 TREE_TYPE (high) = ffecom_f2c_ftnlen_type_node;
c7e4ee3a 1922 item = build_string (newlen,
5ff904cd 1923 ffetarget_text_character1 (val));
c7e4ee3a 1924 /* End FFETARGET-NULL-KLUDGE. */
5ff904cd
JL
1925 TREE_TYPE (item)
1926 = build_type_variant
1927 (build_array_type
1928 (char_type_node,
1929 build_range_type
1930 (ffecom_f2c_ftnlen_type_node,
1931 ffecom_f2c_ftnlen_one_node,
1932 high)),
1933 1, 0);
1934 TREE_CONSTANT (item) = 1;
1935 TREE_STATIC (item) = 1;
1936 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
1937 item);
1938 break;
1939
1940 case FFEBLD_opSYMTER:
1941 {
1942 ffesymbol s = ffebld_symter (expr);
1943
1944 item = ffesymbol_hook (s).decl_tree;
1945 if (item == NULL_TREE)
1946 {
1947 s = ffecom_sym_transform_ (s);
1948 item = ffesymbol_hook (s).decl_tree;
1949 }
1950 if (ffesymbol_kind (s) == FFEINFO_kindENTITY)
1951 {
1952 if (ffesymbol_size (s) == FFETARGET_charactersizeNONE)
1953 *length = ffesymbol_hook (s).length_tree;
1954 else
1955 {
1956 *length = build_int_2 (ffesymbol_size (s), 0);
1957 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
1958 }
1959 }
1960 else if (item == error_mark_node)
1961 *length = error_mark_node;
c7e4ee3a
CB
1962 else
1963 /* FFEINFO_kindFUNCTION. */
5ff904cd
JL
1964 *length = NULL_TREE;
1965 if (!ffesymbol_hook (s).addr
1966 && (item != error_mark_node))
1967 item = ffecom_1 (ADDR_EXPR,
1968 build_pointer_type (TREE_TYPE (item)),
1969 item);
1970 }
1971 break;
1972
1973 case FFEBLD_opARRAYREF:
1974 {
5ff904cd 1975 ffecom_char_args_ (&item, length, ffebld_left (expr));
5ff904cd
JL
1976
1977 if (item == error_mark_node || *length == error_mark_node)
1978 {
1979 item = *length = error_mark_node;
1980 break;
1981 }
1982
6b55276e 1983 item = ffecom_arrayref_ (item, expr, 1);
5ff904cd
JL
1984 }
1985 break;
1986
1987 case FFEBLD_opSUBSTR:
1988 {
1989 ffebld start;
1990 ffebld end;
1991 ffebld thing = ffebld_right (expr);
1992 tree start_tree;
1993 tree end_tree;
3b304f5b 1994 const char *char_name;
6b55276e
CB
1995 ffebld left_symter;
1996 tree array;
5ff904cd
JL
1997
1998 assert (ffebld_op (thing) == FFEBLD_opITEM);
1999 start = ffebld_head (thing);
2000 thing = ffebld_trail (thing);
2001 assert (ffebld_trail (thing) == NULL);
2002 end = ffebld_head (thing);
2003
6b55276e
CB
2004 /* Determine name for pretty-printing range-check errors. */
2005 for (left_symter = ffebld_left (expr);
2006 left_symter && ffebld_op (left_symter) == FFEBLD_opARRAYREF;
2007 left_symter = ffebld_left (left_symter))
2008 ;
2009 if (ffebld_op (left_symter) == FFEBLD_opSYMTER)
2010 char_name = ffesymbol_text (ffebld_symter (left_symter));
2011 else
2012 char_name = "[expr?]";
2013
5ff904cd 2014 ffecom_char_args_ (&item, length, ffebld_left (expr));
5ff904cd
JL
2015
2016 if (item == error_mark_node || *length == error_mark_node)
2017 {
2018 item = *length = error_mark_node;
2019 break;
2020 }
2021
6b55276e
CB
2022 array = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item)));
2023
ff852b44
CB
2024 /* ~~~~Handle INTEGER*8 start/end, a la FFEBLD_opARRAYREF. */
2025
5ff904cd
JL
2026 if (start == NULL)
2027 {
2028 if (end == NULL)
2029 ;
2030 else
2031 {
6b55276e 2032 end_tree = ffecom_expr (end);
02f06e64 2033 if (flag_bounds_check)
6b55276e
CB
2034 end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0,
2035 char_name);
5ff904cd 2036 end_tree = convert (ffecom_f2c_ftnlen_type_node,
6b55276e 2037 end_tree);
5ff904cd
JL
2038
2039 if (end_tree == error_mark_node)
2040 {
2041 item = *length = error_mark_node;
2042 break;
2043 }
2044
2045 *length = end_tree;
2046 }
2047 }
2048 else
2049 {
6b55276e 2050 start_tree = ffecom_expr (start);
02f06e64 2051 if (flag_bounds_check)
6b55276e
CB
2052 start_tree = ffecom_subscript_check_ (array, start_tree, 0, 0,
2053 char_name);
5ff904cd 2054 start_tree = convert (ffecom_f2c_ftnlen_type_node,
6b55276e 2055 start_tree);
5ff904cd
JL
2056
2057 if (start_tree == error_mark_node)
2058 {
2059 item = *length = error_mark_node;
2060 break;
2061 }
2062
2063 start_tree = ffecom_save_tree (start_tree);
2064
2065 item = ffecom_2 (PLUS_EXPR, TREE_TYPE (item),
2066 item,
2067 ffecom_2 (MINUS_EXPR,
2068 TREE_TYPE (start_tree),
2069 start_tree,
2070 ffecom_f2c_ftnlen_one_node));
2071
2072 if (end == NULL)
2073 {
2074 *length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
2075 ffecom_f2c_ftnlen_one_node,
2076 ffecom_2 (MINUS_EXPR,
2077 ffecom_f2c_ftnlen_type_node,
2078 *length,
2079 start_tree));
2080 }
2081 else
2082 {
6b55276e 2083 end_tree = ffecom_expr (end);
02f06e64 2084 if (flag_bounds_check)
6b55276e
CB
2085 end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0,
2086 char_name);
5ff904cd 2087 end_tree = convert (ffecom_f2c_ftnlen_type_node,
6b55276e 2088 end_tree);
5ff904cd
JL
2089
2090 if (end_tree == error_mark_node)
2091 {
2092 item = *length = error_mark_node;
2093 break;
2094 }
2095
2096 *length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
2097 ffecom_f2c_ftnlen_one_node,
2098 ffecom_2 (MINUS_EXPR,
2099 ffecom_f2c_ftnlen_type_node,
2100 end_tree, start_tree));
2101 }
2102 }
2103 }
2104 break;
2105
2106 case FFEBLD_opFUNCREF:
2107 {
2108 ffesymbol s = ffebld_symter (ffebld_left (expr));
2109 tree tempvar;
2110 tree args;
2111 ffetargetCharacterSize size = ffeinfo_size (ffebld_info (expr));
2112 ffecomGfrt ix;
2113
2114 if (size == FFETARGET_charactersizeNONE)
c7e4ee3a
CB
2115 /* ~~Kludge alert! This should someday be fixed. */
2116 size = 24;
5ff904cd
JL
2117
2118 *length = build_int_2 (size, 0);
2119 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
2120
2121 if (ffeinfo_where (ffebld_info (ffebld_left (expr)))
2122 == FFEINFO_whereINTRINSIC)
2123 {
2124 if (size == 1)
c7e4ee3a
CB
2125 {
2126 /* Invocation of an intrinsic returning CHARACTER*1. */
5ff904cd
JL
2127 item = ffecom_expr_intrinsic_ (expr, NULL_TREE,
2128 NULL, NULL);
2129 break;
2130 }
2131 ix = ffeintrin_gfrt_direct (ffebld_symter_implementation (ffebld_left (expr)));
2132 assert (ix != FFECOM_gfrt);
2133 item = ffecom_gfrt_tree_ (ix);
2134 }
2135 else
2136 {
2137 ix = FFECOM_gfrt;
2138 item = ffesymbol_hook (s).decl_tree;
2139 if (item == NULL_TREE)
2140 {
2141 s = ffecom_sym_transform_ (s);
2142 item = ffesymbol_hook (s).decl_tree;
2143 }
2144 if (item == error_mark_node)
2145 {
2146 item = *length = error_mark_node;
2147 break;
2148 }
2149
2150 if (!ffesymbol_hook (s).addr)
2151 item = ffecom_1_fn (item);
2152 }
2153
c7e4ee3a 2154#ifdef HOHO
5ff904cd 2155 tempvar = ffecom_push_tempvar (char_type_node, size, -1, TRUE);
c7e4ee3a
CB
2156#else
2157 tempvar = ffebld_nonter_hook (expr);
2158 assert (tempvar);
2159#endif
5ff904cd
JL
2160 tempvar = ffecom_1 (ADDR_EXPR,
2161 build_pointer_type (TREE_TYPE (tempvar)),
2162 tempvar);
2163
5ff904cd
JL
2164 args = build_tree_list (NULL_TREE, tempvar);
2165
2166 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT) /* Sfunc args by value. */
2167 TREE_CHAIN (args) = ffecom_list_expr (ffebld_right (expr));
2168 else
2169 {
2170 TREE_CHAIN (args) = build_tree_list (NULL_TREE, *length);
2171 if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC)
2172 {
2173 TREE_CHAIN (TREE_CHAIN (args))
2174 = ffecom_arglist_expr_ (ffecom_gfrt_args_ (ix),
2175 ffebld_right (expr));
2176 }
2177 else
2178 {
2179 TREE_CHAIN (TREE_CHAIN (args))
2180 = ffecom_list_ptr_to_expr (ffebld_right (expr));
2181 }
2182 }
2183
2184 item = ffecom_3s (CALL_EXPR,
2185 TREE_TYPE (TREE_TYPE (TREE_TYPE (item))),
2186 item, args, NULL_TREE);
2187 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), item,
2188 tempvar);
5ff904cd
JL
2189 }
2190 break;
2191
2192 case FFEBLD_opCONVERT:
2193
5ff904cd 2194 ffecom_char_args_ (&item, length, ffebld_left (expr));
5ff904cd
JL
2195
2196 if (item == error_mark_node || *length == error_mark_node)
2197 {
2198 item = *length = error_mark_node;
2199 break;
2200 }
2201
2202 if ((ffebld_size_known (ffebld_left (expr))
2203 == FFETARGET_charactersizeNONE)
2204 || (ffebld_size_known (ffebld_left (expr)) < (ffebld_size (expr))))
2205 { /* Possible blank-padding needed, copy into
2206 temporary. */
2207 tree tempvar;
2208 tree args;
2209 tree newlen;
2210
c7e4ee3a
CB
2211#ifdef HOHO
2212 tempvar = ffecom_make_tempvar (char_type_node,
2213 ffebld_size (expr), -1);
2214#else
2215 tempvar = ffebld_nonter_hook (expr);
2216 assert (tempvar);
2217#endif
5ff904cd
JL
2218 tempvar = ffecom_1 (ADDR_EXPR,
2219 build_pointer_type (TREE_TYPE (tempvar)),
2220 tempvar);
2221
2222 newlen = build_int_2 (ffebld_size (expr), 0);
2223 TREE_TYPE (newlen) = ffecom_f2c_ftnlen_type_node;
2224
2225 args = build_tree_list (NULL_TREE, tempvar);
2226 TREE_CHAIN (args) = build_tree_list (NULL_TREE, item);
2227 TREE_CHAIN (TREE_CHAIN (args)) = build_tree_list (NULL_TREE, newlen);
2228 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (args)))
2229 = build_tree_list (NULL_TREE, *length);
2230
c7e4ee3a 2231 item = ffecom_call_gfrt (FFECOM_gfrtCOPY, args, NULL_TREE);
5ff904cd
JL
2232 TREE_SIDE_EFFECTS (item) = 1;
2233 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), fold (item),
2234 tempvar);
2235 *length = newlen;
2236 }
2237 else
2238 { /* Just truncate the length. */
2239 *length = build_int_2 (ffebld_size (expr), 0);
2240 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
2241 }
2242 break;
2243
2244 default:
2245 assert ("bad op for single char arg expr" == NULL);
2246 item = NULL_TREE;
2247 break;
2248 }
2249
2250 *xitem = item;
2251}
5ff904cd
JL
2252
2253/* Check the size of the type to be sure it doesn't overflow the
2254 "portable" capacities of the compiler back end. `dummy' types
2255 can generally overflow the normal sizes as long as the computations
2256 themselves don't overflow. A particular target of the back end
2257 must still enforce its size requirements, though, and the back
2258 end takes care of this in stor-layout.c. */
2259
5ff904cd
JL
2260static tree
2261ffecom_check_size_overflow_ (ffesymbol s, tree type, bool dummy)
2262{
2263 if (TREE_CODE (type) == ERROR_MARK)
2264 return type;
2265
2266 if (TYPE_SIZE (type) == NULL_TREE)
2267 return type;
2268
2269 if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
2270 return type;
2271
7b119cc6
TM
2272 /* An array is too large if size is negative or the type_size overflows
2273 or its "upper half" is larger than 3 (which would make the signed
2274 byte size and offset computations overflow). */
2275
5ff904cd 2276 if ((tree_int_cst_sgn (TYPE_SIZE (type)) < 0)
7b119cc6
TM
2277 || (!dummy && (TREE_INT_CST_HIGH (TYPE_SIZE (type)) > 3
2278 || TREE_OVERFLOW (TYPE_SIZE (type)))))
5ff904cd
JL
2279 {
2280 ffebad_start (FFEBAD_ARRAY_LARGE);
2281 ffebad_string (ffesymbol_text (s));
2282 ffebad_here (0, ffesymbol_where_line (s), ffesymbol_where_column (s));
2283 ffebad_finish ();
2284
2285 return error_mark_node;
2286 }
2287
2288 return type;
2289}
5ff904cd
JL
2290
2291/* Builds a length argument (PARM_DECL). Also wraps type in an array type
2292 where the dimension info is (1:size) where <size> is ffesymbol_size(s) if
2293 known, length_arg if not known (FFETARGET_charactersizeNONE). */
2294
5ff904cd
JL
2295static tree
2296ffecom_char_enhance_arg_ (tree *xtype, ffesymbol s)
2297{
2298 ffetargetCharacterSize sz = ffesymbol_size (s);
2299 tree highval;
2300 tree tlen;
2301 tree type = *xtype;
2302
2303 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT)
2304 tlen = NULL_TREE; /* A statement function, no length passed. */
2305 else
2306 {
2307 if (ffesymbol_where (s) == FFEINFO_whereDUMMY)
2308 tlen = ffecom_get_invented_identifier ("__g77_length_%s",
14657de8 2309 ffesymbol_text (s));
5ff904cd 2310 else
14657de8 2311 tlen = ffecom_get_invented_identifier ("__g77_%s", "length");
5ff904cd 2312 tlen = build_decl (PARM_DECL, tlen, ffecom_f2c_ftnlen_type_node);
5ff904cd 2313 DECL_ARTIFICIAL (tlen) = 1;
5ff904cd
JL
2314 }
2315
2316 if (sz == FFETARGET_charactersizeNONE)
2317 {
2318 assert (tlen != NULL_TREE);
2b0c2df0 2319 highval = variable_size (tlen);
5ff904cd
JL
2320 }
2321 else
2322 {
2323 highval = build_int_2 (sz, 0);
2324 TREE_TYPE (highval) = ffecom_f2c_ftnlen_type_node;
2325 }
2326
2327 type = build_array_type (type,
2328 build_range_type (ffecom_f2c_ftnlen_type_node,
2329 ffecom_f2c_ftnlen_one_node,
2330 highval));
2331
2332 *xtype = type;
2333 return tlen;
2334}
2335
5ff904cd
JL
2336/* ffecom_concat_list_gather_ -- Gather list of concatenated string exprs
2337
2338 ffecomConcatList_ catlist;
2339 ffebld expr; // expr of CHARACTER basictype.
2340 ffetargetCharacterSize max; // max chars to gather or _...NONE if no max
2341 catlist = ffecom_concat_list_gather_(catlist,expr,max);
2342
2343 Scans expr for character subexpressions, updates and returns catlist
2344 accordingly. */
2345
5ff904cd
JL
2346static ffecomConcatList_
2347ffecom_concat_list_gather_ (ffecomConcatList_ catlist, ffebld expr,
2348 ffetargetCharacterSize max)
2349{
2350 ffetargetCharacterSize sz;
2351
516b69ff 2352 recurse:
5ff904cd
JL
2353
2354 if (expr == NULL)
2355 return catlist;
2356
2357 if ((max != FFETARGET_charactersizeNONE) && (catlist.minlen >= max))
2358 return catlist; /* Don't append any more items. */
2359
2360 switch (ffebld_op (expr))
2361 {
2362 case FFEBLD_opCONTER:
2363 case FFEBLD_opSYMTER:
2364 case FFEBLD_opARRAYREF:
2365 case FFEBLD_opFUNCREF:
2366 case FFEBLD_opSUBSTR:
2367 case FFEBLD_opCONVERT: /* Callers should strip this off beforehand
2368 if they don't need to preserve it. */
2369 if (catlist.count == catlist.max)
2370 { /* Make a (larger) list. */
2371 ffebld *newx;
2372 int newmax;
2373
2374 newmax = (catlist.max == 0) ? 8 : catlist.max * 2;
2375 newx = malloc_new_ks (malloc_pool_image (), "catlist",
2376 newmax * sizeof (newx[0]));
2377 if (catlist.max != 0)
2378 {
2379 memcpy (newx, catlist.exprs, catlist.max * sizeof (newx[0]));
2380 malloc_kill_ks (malloc_pool_image (), catlist.exprs,
2381 catlist.max * sizeof (newx[0]));
2382 }
2383 catlist.max = newmax;
2384 catlist.exprs = newx;
2385 }
2386 if ((sz = ffebld_size_known (expr)) != FFETARGET_charactersizeNONE)
2387 catlist.minlen += sz;
2388 else
2389 ++catlist.minlen; /* Not true for F90; can be 0 length. */
2390 if ((sz = ffebld_size_max (expr)) == FFETARGET_charactersizeNONE)
2391 catlist.maxlen = sz;
2392 else
2393 catlist.maxlen += sz;
2394 if ((max != FFETARGET_charactersizeNONE) && (catlist.minlen > max))
2395 { /* This item overlaps (or is beyond) the end
2396 of the destination. */
2397 switch (ffebld_op (expr))
2398 {
2399 case FFEBLD_opCONTER:
2400 case FFEBLD_opSYMTER:
2401 case FFEBLD_opARRAYREF:
2402 case FFEBLD_opFUNCREF:
2403 case FFEBLD_opSUBSTR:
c7e4ee3a
CB
2404 /* ~~Do useful truncations here. */
2405 break;
5ff904cd
JL
2406
2407 default:
2408 assert ("op changed or inconsistent switches!" == NULL);
2409 break;
2410 }
2411 }
2412 catlist.exprs[catlist.count++] = expr;
2413 return catlist;
2414
2415 case FFEBLD_opPAREN:
2416 expr = ffebld_left (expr);
2417 goto recurse; /* :::::::::::::::::::: */
2418
2419 case FFEBLD_opCONCATENATE:
2420 catlist = ffecom_concat_list_gather_ (catlist, ffebld_left (expr), max);
2421 expr = ffebld_right (expr);
2422 goto recurse; /* :::::::::::::::::::: */
2423
2424#if 0 /* Breaks passing small actual arg to larger
2425 dummy arg of sfunc */
2426 case FFEBLD_opCONVERT:
2427 expr = ffebld_left (expr);
2428 {
2429 ffetargetCharacterSize cmax;
2430
2431 cmax = catlist.len + ffebld_size_known (expr);
2432
2433 if ((max == FFETARGET_charactersizeNONE) || (max > cmax))
2434 max = cmax;
2435 }
2436 goto recurse; /* :::::::::::::::::::: */
2437#endif
2438
2439 case FFEBLD_opANY:
2440 return catlist;
2441
2442 default:
2443 assert ("bad op in _gather_" == NULL);
2444 return catlist;
2445 }
2446}
2447
5ff904cd
JL
2448/* ffecom_concat_list_kill_ -- Kill list of concatenated string exprs
2449
2450 ffecomConcatList_ catlist;
2451 ffecom_concat_list_kill_(catlist);
2452
2453 Anything allocated within the list info is deallocated. */
2454
5ff904cd
JL
2455static void
2456ffecom_concat_list_kill_ (ffecomConcatList_ catlist)
2457{
2458 if (catlist.max != 0)
2459 malloc_kill_ks (malloc_pool_image (), catlist.exprs,
2460 catlist.max * sizeof (catlist.exprs[0]));
2461}
2462
c7e4ee3a 2463/* Make list of concatenated string exprs.
5ff904cd
JL
2464
2465 Returns a flattened list of concatenated subexpressions given a
2466 tree of such expressions. */
2467
5ff904cd
JL
2468static ffecomConcatList_
2469ffecom_concat_list_new_ (ffebld expr, ffetargetCharacterSize max)
2470{
2471 ffecomConcatList_ catlist;
2472
2473 catlist.maxlen = catlist.minlen = catlist.max = catlist.count = 0;
2474 return ffecom_concat_list_gather_ (catlist, expr, max);
2475}
2476
5ff904cd
JL
2477/* Provide some kind of useful info on member of aggregate area,
2478 since current g77/gcc technology does not provide debug info
2479 on these members. */
2480
5ff904cd 2481static void
26f096f9 2482ffecom_debug_kludge_ (tree aggr, const char *aggr_type, ffesymbol member,
5ff904cd
JL
2483 tree member_type UNUSED, ffetargetOffset offset)
2484{
2485 tree value;
2486 tree decl;
2487 int len;
2488 char *buff;
2489 char space[120];
2490#if 0
2491 tree type_id;
2492
2493 for (type_id = member_type;
2494 TREE_CODE (type_id) != IDENTIFIER_NODE;
2495 )
2496 {
2497 switch (TREE_CODE (type_id))
2498 {
2499 case INTEGER_TYPE:
2500 case REAL_TYPE:
2501 type_id = TYPE_NAME (type_id);
2502 break;
2503
2504 case ARRAY_TYPE:
2505 case COMPLEX_TYPE:
2506 type_id = TREE_TYPE (type_id);
2507 break;
2508
2509 default:
2510 assert ("no IDENTIFIER_NODE for type!" == NULL);
2511 type_id = error_mark_node;
2512 break;
2513 }
2514 }
2515#endif
2516
2517 if (ffecom_transform_only_dummies_
2518 || !ffe_is_debug_kludge ())
2519 return; /* Can't do this yet, maybe later. */
2520
2521 len = 60
2522 + strlen (aggr_type)
2523 + IDENTIFIER_LENGTH (DECL_NAME (aggr));
2524#if 0
2525 + IDENTIFIER_LENGTH (type_id);
2526#endif
2527
2528 if (((size_t) len) >= ARRAY_SIZE (space))
2529 buff = malloc_new_ks (malloc_pool_image (), "debug_kludge", len + 1);
2530 else
2531 buff = &space[0];
2532
2533 sprintf (&buff[0], "At (%s) `%s' plus %ld bytes",
2534 aggr_type,
2535 IDENTIFIER_POINTER (DECL_NAME (aggr)),
2536 (long int) offset);
2537
2538 value = build_string (len, buff);
2539 TREE_TYPE (value)
2540 = build_type_variant (build_array_type (char_type_node,
2541 build_range_type
2542 (integer_type_node,
2543 integer_one_node,
2544 build_int_2 (strlen (buff), 0))),
2545 1, 0);
2546 decl = build_decl (VAR_DECL,
2547 ffecom_get_identifier_ (ffesymbol_text (member)),
2548 TREE_TYPE (value));
2549 TREE_CONSTANT (decl) = 1;
2550 TREE_STATIC (decl) = 1;
2551 DECL_INITIAL (decl) = error_mark_node;
2552 DECL_IN_SYSTEM_HEADER (decl) = 1; /* Don't let -Wunused complain. */
2553 decl = start_decl (decl, FALSE);
2554 finish_decl (decl, value, FALSE);
2555
2556 if (buff != &space[0])
2557 malloc_kill_ks (malloc_pool_image (), buff, len + 1);
2558}
5ff904cd
JL
2559
2560/* ffecom_do_entry_ -- Do compilation of a particular entrypoint
2561
2562 ffesymbol fn; // the SUBROUTINE, FUNCTION, or ENTRY symbol itself
2563 int i; // entry# for this entrypoint (used by master fn)
2564 ffecom_do_entrypoint_(s,i);
2565
2566 Makes a public entry point that calls our private master fn (already
2567 compiled). */
2568
5ff904cd
JL
2569static void
2570ffecom_do_entry_ (ffesymbol fn, int entrynum)
2571{
2572 ffebld item;
2573 tree type; /* Type of function. */
2574 tree multi_retval; /* Var holding return value (union). */
2575 tree result; /* Var holding result. */
2576 ffeinfoBasictype bt;
2577 ffeinfoKindtype kt;
2578 ffeglobal g;
2579 ffeglobalType gt;
2580 bool charfunc; /* All entry points return same type
2581 CHARACTER. */
2582 bool cmplxfunc; /* Use f2c way of returning COMPLEX. */
2583 bool multi; /* Master fn has multiple return types. */
2584 bool altreturning = FALSE; /* This entry point has alternate returns. */
44d2eabc 2585 int old_lineno = lineno;
3b304f5b 2586 const char *old_input_filename = input_filename;
44d2eabc
JL
2587
2588 input_filename = ffesymbol_where_filename (fn);
2589 lineno = ffesymbol_where_filelinenum (fn);
5ff904cd 2590
5ff904cd
JL
2591 ffecom_doing_entry_ = TRUE; /* Don't bother with array dimensions. */
2592
2593 switch (ffecom_primary_entry_kind_)
2594 {
2595 case FFEINFO_kindFUNCTION:
2596
2597 /* Determine actual return type for function. */
2598
2599 gt = FFEGLOBAL_typeFUNC;
2600 bt = ffesymbol_basictype (fn);
2601 kt = ffesymbol_kindtype (fn);
2602 if (bt == FFEINFO_basictypeNONE)
2603 {
2604 ffeimplic_establish_symbol (fn);
2605 if (ffesymbol_funcresult (fn) != NULL)
2606 ffeimplic_establish_symbol (ffesymbol_funcresult (fn));
2607 bt = ffesymbol_basictype (fn);
2608 kt = ffesymbol_kindtype (fn);
2609 }
2610
2611 if (bt == FFEINFO_basictypeCHARACTER)
2612 charfunc = TRUE, cmplxfunc = FALSE;
2613 else if ((bt == FFEINFO_basictypeCOMPLEX)
2614 && ffesymbol_is_f2c (fn))
2615 charfunc = FALSE, cmplxfunc = TRUE;
2616 else
2617 charfunc = cmplxfunc = FALSE;
2618
2619 if (charfunc)
2620 type = ffecom_tree_fun_type_void;
2621 else if (ffesymbol_is_f2c (fn))
2622 type = ffecom_tree_fun_type[bt][kt];
2623 else
2624 type = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
2625
2626 if ((type == NULL_TREE)
2627 || (TREE_TYPE (type) == NULL_TREE))
2628 type = ffecom_tree_fun_type_void; /* _sym_exec_transition. */
2629
2630 multi = (ffecom_master_bt_ == FFEINFO_basictypeNONE);
2631 break;
2632
2633 case FFEINFO_kindSUBROUTINE:
2634 gt = FFEGLOBAL_typeSUBR;
2635 bt = FFEINFO_basictypeNONE;
2636 kt = FFEINFO_kindtypeNONE;
2637 if (ffecom_is_altreturning_)
2638 { /* Am _I_ altreturning? */
2639 for (item = ffesymbol_dummyargs (fn);
2640 item != NULL;
2641 item = ffebld_trail (item))
2642 {
2643 if (ffebld_op (ffebld_head (item)) == FFEBLD_opSTAR)
2644 {
2645 altreturning = TRUE;
2646 break;
2647 }
2648 }
2649 if (altreturning)
2650 type = ffecom_tree_subr_type;
2651 else
2652 type = ffecom_tree_fun_type_void;
2653 }
2654 else
2655 type = ffecom_tree_fun_type_void;
2656 charfunc = FALSE;
2657 cmplxfunc = FALSE;
2658 multi = FALSE;
2659 break;
2660
2661 default:
2662 assert ("say what??" == NULL);
2663 /* Fall through. */
2664 case FFEINFO_kindANY:
2665 gt = FFEGLOBAL_typeANY;
2666 bt = FFEINFO_basictypeNONE;
2667 kt = FFEINFO_kindtypeNONE;
2668 type = error_mark_node;
2669 charfunc = FALSE;
2670 cmplxfunc = FALSE;
2671 multi = FALSE;
2672 break;
2673 }
2674
2675 /* build_decl uses the current lineno and input_filename to set the decl
2676 source info. So, I've putzed with ffestd and ffeste code to update that
2677 source info to point to the appropriate statement just before calling
2678 ffecom_do_entrypoint (which calls this fn). */
2679
2680 start_function (ffecom_get_external_identifier_ (fn),
2681 type,
2682 0, /* nested/inline */
2683 1); /* TREE_PUBLIC */
2684
2685 if (((g = ffesymbol_global (fn)) != NULL)
2686 && ((ffeglobal_type (g) == gt)
2687 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
2688 {
2689 ffeglobal_set_hook (g, current_function_decl);
2690 }
2691
2692 /* Reset args in master arg list so they get retransitioned. */
2693
2694 for (item = ffecom_master_arglist_;
2695 item != NULL;
2696 item = ffebld_trail (item))
2697 {
2698 ffebld arg;
2699 ffesymbol s;
2700
2701 arg = ffebld_head (item);
2702 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2703 continue; /* Alternate return or some such thing. */
2704 s = ffebld_symter (arg);
2705 ffesymbol_hook (s).decl_tree = NULL_TREE;
2706 ffesymbol_hook (s).length_tree = NULL_TREE;
2707 }
2708
2709 /* Build dummy arg list for this entry point. */
2710
5ff904cd
JL
2711 if (charfunc || cmplxfunc)
2712 { /* Prepend arg for where result goes. */
2713 tree type;
2714 tree length;
2715
2716 if (charfunc)
2717 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
2718 else
2719 type = ffecom_tree_type[FFEINFO_basictypeCOMPLEX][kt];
2720
14657de8 2721 result = ffecom_get_invented_identifier ("__g77_%s", "result");
5ff904cd
JL
2722
2723 /* Make length arg _and_ enhance type info for CHAR arg itself. */
2724
2725 if (charfunc)
2726 length = ffecom_char_enhance_arg_ (&type, fn);
2727 else
2728 length = NULL_TREE; /* Not ref'd if !charfunc. */
2729
2730 type = build_pointer_type (type);
2731 result = build_decl (PARM_DECL, result, type);
2732
2733 push_parm_decl (result);
2734 ffecom_func_result_ = result;
2735
2736 if (charfunc)
2737 {
2738 push_parm_decl (length);
2739 ffecom_func_length_ = length;
2740 }
2741 }
2742 else
2743 result = DECL_RESULT (current_function_decl);
2744
2745 ffecom_push_dummy_decls_ (ffesymbol_dummyargs (fn), FALSE);
2746
5ff904cd
JL
2747 store_parm_decls (0);
2748
c7e4ee3a
CB
2749 ffecom_start_compstmt ();
2750 /* Disallow temp vars at this level. */
2751 current_binding_level->prep_state = 2;
5ff904cd
JL
2752
2753 /* Make local var to hold return type for multi-type master fn. */
2754
2755 if (multi)
2756 {
5ff904cd 2757 multi_retval = ffecom_get_invented_identifier ("__g77_%s",
14657de8 2758 "multi_retval");
5ff904cd
JL
2759 multi_retval = build_decl (VAR_DECL, multi_retval,
2760 ffecom_multi_type_node_);
2761 multi_retval = start_decl (multi_retval, FALSE);
2762 finish_decl (multi_retval, NULL_TREE, FALSE);
5ff904cd
JL
2763 }
2764 else
2765 multi_retval = NULL_TREE; /* Not actually ref'd if !multi. */
2766
2767 /* Here we emit the actual code for the entry point. */
2768
2769 {
2770 ffebld list;
2771 ffebld arg;
2772 ffesymbol s;
2773 tree arglist = NULL_TREE;
2774 tree *plist = &arglist;
2775 tree prepend;
2776 tree call;
2777 tree actarg;
2778 tree master_fn;
2779
2780 /* Prepare actual arg list based on master arg list. */
2781
2782 for (list = ffecom_master_arglist_;
2783 list != NULL;
2784 list = ffebld_trail (list))
2785 {
2786 arg = ffebld_head (list);
2787 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2788 continue;
2789 s = ffebld_symter (arg);
702edf1d
CB
2790 if (ffesymbol_hook (s).decl_tree == NULL_TREE
2791 || ffesymbol_hook (s).decl_tree == error_mark_node)
5ff904cd
JL
2792 actarg = null_pointer_node; /* We don't have this arg. */
2793 else
2794 actarg = ffesymbol_hook (s).decl_tree;
2795 *plist = build_tree_list (NULL_TREE, actarg);
2796 plist = &TREE_CHAIN (*plist);
2797 }
2798
2799 /* This code appends the length arguments for character
2800 variables/arrays. */
2801
2802 for (list = ffecom_master_arglist_;
2803 list != NULL;
2804 list = ffebld_trail (list))
2805 {
2806 arg = ffebld_head (list);
2807 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2808 continue;
2809 s = ffebld_symter (arg);
2810 if (ffesymbol_basictype (s) != FFEINFO_basictypeCHARACTER)
2811 continue; /* Only looking for CHARACTER arguments. */
2812 if (ffesymbol_kind (s) != FFEINFO_kindENTITY)
2813 continue; /* Only looking for variables and arrays. */
702edf1d
CB
2814 if (ffesymbol_hook (s).length_tree == NULL_TREE
2815 || ffesymbol_hook (s).length_tree == error_mark_node)
5ff904cd
JL
2816 actarg = ffecom_f2c_ftnlen_zero_node; /* We don't have this arg. */
2817 else
2818 actarg = ffesymbol_hook (s).length_tree;
2819 *plist = build_tree_list (NULL_TREE, actarg);
2820 plist = &TREE_CHAIN (*plist);
2821 }
2822
2823 /* Prepend character-value return info to actual arg list. */
2824
2825 if (charfunc)
2826 {
2827 prepend = build_tree_list (NULL_TREE, ffecom_func_result_);
2828 TREE_CHAIN (prepend)
2829 = build_tree_list (NULL_TREE, ffecom_func_length_);
2830 TREE_CHAIN (TREE_CHAIN (prepend)) = arglist;
2831 arglist = prepend;
2832 }
2833
2834 /* Prepend multi-type return value to actual arg list. */
2835
2836 if (multi)
2837 {
2838 prepend
2839 = build_tree_list (NULL_TREE,
2840 ffecom_1 (ADDR_EXPR,
2841 build_pointer_type (TREE_TYPE (multi_retval)),
2842 multi_retval));
2843 TREE_CHAIN (prepend) = arglist;
2844 arglist = prepend;
2845 }
2846
2847 /* Prepend my entry-point number to the actual arg list. */
2848
2849 prepend = build_tree_list (NULL_TREE, build_int_2 (entrynum, 0));
2850 TREE_CHAIN (prepend) = arglist;
2851 arglist = prepend;
2852
2853 /* Build the call to the master function. */
2854
2855 master_fn = ffecom_1_fn (ffecom_previous_function_decl_);
2856 call = ffecom_3s (CALL_EXPR,
2857 TREE_TYPE (TREE_TYPE (TREE_TYPE (master_fn))),
2858 master_fn, arglist, NULL_TREE);
2859
2860 /* Decide whether the master function is a function or subroutine, and
2861 handle the return value for my entry point. */
2862
2863 if (charfunc || ((ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE)
2864 && !altreturning))
2865 {
2866 expand_expr_stmt (call);
2867 expand_null_return ();
2868 }
2869 else if (multi && cmplxfunc)
2870 {
2871 expand_expr_stmt (call);
2872 result
2873 = ffecom_1 (INDIRECT_REF,
2874 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result))),
2875 result);
2876 result = ffecom_modify (NULL_TREE, result,
2877 ffecom_2 (COMPONENT_REF, TREE_TYPE (result),
2878 multi_retval,
2879 ffecom_multi_fields_[bt][kt]));
2880 expand_expr_stmt (result);
2881 expand_null_return ();
2882 }
2883 else if (multi)
2884 {
2885 expand_expr_stmt (call);
2886 result
2887 = ffecom_modify (NULL_TREE, result,
2888 convert (TREE_TYPE (result),
2889 ffecom_2 (COMPONENT_REF,
2890 ffecom_tree_type[bt][kt],
2891 multi_retval,
2892 ffecom_multi_fields_[bt][kt])));
2893 expand_return (result);
2894 }
2895 else if (cmplxfunc)
2896 {
2897 result
2898 = ffecom_1 (INDIRECT_REF,
2899 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result))),
2900 result);
2901 result = ffecom_modify (NULL_TREE, result, call);
2902 expand_expr_stmt (result);
2903 expand_null_return ();
2904 }
2905 else
2906 {
2907 result = ffecom_modify (NULL_TREE,
2908 result,
2909 convert (TREE_TYPE (result),
2910 call));
2911 expand_return (result);
2912 }
5ff904cd
JL
2913 }
2914
c7e4ee3a 2915 ffecom_end_compstmt ();
5ff904cd
JL
2916
2917 finish_function (0);
2918
44d2eabc
JL
2919 lineno = old_lineno;
2920 input_filename = old_input_filename;
2921
5ff904cd
JL
2922 ffecom_doing_entry_ = FALSE;
2923}
2924
5ff904cd
JL
2925/* Transform expr into gcc tree with possible destination
2926
2927 Recursive descent on expr while making corresponding tree nodes and
2928 attaching type info and such. If destination supplied and compatible
2929 with temporary that would be made in certain cases, temporary isn't
092a4ef8 2930 made, destination used instead, and dest_used flag set TRUE. */
5ff904cd 2931
5ff904cd 2932static tree
092a4ef8
RH
2933ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest,
2934 bool *dest_used, bool assignp, bool widenp)
5ff904cd
JL
2935{
2936 tree item;
2937 tree list;
2938 tree args;
2939 ffeinfoBasictype bt;
2940 ffeinfoKindtype kt;
2941 tree t;
5ff904cd 2942 tree dt; /* decl_tree for an ffesymbol. */
092a4ef8 2943 tree tree_type, tree_type_x;
af752698 2944 tree left, right;
5ff904cd
JL
2945 ffesymbol s;
2946 enum tree_code code;
2947
2948 assert (expr != NULL);
2949
2950 if (dest_used != NULL)
2951 *dest_used = FALSE;
2952
2953 bt = ffeinfo_basictype (ffebld_info (expr));
2954 kt = ffeinfo_kindtype (ffebld_info (expr));
af752698 2955 tree_type = ffecom_tree_type[bt][kt];
5ff904cd 2956
092a4ef8
RH
2957 /* Widen integral arithmetic as desired while preserving signedness. */
2958 tree_type_x = NULL_TREE;
2959 if (widenp && tree_type
2960 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
2961 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
2962 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
2963
5ff904cd
JL
2964 switch (ffebld_op (expr))
2965 {
2966 case FFEBLD_opACCTER:
5ff904cd
JL
2967 {
2968 ffebitCount i;
2969 ffebit bits = ffebld_accter_bits (expr);
2970 ffetargetOffset source_offset = 0;
a6fa6420 2971 ffetargetOffset dest_offset = ffebld_accter_pad (expr);
5ff904cd
JL
2972 tree purpose;
2973
a6fa6420
CB
2974 assert (dest_offset == 0
2975 || (bt == FFEINFO_basictypeCHARACTER
2976 && kt == FFEINFO_kindtypeCHARACTER1));
5ff904cd
JL
2977
2978 list = item = NULL;
2979 for (;;)
2980 {
2981 ffebldConstantUnion cu;
2982 ffebitCount length;
2983 bool value;
2984 ffebldConstantArray ca = ffebld_accter (expr);
2985
2986 ffebit_test (bits, source_offset, &value, &length);
2987 if (length == 0)
2988 break;
2989
2990 if (value)
2991 {
2992 for (i = 0; i < length; ++i)
2993 {
2994 cu = ffebld_constantarray_get (ca, bt, kt,
2995 source_offset + i);
2996
2997 t = ffecom_constantunion (&cu, bt, kt, tree_type);
2998
a6fa6420
CB
2999 if (i == 0
3000 && dest_offset != 0)
3001 purpose = build_int_2 (dest_offset, 0);
5ff904cd
JL
3002 else
3003 purpose = NULL_TREE;
3004
3005 if (list == NULL_TREE)
3006 list = item = build_tree_list (purpose, t);
3007 else
3008 {
3009 TREE_CHAIN (item) = build_tree_list (purpose, t);
3010 item = TREE_CHAIN (item);
3011 }
3012 }
3013 }
3014 source_offset += length;
a6fa6420 3015 dest_offset += length;
5ff904cd
JL
3016 }
3017 }
3018
a6fa6420
CB
3019 item = build_int_2 ((ffebld_accter_size (expr)
3020 + ffebld_accter_pad (expr)) - 1, 0);
5ff904cd
JL
3021 ffebit_kill (ffebld_accter_bits (expr));
3022 TREE_TYPE (item) = ffecom_integer_type_node;
3023 item
3024 = build_array_type
3025 (tree_type,
3026 build_range_type (ffecom_integer_type_node,
3027 ffecom_integer_zero_node,
3028 item));
3029 list = build (CONSTRUCTOR, item, NULL_TREE, list);
3030 TREE_CONSTANT (list) = 1;
3031 TREE_STATIC (list) = 1;
3032 return list;
3033
3034 case FFEBLD_opARRTER:
5ff904cd
JL
3035 {
3036 ffetargetOffset i;
3037
a6fa6420
CB
3038 list = NULL_TREE;
3039 if (ffebld_arrter_pad (expr) == 0)
3040 item = NULL_TREE;
3041 else
3042 {
3043 assert (bt == FFEINFO_basictypeCHARACTER
3044 && kt == FFEINFO_kindtypeCHARACTER1);
3045
3046 /* Becomes PURPOSE first time through loop. */
3047 item = build_int_2 (ffebld_arrter_pad (expr), 0);
3048 }
3049
5ff904cd
JL
3050 for (i = 0; i < ffebld_arrter_size (expr); ++i)
3051 {
3052 ffebldConstantUnion cu
3053 = ffebld_constantarray_get (ffebld_arrter (expr), bt, kt, i);
3054
3055 t = ffecom_constantunion (&cu, bt, kt, tree_type);
3056
3057 if (list == NULL_TREE)
a6fa6420
CB
3058 /* Assume item is PURPOSE first time through loop. */
3059 list = item = build_tree_list (item, t);
5ff904cd
JL
3060 else
3061 {
3062 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
3063 item = TREE_CHAIN (item);
3064 }
3065 }
3066 }
3067
a6fa6420
CB
3068 item = build_int_2 ((ffebld_arrter_size (expr)
3069 + ffebld_arrter_pad (expr)) - 1, 0);
5ff904cd
JL
3070 TREE_TYPE (item) = ffecom_integer_type_node;
3071 item
3072 = build_array_type
3073 (tree_type,
3074 build_range_type (ffecom_integer_type_node,
a6fa6420 3075 ffecom_integer_zero_node,
5ff904cd
JL
3076 item));
3077 list = build (CONSTRUCTOR, item, NULL_TREE, list);
3078 TREE_CONSTANT (list) = 1;
3079 TREE_STATIC (list) = 1;
3080 return list;
3081
3082 case FFEBLD_opCONTER:
c264f113 3083 assert (ffebld_conter_pad (expr) == 0);
5ff904cd
JL
3084 item
3085 = ffecom_constantunion (&ffebld_constant_union (ffebld_conter (expr)),
3086 bt, kt, tree_type);
3087 return item;
3088
3089 case FFEBLD_opSYMTER:
3090 if ((ffebld_symter_generic (expr) != FFEINTRIN_genNONE)
3091 || (ffebld_symter_specific (expr) != FFEINTRIN_specNONE))
3092 return ffecom_ptr_to_expr (expr); /* Same as %REF(intrinsic). */
3093 s = ffebld_symter (expr);
3094 t = ffesymbol_hook (s).decl_tree;
3095
3096 if (assignp)
3097 { /* ASSIGN'ed-label expr. */
3098 if (ffe_is_ugly_assign ())
3099 {
3100 /* User explicitly wants ASSIGN'ed variables to be at the same
3101 memory address as the variables when used in non-ASSIGN
3102 contexts. That can make old, arcane, non-standard code
3103 work, but don't try to do it when a pointer wouldn't fit
3104 in the normal variable (take other approach, and warn,
3105 instead). */
3106
3107 if (t == NULL_TREE)
3108 {
3109 s = ffecom_sym_transform_ (s);
3110 t = ffesymbol_hook (s).decl_tree;
3111 assert (t != NULL_TREE);
3112 }
3113
3114 if (t == error_mark_node)
3115 return t;
3116
3117 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (t)))
3118 >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
3119 {
3120 if (ffesymbol_hook (s).addr)
3121 t = ffecom_1 (INDIRECT_REF,
3122 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), t);
3123 return t;
3124 }
3125
3126 if (ffesymbol_hook (s).assign_tree == NULL_TREE)
3127 {
5987ca1c 3128 /* xgettext:no-c-format */
5ff904cd
JL
3129 ffebad_start_msg ("ASSIGN'ed label cannot fit into `%A' at %0 -- using wider sibling",
3130 FFEBAD_severityWARNING);
3131 ffebad_string (ffesymbol_text (s));
3132 ffebad_here (0, ffesymbol_where_line (s),
3133 ffesymbol_where_column (s));
3134 ffebad_finish ();
3135 }
3136 }
3137
3138 /* Don't use the normal variable's tree for ASSIGN, though mark
3139 it as in the system header (housekeeping). Use an explicit,
3140 specially created sibling that is known to be wide enough
3141 to hold pointers to labels. */
3142
3143 if (t != NULL_TREE
3144 && TREE_CODE (t) == VAR_DECL)
3145 DECL_IN_SYSTEM_HEADER (t) = 1; /* Don't let -Wunused complain. */
3146
3147 t = ffesymbol_hook (s).assign_tree;
3148 if (t == NULL_TREE)
3149 {
3150 s = ffecom_sym_transform_assign_ (s);
3151 t = ffesymbol_hook (s).assign_tree;
3152 assert (t != NULL_TREE);
3153 }
3154 }
3155 else
3156 {
3157 if (t == NULL_TREE)
3158 {
3159 s = ffecom_sym_transform_ (s);
3160 t = ffesymbol_hook (s).decl_tree;
3161 assert (t != NULL_TREE);
3162 }
3163 if (ffesymbol_hook (s).addr)
3164 t = ffecom_1 (INDIRECT_REF,
3165 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), t);
3166 }
3167 return t;
3168
3169 case FFEBLD_opARRAYREF:
ff852b44 3170 return ffecom_arrayref_ (NULL_TREE, expr, 0);
5ff904cd
JL
3171
3172 case FFEBLD_opUPLUS:
092a4ef8 3173 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
af752698 3174 return ffecom_1 (NOP_EXPR, tree_type, left);
5ff904cd 3175
c7e4ee3a
CB
3176 case FFEBLD_opPAREN:
3177 /* ~~~Make sure Fortran rules respected here */
092a4ef8 3178 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
af752698 3179 return ffecom_1 (NOP_EXPR, tree_type, left);
5ff904cd
JL
3180
3181 case FFEBLD_opUMINUS:
092a4ef8 3182 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
516b69ff 3183 if (tree_type_x)
af752698
RH
3184 {
3185 tree_type = tree_type_x;
3186 left = convert (tree_type, left);
3187 }
3188 return ffecom_1 (NEGATE_EXPR, tree_type, left);
5ff904cd
JL
3189
3190 case FFEBLD_opADD:
092a4ef8
RH
3191 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3192 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
516b69ff 3193 if (tree_type_x)
af752698
RH
3194 {
3195 tree_type = tree_type_x;
3196 left = convert (tree_type, left);
3197 right = convert (tree_type, right);
3198 }
3199 return ffecom_2 (PLUS_EXPR, tree_type, left, right);
5ff904cd
JL
3200
3201 case FFEBLD_opSUBTRACT:
092a4ef8
RH
3202 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3203 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
516b69ff 3204 if (tree_type_x)
af752698
RH
3205 {
3206 tree_type = tree_type_x;
3207 left = convert (tree_type, left);
3208 right = convert (tree_type, right);
3209 }
3210 return ffecom_2 (MINUS_EXPR, tree_type, left, right);
5ff904cd
JL
3211
3212 case FFEBLD_opMULTIPLY:
092a4ef8
RH
3213 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3214 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
516b69ff 3215 if (tree_type_x)
af752698
RH
3216 {
3217 tree_type = tree_type_x;
3218 left = convert (tree_type, left);
3219 right = convert (tree_type, right);
3220 }
3221 return ffecom_2 (MULT_EXPR, tree_type, left, right);
5ff904cd
JL
3222
3223 case FFEBLD_opDIVIDE:
092a4ef8
RH
3224 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3225 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
516b69ff 3226 if (tree_type_x)
af752698
RH
3227 {
3228 tree_type = tree_type_x;
3229 left = convert (tree_type, left);
3230 right = convert (tree_type, right);
3231 }
3232 return ffecom_tree_divide_ (tree_type, left, right,
c7e4ee3a
CB
3233 dest_tree, dest, dest_used,
3234 ffebld_nonter_hook (expr));
5ff904cd
JL
3235
3236 case FFEBLD_opPOWER:
5ff904cd
JL
3237 {
3238 ffebld left = ffebld_left (expr);
3239 ffebld right = ffebld_right (expr);
3240 ffecomGfrt code;
3241 ffeinfoKindtype rtkt;
270fc4e8 3242 ffeinfoKindtype ltkt;
95eb4fd9 3243 bool ref = TRUE;
5ff904cd
JL
3244
3245 switch (ffeinfo_basictype (ffebld_info (right)))
3246 {
95eb4fd9 3247
5ff904cd
JL
3248 case FFEINFO_basictypeINTEGER:
3249 if (1 || optimize)
3250 {
c7e4ee3a 3251 item = ffecom_expr_power_integer_ (expr);
5ff904cd
JL
3252 if (item != NULL_TREE)
3253 return item;
3254 }
3255
3256 rtkt = FFEINFO_kindtypeINTEGER1;
3257 switch (ffeinfo_basictype (ffebld_info (left)))
3258 {
3259 case FFEINFO_basictypeINTEGER:
3260 if ((ffeinfo_kindtype (ffebld_info (left))
3261 == FFEINFO_kindtypeINTEGER4)
3262 || (ffeinfo_kindtype (ffebld_info (right))
3263 == FFEINFO_kindtypeINTEGER4))
3264 {
3265 code = FFECOM_gfrtPOW_QQ;
270fc4e8 3266 ltkt = FFEINFO_kindtypeINTEGER4;
5ff904cd
JL
3267 rtkt = FFEINFO_kindtypeINTEGER4;
3268 }
3269 else
6a047254
CB
3270 {
3271 code = FFECOM_gfrtPOW_II;
3272 ltkt = FFEINFO_kindtypeINTEGER1;
3273 }
5ff904cd
JL
3274 break;
3275
3276 case FFEINFO_basictypeREAL:
3277 if (ffeinfo_kindtype (ffebld_info (left))
3278 == FFEINFO_kindtypeREAL1)
6a047254
CB
3279 {
3280 code = FFECOM_gfrtPOW_RI;
3281 ltkt = FFEINFO_kindtypeREAL1;
3282 }
5ff904cd 3283 else
6a047254
CB
3284 {
3285 code = FFECOM_gfrtPOW_DI;
3286 ltkt = FFEINFO_kindtypeREAL2;
3287 }
5ff904cd
JL
3288 break;
3289
3290 case FFEINFO_basictypeCOMPLEX:
3291 if (ffeinfo_kindtype (ffebld_info (left))
3292 == FFEINFO_kindtypeREAL1)
6a047254
CB
3293 {
3294 code = FFECOM_gfrtPOW_CI; /* Overlapping result okay. */
3295 ltkt = FFEINFO_kindtypeREAL1;
3296 }
5ff904cd 3297 else
6a047254
CB
3298 {
3299 code = FFECOM_gfrtPOW_ZI; /* Overlapping result okay. */
3300 ltkt = FFEINFO_kindtypeREAL2;
3301 }
5ff904cd
JL
3302 break;
3303
3304 default:
3305 assert ("bad pow_*i" == NULL);
3306 code = FFECOM_gfrtPOW_CI; /* Overlapping result okay. */
6a047254 3307 ltkt = FFEINFO_kindtypeREAL1;
5ff904cd
JL
3308 break;
3309 }
270fc4e8 3310 if (ffeinfo_kindtype (ffebld_info (left)) != ltkt)
5ff904cd 3311 left = ffeexpr_convert (left, NULL, NULL,
6a047254 3312 ffeinfo_basictype (ffebld_info (left)),
270fc4e8 3313 ltkt, 0,
5ff904cd
JL
3314 FFETARGET_charactersizeNONE,
3315 FFEEXPR_contextLET);
3316 if (ffeinfo_kindtype (ffebld_info (right)) != rtkt)
3317 right = ffeexpr_convert (right, NULL, NULL,
3318 FFEINFO_basictypeINTEGER,
3319 rtkt, 0,
3320 FFETARGET_charactersizeNONE,
3321 FFEEXPR_contextLET);
3322 break;
3323
3324 case FFEINFO_basictypeREAL:
3325 if (ffeinfo_kindtype (ffebld_info (left)) == FFEINFO_kindtypeREAL1)
3326 left = ffeexpr_convert (left, NULL, NULL, FFEINFO_basictypeREAL,
3327 FFEINFO_kindtypeREALDOUBLE, 0,
3328 FFETARGET_charactersizeNONE,
3329 FFEEXPR_contextLET);
3330 if (ffeinfo_kindtype (ffebld_info (right))
3331 == FFEINFO_kindtypeREAL1)
3332 right = ffeexpr_convert (right, NULL, NULL,
3333 FFEINFO_basictypeREAL,
3334 FFEINFO_kindtypeREALDOUBLE, 0,
3335 FFETARGET_charactersizeNONE,
3336 FFEEXPR_contextLET);
95eb4fd9
TM
3337 /* We used to call FFECOM_gfrtPOW_DD here,
3338 which passes arguments by reference. */
3339 code = FFECOM_gfrtL_POW;
3340 /* Pass arguments by value. */
3341 ref = FALSE;
5ff904cd
JL
3342 break;
3343
3344 case FFEINFO_basictypeCOMPLEX:
3345 if (ffeinfo_kindtype (ffebld_info (left)) == FFEINFO_kindtypeREAL1)
3346 left = ffeexpr_convert (left, NULL, NULL,
3347 FFEINFO_basictypeCOMPLEX,
3348 FFEINFO_kindtypeREALDOUBLE, 0,
3349 FFETARGET_charactersizeNONE,
3350 FFEEXPR_contextLET);
3351 if (ffeinfo_kindtype (ffebld_info (right))
3352 == FFEINFO_kindtypeREAL1)
3353 right = ffeexpr_convert (right, NULL, NULL,
3354 FFEINFO_basictypeCOMPLEX,
3355 FFEINFO_kindtypeREALDOUBLE, 0,
3356 FFETARGET_charactersizeNONE,
3357 FFEEXPR_contextLET);
3358 code = FFECOM_gfrtPOW_ZZ; /* Overlapping result okay. */
95eb4fd9 3359 ref = TRUE; /* Pass arguments by reference. */
5ff904cd
JL
3360 break;
3361
3362 default:
3363 assert ("bad pow_x*" == NULL);
3364 code = FFECOM_gfrtPOW_II;
3365 break;
3366 }
3367 return ffecom_call_binop_ (ffecom_gfrt_tree_ (code),
3368 ffecom_gfrt_kindtype (code),
3369 (ffe_is_f2c_library ()
3370 && ffecom_gfrt_complex_[code]),
3371 tree_type, left, right,
3372 dest_tree, dest, dest_used,
95eb4fd9 3373 NULL_TREE, FALSE, ref,
c7e4ee3a 3374 ffebld_nonter_hook (expr));
5ff904cd
JL
3375 }
3376
3377 case FFEBLD_opNOT:
5ff904cd
JL
3378 switch (bt)
3379 {
3380 case FFEINFO_basictypeLOGICAL:
83ffecd2 3381 item = ffecom_truth_value_invert (ffecom_expr (ffebld_left (expr)));
5ff904cd
JL
3382 return convert (tree_type, item);
3383
3384 case FFEINFO_basictypeINTEGER:
3385 return ffecom_1 (BIT_NOT_EXPR, tree_type,
3386 ffecom_expr (ffebld_left (expr)));
3387
3388 default:
3389 assert ("NOT bad basictype" == NULL);
3390 /* Fall through. */
3391 case FFEINFO_basictypeANY:
3392 return error_mark_node;
3393 }
3394 break;
3395
3396 case FFEBLD_opFUNCREF:
3397 assert (ffeinfo_basictype (ffebld_info (expr))
3398 != FFEINFO_basictypeCHARACTER);
3399 /* Fall through. */
3400 case FFEBLD_opSUBRREF:
5ff904cd
JL
3401 if (ffeinfo_where (ffebld_info (ffebld_left (expr)))
3402 == FFEINFO_whereINTRINSIC)
3403 { /* Invocation of an intrinsic. */
3404 item = ffecom_expr_intrinsic_ (expr, dest_tree, dest,
3405 dest_used);
3406 return item;
3407 }
3408 s = ffebld_symter (ffebld_left (expr));
3409 dt = ffesymbol_hook (s).decl_tree;
3410 if (dt == NULL_TREE)
3411 {
3412 s = ffecom_sym_transform_ (s);
3413 dt = ffesymbol_hook (s).decl_tree;
3414 }
3415 if (dt == error_mark_node)
3416 return dt;
3417
3418 if (ffesymbol_hook (s).addr)
3419 item = dt;
3420 else
3421 item = ffecom_1_fn (dt);
3422
5ff904cd
JL
3423 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT)
3424 args = ffecom_list_expr (ffebld_right (expr));
3425 else
3426 args = ffecom_list_ptr_to_expr (ffebld_right (expr));
5ff904cd 3427
702edf1d
CB
3428 if (args == error_mark_node)
3429 return error_mark_node;
3430
5ff904cd
JL
3431 item = ffecom_call_ (item, kt,
3432 ffesymbol_is_f2c (s)
3433 && (bt == FFEINFO_basictypeCOMPLEX)
3434 && (ffesymbol_where (s)
3435 != FFEINFO_whereCONSTANT),
3436 tree_type,
3437 args,
3438 dest_tree, dest, dest_used,
c7e4ee3a
CB
3439 error_mark_node, FALSE,
3440 ffebld_nonter_hook (expr));
5ff904cd
JL
3441 TREE_SIDE_EFFECTS (item) = 1;
3442 return item;
3443
3444 case FFEBLD_opAND:
5ff904cd
JL
3445 switch (bt)
3446 {
3447 case FFEINFO_basictypeLOGICAL:
3448 item
3449 = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
3450 ffecom_truth_value (ffecom_expr (ffebld_left (expr))),
3451 ffecom_truth_value (ffecom_expr (ffebld_right (expr))));
3452 return convert (tree_type, item);
3453
3454 case FFEINFO_basictypeINTEGER:
3455 return ffecom_2 (BIT_AND_EXPR, tree_type,
3456 ffecom_expr (ffebld_left (expr)),
3457 ffecom_expr (ffebld_right (expr)));
3458
3459 default:
3460 assert ("AND bad basictype" == NULL);
3461 /* Fall through. */
3462 case FFEINFO_basictypeANY:
3463 return error_mark_node;
3464 }
3465 break;
3466
3467 case FFEBLD_opOR:
5ff904cd
JL
3468 switch (bt)
3469 {
3470 case FFEINFO_basictypeLOGICAL:
3471 item
3472 = ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
3473 ffecom_truth_value (ffecom_expr (ffebld_left (expr))),
3474 ffecom_truth_value (ffecom_expr (ffebld_right (expr))));
3475 return convert (tree_type, item);
3476
3477 case FFEINFO_basictypeINTEGER:
3478 return ffecom_2 (BIT_IOR_EXPR, tree_type,
3479 ffecom_expr (ffebld_left (expr)),
3480 ffecom_expr (ffebld_right (expr)));
3481
3482 default:
3483 assert ("OR bad basictype" == NULL);
3484 /* Fall through. */
3485 case FFEINFO_basictypeANY:
3486 return error_mark_node;
3487 }
3488 break;
3489
3490 case FFEBLD_opXOR:
3491 case FFEBLD_opNEQV:
5ff904cd
JL
3492 switch (bt)
3493 {
3494 case FFEINFO_basictypeLOGICAL:
3495 item
3496 = ffecom_2 (NE_EXPR, integer_type_node,
3497 ffecom_expr (ffebld_left (expr)),
3498 ffecom_expr (ffebld_right (expr)));
3499 return convert (tree_type, ffecom_truth_value (item));
3500
3501 case FFEINFO_basictypeINTEGER:
3502 return ffecom_2 (BIT_XOR_EXPR, tree_type,
3503 ffecom_expr (ffebld_left (expr)),
3504 ffecom_expr (ffebld_right (expr)));
3505
3506 default:
3507 assert ("XOR/NEQV bad basictype" == NULL);
3508 /* Fall through. */
3509 case FFEINFO_basictypeANY:
3510 return error_mark_node;
3511 }
3512 break;
3513
3514 case FFEBLD_opEQV:
5ff904cd
JL
3515 switch (bt)
3516 {
3517 case FFEINFO_basictypeLOGICAL:
3518 item
3519 = ffecom_2 (EQ_EXPR, integer_type_node,
3520 ffecom_expr (ffebld_left (expr)),
3521 ffecom_expr (ffebld_right (expr)));
3522 return convert (tree_type, ffecom_truth_value (item));
3523
3524 case FFEINFO_basictypeINTEGER:
3525 return
3526 ffecom_1 (BIT_NOT_EXPR, tree_type,
3527 ffecom_2 (BIT_XOR_EXPR, tree_type,
3528 ffecom_expr (ffebld_left (expr)),
3529 ffecom_expr (ffebld_right (expr))));
3530
3531 default:
3532 assert ("EQV bad basictype" == NULL);
3533 /* Fall through. */
3534 case FFEINFO_basictypeANY:
3535 return error_mark_node;
3536 }
3537 break;
3538
3539 case FFEBLD_opCONVERT:
3540 if (ffebld_op (ffebld_left (expr)) == FFEBLD_opANY)
3541 return error_mark_node;
3542
5ff904cd
JL
3543 switch (bt)
3544 {
3545 case FFEINFO_basictypeLOGICAL:
3546 case FFEINFO_basictypeINTEGER:
3547 case FFEINFO_basictypeREAL:
3548 return convert (tree_type, ffecom_expr (ffebld_left (expr)));
3549
3550 case FFEINFO_basictypeCOMPLEX:
3551 switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr))))
3552 {
3553 case FFEINFO_basictypeINTEGER:
3554 case FFEINFO_basictypeLOGICAL:
3555 case FFEINFO_basictypeREAL:
3556 item = ffecom_expr (ffebld_left (expr));
3557 if (item == error_mark_node)
3558 return error_mark_node;
3559 /* convert() takes care of converting to the subtype first,
3560 at least in gcc-2.7.2. */
3561 item = convert (tree_type, item);
3562 return item;
3563
3564 case FFEINFO_basictypeCOMPLEX:
3565 return convert (tree_type, ffecom_expr (ffebld_left (expr)));
3566
3567 default:
3568 assert ("CONVERT COMPLEX bad basictype" == NULL);
3569 /* Fall through. */
3570 case FFEINFO_basictypeANY:
3571 return error_mark_node;
3572 }
3573 break;
3574
3575 default:
3576 assert ("CONVERT bad basictype" == NULL);
3577 /* Fall through. */
3578 case FFEINFO_basictypeANY:
3579 return error_mark_node;
3580 }
3581 break;
3582
3583 case FFEBLD_opLT:
3584 code = LT_EXPR;
3585 goto relational; /* :::::::::::::::::::: */
3586
3587 case FFEBLD_opLE:
3588 code = LE_EXPR;
3589 goto relational; /* :::::::::::::::::::: */
3590
3591 case FFEBLD_opEQ:
3592 code = EQ_EXPR;
3593 goto relational; /* :::::::::::::::::::: */
3594
3595 case FFEBLD_opNE:
3596 code = NE_EXPR;
3597 goto relational; /* :::::::::::::::::::: */
3598
3599 case FFEBLD_opGT:
3600 code = GT_EXPR;
3601 goto relational; /* :::::::::::::::::::: */
3602
3603 case FFEBLD_opGE:
3604 code = GE_EXPR;
3605
3606 relational: /* :::::::::::::::::::: */
5ff904cd
JL
3607 switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr))))
3608 {
3609 case FFEINFO_basictypeLOGICAL:
3610 case FFEINFO_basictypeINTEGER:
3611 case FFEINFO_basictypeREAL:
3612 item = ffecom_2 (code, integer_type_node,
3613 ffecom_expr (ffebld_left (expr)),
3614 ffecom_expr (ffebld_right (expr)));
3615 return convert (tree_type, item);
3616
3617 case FFEINFO_basictypeCOMPLEX:
3618 assert (code == EQ_EXPR || code == NE_EXPR);
3619 {
3620 tree real_type;
3621 tree arg1 = ffecom_expr (ffebld_left (expr));
3622 tree arg2 = ffecom_expr (ffebld_right (expr));
3623
3624 if (arg1 == error_mark_node || arg2 == error_mark_node)
3625 return error_mark_node;
3626
3627 arg1 = ffecom_save_tree (arg1);
3628 arg2 = ffecom_save_tree (arg2);
3629
3630 if (TREE_CODE (TREE_TYPE (arg1)) == COMPLEX_TYPE)
3631 {
3632 real_type = TREE_TYPE (TREE_TYPE (arg1));
3633 assert (real_type == TREE_TYPE (TREE_TYPE (arg2)));
3634 }
3635 else
3636 {
3637 real_type = TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg1)));
3638 assert (real_type == TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg2))));
3639 }
3640
3641 item
3642 = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
3643 ffecom_2 (EQ_EXPR, integer_type_node,
3644 ffecom_1 (REALPART_EXPR, real_type, arg1),
3645 ffecom_1 (REALPART_EXPR, real_type, arg2)),
3646 ffecom_2 (EQ_EXPR, integer_type_node,
3647 ffecom_1 (IMAGPART_EXPR, real_type, arg1),
3648 ffecom_1 (IMAGPART_EXPR, real_type,
3649 arg2)));
3650 if (code == EQ_EXPR)
3651 item = ffecom_truth_value (item);
3652 else
3653 item = ffecom_truth_value_invert (item);
3654 return convert (tree_type, item);
3655 }
3656
3657 case FFEINFO_basictypeCHARACTER:
5ff904cd
JL
3658 {
3659 ffebld left = ffebld_left (expr);
3660 ffebld right = ffebld_right (expr);
3661 tree left_tree;
3662 tree right_tree;
3663 tree left_length;
3664 tree right_length;
3665
3666 /* f2c run-time functions do the implicit blank-padding for us,
3667 so we don't usually have to implement blank-padding ourselves.
3668 (The exception is when we pass an argument to a separately
3669 compiled statement function -- if we know the arg is not the
3670 same length as the dummy, we must truncate or extend it. If
3671 we "inline" statement functions, that necessity goes away as
3672 well.)
3673
3674 Strip off the CONVERT operators that blank-pad. (Truncation by
3675 CONVERT shouldn't happen here, but it can happen in
3676 assignments.) */
3677
3678 while (ffebld_op (left) == FFEBLD_opCONVERT)
3679 left = ffebld_left (left);
3680 while (ffebld_op (right) == FFEBLD_opCONVERT)
3681 right = ffebld_left (right);
3682
3683 left_tree = ffecom_arg_ptr_to_expr (left, &left_length);
3684 right_tree = ffecom_arg_ptr_to_expr (right, &right_length);
3685
3686 if (left_tree == error_mark_node || left_length == error_mark_node
3687 || right_tree == error_mark_node
3688 || right_length == error_mark_node)
c7e4ee3a 3689 return error_mark_node;
5ff904cd
JL
3690
3691 if ((ffebld_size_known (left) == 1)
3692 && (ffebld_size_known (right) == 1))
3693 {
3694 left_tree
3695 = ffecom_1 (INDIRECT_REF,
3696 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree))),
3697 left_tree);
3698 right_tree
3699 = ffecom_1 (INDIRECT_REF,
3700 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree))),
3701 right_tree);
3702
3703 item
3704 = ffecom_2 (code, integer_type_node,
3705 ffecom_2 (ARRAY_REF,
3706 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree))),
3707 left_tree,
3708 integer_one_node),
3709 ffecom_2 (ARRAY_REF,
3710 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree))),
3711 right_tree,
3712 integer_one_node));
3713 }
3714 else
3715 {
3716 item = build_tree_list (NULL_TREE, left_tree);
3717 TREE_CHAIN (item) = build_tree_list (NULL_TREE, right_tree);
3718 TREE_CHAIN (TREE_CHAIN (item)) = build_tree_list (NULL_TREE,
3719 left_length);
3720 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item)))
3721 = build_tree_list (NULL_TREE, right_length);
c7e4ee3a 3722 item = ffecom_call_gfrt (FFECOM_gfrtCMP, item, NULL_TREE);
5ff904cd
JL
3723 item = ffecom_2 (code, integer_type_node,
3724 item,
3725 convert (TREE_TYPE (item),
3726 integer_zero_node));
3727 }
3728 item = convert (tree_type, item);
3729 }
3730
5ff904cd
JL
3731 return item;
3732
3733 default:
3734 assert ("relational bad basictype" == NULL);
3735 /* Fall through. */
3736 case FFEINFO_basictypeANY:
3737 return error_mark_node;
3738 }
3739 break;
3740
3741 case FFEBLD_opPERCENT_LOC:
5ff904cd
JL
3742 item = ffecom_arg_ptr_to_expr (ffebld_left (expr), &list);
3743 return convert (tree_type, item);
3744
5e3f4df7
TM
3745 case FFEBLD_opPERCENT_VAL:
3746 item = ffecom_arg_expr (ffebld_left (expr), &list);
3747 return convert (tree_type, item);
3748
5ff904cd
JL
3749 case FFEBLD_opITEM:
3750 case FFEBLD_opSTAR:
3751 case FFEBLD_opBOUNDS:
3752 case FFEBLD_opREPEAT:
3753 case FFEBLD_opLABTER:
3754 case FFEBLD_opLABTOK:
3755 case FFEBLD_opIMPDO:
3756 case FFEBLD_opCONCATENATE:
3757 case FFEBLD_opSUBSTR:
3758 default:
3759 assert ("bad op" == NULL);
3760 /* Fall through. */
3761 case FFEBLD_opANY:
3762 return error_mark_node;
3763 }
3764
3765#if 1
3766 assert ("didn't think anything got here anymore!!" == NULL);
3767#else
3768 switch (ffebld_arity (expr))
3769 {
3770 case 2:
3771 TREE_OPERAND (item, 0) = ffecom_expr (ffebld_left (expr));
3772 TREE_OPERAND (item, 1) = ffecom_expr (ffebld_right (expr));
3773 if (TREE_OPERAND (item, 0) == error_mark_node
3774 || TREE_OPERAND (item, 1) == error_mark_node)
3775 return error_mark_node;
3776 break;
3777
3778 case 1:
3779 TREE_OPERAND (item, 0) = ffecom_expr (ffebld_left (expr));
3780 if (TREE_OPERAND (item, 0) == error_mark_node)
3781 return error_mark_node;
3782 break;
3783
3784 default:
3785 break;
3786 }
3787
3788 return fold (item);
3789#endif
3790}
3791
5ff904cd
JL
3792/* Returns the tree that does the intrinsic invocation.
3793
3794 Note: this function applies only to intrinsics returning
3795 CHARACTER*1 or non-CHARACTER results, and to intrinsic
3796 subroutines. */
3797
5ff904cd
JL
3798static tree
3799ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree,
3800 ffebld dest, bool *dest_used)
3801{
3802 tree expr_tree;
3803 tree saved_expr1; /* For those who need it. */
3804 tree saved_expr2; /* For those who need it. */
3805 ffeinfoBasictype bt;
3806 ffeinfoKindtype kt;
3807 tree tree_type;
3808 tree arg1_type;
3809 tree real_type; /* REAL type corresponding to COMPLEX. */
3810 tree tempvar;
3811 ffebld list = ffebld_right (expr); /* List of (some) args. */
3812 ffebld arg1; /* For handy reference. */
3813 ffebld arg2;
3814 ffebld arg3;
3815 ffeintrinImp codegen_imp;
3816 ffecomGfrt gfrt;
3817
3818 assert (ffebld_op (ffebld_left (expr)) == FFEBLD_opSYMTER);
3819
3820 if (dest_used != NULL)
3821 *dest_used = FALSE;
3822
3823 bt = ffeinfo_basictype (ffebld_info (expr));
3824 kt = ffeinfo_kindtype (ffebld_info (expr));
3825 tree_type = ffecom_tree_type[bt][kt];
3826
3827 if (list != NULL)
3828 {
3829 arg1 = ffebld_head (list);
3830 if (arg1 != NULL && ffebld_op (arg1) == FFEBLD_opANY)
3831 return error_mark_node;
3832 if ((list = ffebld_trail (list)) != NULL)
3833 {
3834 arg2 = ffebld_head (list);
3835 if (arg2 != NULL && ffebld_op (arg2) == FFEBLD_opANY)
3836 return error_mark_node;
3837 if ((list = ffebld_trail (list)) != NULL)
3838 {
3839 arg3 = ffebld_head (list);
3840 if (arg3 != NULL && ffebld_op (arg3) == FFEBLD_opANY)
3841 return error_mark_node;
3842 }
3843 else
3844 arg3 = NULL;
3845 }
3846 else
3847 arg2 = arg3 = NULL;
3848 }
3849 else
3850 arg1 = arg2 = arg3 = NULL;
3851
3852 /* <list> ends up at the opITEM of the 3rd arg, or NULL if there are < 3
3853 args. This is used by the MAX/MIN expansions. */
3854
3855 if (arg1 != NULL)
3856 arg1_type = ffecom_tree_type
3857 [ffeinfo_basictype (ffebld_info (arg1))]
3858 [ffeinfo_kindtype (ffebld_info (arg1))];
3859 else
3860 arg1_type = NULL_TREE; /* Really not needed, but might catch bugs
3861 here. */
3862
3863 /* There are several ways for each of the cases in the following switch
3864 statements to exit (from simplest to use to most complicated):
3865
3866 break; (when expr_tree == NULL)
3867
3868 A standard call is made to the specific intrinsic just as if it had been
3869 passed in as a dummy procedure and called as any old procedure. This
3870 method can produce slower code but in some cases it's the easiest way for
3871 now. However, if a (presumably faster) direct call is available,
3872 that is used, so this is the easiest way in many more cases now.
3873
3874 gfrt = FFECOM_gfrtWHATEVER;
3875 break;
3876
3877 gfrt contains the gfrt index of a library function to call, passing the
3878 argument(s) by value rather than by reference. Used when a more
3879 careful choice of library function is needed than that provided
3880 by the vanilla `break;'.
3881
3882 return expr_tree;
3883
3884 The expr_tree has been completely set up and is ready to be returned
3885 as is. No further actions are taken. Use this when the tree is not
3886 in the simple form for one of the arity_n labels. */
3887
3888 /* For info on how the switch statement cases were written, see the files
3889 enclosed in comments below the switch statement. */
3890
3891 codegen_imp = ffebld_symter_implementation (ffebld_left (expr));
3892 gfrt = ffeintrin_gfrt_direct (codegen_imp);
3893 if (gfrt == FFECOM_gfrt)
3894 gfrt = ffeintrin_gfrt_indirect (codegen_imp);
3895
3896 switch (codegen_imp)
3897 {
3898 case FFEINTRIN_impABS:
3899 case FFEINTRIN_impCABS:
3900 case FFEINTRIN_impCDABS:
3901 case FFEINTRIN_impDABS:
3902 case FFEINTRIN_impIABS:
3903 if (ffeinfo_basictype (ffebld_info (arg1))
3904 == FFEINFO_basictypeCOMPLEX)
3905 {
3906 if (kt == FFEINFO_kindtypeREAL1)
3907 gfrt = FFECOM_gfrtCABS;
3908 else if (kt == FFEINFO_kindtypeREAL2)
3909 gfrt = FFECOM_gfrtCDABS;
3910 break;
3911 }
3912 return ffecom_1 (ABS_EXPR, tree_type,
3913 convert (tree_type, ffecom_expr (arg1)));
3914
3915 case FFEINTRIN_impACOS:
3916 case FFEINTRIN_impDACOS:
3917 break;
3918
3919 case FFEINTRIN_impAIMAG:
3920 case FFEINTRIN_impDIMAG:
3921 case FFEINTRIN_impIMAGPART:
3922 if (TREE_CODE (arg1_type) == COMPLEX_TYPE)
3923 arg1_type = TREE_TYPE (arg1_type);
3924 else
3925 arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type));
3926
3927 return
3928 convert (tree_type,
3929 ffecom_1 (IMAGPART_EXPR, arg1_type,
3930 ffecom_expr (arg1)));
3931
3932 case FFEINTRIN_impAINT:
3933 case FFEINTRIN_impDINT:
c7e4ee3a
CB
3934#if 0
3935 /* ~~Someday implement FIX_TRUNC_EXPR yielding same type as arg. */
5ff904cd
JL
3936 return ffecom_1 (FIX_TRUNC_EXPR, tree_type, ffecom_expr (arg1));
3937#else /* in the meantime, must use floor to avoid range problems with ints */
3938 /* r__1 = r1 >= 0 ? floor(r1) : -floor(-r1); */
3939 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
3940 return
3941 convert (tree_type,
3942 ffecom_3 (COND_EXPR, double_type_node,
3943 ffecom_truth_value
3944 (ffecom_2 (GE_EXPR, integer_type_node,
3945 saved_expr1,
3946 convert (arg1_type,
3947 ffecom_float_zero_))),
3948 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
3949 build_tree_list (NULL_TREE,
3950 convert (double_type_node,
c7e4ee3a
CB
3951 saved_expr1)),
3952 NULL_TREE),
5ff904cd
JL
3953 ffecom_1 (NEGATE_EXPR, double_type_node,
3954 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
3955 build_tree_list (NULL_TREE,
3956 convert (double_type_node,
3957 ffecom_1 (NEGATE_EXPR,
3958 arg1_type,
c7e4ee3a
CB
3959 saved_expr1))),
3960 NULL_TREE)
5ff904cd
JL
3961 ))
3962 );
3963#endif
3964
3965 case FFEINTRIN_impANINT:
3966 case FFEINTRIN_impDNINT:
3967#if 0 /* This way of doing it won't handle real
3968 numbers of large magnitudes. */
3969 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
3970 expr_tree = convert (tree_type,
3971 convert (integer_type_node,
3972 ffecom_3 (COND_EXPR, tree_type,
3973 ffecom_truth_value
3974 (ffecom_2 (GE_EXPR,
3975 integer_type_node,
3976 saved_expr1,
3977 ffecom_float_zero_)),
3978 ffecom_2 (PLUS_EXPR,
3979 tree_type,
3980 saved_expr1,
3981 ffecom_float_half_),
3982 ffecom_2 (MINUS_EXPR,
3983 tree_type,
3984 saved_expr1,
3985 ffecom_float_half_))));
3986 return expr_tree;
3987#else /* So we instead call floor. */
3988 /* r__1 = r1 >= 0 ? floor(r1 + .5) : -floor(.5 - r1) */
3989 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
3990 return
3991 convert (tree_type,
3992 ffecom_3 (COND_EXPR, double_type_node,
3993 ffecom_truth_value
3994 (ffecom_2 (GE_EXPR, integer_type_node,
3995 saved_expr1,
3996 convert (arg1_type,
3997 ffecom_float_zero_))),
3998 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
3999 build_tree_list (NULL_TREE,
4000 convert (double_type_node,
4001 ffecom_2 (PLUS_EXPR,
4002 arg1_type,
4003 saved_expr1,
4004 convert (arg1_type,
c7e4ee3a
CB
4005 ffecom_float_half_)))),
4006 NULL_TREE),
5ff904cd
JL
4007 ffecom_1 (NEGATE_EXPR, double_type_node,
4008 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
4009 build_tree_list (NULL_TREE,
4010 convert (double_type_node,
4011 ffecom_2 (MINUS_EXPR,
4012 arg1_type,
4013 convert (arg1_type,
4014 ffecom_float_half_),
c7e4ee3a
CB
4015 saved_expr1))),
4016 NULL_TREE))
5ff904cd
JL
4017 )
4018 );
4019#endif
4020
4021 case FFEINTRIN_impASIN:
4022 case FFEINTRIN_impDASIN:
4023 case FFEINTRIN_impATAN:
4024 case FFEINTRIN_impDATAN:
4025 case FFEINTRIN_impATAN2:
4026 case FFEINTRIN_impDATAN2:
4027 break;
4028
4029 case FFEINTRIN_impCHAR:
4030 case FFEINTRIN_impACHAR:
c7e4ee3a
CB
4031#ifdef HOHO
4032 tempvar = ffecom_make_tempvar (char_type_node, 1, -1);
4033#else
4034 tempvar = ffebld_nonter_hook (expr);
4035 assert (tempvar);
4036#endif
5ff904cd
JL
4037 {
4038 tree tmv = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (tempvar)));
4039
4040 expr_tree = ffecom_modify (tmv,
4041 ffecom_2 (ARRAY_REF, tmv, tempvar,
4042 integer_one_node),
4043 convert (tmv, ffecom_expr (arg1)));
4044 }
4045 expr_tree = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar),
4046 expr_tree,
4047 tempvar);
4048 expr_tree = ffecom_1 (ADDR_EXPR,
4049 build_pointer_type (TREE_TYPE (expr_tree)),
4050 expr_tree);
4051 return expr_tree;
4052
4053 case FFEINTRIN_impCMPLX:
4054 case FFEINTRIN_impDCMPLX:
4055 if (arg2 == NULL)
4056 return
4057 convert (tree_type, ffecom_expr (arg1));
4058
4059 real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
4060 return
4061 ffecom_2 (COMPLEX_EXPR, tree_type,
4062 convert (real_type, ffecom_expr (arg1)),
4063 convert (real_type,
4064 ffecom_expr (arg2)));
4065
4066 case FFEINTRIN_impCOMPLEX:
4067 return
4068 ffecom_2 (COMPLEX_EXPR, tree_type,
4069 ffecom_expr (arg1),
4070 ffecom_expr (arg2));
4071
4072 case FFEINTRIN_impCONJG:
4073 case FFEINTRIN_impDCONJG:
4074 {
4075 tree arg1_tree;
4076
4077 real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
4078 arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4079 return
4080 ffecom_2 (COMPLEX_EXPR, tree_type,
4081 ffecom_1 (REALPART_EXPR, real_type, arg1_tree),
4082 ffecom_1 (NEGATE_EXPR, real_type,
4083 ffecom_1 (IMAGPART_EXPR, real_type, arg1_tree)));
4084 }
4085
4086 case FFEINTRIN_impCOS:
4087 case FFEINTRIN_impCCOS:
4088 case FFEINTRIN_impCDCOS:
4089 case FFEINTRIN_impDCOS:
4090 if (bt == FFEINFO_basictypeCOMPLEX)
4091 {
4092 if (kt == FFEINFO_kindtypeREAL1)
4093 gfrt = FFECOM_gfrtCCOS; /* Overlapping result okay. */
4094 else if (kt == FFEINFO_kindtypeREAL2)
4095 gfrt = FFECOM_gfrtCDCOS; /* Overlapping result okay. */
4096 }
4097 break;
4098
4099 case FFEINTRIN_impCOSH:
4100 case FFEINTRIN_impDCOSH:
4101 break;
4102
4103 case FFEINTRIN_impDBLE:
4104 case FFEINTRIN_impDFLOAT:
4105 case FFEINTRIN_impDREAL:
4106 case FFEINTRIN_impFLOAT:
4107 case FFEINTRIN_impIDINT:
4108 case FFEINTRIN_impIFIX:
4109 case FFEINTRIN_impINT2:
4110 case FFEINTRIN_impINT8:
4111 case FFEINTRIN_impINT:
4112 case FFEINTRIN_impLONG:
4113 case FFEINTRIN_impREAL:
4114 case FFEINTRIN_impSHORT:
4115 case FFEINTRIN_impSNGL:
4116 return convert (tree_type, ffecom_expr (arg1));
4117
4118 case FFEINTRIN_impDIM:
4119 case FFEINTRIN_impDDIM:
4120 case FFEINTRIN_impIDIM:
4121 saved_expr1 = ffecom_save_tree (convert (tree_type,
4122 ffecom_expr (arg1)));
4123 saved_expr2 = ffecom_save_tree (convert (tree_type,
4124 ffecom_expr (arg2)));
4125 return
4126 ffecom_3 (COND_EXPR, tree_type,
4127 ffecom_truth_value
4128 (ffecom_2 (GT_EXPR, integer_type_node,
4129 saved_expr1,
4130 saved_expr2)),
4131 ffecom_2 (MINUS_EXPR, tree_type,
4132 saved_expr1,
4133 saved_expr2),
4134 convert (tree_type, ffecom_float_zero_));
4135
4136 case FFEINTRIN_impDPROD:
4137 return
4138 ffecom_2 (MULT_EXPR, tree_type,
4139 convert (tree_type, ffecom_expr (arg1)),
4140 convert (tree_type, ffecom_expr (arg2)));
4141
4142 case FFEINTRIN_impEXP:
4143 case FFEINTRIN_impCDEXP:
4144 case FFEINTRIN_impCEXP:
4145 case FFEINTRIN_impDEXP:
4146 if (bt == FFEINFO_basictypeCOMPLEX)
4147 {
4148 if (kt == FFEINFO_kindtypeREAL1)
4149 gfrt = FFECOM_gfrtCEXP; /* Overlapping result okay. */
4150 else if (kt == FFEINFO_kindtypeREAL2)
4151 gfrt = FFECOM_gfrtCDEXP; /* Overlapping result okay. */
4152 }
4153 break;
4154
4155 case FFEINTRIN_impICHAR:
4156 case FFEINTRIN_impIACHAR:
4157#if 0 /* The simple approach. */
4158 ffecom_char_args_ (&expr_tree, &saved_expr1 /* Ignored */ , arg1);
4159 expr_tree
4160 = ffecom_1 (INDIRECT_REF,
4161 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
4162 expr_tree);
4163 expr_tree
4164 = ffecom_2 (ARRAY_REF,
4165 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
4166 expr_tree,
4167 integer_one_node);
4168 return convert (tree_type, expr_tree);
4169#else /* The more interesting (and more optimal) approach. */
4170 expr_tree = ffecom_intrinsic_ichar_ (tree_type, arg1, &saved_expr1);
4171 expr_tree = ffecom_3 (COND_EXPR, tree_type,
4172 saved_expr1,
4173 expr_tree,
4174 convert (tree_type, integer_zero_node));
4175 return expr_tree;
4176#endif
4177
4178 case FFEINTRIN_impINDEX:
4179 break;
4180
4181 case FFEINTRIN_impLEN:
4182#if 0
4183 break; /* The simple approach. */
4184#else
4185 return ffecom_intrinsic_len_ (arg1); /* The more optimal approach. */
4186#endif
4187
4188 case FFEINTRIN_impLGE:
4189 case FFEINTRIN_impLGT:
4190 case FFEINTRIN_impLLE:
4191 case FFEINTRIN_impLLT:
4192 break;
4193
4194 case FFEINTRIN_impLOG:
4195 case FFEINTRIN_impALOG:
4196 case FFEINTRIN_impCDLOG:
4197 case FFEINTRIN_impCLOG:
4198 case FFEINTRIN_impDLOG:
4199 if (bt == FFEINFO_basictypeCOMPLEX)
4200 {
4201 if (kt == FFEINFO_kindtypeREAL1)
4202 gfrt = FFECOM_gfrtCLOG; /* Overlapping result okay. */
4203 else if (kt == FFEINFO_kindtypeREAL2)
4204 gfrt = FFECOM_gfrtCDLOG; /* Overlapping result okay. */
4205 }
4206 break;
4207
4208 case FFEINTRIN_impLOG10:
4209 case FFEINTRIN_impALOG10:
4210 case FFEINTRIN_impDLOG10:
4211 if (gfrt != FFECOM_gfrt)
4212 break; /* Already picked one, stick with it. */
4213
4214 if (kt == FFEINFO_kindtypeREAL1)
95eb4fd9
TM
4215 /* We used to call FFECOM_gfrtALOG10 here. */
4216 gfrt = FFECOM_gfrtL_LOG10;
5ff904cd 4217 else if (kt == FFEINFO_kindtypeREAL2)
95eb4fd9
TM
4218 /* We used to call FFECOM_gfrtDLOG10 here. */
4219 gfrt = FFECOM_gfrtL_LOG10;
5ff904cd
JL
4220 break;
4221
4222 case FFEINTRIN_impMAX:
4223 case FFEINTRIN_impAMAX0:
4224 case FFEINTRIN_impAMAX1:
4225 case FFEINTRIN_impDMAX1:
4226 case FFEINTRIN_impMAX0:
4227 case FFEINTRIN_impMAX1:
4228 if (bt != ffeinfo_basictype (ffebld_info (arg1)))
4229 arg1_type = ffecom_widest_expr_type_ (ffebld_right (expr));
4230 else
4231 arg1_type = tree_type;
4232 expr_tree = ffecom_2 (MAX_EXPR, arg1_type,
4233 convert (arg1_type, ffecom_expr (arg1)),
4234 convert (arg1_type, ffecom_expr (arg2)));
4235 for (; list != NULL; list = ffebld_trail (list))
4236 {
4237 if ((ffebld_head (list) == NULL)
4238 || (ffebld_op (ffebld_head (list)) == FFEBLD_opANY))
4239 continue;
4240 expr_tree = ffecom_2 (MAX_EXPR, arg1_type,
4241 expr_tree,
4242 convert (arg1_type,
4243 ffecom_expr (ffebld_head (list))));
4244 }
4245 return convert (tree_type, expr_tree);
4246
4247 case FFEINTRIN_impMIN:
4248 case FFEINTRIN_impAMIN0:
4249 case FFEINTRIN_impAMIN1:
4250 case FFEINTRIN_impDMIN1:
4251 case FFEINTRIN_impMIN0:
4252 case FFEINTRIN_impMIN1:
4253 if (bt != ffeinfo_basictype (ffebld_info (arg1)))
4254 arg1_type = ffecom_widest_expr_type_ (ffebld_right (expr));
4255 else
4256 arg1_type = tree_type;
4257 expr_tree = ffecom_2 (MIN_EXPR, arg1_type,
4258 convert (arg1_type, ffecom_expr (arg1)),
4259 convert (arg1_type, ffecom_expr (arg2)));
4260 for (; list != NULL; list = ffebld_trail (list))
4261 {
4262 if ((ffebld_head (list) == NULL)
4263 || (ffebld_op (ffebld_head (list)) == FFEBLD_opANY))
4264 continue;
4265 expr_tree = ffecom_2 (MIN_EXPR, arg1_type,
4266 expr_tree,
4267 convert (arg1_type,
4268 ffecom_expr (ffebld_head (list))));
4269 }
4270 return convert (tree_type, expr_tree);
4271
4272 case FFEINTRIN_impMOD:
4273 case FFEINTRIN_impAMOD:
4274 case FFEINTRIN_impDMOD:
4275 if (bt != FFEINFO_basictypeREAL)
4276 return ffecom_2 (TRUNC_MOD_EXPR, tree_type,
4277 convert (tree_type, ffecom_expr (arg1)),
4278 convert (tree_type, ffecom_expr (arg2)));
4279
4280 if (kt == FFEINFO_kindtypeREAL1)
95eb4fd9
TM
4281 /* We used to call FFECOM_gfrtAMOD here. */
4282 gfrt = FFECOM_gfrtL_FMOD;
5ff904cd 4283 else if (kt == FFEINFO_kindtypeREAL2)
95eb4fd9
TM
4284 /* We used to call FFECOM_gfrtDMOD here. */
4285 gfrt = FFECOM_gfrtL_FMOD;
5ff904cd
JL
4286 break;
4287
4288 case FFEINTRIN_impNINT:
4289 case FFEINTRIN_impIDNINT:
c7e4ee3a
CB
4290#if 0
4291 /* ~~Ideally FIX_ROUND_EXPR would be implemented, but it ain't yet. */
5ff904cd
JL
4292 return ffecom_1 (FIX_ROUND_EXPR, tree_type, ffecom_expr (arg1));
4293#else
4294 /* i__1 = r1 >= 0 ? floor(r1 + .5) : -floor(.5 - r1); */
4295 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
4296 return
4297 convert (ffecom_integer_type_node,
4298 ffecom_3 (COND_EXPR, arg1_type,
4299 ffecom_truth_value
4300 (ffecom_2 (GE_EXPR, integer_type_node,
4301 saved_expr1,
4302 convert (arg1_type,
4303 ffecom_float_zero_))),
4304 ffecom_2 (PLUS_EXPR, arg1_type,
4305 saved_expr1,
4306 convert (arg1_type,
4307 ffecom_float_half_)),
4308 ffecom_2 (MINUS_EXPR, arg1_type,
4309 saved_expr1,
4310 convert (arg1_type,
4311 ffecom_float_half_))));
4312#endif
4313
4314 case FFEINTRIN_impSIGN:
4315 case FFEINTRIN_impDSIGN:
4316 case FFEINTRIN_impISIGN:
4317 {
4318 tree arg2_tree = ffecom_expr (arg2);
4319
4320 saved_expr1
4321 = ffecom_save_tree
4322 (ffecom_1 (ABS_EXPR, tree_type,
4323 convert (tree_type,
4324 ffecom_expr (arg1))));
4325 expr_tree
4326 = ffecom_3 (COND_EXPR, tree_type,
4327 ffecom_truth_value
4328 (ffecom_2 (GE_EXPR, integer_type_node,
4329 arg2_tree,
4330 convert (TREE_TYPE (arg2_tree),
4331 integer_zero_node))),
4332 saved_expr1,
4333 ffecom_1 (NEGATE_EXPR, tree_type, saved_expr1));
4334 /* Make sure SAVE_EXPRs get referenced early enough. */
4335 expr_tree
4336 = ffecom_2 (COMPOUND_EXPR, tree_type,
4337 convert (void_type_node, saved_expr1),
4338 expr_tree);
4339 }
4340 return expr_tree;
4341
4342 case FFEINTRIN_impSIN:
4343 case FFEINTRIN_impCDSIN:
4344 case FFEINTRIN_impCSIN:
4345 case FFEINTRIN_impDSIN:
4346 if (bt == FFEINFO_basictypeCOMPLEX)
4347 {
4348 if (kt == FFEINFO_kindtypeREAL1)
4349 gfrt = FFECOM_gfrtCSIN; /* Overlapping result okay. */
4350 else if (kt == FFEINFO_kindtypeREAL2)
4351 gfrt = FFECOM_gfrtCDSIN; /* Overlapping result okay. */
4352 }
4353 break;
4354
4355 case FFEINTRIN_impSINH:
4356 case FFEINTRIN_impDSINH:
4357 break;
4358
4359 case FFEINTRIN_impSQRT:
4360 case FFEINTRIN_impCDSQRT:
4361 case FFEINTRIN_impCSQRT:
4362 case FFEINTRIN_impDSQRT:
4363 if (bt == FFEINFO_basictypeCOMPLEX)
4364 {
4365 if (kt == FFEINFO_kindtypeREAL1)
4366 gfrt = FFECOM_gfrtCSQRT; /* Overlapping result okay. */
4367 else if (kt == FFEINFO_kindtypeREAL2)
4368 gfrt = FFECOM_gfrtCDSQRT; /* Overlapping result okay. */
4369 }
4370 break;
4371
4372 case FFEINTRIN_impTAN:
4373 case FFEINTRIN_impDTAN:
4374 case FFEINTRIN_impTANH:
4375 case FFEINTRIN_impDTANH:
4376 break;
4377
4378 case FFEINTRIN_impREALPART:
4379 if (TREE_CODE (arg1_type) == COMPLEX_TYPE)
4380 arg1_type = TREE_TYPE (arg1_type);
4381 else
4382 arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type));
4383
4384 return
4385 convert (tree_type,
4386 ffecom_1 (REALPART_EXPR, arg1_type,
4387 ffecom_expr (arg1)));
4388
4389 case FFEINTRIN_impIAND:
4390 case FFEINTRIN_impAND:
4391 return ffecom_2 (BIT_AND_EXPR, tree_type,
4392 convert (tree_type,
4393 ffecom_expr (arg1)),
4394 convert (tree_type,
4395 ffecom_expr (arg2)));
4396
4397 case FFEINTRIN_impIOR:
4398 case FFEINTRIN_impOR:
4399 return ffecom_2 (BIT_IOR_EXPR, tree_type,
4400 convert (tree_type,
4401 ffecom_expr (arg1)),
4402 convert (tree_type,
4403 ffecom_expr (arg2)));
4404
4405 case FFEINTRIN_impIEOR:
4406 case FFEINTRIN_impXOR:
4407 return ffecom_2 (BIT_XOR_EXPR, tree_type,
4408 convert (tree_type,
4409 ffecom_expr (arg1)),
4410 convert (tree_type,
4411 ffecom_expr (arg2)));
4412
4413 case FFEINTRIN_impLSHIFT:
4414 return ffecom_2 (LSHIFT_EXPR, tree_type,
4415 ffecom_expr (arg1),
4416 convert (integer_type_node,
4417 ffecom_expr (arg2)));
4418
4419 case FFEINTRIN_impRSHIFT:
4420 return ffecom_2 (RSHIFT_EXPR, tree_type,
4421 ffecom_expr (arg1),
4422 convert (integer_type_node,
4423 ffecom_expr (arg2)));
4424
4425 case FFEINTRIN_impNOT:
4426 return ffecom_1 (BIT_NOT_EXPR, tree_type, ffecom_expr (arg1));
4427
4428 case FFEINTRIN_impBIT_SIZE:
4429 return convert (tree_type, TYPE_SIZE (arg1_type));
4430
4431 case FFEINTRIN_impBTEST:
4432 {
d6edb99e
ZW
4433 ffetargetLogical1 target_true;
4434 ffetargetLogical1 target_false;
5ff904cd
JL
4435 tree true_tree;
4436 tree false_tree;
4437
d6edb99e
ZW
4438 ffetarget_logical1 (&target_true, TRUE);
4439 ffetarget_logical1 (&target_false, FALSE);
4440 if (target_true == 1)
5ff904cd
JL
4441 true_tree = convert (tree_type, integer_one_node);
4442 else
d6edb99e
ZW
4443 true_tree = convert (tree_type, build_int_2 (target_true, 0));
4444 if (target_false == 0)
5ff904cd
JL
4445 false_tree = convert (tree_type, integer_zero_node);
4446 else
d6edb99e 4447 false_tree = convert (tree_type, build_int_2 (target_false, 0));
5ff904cd
JL
4448
4449 return
4450 ffecom_3 (COND_EXPR, tree_type,
4451 ffecom_truth_value
4452 (ffecom_2 (EQ_EXPR, integer_type_node,
4453 ffecom_2 (BIT_AND_EXPR, arg1_type,
4454 ffecom_expr (arg1),
4455 ffecom_2 (LSHIFT_EXPR, arg1_type,
4456 convert (arg1_type,
4457 integer_one_node),
4458 convert (integer_type_node,
4459 ffecom_expr (arg2)))),
4460 convert (arg1_type,
4461 integer_zero_node))),
4462 false_tree,
4463 true_tree);
4464 }
4465
4466 case FFEINTRIN_impIBCLR:
4467 return
4468 ffecom_2 (BIT_AND_EXPR, tree_type,
4469 ffecom_expr (arg1),
4470 ffecom_1 (BIT_NOT_EXPR, tree_type,
4471 ffecom_2 (LSHIFT_EXPR, tree_type,
4472 convert (tree_type,
4473 integer_one_node),
4474 convert (integer_type_node,
4475 ffecom_expr (arg2)))));
4476
4477 case FFEINTRIN_impIBITS:
4478 {
4479 tree arg3_tree = ffecom_save_tree (convert (integer_type_node,
4480 ffecom_expr (arg3)));
4481 tree uns_type
4482 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4483
4484 expr_tree
4485 = ffecom_2 (BIT_AND_EXPR, tree_type,
4486 ffecom_2 (RSHIFT_EXPR, tree_type,
4487 ffecom_expr (arg1),
4488 convert (integer_type_node,
4489 ffecom_expr (arg2))),
4490 convert (tree_type,
4491 ffecom_2 (RSHIFT_EXPR, uns_type,
4492 ffecom_1 (BIT_NOT_EXPR,
4493 uns_type,
4494 convert (uns_type,
4495 integer_zero_node)),
4496 ffecom_2 (MINUS_EXPR,
4497 integer_type_node,
4498 TYPE_SIZE (uns_type),
4499 arg3_tree))));
eec9ac3d 4500 /* Fix up, because the RSHIFT_EXPR above can't shift over TYPE_SIZE. */
5ff904cd
JL
4501 expr_tree
4502 = ffecom_3 (COND_EXPR, tree_type,
4503 ffecom_truth_value
4504 (ffecom_2 (NE_EXPR, integer_type_node,
4505 arg3_tree,
4506 integer_zero_node)),
4507 expr_tree,
4508 convert (tree_type, integer_zero_node));
5ff904cd
JL
4509 }
4510 return expr_tree;
4511
4512 case FFEINTRIN_impIBSET:
4513 return
4514 ffecom_2 (BIT_IOR_EXPR, tree_type,
4515 ffecom_expr (arg1),
4516 ffecom_2 (LSHIFT_EXPR, tree_type,
4517 convert (tree_type, integer_one_node),
4518 convert (integer_type_node,
4519 ffecom_expr (arg2))));
4520
4521 case FFEINTRIN_impISHFT:
4522 {
4523 tree arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4524 tree arg2_tree = ffecom_save_tree (convert (integer_type_node,
4525 ffecom_expr (arg2)));
4526 tree uns_type
4527 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4528
4529 expr_tree
4530 = ffecom_3 (COND_EXPR, tree_type,
4531 ffecom_truth_value
4532 (ffecom_2 (GE_EXPR, integer_type_node,
4533 arg2_tree,
4534 integer_zero_node)),
4535 ffecom_2 (LSHIFT_EXPR, tree_type,
4536 arg1_tree,
4537 arg2_tree),
4538 convert (tree_type,
4539 ffecom_2 (RSHIFT_EXPR, uns_type,
4540 convert (uns_type, arg1_tree),
4541 ffecom_1 (NEGATE_EXPR,
4542 integer_type_node,
4543 arg2_tree))));
eec9ac3d 4544 /* Fix up, because {L|R}SHIFT_EXPR don't go over TYPE_SIZE bounds. */
5ff904cd
JL
4545 expr_tree
4546 = ffecom_3 (COND_EXPR, tree_type,
4547 ffecom_truth_value
eec9ac3d 4548 (ffecom_2 (NE_EXPR, integer_type_node,
7d46d516
TM
4549 ffecom_1 (ABS_EXPR,
4550 integer_type_node,
4551 arg2_tree),
5ff904cd
JL
4552 TYPE_SIZE (uns_type))),
4553 expr_tree,
4554 convert (tree_type, integer_zero_node));
5ff904cd
JL
4555 /* Make sure SAVE_EXPRs get referenced early enough. */
4556 expr_tree
4557 = ffecom_2 (COMPOUND_EXPR, tree_type,
4558 convert (void_type_node, arg1_tree),
4559 ffecom_2 (COMPOUND_EXPR, tree_type,
4560 convert (void_type_node, arg2_tree),
4561 expr_tree));
4562 }
4563 return expr_tree;
4564
4565 case FFEINTRIN_impISHFTC:
4566 {
4567 tree arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4568 tree arg2_tree = ffecom_save_tree (convert (integer_type_node,
4569 ffecom_expr (arg2)));
4570 tree arg3_tree = (arg3 == NULL) ? TYPE_SIZE (tree_type)
4571 : ffecom_save_tree (convert (integer_type_node, ffecom_expr (arg3)));
4572 tree shift_neg;
4573 tree shift_pos;
4574 tree mask_arg1;
4575 tree masked_arg1;
4576 tree uns_type
4577 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4578
4579 mask_arg1
4580 = ffecom_2 (LSHIFT_EXPR, tree_type,
4581 ffecom_1 (BIT_NOT_EXPR, tree_type,
4582 convert (tree_type, integer_zero_node)),
4583 arg3_tree);
eec9ac3d 4584 /* Fix up, because LSHIFT_EXPR above can't shift over TYPE_SIZE. */
5ff904cd
JL
4585 mask_arg1
4586 = ffecom_3 (COND_EXPR, tree_type,
4587 ffecom_truth_value
4588 (ffecom_2 (NE_EXPR, integer_type_node,
4589 arg3_tree,
4590 TYPE_SIZE (uns_type))),
4591 mask_arg1,
4592 convert (tree_type, integer_zero_node));
5ff904cd
JL
4593 mask_arg1 = ffecom_save_tree (mask_arg1);
4594 masked_arg1
4595 = ffecom_2 (BIT_AND_EXPR, tree_type,
4596 arg1_tree,
4597 ffecom_1 (BIT_NOT_EXPR, tree_type,
4598 mask_arg1));
4599 masked_arg1 = ffecom_save_tree (masked_arg1);
4600 shift_neg
4601 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4602 convert (tree_type,
4603 ffecom_2 (RSHIFT_EXPR, uns_type,
4604 convert (uns_type, masked_arg1),
4605 ffecom_1 (NEGATE_EXPR,
4606 integer_type_node,
4607 arg2_tree))),
4608 ffecom_2 (LSHIFT_EXPR, tree_type,
4609 arg1_tree,
4610 ffecom_2 (PLUS_EXPR, integer_type_node,
4611 arg2_tree,
4612 arg3_tree)));
4613 shift_pos
4614 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4615 ffecom_2 (LSHIFT_EXPR, tree_type,
4616 arg1_tree,
4617 arg2_tree),
4618 convert (tree_type,
4619 ffecom_2 (RSHIFT_EXPR, uns_type,
4620 convert (uns_type, masked_arg1),
4621 ffecom_2 (MINUS_EXPR,
4622 integer_type_node,
4623 arg3_tree,
4624 arg2_tree))));
4625 expr_tree
4626 = ffecom_3 (COND_EXPR, tree_type,
4627 ffecom_truth_value
4628 (ffecom_2 (LT_EXPR, integer_type_node,
4629 arg2_tree,
4630 integer_zero_node)),
4631 shift_neg,
4632 shift_pos);
4633 expr_tree
4634 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4635 ffecom_2 (BIT_AND_EXPR, tree_type,
4636 mask_arg1,
4637 arg1_tree),
4638 ffecom_2 (BIT_AND_EXPR, tree_type,
4639 ffecom_1 (BIT_NOT_EXPR, tree_type,
4640 mask_arg1),
4641 expr_tree));
4642 expr_tree
4643 = ffecom_3 (COND_EXPR, tree_type,
4644 ffecom_truth_value
4645 (ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
4646 ffecom_2 (EQ_EXPR, integer_type_node,
4647 ffecom_1 (ABS_EXPR,
4648 integer_type_node,
4649 arg2_tree),
4650 arg3_tree),
4651 ffecom_2 (EQ_EXPR, integer_type_node,
4652 arg2_tree,
4653 integer_zero_node))),
4654 arg1_tree,
4655 expr_tree);
4656 /* Make sure SAVE_EXPRs get referenced early enough. */
4657 expr_tree
4658 = ffecom_2 (COMPOUND_EXPR, tree_type,
4659 convert (void_type_node, arg1_tree),
4660 ffecom_2 (COMPOUND_EXPR, tree_type,
4661 convert (void_type_node, arg2_tree),
4662 ffecom_2 (COMPOUND_EXPR, tree_type,
4663 convert (void_type_node,
4664 mask_arg1),
4665 ffecom_2 (COMPOUND_EXPR, tree_type,
4666 convert (void_type_node,
4667 masked_arg1),
4668 expr_tree))));
4669 expr_tree
4670 = ffecom_2 (COMPOUND_EXPR, tree_type,
4671 convert (void_type_node,
4672 arg3_tree),
4673 expr_tree);
4674 }
4675 return expr_tree;
4676
4677 case FFEINTRIN_impLOC:
4678 {
4679 tree arg1_tree = ffecom_expr (arg1);
4680
4681 expr_tree
4682 = convert (tree_type,
4683 ffecom_1 (ADDR_EXPR,
4684 build_pointer_type (TREE_TYPE (arg1_tree)),
4685 arg1_tree));
4686 }
4687 return expr_tree;
4688
4689 case FFEINTRIN_impMVBITS:
4690 {
4691 tree arg1_tree;
4692 tree arg2_tree;
4693 tree arg3_tree;
4694 ffebld arg4 = ffebld_head (ffebld_trail (list));
4695 tree arg4_tree;
4696 tree arg4_type;
4697 ffebld arg5 = ffebld_head (ffebld_trail (ffebld_trail (list)));
4698 tree arg5_tree;
4699 tree prep_arg1;
4700 tree prep_arg4;
4701 tree arg5_plus_arg3;
4702
5ff904cd
JL
4703 arg2_tree = convert (integer_type_node,
4704 ffecom_expr (arg2));
4705 arg3_tree = ffecom_save_tree (convert (integer_type_node,
4706 ffecom_expr (arg3)));
c7e4ee3a 4707 arg4_tree = ffecom_expr_rw (NULL_TREE, arg4);
5ff904cd
JL
4708 arg4_type = TREE_TYPE (arg4_tree);
4709
4710 arg1_tree = ffecom_save_tree (convert (arg4_type,
4711 ffecom_expr (arg1)));
4712
4713 arg5_tree = ffecom_save_tree (convert (integer_type_node,
4714 ffecom_expr (arg5)));
4715
5ff904cd
JL
4716 prep_arg1
4717 = ffecom_2 (LSHIFT_EXPR, arg4_type,
4718 ffecom_2 (BIT_AND_EXPR, arg4_type,
4719 ffecom_2 (RSHIFT_EXPR, arg4_type,
4720 arg1_tree,
4721 arg2_tree),
4722 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4723 ffecom_2 (LSHIFT_EXPR, arg4_type,
4724 ffecom_1 (BIT_NOT_EXPR,
4725 arg4_type,
4726 convert
4727 (arg4_type,
4728 integer_zero_node)),
4729 arg3_tree))),
4730 arg5_tree);
4731 arg5_plus_arg3
4732 = ffecom_save_tree (ffecom_2 (PLUS_EXPR, arg4_type,
4733 arg5_tree,
4734 arg3_tree));
4735 prep_arg4
4736 = ffecom_2 (LSHIFT_EXPR, arg4_type,
4737 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4738 convert (arg4_type,
4739 integer_zero_node)),
4740 arg5_plus_arg3);
eec9ac3d 4741 /* Fix up, because LSHIFT_EXPR above can't shift over TYPE_SIZE. */
5ff904cd
JL
4742 prep_arg4
4743 = ffecom_3 (COND_EXPR, arg4_type,
4744 ffecom_truth_value
4745 (ffecom_2 (NE_EXPR, integer_type_node,
4746 arg5_plus_arg3,
4747 convert (TREE_TYPE (arg5_plus_arg3),
4748 TYPE_SIZE (arg4_type)))),
4749 prep_arg4,
4750 convert (arg4_type, integer_zero_node));
5ff904cd
JL
4751 prep_arg4
4752 = ffecom_2 (BIT_AND_EXPR, arg4_type,
4753 arg4_tree,
4754 ffecom_2 (BIT_IOR_EXPR, arg4_type,
4755 prep_arg4,
4756 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4757 ffecom_2 (LSHIFT_EXPR, arg4_type,
4758 ffecom_1 (BIT_NOT_EXPR,
4759 arg4_type,
4760 convert
4761 (arg4_type,
4762 integer_zero_node)),
4763 arg5_tree))));
4764 prep_arg1
4765 = ffecom_2 (BIT_IOR_EXPR, arg4_type,
4766 prep_arg1,
4767 prep_arg4);
eec9ac3d
TM
4768 /* Fix up (twice), because LSHIFT_EXPR above
4769 can't shift over TYPE_SIZE. */
5ff904cd
JL
4770 prep_arg1
4771 = ffecom_3 (COND_EXPR, arg4_type,
4772 ffecom_truth_value
4773 (ffecom_2 (NE_EXPR, integer_type_node,
4774 arg3_tree,
4775 convert (TREE_TYPE (arg3_tree),
4776 integer_zero_node))),
4777 prep_arg1,
4778 arg4_tree);
4779 prep_arg1
4780 = ffecom_3 (COND_EXPR, arg4_type,
4781 ffecom_truth_value
4782 (ffecom_2 (NE_EXPR, integer_type_node,
4783 arg3_tree,
4784 convert (TREE_TYPE (arg3_tree),
4785 TYPE_SIZE (arg4_type)))),
4786 prep_arg1,
4787 arg1_tree);
5ff904cd
JL
4788 expr_tree
4789 = ffecom_2s (MODIFY_EXPR, void_type_node,
4790 arg4_tree,
4791 prep_arg1);
4792 /* Make sure SAVE_EXPRs get referenced early enough. */
4793 expr_tree
4794 = ffecom_2 (COMPOUND_EXPR, void_type_node,
4795 arg1_tree,
4796 ffecom_2 (COMPOUND_EXPR, void_type_node,
4797 arg3_tree,
4798 ffecom_2 (COMPOUND_EXPR, void_type_node,
4799 arg5_tree,
4800 ffecom_2 (COMPOUND_EXPR, void_type_node,
4801 arg5_plus_arg3,
4802 expr_tree))));
4803 expr_tree
4804 = ffecom_2 (COMPOUND_EXPR, void_type_node,
4805 arg4_tree,
4806 expr_tree);
4807
4808 }
4809 return expr_tree;
4810
4811 case FFEINTRIN_impDERF:
4812 case FFEINTRIN_impERF:
4813 case FFEINTRIN_impDERFC:
4814 case FFEINTRIN_impERFC:
4815 break;
4816
4817 case FFEINTRIN_impIARGC:
4818 /* extern int xargc; i__1 = xargc - 1; */
4819 expr_tree = ffecom_2 (MINUS_EXPR, TREE_TYPE (ffecom_tree_xargc_),
4820 ffecom_tree_xargc_,
4821 convert (TREE_TYPE (ffecom_tree_xargc_),
4822 integer_one_node));
4823 return expr_tree;
4824
4825 case FFEINTRIN_impSIGNAL_func:
4826 case FFEINTRIN_impSIGNAL_subr:
4827 {
4828 tree arg1_tree;
4829 tree arg2_tree;
4830 tree arg3_tree;
4831
5ff904cd
JL
4832 arg1_tree = convert (ffecom_f2c_integer_type_node,
4833 ffecom_expr (arg1));
4834 arg1_tree = ffecom_1 (ADDR_EXPR,
4835 build_pointer_type (TREE_TYPE (arg1_tree)),
4836 arg1_tree);
4837
4838 /* Pass procedure as a pointer to it, anything else by value. */
4839 if (ffeinfo_kind (ffebld_info (arg2)) == FFEINFO_kindENTITY)
4840 arg2_tree = convert (integer_type_node, ffecom_expr (arg2));
4841 else
4842 arg2_tree = ffecom_ptr_to_expr (arg2);
4843 arg2_tree = convert (TREE_TYPE (null_pointer_node),
4844 arg2_tree);
4845
4846 if (arg3 != NULL)
c7e4ee3a 4847 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
4848 else
4849 arg3_tree = NULL_TREE;
4850
5ff904cd
JL
4851 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4852 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
4853 TREE_CHAIN (arg1_tree) = arg2_tree;
4854
4855 expr_tree
4856 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4857 ffecom_gfrt_kindtype (gfrt),
4858 FALSE,
4859 ((codegen_imp == FFEINTRIN_impSIGNAL_subr) ?
4860 NULL_TREE :
4861 tree_type),
4862 arg1_tree,
c7e4ee3a
CB
4863 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4864 ffebld_nonter_hook (expr));
5ff904cd
JL
4865
4866 if (arg3_tree != NULL_TREE)
4867 expr_tree
4868 = ffecom_modify (NULL_TREE, arg3_tree,
4869 convert (TREE_TYPE (arg3_tree),
4870 expr_tree));
4871 }
4872 return expr_tree;
4873
4874 case FFEINTRIN_impALARM:
4875 {
4876 tree arg1_tree;
4877 tree arg2_tree;
4878 tree arg3_tree;
4879
5ff904cd
JL
4880 arg1_tree = convert (ffecom_f2c_integer_type_node,
4881 ffecom_expr (arg1));
4882 arg1_tree = ffecom_1 (ADDR_EXPR,
4883 build_pointer_type (TREE_TYPE (arg1_tree)),
4884 arg1_tree);
4885
4886 /* Pass procedure as a pointer to it, anything else by value. */
4887 if (ffeinfo_kind (ffebld_info (arg2)) == FFEINFO_kindENTITY)
4888 arg2_tree = convert (integer_type_node, ffecom_expr (arg2));
4889 else
4890 arg2_tree = ffecom_ptr_to_expr (arg2);
4891 arg2_tree = convert (TREE_TYPE (null_pointer_node),
4892 arg2_tree);
4893
4894 if (arg3 != NULL)
c7e4ee3a 4895 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
4896 else
4897 arg3_tree = NULL_TREE;
4898
5ff904cd
JL
4899 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4900 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
4901 TREE_CHAIN (arg1_tree) = arg2_tree;
4902
4903 expr_tree
4904 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4905 ffecom_gfrt_kindtype (gfrt),
4906 FALSE,
4907 NULL_TREE,
4908 arg1_tree,
c7e4ee3a
CB
4909 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4910 ffebld_nonter_hook (expr));
5ff904cd
JL
4911
4912 if (arg3_tree != NULL_TREE)
4913 expr_tree
4914 = ffecom_modify (NULL_TREE, arg3_tree,
4915 convert (TREE_TYPE (arg3_tree),
4916 expr_tree));
4917 }
4918 return expr_tree;
4919
4920 case FFEINTRIN_impCHDIR_subr:
4921 case FFEINTRIN_impFDATE_subr:
4922 case FFEINTRIN_impFGET_subr:
4923 case FFEINTRIN_impFPUT_subr:
4924 case FFEINTRIN_impGETCWD_subr:
4925 case FFEINTRIN_impHOSTNM_subr:
4926 case FFEINTRIN_impSYSTEM_subr:
4927 case FFEINTRIN_impUNLINK_subr:
4928 {
4929 tree arg1_len = integer_zero_node;
4930 tree arg1_tree;
4931 tree arg2_tree;
4932
5ff904cd
JL
4933 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
4934
4935 if (arg2 != NULL)
c7e4ee3a 4936 arg2_tree = ffecom_expr_w (NULL_TREE, arg2);
5ff904cd
JL
4937 else
4938 arg2_tree = NULL_TREE;
4939
5ff904cd
JL
4940 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4941 arg1_len = build_tree_list (NULL_TREE, arg1_len);
4942 TREE_CHAIN (arg1_tree) = arg1_len;
4943
4944 expr_tree
4945 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4946 ffecom_gfrt_kindtype (gfrt),
4947 FALSE,
4948 NULL_TREE,
4949 arg1_tree,
c7e4ee3a
CB
4950 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4951 ffebld_nonter_hook (expr));
5ff904cd
JL
4952
4953 if (arg2_tree != NULL_TREE)
4954 expr_tree
4955 = ffecom_modify (NULL_TREE, arg2_tree,
4956 convert (TREE_TYPE (arg2_tree),
4957 expr_tree));
4958 }
4959 return expr_tree;
4960
4961 case FFEINTRIN_impEXIT:
4962 if (arg1 != NULL)
4963 break;
4964
4965 expr_tree = build_tree_list (NULL_TREE,
4966 ffecom_1 (ADDR_EXPR,
4967 build_pointer_type
4968 (ffecom_integer_type_node),
4969 integer_zero_node));
4970
4971 return
4972 ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4973 ffecom_gfrt_kindtype (gfrt),
4974 FALSE,
4975 void_type_node,
4976 expr_tree,
c7e4ee3a
CB
4977 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4978 ffebld_nonter_hook (expr));
5ff904cd
JL
4979
4980 case FFEINTRIN_impFLUSH:
4981 if (arg1 == NULL)
4982 gfrt = FFECOM_gfrtFLUSH;
4983 else
4984 gfrt = FFECOM_gfrtFLUSH1;
4985 break;
4986
4987 case FFEINTRIN_impCHMOD_subr:
4988 case FFEINTRIN_impLINK_subr:
4989 case FFEINTRIN_impRENAME_subr:
4990 case FFEINTRIN_impSYMLNK_subr:
4991 {
4992 tree arg1_len = integer_zero_node;
4993 tree arg1_tree;
4994 tree arg2_len = integer_zero_node;
4995 tree arg2_tree;
4996 tree arg3_tree;
4997
5ff904cd
JL
4998 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
4999 arg2_tree = ffecom_arg_ptr_to_expr (arg2, &arg2_len);
5000 if (arg3 != NULL)
c7e4ee3a 5001 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
5002 else
5003 arg3_tree = NULL_TREE;
5004
5ff904cd
JL
5005 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5006 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5007 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5008 arg2_len = build_tree_list (NULL_TREE, arg2_len);
5009 TREE_CHAIN (arg1_tree) = arg2_tree;
5010 TREE_CHAIN (arg2_tree) = arg1_len;
5011 TREE_CHAIN (arg1_len) = arg2_len;
5012 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5013 ffecom_gfrt_kindtype (gfrt),
5014 FALSE,
5015 NULL_TREE,
5016 arg1_tree,
c7e4ee3a
CB
5017 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5018 ffebld_nonter_hook (expr));
5ff904cd
JL
5019 if (arg3_tree != NULL_TREE)
5020 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5021 convert (TREE_TYPE (arg3_tree),
5022 expr_tree));
5023 }
5024 return expr_tree;
5025
5026 case FFEINTRIN_impLSTAT_subr:
5027 case FFEINTRIN_impSTAT_subr:
5028 {
5029 tree arg1_len = integer_zero_node;
5030 tree arg1_tree;
5031 tree arg2_tree;
5032 tree arg3_tree;
5033
5ff904cd
JL
5034 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
5035
5036 arg2_tree = ffecom_ptr_to_expr (arg2);
5037
5038 if (arg3 != NULL)
c7e4ee3a 5039 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
5040 else
5041 arg3_tree = NULL_TREE;
5042
5ff904cd
JL
5043 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5044 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5045 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5046 TREE_CHAIN (arg1_tree) = arg2_tree;
5047 TREE_CHAIN (arg2_tree) = arg1_len;
5048 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5049 ffecom_gfrt_kindtype (gfrt),
5050 FALSE,
5051 NULL_TREE,
5052 arg1_tree,
c7e4ee3a
CB
5053 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5054 ffebld_nonter_hook (expr));
5ff904cd
JL
5055 if (arg3_tree != NULL_TREE)
5056 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5057 convert (TREE_TYPE (arg3_tree),
5058 expr_tree));
5059 }
5060 return expr_tree;
5061
5062 case FFEINTRIN_impFGETC_subr:
5063 case FFEINTRIN_impFPUTC_subr:
5064 {
5065 tree arg1_tree;
5066 tree arg2_tree;
5067 tree arg2_len = integer_zero_node;
5068 tree arg3_tree;
5069
5ff904cd
JL
5070 arg1_tree = convert (ffecom_f2c_integer_type_node,
5071 ffecom_expr (arg1));
5072 arg1_tree = ffecom_1 (ADDR_EXPR,
5073 build_pointer_type (TREE_TYPE (arg1_tree)),
5074 arg1_tree);
5075
5076 arg2_tree = ffecom_arg_ptr_to_expr (arg2, &arg2_len);
62b3b9db
TM
5077 if (arg3 != NULL)
5078 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5079 else
5080 arg3_tree = NULL_TREE;
5ff904cd
JL
5081
5082 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5083 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5084 arg2_len = build_tree_list (NULL_TREE, arg2_len);
5085 TREE_CHAIN (arg1_tree) = arg2_tree;
5086 TREE_CHAIN (arg2_tree) = arg2_len;
5087
5088 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5089 ffecom_gfrt_kindtype (gfrt),
5090 FALSE,
5091 NULL_TREE,
5092 arg1_tree,
c7e4ee3a
CB
5093 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5094 ffebld_nonter_hook (expr));
62b3b9db
TM
5095 if (arg3_tree != NULL_TREE)
5096 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5097 convert (TREE_TYPE (arg3_tree),
5098 expr_tree));
5ff904cd
JL
5099 }
5100 return expr_tree;
5101
5102 case FFEINTRIN_impFSTAT_subr:
5103 {
5104 tree arg1_tree;
5105 tree arg2_tree;
5106 tree arg3_tree;
5107
5ff904cd
JL
5108 arg1_tree = convert (ffecom_f2c_integer_type_node,
5109 ffecom_expr (arg1));
5110 arg1_tree = ffecom_1 (ADDR_EXPR,
5111 build_pointer_type (TREE_TYPE (arg1_tree)),
5112 arg1_tree);
5113
5114 arg2_tree = convert (ffecom_f2c_ptr_to_integer_type_node,
5115 ffecom_ptr_to_expr (arg2));
5116
5117 if (arg3 == NULL)
5118 arg3_tree = NULL_TREE;
5119 else
c7e4ee3a 5120 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
5121
5122 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5123 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5124 TREE_CHAIN (arg1_tree) = arg2_tree;
5125 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5126 ffecom_gfrt_kindtype (gfrt),
5127 FALSE,
5128 NULL_TREE,
5129 arg1_tree,
c7e4ee3a
CB
5130 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5131 ffebld_nonter_hook (expr));
5ff904cd
JL
5132 if (arg3_tree != NULL_TREE) {
5133 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5134 convert (TREE_TYPE (arg3_tree),
5135 expr_tree));
5136 }
5137 }
5138 return expr_tree;
5139
5140 case FFEINTRIN_impKILL_subr:
5141 {
5142 tree arg1_tree;
5143 tree arg2_tree;
5144 tree arg3_tree;
5145
5ff904cd
JL
5146 arg1_tree = convert (ffecom_f2c_integer_type_node,
5147 ffecom_expr (arg1));
5148 arg1_tree = ffecom_1 (ADDR_EXPR,
5149 build_pointer_type (TREE_TYPE (arg1_tree)),
5150 arg1_tree);
5151
5152 arg2_tree = convert (ffecom_f2c_integer_type_node,
5153 ffecom_expr (arg2));
5154 arg2_tree = ffecom_1 (ADDR_EXPR,
5155 build_pointer_type (TREE_TYPE (arg2_tree)),
5156 arg2_tree);
5157
5158 if (arg3 == NULL)
5159 arg3_tree = NULL_TREE;
5160 else
c7e4ee3a 5161 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
5162
5163 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5164 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5165 TREE_CHAIN (arg1_tree) = arg2_tree;
5166 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5167 ffecom_gfrt_kindtype (gfrt),
5168 FALSE,
5169 NULL_TREE,
5170 arg1_tree,
c7e4ee3a
CB
5171 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5172 ffebld_nonter_hook (expr));
5ff904cd
JL
5173 if (arg3_tree != NULL_TREE) {
5174 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5175 convert (TREE_TYPE (arg3_tree),
5176 expr_tree));
5177 }
5178 }
5179 return expr_tree;
5180
5181 case FFEINTRIN_impCTIME_subr:
5182 case FFEINTRIN_impTTYNAM_subr:
5183 {
5184 tree arg1_len = integer_zero_node;
5185 tree arg1_tree;
5186 tree arg2_tree;
5187
2b0bdd9a 5188 arg1_tree = ffecom_arg_ptr_to_expr (arg2, &arg1_len);
5ff904cd 5189
c56f65d6 5190 arg2_tree = convert (((codegen_imp == FFEINTRIN_impCTIME_subr) ?
5ff904cd
JL
5191 ffecom_f2c_longint_type_node :
5192 ffecom_f2c_integer_type_node),
2b0bdd9a 5193 ffecom_expr (arg1));
5ff904cd
JL
5194 arg2_tree = ffecom_1 (ADDR_EXPR,
5195 build_pointer_type (TREE_TYPE (arg2_tree)),
5196 arg2_tree);
5197
5ff904cd
JL
5198 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5199 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5200 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5201 TREE_CHAIN (arg1_len) = arg2_tree;
5202 TREE_CHAIN (arg1_tree) = arg1_len;
5203
5204 expr_tree
5205 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5206 ffecom_gfrt_kindtype (gfrt),
5207 FALSE,
5208 NULL_TREE,
5209 arg1_tree,
c7e4ee3a
CB
5210 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5211 ffebld_nonter_hook (expr));
2b0bdd9a 5212 TREE_SIDE_EFFECTS (expr_tree) = 1;
5ff904cd
JL
5213 }
5214 return expr_tree;
5215
5216 case FFEINTRIN_impIRAND:
5217 case FFEINTRIN_impRAND:
5218 /* Arg defaults to 0 (normal random case) */
5219 {
5220 tree arg1_tree;
5221
5222 if (arg1 == NULL)
5223 arg1_tree = ffecom_integer_zero_node;
5224 else
5225 arg1_tree = ffecom_expr (arg1);
5226 arg1_tree = convert (ffecom_f2c_integer_type_node,
5227 arg1_tree);
5228 arg1_tree = ffecom_1 (ADDR_EXPR,
5229 build_pointer_type (TREE_TYPE (arg1_tree)),
5230 arg1_tree);
5231 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5232
5233 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5234 ffecom_gfrt_kindtype (gfrt),
5235 FALSE,
5236 ((codegen_imp == FFEINTRIN_impIRAND) ?
5237 ffecom_f2c_integer_type_node :
de7f278a 5238 ffecom_f2c_real_type_node),
5ff904cd
JL
5239 arg1_tree,
5240 dest_tree, dest, dest_used,
c7e4ee3a
CB
5241 NULL_TREE, TRUE,
5242 ffebld_nonter_hook (expr));
5ff904cd
JL
5243 }
5244 return expr_tree;
5245
5246 case FFEINTRIN_impFTELL_subr:
5247 case FFEINTRIN_impUMASK_subr:
5248 {
5249 tree arg1_tree;
5250 tree arg2_tree;
5251
5ff904cd
JL
5252 arg1_tree = convert (ffecom_f2c_integer_type_node,
5253 ffecom_expr (arg1));
5254 arg1_tree = ffecom_1 (ADDR_EXPR,
5255 build_pointer_type (TREE_TYPE (arg1_tree)),
5256 arg1_tree);
5257
5258 if (arg2 == NULL)
5259 arg2_tree = NULL_TREE;
5260 else
c7e4ee3a 5261 arg2_tree = ffecom_expr_w (NULL_TREE, arg2);
5ff904cd
JL
5262
5263 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5264 ffecom_gfrt_kindtype (gfrt),
5265 FALSE,
5266 NULL_TREE,
5267 build_tree_list (NULL_TREE, arg1_tree),
5268 NULL_TREE, NULL, NULL, NULL_TREE,
c7e4ee3a
CB
5269 TRUE,
5270 ffebld_nonter_hook (expr));
5ff904cd
JL
5271 if (arg2_tree != NULL_TREE) {
5272 expr_tree = ffecom_modify (NULL_TREE, arg2_tree,
5273 convert (TREE_TYPE (arg2_tree),
5274 expr_tree));
5275 }
5276 }
5277 return expr_tree;
5278
5279 case FFEINTRIN_impCPU_TIME:
5280 case FFEINTRIN_impSECOND_subr:
5281 {
5282 tree arg1_tree;
5283
c7e4ee3a 5284 arg1_tree = ffecom_expr_w (NULL_TREE, arg1);
5ff904cd
JL
5285
5286 expr_tree
5287 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5288 ffecom_gfrt_kindtype (gfrt),
5289 FALSE,
5290 NULL_TREE,
5291 NULL_TREE,
c7e4ee3a
CB
5292 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5293 ffebld_nonter_hook (expr));
5ff904cd
JL
5294
5295 expr_tree
5296 = ffecom_modify (NULL_TREE, arg1_tree,
5297 convert (TREE_TYPE (arg1_tree),
5298 expr_tree));
5299 }
5300 return expr_tree;
5301
5302 case FFEINTRIN_impDTIME_subr:
5303 case FFEINTRIN_impETIME_subr:
5304 {
5305 tree arg1_tree;
2b0bdd9a 5306 tree result_tree;
5ff904cd 5307
2b0bdd9a 5308 result_tree = ffecom_expr_w (NULL_TREE, arg2);
5ff904cd 5309
2b0bdd9a 5310 arg1_tree = ffecom_ptr_to_expr (arg1);
5ff904cd 5311
5ff904cd
JL
5312 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5313 ffecom_gfrt_kindtype (gfrt),
5314 FALSE,
5315 NULL_TREE,
2b0bdd9a 5316 build_tree_list (NULL_TREE, arg1_tree),
5ff904cd 5317 NULL_TREE, NULL, NULL, NULL_TREE,
c7e4ee3a
CB
5318 TRUE,
5319 ffebld_nonter_hook (expr));
2b0bdd9a
CB
5320 expr_tree = ffecom_modify (NULL_TREE, result_tree,
5321 convert (TREE_TYPE (result_tree),
5ff904cd
JL
5322 expr_tree));
5323 }
5324 return expr_tree;
5325
c7e4ee3a 5326 /* Straightforward calls of libf2c routines: */
5ff904cd
JL
5327 case FFEINTRIN_impABORT:
5328 case FFEINTRIN_impACCESS:
5329 case FFEINTRIN_impBESJ0:
5330 case FFEINTRIN_impBESJ1:
5331 case FFEINTRIN_impBESJN:
5332 case FFEINTRIN_impBESY0:
5333 case FFEINTRIN_impBESY1:
5334 case FFEINTRIN_impBESYN:
5335 case FFEINTRIN_impCHDIR_func:
5336 case FFEINTRIN_impCHMOD_func:
5337 case FFEINTRIN_impDATE:
9e8e701d 5338 case FFEINTRIN_impDATE_AND_TIME:
5ff904cd
JL
5339 case FFEINTRIN_impDBESJ0:
5340 case FFEINTRIN_impDBESJ1:
5341 case FFEINTRIN_impDBESJN:
5342 case FFEINTRIN_impDBESY0:
5343 case FFEINTRIN_impDBESY1:
5344 case FFEINTRIN_impDBESYN:
5345 case FFEINTRIN_impDTIME_func:
5346 case FFEINTRIN_impETIME_func:
5347 case FFEINTRIN_impFGETC_func:
5348 case FFEINTRIN_impFGET_func:
5349 case FFEINTRIN_impFNUM:
5350 case FFEINTRIN_impFPUTC_func:
5351 case FFEINTRIN_impFPUT_func:
5352 case FFEINTRIN_impFSEEK:
5353 case FFEINTRIN_impFSTAT_func:
5354 case FFEINTRIN_impFTELL_func:
5355 case FFEINTRIN_impGERROR:
5356 case FFEINTRIN_impGETARG:
5357 case FFEINTRIN_impGETCWD_func:
5358 case FFEINTRIN_impGETENV:
5359 case FFEINTRIN_impGETGID:
5360 case FFEINTRIN_impGETLOG:
5361 case FFEINTRIN_impGETPID:
5362 case FFEINTRIN_impGETUID:
5363 case FFEINTRIN_impGMTIME:
5364 case FFEINTRIN_impHOSTNM_func:
5365 case FFEINTRIN_impIDATE_unix:
5366 case FFEINTRIN_impIDATE_vxt:
5367 case FFEINTRIN_impIERRNO:
5368 case FFEINTRIN_impISATTY:
5369 case FFEINTRIN_impITIME:
5370 case FFEINTRIN_impKILL_func:
5371 case FFEINTRIN_impLINK_func:
5372 case FFEINTRIN_impLNBLNK:
5373 case FFEINTRIN_impLSTAT_func:
5374 case FFEINTRIN_impLTIME:
5375 case FFEINTRIN_impMCLOCK8:
5376 case FFEINTRIN_impMCLOCK:
5377 case FFEINTRIN_impPERROR:
5378 case FFEINTRIN_impRENAME_func:
5379 case FFEINTRIN_impSECNDS:
5380 case FFEINTRIN_impSECOND_func:
5381 case FFEINTRIN_impSLEEP:
5382 case FFEINTRIN_impSRAND:
5383 case FFEINTRIN_impSTAT_func:
5384 case FFEINTRIN_impSYMLNK_func:
5385 case FFEINTRIN_impSYSTEM_CLOCK:
5386 case FFEINTRIN_impSYSTEM_func:
5387 case FFEINTRIN_impTIME8:
5388 case FFEINTRIN_impTIME_unix:
5389 case FFEINTRIN_impTIME_vxt:
5390 case FFEINTRIN_impUMASK_func:
5391 case FFEINTRIN_impUNLINK_func:
5392 break;
5393
5394 case FFEINTRIN_impCTIME_func: /* CHARACTER functions not handled here. */
5395 case FFEINTRIN_impFDATE_func: /* CHARACTER functions not handled here. */
5396 case FFEINTRIN_impTTYNAM_func: /* CHARACTER functions not handled here. */
5397 case FFEINTRIN_impNONE:
5398 case FFEINTRIN_imp: /* Hush up gcc warning. */
5399 fprintf (stderr, "No %s implementation.\n",
5400 ffeintrin_name_implementation (ffebld_symter_implementation (ffebld_left (expr))));
5401 assert ("unimplemented intrinsic" == NULL);
5402 return error_mark_node;
5403 }
5404
5405 assert (gfrt != FFECOM_gfrt); /* Must have an implementation! */
5406
5ff904cd
JL
5407 expr_tree = ffecom_arglist_expr_ (ffecom_gfrt_args_ (gfrt),
5408 ffebld_right (expr));
5ff904cd
JL
5409
5410 return ffecom_call_ (ffecom_gfrt_tree_ (gfrt), ffecom_gfrt_kindtype (gfrt),
5411 (ffe_is_f2c_library () && ffecom_gfrt_complex_[gfrt]),
5412 tree_type,
5413 expr_tree, dest_tree, dest, dest_used,
c7e4ee3a
CB
5414 NULL_TREE, TRUE,
5415 ffebld_nonter_hook (expr));
5ff904cd 5416
c7e4ee3a
CB
5417 /* See bottom of this file for f2c transforms used to determine
5418 many of the above implementations. The info seems to confuse
5419 Emacs's C mode indentation, which is why it's been moved to
5420 the bottom of this source file. */
5421}
5ff904cd 5422
c7e4ee3a
CB
5423/* For power (exponentiation) where right-hand operand is type INTEGER,
5424 generate in-line code to do it the fast way (which, if the operand
5425 is a constant, might just mean a series of multiplies). */
5ff904cd 5426
c7e4ee3a
CB
5427static tree
5428ffecom_expr_power_integer_ (ffebld expr)
5429{
5430 tree l = ffecom_expr (ffebld_left (expr));
5431 tree r = ffecom_expr (ffebld_right (expr));
5432 tree ltype = TREE_TYPE (l);
5433 tree rtype = TREE_TYPE (r);
5434 tree result = NULL_TREE;
5ff904cd 5435
c7e4ee3a
CB
5436 if (l == error_mark_node
5437 || r == error_mark_node)
5438 return error_mark_node;
5ff904cd 5439
c7e4ee3a
CB
5440 if (TREE_CODE (r) == INTEGER_CST)
5441 {
5442 int sgn = tree_int_cst_sgn (r);
5ff904cd 5443
c7e4ee3a
CB
5444 if (sgn == 0)
5445 return convert (ltype, integer_one_node);
5ff904cd 5446
c7e4ee3a
CB
5447 if ((TREE_CODE (ltype) == INTEGER_TYPE)
5448 && (sgn < 0))
5449 {
5450 /* Reciprocal of integer is either 0, -1, or 1, so after
5451 calculating that (which we leave to the back end to do
5452 or not do optimally), don't bother with any multiplying. */
5ff904cd 5453
c7e4ee3a
CB
5454 result = ffecom_tree_divide_ (ltype,
5455 convert (ltype, integer_one_node),
5456 l,
5457 NULL_TREE, NULL, NULL, NULL_TREE);
5458 r = ffecom_1 (NEGATE_EXPR,
5459 rtype,
5460 r);
5461 if ((TREE_INT_CST_LOW (r) & 1) == 0)
5462 result = ffecom_1 (ABS_EXPR, rtype,
5463 result);
5464 }
5ff904cd 5465
c7e4ee3a
CB
5466 /* Generate appropriate series of multiplies, preceded
5467 by divide if the exponent is negative. */
5ff904cd 5468
c7e4ee3a 5469 l = save_expr (l);
5ff904cd 5470
c7e4ee3a
CB
5471 if (sgn < 0)
5472 {
5473 l = ffecom_tree_divide_ (ltype,
5474 convert (ltype, integer_one_node),
5475 l,
5476 NULL_TREE, NULL, NULL,
5477 ffebld_nonter_hook (expr));
5478 r = ffecom_1 (NEGATE_EXPR, rtype, r);
5479 assert (TREE_CODE (r) == INTEGER_CST);
5ff904cd 5480
c7e4ee3a
CB
5481 if (tree_int_cst_sgn (r) < 0)
5482 { /* The "most negative" number. */
5483 r = ffecom_1 (NEGATE_EXPR, rtype,
5484 ffecom_2 (RSHIFT_EXPR, rtype,
5485 r,
5486 integer_one_node));
5487 l = save_expr (l);
5488 l = ffecom_2 (MULT_EXPR, ltype,
5489 l,
5490 l);
5491 }
5492 }
5ff904cd 5493
c7e4ee3a
CB
5494 for (;;)
5495 {
5496 if (TREE_INT_CST_LOW (r) & 1)
5497 {
5498 if (result == NULL_TREE)
5499 result = l;
5500 else
5501 result = ffecom_2 (MULT_EXPR, ltype,
5502 result,
5503 l);
5504 }
5ff904cd 5505
c7e4ee3a
CB
5506 r = ffecom_2 (RSHIFT_EXPR, rtype,
5507 r,
5508 integer_one_node);
5509 if (integer_zerop (r))
5510 break;
5511 assert (TREE_CODE (r) == INTEGER_CST);
5ff904cd 5512
c7e4ee3a
CB
5513 l = save_expr (l);
5514 l = ffecom_2 (MULT_EXPR, ltype,
5515 l,
5516 l);
5517 }
5518 return result;
5519 }
5ff904cd 5520
c7e4ee3a
CB
5521 /* Though rhs isn't a constant, in-line code cannot be expanded
5522 while transforming dummies
5523 because the back end cannot be easily convinced to generate
5524 stores (MODIFY_EXPR), handle temporaries, and so on before
5525 all the appropriate rtx's have been generated for things like
5526 dummy args referenced in rhs -- which doesn't happen until
5527 store_parm_decls() is called (expand_function_start, I believe,
5528 does the actual rtx-stuffing of PARM_DECLs).
5ff904cd 5529
c7e4ee3a
CB
5530 So, in this case, let the caller generate the call to the
5531 run-time-library function to evaluate the power for us. */
5ff904cd 5532
c7e4ee3a
CB
5533 if (ffecom_transform_only_dummies_)
5534 return NULL_TREE;
5ff904cd 5535
c7e4ee3a
CB
5536 /* Right-hand operand not a constant, expand in-line code to figure
5537 out how to do the multiplies, &c.
5ff904cd 5538
c7e4ee3a
CB
5539 The returned expression is expressed this way in GNU C, where l and
5540 r are the "inputs":
5ff904cd 5541
c7e4ee3a
CB
5542 ({ typeof (r) rtmp = r;
5543 typeof (l) ltmp = l;
5544 typeof (l) result;
5ff904cd 5545
c7e4ee3a
CB
5546 if (rtmp == 0)
5547 result = 1;
5548 else
5549 {
5550 if ((basetypeof (l) == basetypeof (int))
5551 && (rtmp < 0))
5552 {
5553 result = ((typeof (l)) 1) / ltmp;
5554 if ((ltmp < 0) && (((-rtmp) & 1) == 0))
5555 result = -result;
5556 }
5557 else
5558 {
5559 result = 1;
5560 if ((basetypeof (l) != basetypeof (int))
5561 && (rtmp < 0))
5562 {
5563 ltmp = ((typeof (l)) 1) / ltmp;
5564 rtmp = -rtmp;
5565 if (rtmp < 0)
5566 {
5567 rtmp = -(rtmp >> 1);
5568 ltmp *= ltmp;
5569 }
5570 }
5571 for (;;)
5572 {
5573 if (rtmp & 1)
5574 result *= ltmp;
5575 if ((rtmp >>= 1) == 0)
5576 break;
5577 ltmp *= ltmp;
5578 }
5579 }
5580 }
5581 result;
5582 })
5ff904cd 5583
c7e4ee3a
CB
5584 Note that some of the above is compile-time collapsable, such as
5585 the first part of the if statements that checks the base type of
5586 l against int. The if statements are phrased that way to suggest
5587 an easy way to generate the if/else constructs here, knowing that
5588 the back end should (and probably does) eliminate the resulting
5589 dead code (either the int case or the non-int case), something
5590 it couldn't do without the redundant phrasing, requiring explicit
5591 dead-code elimination here, which would be kind of difficult to
5592 read. */
5ff904cd 5593
c7e4ee3a
CB
5594 {
5595 tree rtmp;
5596 tree ltmp;
5597 tree divide;
5598 tree basetypeof_l_is_int;
5599 tree se;
5600 tree t;
5ff904cd 5601
c7e4ee3a
CB
5602 basetypeof_l_is_int
5603 = build_int_2 ((TREE_CODE (ltype) == INTEGER_TYPE), 0);
5ff904cd 5604
b0ca54af 5605 se = expand_start_stmt_expr ();
5ff904cd 5606
c7e4ee3a
CB
5607 ffecom_start_compstmt ();
5608
5609#ifndef HAHA
5610 rtmp = ffecom_make_tempvar ("power_r", rtype,
5611 FFETARGET_charactersizeNONE, -1);
5612 ltmp = ffecom_make_tempvar ("power_l", ltype,
5613 FFETARGET_charactersizeNONE, -1);
5614 result = ffecom_make_tempvar ("power_res", ltype,
5615 FFETARGET_charactersizeNONE, -1);
5616 if (TREE_CODE (ltype) == COMPLEX_TYPE
5617 || TREE_CODE (ltype) == RECORD_TYPE)
5618 divide = ffecom_make_tempvar ("power_div", ltype,
5619 FFETARGET_charactersizeNONE, -1);
5620 else
5621 divide = NULL_TREE;
5622#else /* HAHA */
5623 {
5624 tree hook;
5625
5626 hook = ffebld_nonter_hook (expr);
5627 assert (hook);
5628 assert (TREE_CODE (hook) == TREE_VEC);
5629 assert (TREE_VEC_LENGTH (hook) == 4);
5630 rtmp = TREE_VEC_ELT (hook, 0);
5631 ltmp = TREE_VEC_ELT (hook, 1);
5632 result = TREE_VEC_ELT (hook, 2);
5633 divide = TREE_VEC_ELT (hook, 3);
5634 if (TREE_CODE (ltype) == COMPLEX_TYPE
5635 || TREE_CODE (ltype) == RECORD_TYPE)
5636 assert (divide);
5637 else
5638 assert (! divide);
5639 }
5640#endif /* HAHA */
5ff904cd 5641
c7e4ee3a
CB
5642 expand_expr_stmt (ffecom_modify (void_type_node,
5643 rtmp,
5644 r));
5645 expand_expr_stmt (ffecom_modify (void_type_node,
5646 ltmp,
5647 l));
5648 expand_start_cond (ffecom_truth_value
5649 (ffecom_2 (EQ_EXPR, integer_type_node,
5650 rtmp,
5651 convert (rtype, integer_zero_node))),
5652 0);
5653 expand_expr_stmt (ffecom_modify (void_type_node,
5654 result,
5655 convert (ltype, integer_one_node)));
5656 expand_start_else ();
5657 if (! integer_zerop (basetypeof_l_is_int))
5658 {
5659 expand_start_cond (ffecom_2 (LT_EXPR, integer_type_node,
5660 rtmp,
5661 convert (rtype,
5662 integer_zero_node)),
5663 0);
5664 expand_expr_stmt (ffecom_modify (void_type_node,
5665 result,
5666 ffecom_tree_divide_
5667 (ltype,
5668 convert (ltype, integer_one_node),
5669 ltmp,
5670 NULL_TREE, NULL, NULL,
5671 divide)));
5672 expand_start_cond (ffecom_truth_value
5673 (ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
5674 ffecom_2 (LT_EXPR, integer_type_node,
5675 ltmp,
5676 convert (ltype,
5677 integer_zero_node)),
5678 ffecom_2 (EQ_EXPR, integer_type_node,
5679 ffecom_2 (BIT_AND_EXPR,
5680 rtype,
5681 ffecom_1 (NEGATE_EXPR,
5682 rtype,
5683 rtmp),
5684 convert (rtype,
5685 integer_one_node)),
5686 convert (rtype,
5687 integer_zero_node)))),
5688 0);
5689 expand_expr_stmt (ffecom_modify (void_type_node,
5690 result,
5691 ffecom_1 (NEGATE_EXPR,
5692 ltype,
5693 result)));
5694 expand_end_cond ();
5695 expand_start_else ();
5696 }
5697 expand_expr_stmt (ffecom_modify (void_type_node,
5698 result,
5699 convert (ltype, integer_one_node)));
5700 expand_start_cond (ffecom_truth_value
5701 (ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
5702 ffecom_truth_value_invert
5703 (basetypeof_l_is_int),
5704 ffecom_2 (LT_EXPR, integer_type_node,
5705 rtmp,
5706 convert (rtype,
5707 integer_zero_node)))),
5708 0);
5709 expand_expr_stmt (ffecom_modify (void_type_node,
5710 ltmp,
5711 ffecom_tree_divide_
5712 (ltype,
5713 convert (ltype, integer_one_node),
5714 ltmp,
5715 NULL_TREE, NULL, NULL,
5716 divide)));
5717 expand_expr_stmt (ffecom_modify (void_type_node,
5718 rtmp,
5719 ffecom_1 (NEGATE_EXPR, rtype,
5720 rtmp)));
5721 expand_start_cond (ffecom_truth_value
5722 (ffecom_2 (LT_EXPR, integer_type_node,
5723 rtmp,
5724 convert (rtype, integer_zero_node))),
5725 0);
5726 expand_expr_stmt (ffecom_modify (void_type_node,
5727 rtmp,
5728 ffecom_1 (NEGATE_EXPR, rtype,
5729 ffecom_2 (RSHIFT_EXPR,
5730 rtype,
5731 rtmp,
5732 integer_one_node))));
5733 expand_expr_stmt (ffecom_modify (void_type_node,
5734 ltmp,
5735 ffecom_2 (MULT_EXPR, ltype,
5736 ltmp,
5737 ltmp)));
5738 expand_end_cond ();
5739 expand_end_cond ();
5740 expand_start_loop (1);
5741 expand_start_cond (ffecom_truth_value
5742 (ffecom_2 (BIT_AND_EXPR, rtype,
5743 rtmp,
5744 convert (rtype, integer_one_node))),
5745 0);
5746 expand_expr_stmt (ffecom_modify (void_type_node,
5747 result,
5748 ffecom_2 (MULT_EXPR, ltype,
5749 result,
5750 ltmp)));
5751 expand_end_cond ();
5752 expand_exit_loop_if_false (NULL,
5753 ffecom_truth_value
5754 (ffecom_modify (rtype,
5755 rtmp,
5756 ffecom_2 (RSHIFT_EXPR,
5757 rtype,
5758 rtmp,
5759 integer_one_node))));
5760 expand_expr_stmt (ffecom_modify (void_type_node,
5761 ltmp,
5762 ffecom_2 (MULT_EXPR, ltype,
5763 ltmp,
5764 ltmp)));
5765 expand_end_loop ();
5766 expand_end_cond ();
5767 if (!integer_zerop (basetypeof_l_is_int))
5768 expand_end_cond ();
5769 expand_expr_stmt (result);
5ff904cd 5770
c7e4ee3a 5771 t = ffecom_end_compstmt ();
5ff904cd 5772
c7e4ee3a 5773 result = expand_end_stmt_expr (se);
5ff904cd 5774
c7e4ee3a 5775 /* This code comes from c-parse.in, after its expand_end_stmt_expr. */
5ff904cd 5776
c7e4ee3a
CB
5777 if (TREE_CODE (t) == BLOCK)
5778 {
5779 /* Make a BIND_EXPR for the BLOCK already made. */
5780 result = build (BIND_EXPR, TREE_TYPE (result),
5781 NULL_TREE, result, t);
5782 /* Remove the block from the tree at this point.
5783 It gets put back at the proper place
5784 when the BIND_EXPR is expanded. */
5785 delete_block (t);
5786 }
5787 else
5788 result = t;
5789 }
5ff904cd 5790
c7e4ee3a
CB
5791 return result;
5792}
5ff904cd 5793
c7e4ee3a 5794/* ffecom_expr_transform_ -- Transform symbols in expr
5ff904cd 5795
c7e4ee3a
CB
5796 ffebld expr; // FFE expression.
5797 ffecom_expr_transform_ (expr);
5ff904cd 5798
c7e4ee3a 5799 Recursive descent on expr while transforming any untransformed SYMTERs. */
5ff904cd 5800
c7e4ee3a
CB
5801static void
5802ffecom_expr_transform_ (ffebld expr)
5803{
5804 tree t;
5805 ffesymbol s;
5ff904cd 5806
516b69ff 5807 tail_recurse:
5ff904cd 5808
c7e4ee3a
CB
5809 if (expr == NULL)
5810 return;
5ff904cd 5811
c7e4ee3a
CB
5812 switch (ffebld_op (expr))
5813 {
5814 case FFEBLD_opSYMTER:
5815 s = ffebld_symter (expr);
5816 t = ffesymbol_hook (s).decl_tree;
5817 if ((t == NULL_TREE)
5818 && ((ffesymbol_kind (s) != FFEINFO_kindNONE)
5819 || ((ffesymbol_where (s) != FFEINFO_whereNONE)
5820 && (ffesymbol_where (s) != FFEINFO_whereINTRINSIC))))
5821 {
5822 s = ffecom_sym_transform_ (s);
5823 t = ffesymbol_hook (s).decl_tree; /* Sfunc expr non-dummy,
5824 DIMENSION expr? */
5825 }
5826 break; /* Ok if (t == NULL) here. */
5ff904cd 5827
c7e4ee3a
CB
5828 case FFEBLD_opITEM:
5829 ffecom_expr_transform_ (ffebld_head (expr));
5830 expr = ffebld_trail (expr);
5831 goto tail_recurse; /* :::::::::::::::::::: */
5ff904cd 5832
c7e4ee3a
CB
5833 default:
5834 break;
5835 }
5ff904cd 5836
c7e4ee3a
CB
5837 switch (ffebld_arity (expr))
5838 {
5839 case 2:
5840 ffecom_expr_transform_ (ffebld_left (expr));
5841 expr = ffebld_right (expr);
5842 goto tail_recurse; /* :::::::::::::::::::: */
5ff904cd 5843
c7e4ee3a
CB
5844 case 1:
5845 expr = ffebld_left (expr);
5846 goto tail_recurse; /* :::::::::::::::::::: */
5ff904cd 5847
c7e4ee3a
CB
5848 default:
5849 break;
5850 }
5ff904cd 5851
c7e4ee3a
CB
5852 return;
5853}
5ff904cd 5854
c7e4ee3a 5855/* Make a type based on info in live f2c.h file. */
5ff904cd 5856
c7e4ee3a
CB
5857static void
5858ffecom_f2c_make_type_ (tree *type, int tcode, const char *name)
5859{
5860 switch (tcode)
5861 {
5862 case FFECOM_f2ccodeCHAR:
5863 *type = make_signed_type (CHAR_TYPE_SIZE);
5864 break;
5ff904cd 5865
c7e4ee3a
CB
5866 case FFECOM_f2ccodeSHORT:
5867 *type = make_signed_type (SHORT_TYPE_SIZE);
5868 break;
5ff904cd 5869
c7e4ee3a
CB
5870 case FFECOM_f2ccodeINT:
5871 *type = make_signed_type (INT_TYPE_SIZE);
5872 break;
5ff904cd 5873
c7e4ee3a
CB
5874 case FFECOM_f2ccodeLONG:
5875 *type = make_signed_type (LONG_TYPE_SIZE);
5876 break;
5ff904cd 5877
c7e4ee3a
CB
5878 case FFECOM_f2ccodeLONGLONG:
5879 *type = make_signed_type (LONG_LONG_TYPE_SIZE);
5880 break;
5ff904cd 5881
c7e4ee3a
CB
5882 case FFECOM_f2ccodeCHARPTR:
5883 *type = build_pointer_type (DEFAULT_SIGNED_CHAR
5884 ? signed_char_type_node
5885 : unsigned_char_type_node);
5886 break;
5ff904cd 5887
c7e4ee3a
CB
5888 case FFECOM_f2ccodeFLOAT:
5889 *type = make_node (REAL_TYPE);
5890 TYPE_PRECISION (*type) = FLOAT_TYPE_SIZE;
5891 layout_type (*type);
5892 break;
5893
5894 case FFECOM_f2ccodeDOUBLE:
5895 *type = make_node (REAL_TYPE);
5896 TYPE_PRECISION (*type) = DOUBLE_TYPE_SIZE;
5897 layout_type (*type);
5898 break;
5899
5900 case FFECOM_f2ccodeLONGDOUBLE:
5901 *type = make_node (REAL_TYPE);
5902 TYPE_PRECISION (*type) = LONG_DOUBLE_TYPE_SIZE;
5903 layout_type (*type);
5904 break;
5ff904cd 5905
c7e4ee3a
CB
5906 case FFECOM_f2ccodeTWOREALS:
5907 *type = ffecom_make_complex_type_ (ffecom_f2c_real_type_node);
5908 break;
5ff904cd 5909
c7e4ee3a
CB
5910 case FFECOM_f2ccodeTWODOUBLEREALS:
5911 *type = ffecom_make_complex_type_ (ffecom_f2c_doublereal_type_node);
5912 break;
5ff904cd 5913
c7e4ee3a
CB
5914 default:
5915 assert ("unexpected FFECOM_f2ccodeXYZZY!" == NULL);
5916 *type = error_mark_node;
5917 return;
5918 }
5ff904cd 5919
c7e4ee3a 5920 pushdecl (build_decl (TYPE_DECL,
14657de8 5921 ffecom_get_invented_identifier ("__g77_f2c_%s", name),
c7e4ee3a
CB
5922 *type));
5923}
5ff904cd 5924
c7e4ee3a
CB
5925/* Set the f2c list-directed-I/O code for whatever (integral) type has the
5926 given size. */
5ff904cd 5927
c7e4ee3a
CB
5928static void
5929ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size,
5930 int code)
5931{
5932 int j;
5933 tree t;
5ff904cd 5934
c7e4ee3a 5935 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
05bccae2
RK
5936 if ((t = ffecom_tree_type[bt][j]) != NULL_TREE
5937 && compare_tree_int (TYPE_SIZE (t), size) == 0)
c7e4ee3a
CB
5938 {
5939 assert (code != -1);
5940 ffecom_f2c_typecode_[bt][j] = code;
5941 code = -1;
5942 }
5943}
5ff904cd 5944
c7e4ee3a 5945/* Finish up globals after doing all program units in file
5ff904cd 5946
c7e4ee3a 5947 Need to handle only uninitialized COMMON areas. */
5ff904cd 5948
c7e4ee3a
CB
5949static ffeglobal
5950ffecom_finish_global_ (ffeglobal global)
5951{
5952 tree cbtype;
5953 tree cbt;
5954 tree size;
5ff904cd 5955
c7e4ee3a
CB
5956 if (ffeglobal_type (global) != FFEGLOBAL_typeCOMMON)
5957 return global;
5ff904cd 5958
c7e4ee3a
CB
5959 if (ffeglobal_common_init (global))
5960 return global;
5ff904cd 5961
c7e4ee3a
CB
5962 cbt = ffeglobal_hook (global);
5963 if ((cbt == NULL_TREE)
5964 || !ffeglobal_common_have_size (global))
5965 return global; /* No need to make common, never ref'd. */
5ff904cd 5966
c7e4ee3a 5967 DECL_EXTERNAL (cbt) = 0;
5ff904cd 5968
c7e4ee3a 5969 /* Give the array a size now. */
5ff904cd 5970
c7e4ee3a
CB
5971 size = build_int_2 ((ffeglobal_common_size (global)
5972 + ffeglobal_common_pad (global)) - 1,
5973 0);
5ff904cd 5974
c7e4ee3a
CB
5975 cbtype = TREE_TYPE (cbt);
5976 TYPE_DOMAIN (cbtype) = build_range_type (integer_type_node,
5977 integer_zero_node,
5978 size);
5979 if (!TREE_TYPE (size))
5980 TREE_TYPE (size) = TYPE_DOMAIN (cbtype);
5981 layout_type (cbtype);
5ff904cd 5982
c7e4ee3a
CB
5983 cbt = start_decl (cbt, FALSE);
5984 assert (cbt == ffeglobal_hook (global));
5ff904cd 5985
c7e4ee3a 5986 finish_decl (cbt, NULL_TREE, FALSE);
5ff904cd 5987
c7e4ee3a
CB
5988 return global;
5989}
5ff904cd 5990
c7e4ee3a 5991/* Finish up any untransformed symbols. */
5ff904cd 5992
c7e4ee3a
CB
5993static ffesymbol
5994ffecom_finish_symbol_transform_ (ffesymbol s)
5ff904cd 5995{
c7e4ee3a
CB
5996 if ((s == NULL) || (TREE_CODE (current_function_decl) == ERROR_MARK))
5997 return s;
5ff904cd 5998
c7e4ee3a
CB
5999 /* It's easy to know to transform an untransformed symbol, to make sure
6000 we put out debugging info for it. But COMMON variables, unlike
6001 EQUIVALENCE ones, aren't given declarations in addition to the
6002 tree expressions that specify offsets, because COMMON variables
6003 can be referenced in the outer scope where only dummy arguments
6004 (PARM_DECLs) should really be seen. To be safe, just don't do any
6005 VAR_DECLs for COMMON variables when we transform them for real
6006 use, and therefore we do all the VAR_DECL creating here. */
5ff904cd 6007
c7e4ee3a
CB
6008 if (ffesymbol_hook (s).decl_tree == NULL_TREE)
6009 {
6010 if (ffesymbol_kind (s) != FFEINFO_kindNONE
6011 || (ffesymbol_where (s) != FFEINFO_whereNONE
6012 && ffesymbol_where (s) != FFEINFO_whereINTRINSIC
6013 && ffesymbol_where (s) != FFEINFO_whereDUMMY))
6014 /* Not transformed, and not CHARACTER*(*), and not a dummy
6015 argument, which can happen only if the entry point names
6016 it "rides in on" are all invalidated for other reasons. */
6017 s = ffecom_sym_transform_ (s);
6018 }
5ff904cd 6019
c7e4ee3a
CB
6020 if ((ffesymbol_where (s) == FFEINFO_whereCOMMON)
6021 && (ffesymbol_hook (s).decl_tree != error_mark_node))
6022 {
c7e4ee3a
CB
6023 /* This isn't working, at least for dbxout. The .s file looks
6024 okay to me (burley), but in gdb 4.9 at least, the variables
6025 appear to reside somewhere outside of the common area, so
6026 it doesn't make sense to mislead anyone by generating the info
6027 on those variables until this is fixed. NOTE: Same problem
6028 with EQUIVALENCE, sadly...see similar #if later. */
6029 ffecom_member_phase2_ (ffesymbol_storage (ffesymbol_common (s)),
6030 ffesymbol_storage (s));
5ff904cd
JL
6031 }
6032
c7e4ee3a
CB
6033 return s;
6034}
5ff904cd 6035
c7e4ee3a
CB
6036/* Append underscore(s) to name before calling get_identifier. "us"
6037 is nonzero if the name already contains an underscore and thus
6038 needs two underscores appended. */
5ff904cd 6039
c7e4ee3a
CB
6040static tree
6041ffecom_get_appended_identifier_ (char us, const char *name)
6042{
6043 int i;
6044 char *newname;
6045 tree id;
5ff904cd 6046
c7e4ee3a
CB
6047 newname = xmalloc ((i = strlen (name)) + 1
6048 + ffe_is_underscoring ()
6049 + us);
6050 memcpy (newname, name, i);
6051 newname[i] = '_';
6052 newname[i + us] = '_';
6053 newname[i + 1 + us] = '\0';
6054 id = get_identifier (newname);
5ff904cd 6055
c7e4ee3a 6056 free (newname);
5ff904cd 6057
c7e4ee3a
CB
6058 return id;
6059}
5ff904cd 6060
c7e4ee3a
CB
6061/* Decide whether to append underscore to name before calling
6062 get_identifier. */
5ff904cd 6063
c7e4ee3a
CB
6064static tree
6065ffecom_get_external_identifier_ (ffesymbol s)
6066{
6067 char us;
6068 const char *name = ffesymbol_text (s);
5ff904cd 6069
c7e4ee3a 6070 /* If name is a built-in name, just return it as is. */
5ff904cd 6071
c7e4ee3a
CB
6072 if (!ffe_is_underscoring ()
6073 || (strcmp (name, FFETARGET_nameBLANK_COMMON) == 0)
6074#if FFETARGET_isENFORCED_MAIN_NAME
6075 || (strcmp (name, FFETARGET_nameENFORCED_NAME) == 0)
6076#else
6077 || (strcmp (name, FFETARGET_nameUNNAMED_MAIN) == 0)
6078#endif
6079 || (strcmp (name, FFETARGET_nameUNNAMED_BLOCK_DATA) == 0))
6080 return get_identifier (name);
5ff904cd 6081
c7e4ee3a
CB
6082 us = ffe_is_second_underscore ()
6083 ? (strchr (name, '_') != NULL)
6084 : 0;
5ff904cd 6085
c7e4ee3a
CB
6086 return ffecom_get_appended_identifier_ (us, name);
6087}
5ff904cd 6088
c7e4ee3a
CB
6089/* Decide whether to append underscore to internal name before calling
6090 get_identifier.
6091
6092 This is for non-external, top-function-context names only. Transform
6093 identifier so it doesn't conflict with the transformed result
6094 of using a _different_ external name. E.g. if "CALL FOO" is
6095 transformed into "FOO_();", then the variable in "FOO_ = 3"
6096 must be transformed into something that does not conflict, since
6097 these two things should be independent.
5ff904cd 6098
c7e4ee3a
CB
6099 The transformation is as follows. If the name does not contain
6100 an underscore, there is no possible conflict, so just return.
6101 If the name does contain an underscore, then transform it just
6102 like we transform an external identifier. */
5ff904cd 6103
c7e4ee3a
CB
6104static tree
6105ffecom_get_identifier_ (const char *name)
6106{
6107 /* If name does not contain an underscore, just return it as is. */
6108
6109 if (!ffe_is_underscoring ()
6110 || (strchr (name, '_') == NULL))
6111 return get_identifier (name);
6112
6113 return ffecom_get_appended_identifier_ (ffe_is_second_underscore (),
6114 name);
5ff904cd
JL
6115}
6116
c7e4ee3a 6117/* ffecom_gen_sfuncdef_ -- Generate definition of statement function
5ff904cd 6118
c7e4ee3a
CB
6119 tree t;
6120 ffesymbol s; // kindFUNCTION, whereIMMEDIATE.
6121 t = ffecom_gen_sfuncdef_(s,ffesymbol_basictype(s),
6122 ffesymbol_kindtype(s));
5ff904cd 6123
c7e4ee3a
CB
6124 Call after setting up containing function and getting trees for all
6125 other symbols. */
5ff904cd 6126
c7e4ee3a
CB
6127static tree
6128ffecom_gen_sfuncdef_ (ffesymbol s, ffeinfoBasictype bt, ffeinfoKindtype kt)
5ff904cd 6129{
c7e4ee3a
CB
6130 ffebld expr = ffesymbol_sfexpr (s);
6131 tree type;
6132 tree func;
6133 tree result;
6134 bool charfunc = (bt == FFEINFO_basictypeCHARACTER);
6135 static bool recurse = FALSE;
c7e4ee3a 6136 int old_lineno = lineno;
3b304f5b 6137 const char *old_input_filename = input_filename;
5ff904cd 6138
c7e4ee3a 6139 ffecom_nested_entry_ = s;
5ff904cd 6140
c7e4ee3a
CB
6141 /* For now, we don't have a handy pointer to where the sfunc is actually
6142 defined, though that should be easy to add to an ffesymbol. (The
6143 token/where info available might well point to the place where the type
6144 of the sfunc is declared, especially if that precedes the place where
6145 the sfunc itself is defined, which is typically the case.) We should
6146 put out a null pointer rather than point somewhere wrong, but I want to
6147 see how it works at this point. */
5ff904cd 6148
c7e4ee3a
CB
6149 input_filename = ffesymbol_where_filename (s);
6150 lineno = ffesymbol_where_filelinenum (s);
5ff904cd 6151
c7e4ee3a
CB
6152 /* Pretransform the expression so any newly discovered things belong to the
6153 outer program unit, not to the statement function. */
5ff904cd 6154
c7e4ee3a 6155 ffecom_expr_transform_ (expr);
5ff904cd 6156
c7e4ee3a
CB
6157 /* Make sure no recursive invocation of this fn (a specific case of failing
6158 to pretransform an sfunc's expression, i.e. where its expression
6159 references another untransformed sfunc) happens. */
6160
6161 assert (!recurse);
6162 recurse = TRUE;
6163
c7e4ee3a
CB
6164 push_f_function_context ();
6165
6166 if (charfunc)
6167 type = void_type_node;
6168 else
5ff904cd 6169 {
c7e4ee3a
CB
6170 type = ffecom_tree_type[bt][kt];
6171 if (type == NULL_TREE)
6172 type = integer_type_node; /* _sym_exec_transition reports
6173 error. */
6174 }
5ff904cd 6175
c7e4ee3a
CB
6176 start_function (ffecom_get_identifier_ (ffesymbol_text (s)),
6177 build_function_type (type, NULL_TREE),
6178 1, /* nested/inline */
6179 0); /* TREE_PUBLIC */
5ff904cd 6180
c7e4ee3a
CB
6181 /* We don't worry about COMPLEX return values here, because this is
6182 entirely internal to our code, and gcc has the ability to return COMPLEX
6183 directly as a value. */
6184
c7e4ee3a
CB
6185 if (charfunc)
6186 { /* Prepend arg for where result goes. */
6187 tree type;
6188
6189 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
6190
14657de8 6191 result = ffecom_get_invented_identifier ("__g77_%s", "result");
c7e4ee3a
CB
6192
6193 ffecom_char_enhance_arg_ (&type, s); /* Ignore returned length. */
6194
6195 type = build_pointer_type (type);
6196 result = build_decl (PARM_DECL, result, type);
6197
6198 push_parm_decl (result);
5ff904cd 6199 }
c7e4ee3a
CB
6200 else
6201 result = NULL_TREE; /* Not ref'd if !charfunc. */
5ff904cd 6202
c7e4ee3a 6203 ffecom_push_dummy_decls_ (ffesymbol_dummyargs (s), TRUE);
5ff904cd 6204
c7e4ee3a
CB
6205 store_parm_decls (0);
6206
6207 ffecom_start_compstmt ();
6208
6209 if (expr != NULL)
5ff904cd 6210 {
c7e4ee3a
CB
6211 if (charfunc)
6212 {
6213 ffetargetCharacterSize sz = ffesymbol_size (s);
6214 tree result_length;
5ff904cd 6215
c7e4ee3a
CB
6216 result_length = build_int_2 (sz, 0);
6217 TREE_TYPE (result_length) = ffecom_f2c_ftnlen_type_node;
5ff904cd 6218
c7e4ee3a 6219 ffecom_prepare_let_char_ (sz, expr);
5ff904cd 6220
c7e4ee3a 6221 ffecom_prepare_end ();
5ff904cd 6222
c7e4ee3a
CB
6223 ffecom_let_char_ (result, result_length, sz, expr);
6224 expand_null_return ();
6225 }
6226 else
6227 {
6228 ffecom_prepare_expr (expr);
5ff904cd 6229
c7e4ee3a 6230 ffecom_prepare_end ();
5ff904cd 6231
c7e4ee3a
CB
6232 expand_return (ffecom_modify (NULL_TREE,
6233 DECL_RESULT (current_function_decl),
6234 ffecom_expr (expr)));
6235 }
c7e4ee3a 6236 }
5ff904cd 6237
c7e4ee3a 6238 ffecom_end_compstmt ();
5ff904cd 6239
c7e4ee3a
CB
6240 func = current_function_decl;
6241 finish_function (1);
5ff904cd 6242
c7e4ee3a 6243 pop_f_function_context ();
5ff904cd 6244
c7e4ee3a
CB
6245 recurse = FALSE;
6246
6247 lineno = old_lineno;
6248 input_filename = old_input_filename;
6249
6250 ffecom_nested_entry_ = NULL;
6251
6252 return func;
5ff904cd
JL
6253}
6254
c7e4ee3a
CB
6255static const char *
6256ffecom_gfrt_args_ (ffecomGfrt ix)
5ff904cd 6257{
c7e4ee3a
CB
6258 return ffecom_gfrt_argstring_[ix];
6259}
5ff904cd 6260
c7e4ee3a
CB
6261static tree
6262ffecom_gfrt_tree_ (ffecomGfrt ix)
6263{
6264 if (ffecom_gfrt_[ix] == NULL_TREE)
6265 ffecom_make_gfrt_ (ix);
6266
6267 return ffecom_1 (ADDR_EXPR,
6268 build_pointer_type (TREE_TYPE (ffecom_gfrt_[ix])),
6269 ffecom_gfrt_[ix]);
5ff904cd
JL
6270}
6271
c7e4ee3a 6272/* Return initialize-to-zero expression for this VAR_DECL. */
5ff904cd 6273
7189a4b0
GK
6274/* A somewhat evil way to prevent the garbage collector
6275 from collecting 'tree' structures. */
6276#define NUM_TRACKED_CHUNK 63
516b69ff 6277static struct tree_ggc_tracker
7189a4b0
GK
6278{
6279 struct tree_ggc_tracker *next;
6280 tree trees[NUM_TRACKED_CHUNK];
6281} *tracker_head = NULL;
6282
516b69ff 6283static void
54551044 6284mark_tracker_head (void *arg)
7189a4b0
GK
6285{
6286 struct tree_ggc_tracker *head;
6287 int i;
516b69ff 6288
7189a4b0
GK
6289 for (head = * (struct tree_ggc_tracker **) arg;
6290 head != NULL;
6291 head = head->next)
6292 {
6293 ggc_mark (head);
6294 for (i = 0; i < NUM_TRACKED_CHUNK; i++)
6295 ggc_mark_tree (head->trees[i]);
6296 }
6297}
6298
6299void
6300ffecom_save_tree_forever (tree t)
6301{
6302 int i;
6303 if (tracker_head != NULL)
6304 for (i = 0; i < NUM_TRACKED_CHUNK; i++)
6305 if (tracker_head->trees[i] == NULL)
6306 {
6307 tracker_head->trees[i] = t;
6308 return;
6309 }
6310
6311 {
6312 /* Need to allocate a new block. */
6313 struct tree_ggc_tracker *old_head = tracker_head;
516b69ff 6314
7189a4b0
GK
6315 tracker_head = ggc_alloc (sizeof (*tracker_head));
6316 tracker_head->next = old_head;
6317 tracker_head->trees[0] = t;
6318 for (i = 1; i < NUM_TRACKED_CHUNK; i++)
6319 tracker_head->trees[i] = NULL;
6320 }
6321}
6322
c7e4ee3a
CB
6323static tree
6324ffecom_init_zero_ (tree decl)
5ff904cd 6325{
c7e4ee3a
CB
6326 tree init;
6327 int incremental = TREE_STATIC (decl);
6328 tree type = TREE_TYPE (decl);
5ff904cd 6329
c7e4ee3a
CB
6330 if (incremental)
6331 {
6c418184 6332 make_decl_rtl (decl, NULL);
c7e4ee3a 6333 assemble_variable (decl, TREE_PUBLIC (decl) ? 1 : 0, 0, 1);
c7e4ee3a 6334 }
5ff904cd 6335
c7e4ee3a
CB
6336 if ((TREE_CODE (type) != ARRAY_TYPE)
6337 && (TREE_CODE (type) != RECORD_TYPE)
6338 && (TREE_CODE (type) != UNION_TYPE)
6339 && !incremental)
6340 init = convert (type, integer_zero_node);
6341 else if (!incremental)
6342 {
c7e4ee3a
CB
6343 init = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
6344 TREE_CONSTANT (init) = 1;
6345 TREE_STATIC (init) = 1;
c7e4ee3a
CB
6346 }
6347 else
6348 {
c7e4ee3a
CB
6349 assemble_zeros (int_size_in_bytes (type));
6350 init = error_mark_node;
c7e4ee3a 6351 }
5ff904cd 6352
c7e4ee3a 6353 return init;
5ff904cd
JL
6354}
6355
c7e4ee3a
CB
6356static tree
6357ffecom_intrinsic_ichar_ (tree tree_type, ffebld arg,
6358 tree *maybe_tree)
5ff904cd 6359{
c7e4ee3a
CB
6360 tree expr_tree;
6361 tree length_tree;
5ff904cd 6362
c7e4ee3a 6363 switch (ffebld_op (arg))
6829256f 6364 {
c7e4ee3a
CB
6365 case FFEBLD_opCONTER: /* For F90, check 0-length. */
6366 if (ffetarget_length_character1
6367 (ffebld_constant_character1
6368 (ffebld_conter (arg))) == 0)
6369 {
6370 *maybe_tree = integer_zero_node;
6371 return convert (tree_type, integer_zero_node);
6372 }
5ff904cd 6373
c7e4ee3a
CB
6374 *maybe_tree = integer_one_node;
6375 expr_tree = build_int_2 (*ffetarget_text_character1
6376 (ffebld_constant_character1
6377 (ffebld_conter (arg))),
6378 0);
6379 TREE_TYPE (expr_tree) = tree_type;
6380 return expr_tree;
5ff904cd 6381
c7e4ee3a
CB
6382 case FFEBLD_opSYMTER:
6383 case FFEBLD_opARRAYREF:
6384 case FFEBLD_opFUNCREF:
6385 case FFEBLD_opSUBSTR:
6386 ffecom_char_args_ (&expr_tree, &length_tree, arg);
5ff904cd 6387
c7e4ee3a
CB
6388 if ((expr_tree == error_mark_node)
6389 || (length_tree == error_mark_node))
6390 {
6391 *maybe_tree = error_mark_node;
6392 return error_mark_node;
6393 }
5ff904cd 6394
c7e4ee3a
CB
6395 if (integer_zerop (length_tree))
6396 {
6397 *maybe_tree = integer_zero_node;
6398 return convert (tree_type, integer_zero_node);
6399 }
6400
6401 expr_tree
6402 = ffecom_1 (INDIRECT_REF,
6403 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
6404 expr_tree);
6405 expr_tree
6406 = ffecom_2 (ARRAY_REF,
6407 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
6408 expr_tree,
6409 integer_one_node);
6410 expr_tree = convert (tree_type, expr_tree);
6411
6412 if (TREE_CODE (length_tree) == INTEGER_CST)
6413 *maybe_tree = integer_one_node;
6414 else /* Must check length at run time. */
6415 *maybe_tree
6416 = ffecom_truth_value
6417 (ffecom_2 (GT_EXPR, integer_type_node,
6418 length_tree,
6419 ffecom_f2c_ftnlen_zero_node));
6420 return expr_tree;
6421
6422 case FFEBLD_opPAREN:
6423 case FFEBLD_opCONVERT:
6424 if (ffeinfo_size (ffebld_info (arg)) == 0)
6425 {
6426 *maybe_tree = integer_zero_node;
6427 return convert (tree_type, integer_zero_node);
6428 }
6429 return ffecom_intrinsic_ichar_ (tree_type, ffebld_left (arg),
6430 maybe_tree);
6431
6432 case FFEBLD_opCONCATENATE:
6433 {
6434 tree maybe_left;
6435 tree maybe_right;
6436 tree expr_left;
6437 tree expr_right;
6438
6439 expr_left = ffecom_intrinsic_ichar_ (tree_type, ffebld_left (arg),
6440 &maybe_left);
6441 expr_right = ffecom_intrinsic_ichar_ (tree_type, ffebld_right (arg),
6442 &maybe_right);
6443 *maybe_tree = ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
6444 maybe_left,
6445 maybe_right);
6446 expr_tree = ffecom_3 (COND_EXPR, tree_type,
6447 maybe_left,
6448 expr_left,
6449 expr_right);
6450 return expr_tree;
6451 }
6452
6453 default:
6454 assert ("bad op in ICHAR" == NULL);
6455 return error_mark_node;
6456 }
5ff904cd
JL
6457}
6458
c7e4ee3a
CB
6459/* ffecom_intrinsic_len_ -- Return length info for char arg (LEN())
6460
6461 tree length_arg;
6462 ffebld expr;
6463 length_arg = ffecom_intrinsic_len_ (expr);
6464
6465 Handles CHARACTER-type CONTER, SYMTER, SUBSTR, ARRAYREF, and FUNCREF
6466 subexpressions by constructing the appropriate tree for the
6467 length-of-character-text argument in a calling sequence. */
5ff904cd 6468
5ff904cd 6469static tree
c7e4ee3a 6470ffecom_intrinsic_len_ (ffebld expr)
5ff904cd 6471{
c7e4ee3a
CB
6472 ffetargetCharacter1 val;
6473 tree length;
6474
6475 switch (ffebld_op (expr))
6476 {
6477 case FFEBLD_opCONTER:
6478 val = ffebld_constant_character1 (ffebld_conter (expr));
6479 length = build_int_2 (ffetarget_length_character1 (val), 0);
6480 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6481 break;
6482
6483 case FFEBLD_opSYMTER:
6484 {
6485 ffesymbol s = ffebld_symter (expr);
6486 tree item;
6487
6488 item = ffesymbol_hook (s).decl_tree;
6489 if (item == NULL_TREE)
6490 {
6491 s = ffecom_sym_transform_ (s);
6492 item = ffesymbol_hook (s).decl_tree;
6493 }
6494 if (ffesymbol_kind (s) == FFEINFO_kindENTITY)
6495 {
6496 if (ffesymbol_size (s) == FFETARGET_charactersizeNONE)
6497 length = ffesymbol_hook (s).length_tree;
6498 else
6499 {
6500 length = build_int_2 (ffesymbol_size (s), 0);
6501 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6502 }
6503 }
6504 else if (item == error_mark_node)
6505 length = error_mark_node;
6506 else /* FFEINFO_kindFUNCTION: */
6507 length = NULL_TREE;
6508 }
6509 break;
5ff904cd 6510
c7e4ee3a
CB
6511 case FFEBLD_opARRAYREF:
6512 length = ffecom_intrinsic_len_ (ffebld_left (expr));
6513 break;
5ff904cd 6514
c7e4ee3a
CB
6515 case FFEBLD_opSUBSTR:
6516 {
6517 ffebld start;
6518 ffebld end;
6519 ffebld thing = ffebld_right (expr);
6520 tree start_tree;
6521 tree end_tree;
5ff904cd 6522
c7e4ee3a
CB
6523 assert (ffebld_op (thing) == FFEBLD_opITEM);
6524 start = ffebld_head (thing);
6525 thing = ffebld_trail (thing);
6526 assert (ffebld_trail (thing) == NULL);
6527 end = ffebld_head (thing);
5ff904cd 6528
c7e4ee3a 6529 length = ffecom_intrinsic_len_ (ffebld_left (expr));
5ff904cd 6530
c7e4ee3a
CB
6531 if (length == error_mark_node)
6532 break;
5ff904cd 6533
c7e4ee3a
CB
6534 if (start == NULL)
6535 {
6536 if (end == NULL)
6537 ;
6538 else
6539 {
6540 length = convert (ffecom_f2c_ftnlen_type_node,
6541 ffecom_expr (end));
6542 }
6543 }
6544 else
6545 {
6546 start_tree = convert (ffecom_f2c_ftnlen_type_node,
6547 ffecom_expr (start));
5ff904cd 6548
c7e4ee3a
CB
6549 if (start_tree == error_mark_node)
6550 {
6551 length = error_mark_node;
6552 break;
6553 }
5ff904cd 6554
c7e4ee3a
CB
6555 if (end == NULL)
6556 {
6557 length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6558 ffecom_f2c_ftnlen_one_node,
6559 ffecom_2 (MINUS_EXPR,
6560 ffecom_f2c_ftnlen_type_node,
6561 length,
6562 start_tree));
6563 }
6564 else
6565 {
6566 end_tree = convert (ffecom_f2c_ftnlen_type_node,
6567 ffecom_expr (end));
5ff904cd 6568
c7e4ee3a
CB
6569 if (end_tree == error_mark_node)
6570 {
6571 length = error_mark_node;
6572 break;
6573 }
5ff904cd 6574
c7e4ee3a
CB
6575 length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6576 ffecom_f2c_ftnlen_one_node,
6577 ffecom_2 (MINUS_EXPR,
6578 ffecom_f2c_ftnlen_type_node,
6579 end_tree, start_tree));
6580 }
6581 }
6582 }
6583 break;
5ff904cd 6584
c7e4ee3a
CB
6585 case FFEBLD_opCONCATENATE:
6586 length
6587 = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6588 ffecom_intrinsic_len_ (ffebld_left (expr)),
6589 ffecom_intrinsic_len_ (ffebld_right (expr)));
6590 break;
5ff904cd 6591
c7e4ee3a
CB
6592 case FFEBLD_opFUNCREF:
6593 case FFEBLD_opCONVERT:
6594 length = build_int_2 (ffebld_size (expr), 0);
6595 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6596 break;
5ff904cd 6597
c7e4ee3a
CB
6598 default:
6599 assert ("bad op for single char arg expr" == NULL);
6600 length = ffecom_f2c_ftnlen_zero_node;
6601 break;
6602 }
5ff904cd 6603
c7e4ee3a 6604 assert (length != NULL_TREE);
5ff904cd 6605
c7e4ee3a 6606 return length;
5ff904cd
JL
6607}
6608
c7e4ee3a 6609/* Handle CHARACTER assignments.
5ff904cd 6610
c7e4ee3a
CB
6611 Generates code to do the assignment. Used by ordinary assignment
6612 statement handler ffecom_let_stmt and by statement-function
6613 handler to generate code for a statement function. */
5ff904cd 6614
c7e4ee3a
CB
6615static void
6616ffecom_let_char_ (tree dest_tree, tree dest_length,
6617 ffetargetCharacterSize dest_size, ffebld source)
5ff904cd 6618{
c7e4ee3a
CB
6619 ffecomConcatList_ catlist;
6620 tree source_length;
6621 tree source_tree;
6622 tree expr_tree;
5ff904cd 6623
c7e4ee3a
CB
6624 if ((dest_tree == error_mark_node)
6625 || (dest_length == error_mark_node))
6626 return;
5ff904cd 6627
c7e4ee3a
CB
6628 assert (dest_tree != NULL_TREE);
6629 assert (dest_length != NULL_TREE);
5ff904cd 6630
c7e4ee3a
CB
6631 /* Source might be an opCONVERT, which just means it is a different size
6632 than the destination. Since the underlying implementation here handles
6633 that (directly or via the s_copy or s_cat run-time-library functions),
6634 we don't need the "convenience" of an opCONVERT that tells us to
6635 truncate or blank-pad, particularly since the resulting implementation
6636 would probably be slower than otherwise. */
5ff904cd 6637
c7e4ee3a
CB
6638 while (ffebld_op (source) == FFEBLD_opCONVERT)
6639 source = ffebld_left (source);
5ff904cd 6640
c7e4ee3a
CB
6641 catlist = ffecom_concat_list_new_ (source, dest_size);
6642 switch (ffecom_concat_list_count_ (catlist))
6643 {
6644 case 0: /* Shouldn't happen, but in case it does... */
6645 ffecom_concat_list_kill_ (catlist);
6646 source_tree = null_pointer_node;
6647 source_length = ffecom_f2c_ftnlen_zero_node;
6648 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6649 TREE_CHAIN (expr_tree) = build_tree_list (NULL_TREE, source_tree);
6650 TREE_CHAIN (TREE_CHAIN (expr_tree))
6651 = build_tree_list (NULL_TREE, dest_length);
6652 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6653 = build_tree_list (NULL_TREE, source_length);
5ff904cd 6654
c7e4ee3a
CB
6655 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCOPY, expr_tree, NULL_TREE);
6656 TREE_SIDE_EFFECTS (expr_tree) = 1;
5ff904cd 6657
c7e4ee3a 6658 expand_expr_stmt (expr_tree);
5ff904cd 6659
c7e4ee3a 6660 return;
5ff904cd 6661
c7e4ee3a
CB
6662 case 1: /* The (fairly) easy case. */
6663 ffecom_char_args_ (&source_tree, &source_length,
6664 ffecom_concat_list_expr_ (catlist, 0));
6665 ffecom_concat_list_kill_ (catlist);
6666 assert (source_tree != NULL_TREE);
6667 assert (source_length != NULL_TREE);
6668
6669 if ((source_tree == error_mark_node)
6670 || (source_length == error_mark_node))
6671 return;
6672
6673 if (dest_size == 1)
6674 {
6675 dest_tree
6676 = ffecom_1 (INDIRECT_REF,
6677 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6678 (dest_tree))),
6679 dest_tree);
6680 dest_tree
6681 = ffecom_2 (ARRAY_REF,
6682 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6683 (dest_tree))),
6684 dest_tree,
6685 integer_one_node);
6686 source_tree
6687 = ffecom_1 (INDIRECT_REF,
6688 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6689 (source_tree))),
6690 source_tree);
6691 source_tree
6692 = ffecom_2 (ARRAY_REF,
6693 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6694 (source_tree))),
6695 source_tree,
6696 integer_one_node);
5ff904cd 6697
c7e4ee3a 6698 expr_tree = ffecom_modify (void_type_node, dest_tree, source_tree);
5ff904cd 6699
c7e4ee3a 6700 expand_expr_stmt (expr_tree);
5ff904cd 6701
c7e4ee3a
CB
6702 return;
6703 }
5ff904cd 6704
c7e4ee3a
CB
6705 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6706 TREE_CHAIN (expr_tree) = build_tree_list (NULL_TREE, source_tree);
6707 TREE_CHAIN (TREE_CHAIN (expr_tree))
6708 = build_tree_list (NULL_TREE, dest_length);
6709 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6710 = build_tree_list (NULL_TREE, source_length);
5ff904cd 6711
c7e4ee3a
CB
6712 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCOPY, expr_tree, NULL_TREE);
6713 TREE_SIDE_EFFECTS (expr_tree) = 1;
5ff904cd 6714
c7e4ee3a 6715 expand_expr_stmt (expr_tree);
5ff904cd 6716
c7e4ee3a 6717 return;
5ff904cd 6718
c7e4ee3a
CB
6719 default: /* Must actually concatenate things. */
6720 break;
6721 }
5ff904cd 6722
c7e4ee3a 6723 /* Heavy-duty concatenation. */
5ff904cd 6724
c7e4ee3a
CB
6725 {
6726 int count = ffecom_concat_list_count_ (catlist);
6727 int i;
6728 tree lengths;
6729 tree items;
6730 tree length_array;
6731 tree item_array;
6732 tree citem;
6733 tree clength;
5ff904cd 6734
c7e4ee3a
CB
6735#ifdef HOHO
6736 length_array
6737 = lengths
6738 = ffecom_push_tempvar (ffecom_f2c_ftnlen_type_node,
6739 FFETARGET_charactersizeNONE, count, TRUE);
6740 item_array = items = ffecom_push_tempvar (ffecom_f2c_address_type_node,
6741 FFETARGET_charactersizeNONE,
6742 count, TRUE);
6743#else
6744 {
6745 tree hook;
6746
6747 hook = ffebld_nonter_hook (source);
6748 assert (hook);
6749 assert (TREE_CODE (hook) == TREE_VEC);
6750 assert (TREE_VEC_LENGTH (hook) == 2);
6751 length_array = lengths = TREE_VEC_ELT (hook, 0);
6752 item_array = items = TREE_VEC_ELT (hook, 1);
5ff904cd 6753 }
c7e4ee3a 6754#endif
5ff904cd 6755
c7e4ee3a
CB
6756 for (i = 0; i < count; ++i)
6757 {
6758 ffecom_char_args_ (&citem, &clength,
6759 ffecom_concat_list_expr_ (catlist, i));
6760 if ((citem == error_mark_node)
6761 || (clength == error_mark_node))
6762 {
6763 ffecom_concat_list_kill_ (catlist);
6764 return;
6765 }
5ff904cd 6766
c7e4ee3a
CB
6767 items
6768 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (items),
6769 ffecom_modify (void_type_node,
6770 ffecom_2 (ARRAY_REF,
6771 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array))),
6772 item_array,
6773 build_int_2 (i, 0)),
6774 citem),
6775 items);
6776 lengths
6777 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (lengths),
6778 ffecom_modify (void_type_node,
6779 ffecom_2 (ARRAY_REF,
6780 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array))),
6781 length_array,
6782 build_int_2 (i, 0)),
6783 clength),
6784 lengths);
6785 }
5ff904cd 6786
c7e4ee3a
CB
6787 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6788 TREE_CHAIN (expr_tree)
6789 = build_tree_list (NULL_TREE,
6790 ffecom_1 (ADDR_EXPR,
6791 build_pointer_type (TREE_TYPE (items)),
6792 items));
6793 TREE_CHAIN (TREE_CHAIN (expr_tree))
6794 = build_tree_list (NULL_TREE,
6795 ffecom_1 (ADDR_EXPR,
6796 build_pointer_type (TREE_TYPE (lengths)),
6797 lengths));
6798 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6799 = build_tree_list
6800 (NULL_TREE,
6801 ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
6802 convert (ffecom_f2c_ftnlen_type_node,
6803 build_int_2 (count, 0))));
6804 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree))))
6805 = build_tree_list (NULL_TREE, dest_length);
5ff904cd 6806
c7e4ee3a
CB
6807 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCAT, expr_tree, NULL_TREE);
6808 TREE_SIDE_EFFECTS (expr_tree) = 1;
5ff904cd 6809
c7e4ee3a
CB
6810 expand_expr_stmt (expr_tree);
6811 }
5ff904cd 6812
c7e4ee3a
CB
6813 ffecom_concat_list_kill_ (catlist);
6814}
5ff904cd 6815
c7e4ee3a 6816/* ffecom_make_gfrt_ -- Make initial info for run-time routine
5ff904cd 6817
c7e4ee3a
CB
6818 ffecomGfrt ix;
6819 ffecom_make_gfrt_(ix);
5ff904cd 6820
c7e4ee3a
CB
6821 Assumes gfrt_[ix] is NULL_TREE, and replaces it with the FUNCTION_DECL
6822 for the indicated run-time routine (ix). */
5ff904cd 6823
c7e4ee3a
CB
6824static void
6825ffecom_make_gfrt_ (ffecomGfrt ix)
6826{
6827 tree t;
6828 tree ttype;
5ff904cd 6829
c7e4ee3a
CB
6830 switch (ffecom_gfrt_type_[ix])
6831 {
6832 case FFECOM_rttypeVOID_:
6833 ttype = void_type_node;
6834 break;
5ff904cd 6835
c7e4ee3a
CB
6836 case FFECOM_rttypeVOIDSTAR_:
6837 ttype = TREE_TYPE (null_pointer_node); /* `void *'. */
6838 break;
5ff904cd 6839
c7e4ee3a
CB
6840 case FFECOM_rttypeFTNINT_:
6841 ttype = ffecom_f2c_ftnint_type_node;
6842 break;
5ff904cd 6843
c7e4ee3a
CB
6844 case FFECOM_rttypeINTEGER_:
6845 ttype = ffecom_f2c_integer_type_node;
6846 break;
5ff904cd 6847
c7e4ee3a
CB
6848 case FFECOM_rttypeLONGINT_:
6849 ttype = ffecom_f2c_longint_type_node;
6850 break;
5ff904cd 6851
c7e4ee3a
CB
6852 case FFECOM_rttypeLOGICAL_:
6853 ttype = ffecom_f2c_logical_type_node;
6854 break;
5ff904cd 6855
c7e4ee3a
CB
6856 case FFECOM_rttypeREAL_F2C_:
6857 ttype = double_type_node;
6858 break;
5ff904cd 6859
c7e4ee3a
CB
6860 case FFECOM_rttypeREAL_GNU_:
6861 ttype = float_type_node;
6862 break;
5ff904cd 6863
c7e4ee3a
CB
6864 case FFECOM_rttypeCOMPLEX_F2C_:
6865 ttype = void_type_node;
6866 break;
5ff904cd 6867
c7e4ee3a
CB
6868 case FFECOM_rttypeCOMPLEX_GNU_:
6869 ttype = ffecom_f2c_complex_type_node;
6870 break;
5ff904cd 6871
c7e4ee3a
CB
6872 case FFECOM_rttypeDOUBLE_:
6873 ttype = double_type_node;
6874 break;
5ff904cd 6875
c7e4ee3a
CB
6876 case FFECOM_rttypeDOUBLEREAL_:
6877 ttype = ffecom_f2c_doublereal_type_node;
6878 break;
5ff904cd 6879
c7e4ee3a
CB
6880 case FFECOM_rttypeDBLCMPLX_F2C_:
6881 ttype = void_type_node;
6882 break;
5ff904cd 6883
c7e4ee3a
CB
6884 case FFECOM_rttypeDBLCMPLX_GNU_:
6885 ttype = ffecom_f2c_doublecomplex_type_node;
6886 break;
5ff904cd 6887
c7e4ee3a
CB
6888 case FFECOM_rttypeCHARACTER_:
6889 ttype = void_type_node;
6890 break;
6891
6892 default:
6893 ttype = NULL;
6894 assert ("bad rttype" == NULL);
6895 break;
5ff904cd 6896 }
5ff904cd 6897
c7e4ee3a
CB
6898 ttype = build_function_type (ttype, NULL_TREE);
6899 t = build_decl (FUNCTION_DECL,
6900 get_identifier (ffecom_gfrt_name_[ix]),
6901 ttype);
6902 DECL_EXTERNAL (t) = 1;
95eb4fd9 6903 TREE_READONLY (t) = ffecom_gfrt_const_[ix] ? 1 : 0;
c7e4ee3a
CB
6904 TREE_PUBLIC (t) = 1;
6905 TREE_THIS_VOLATILE (t) = ffecom_gfrt_volatile_[ix] ? 1 : 0;
5ff904cd 6906
95eb4fd9
TM
6907 /* Sanity check: A function that's const cannot be volatile. */
6908
6909 assert (ffecom_gfrt_const_[ix] ? !ffecom_gfrt_volatile_[ix] : 1);
6910
6911 /* Sanity check: A function that's const cannot return complex. */
6912
6913 assert (ffecom_gfrt_const_[ix] ? !ffecom_gfrt_complex_[ix] : 1);
6914
c7e4ee3a 6915 t = start_decl (t, TRUE);
5ff904cd 6916
c7e4ee3a 6917 finish_decl (t, NULL_TREE, TRUE);
5ff904cd 6918
c7e4ee3a 6919 ffecom_gfrt_[ix] = t;
5ff904cd
JL
6920}
6921
c7e4ee3a
CB
6922/* Phase 1 pass over each member of a COMMON/EQUIVALENCE group. */
6923
c7e4ee3a
CB
6924static void
6925ffecom_member_phase1_ (ffestorag mst UNUSED, ffestorag st)
5ff904cd 6926{
c7e4ee3a 6927 ffesymbol s = ffestorag_symbol (st);
5ff904cd 6928
c7e4ee3a
CB
6929 if (ffesymbol_namelisted (s))
6930 ffecom_member_namelisted_ = TRUE;
6931}
5ff904cd 6932
c7e4ee3a
CB
6933/* Phase 2 pass over each member of a COMMON/EQUIVALENCE group. Declare
6934 the member so debugger will see it. Otherwise nobody should be
6935 referencing the member. */
5ff904cd 6936
c7e4ee3a
CB
6937static void
6938ffecom_member_phase2_ (ffestorag mst, ffestorag st)
6939{
6940 ffesymbol s;
6941 tree t;
6942 tree mt;
6943 tree type;
5ff904cd 6944
c7e4ee3a
CB
6945 if ((mst == NULL)
6946 || ((mt = ffestorag_hook (mst)) == NULL)
6947 || (mt == error_mark_node))
6948 return;
5ff904cd 6949
c7e4ee3a
CB
6950 if ((st == NULL)
6951 || ((s = ffestorag_symbol (st)) == NULL))
6952 return;
5ff904cd 6953
c7e4ee3a
CB
6954 type = ffecom_type_localvar_ (s,
6955 ffesymbol_basictype (s),
6956 ffesymbol_kindtype (s));
6957 if (type == error_mark_node)
6958 return;
5ff904cd 6959
c7e4ee3a
CB
6960 t = build_decl (VAR_DECL,
6961 ffecom_get_identifier_ (ffesymbol_text (s)),
6962 type);
5ff904cd 6963
c7e4ee3a
CB
6964 TREE_STATIC (t) = TREE_STATIC (mt);
6965 DECL_INITIAL (t) = NULL_TREE;
6966 TREE_ASM_WRITTEN (t) = 1;
045edebe 6967 TREE_USED (t) = 1;
5ff904cd 6968
19e7881c
MM
6969 SET_DECL_RTL (t,
6970 gen_rtx (MEM, TYPE_MODE (type),
6971 plus_constant (XEXP (DECL_RTL (mt), 0),
6972 ffestorag_modulo (mst)
6973 + ffestorag_offset (st)
6974 - ffestorag_offset (mst))));
5ff904cd 6975
c7e4ee3a 6976 t = start_decl (t, FALSE);
5ff904cd 6977
c7e4ee3a 6978 finish_decl (t, NULL_TREE, FALSE);
5ff904cd
JL
6979}
6980
c7e4ee3a
CB
6981/* Prepare source expression for assignment into a destination perhaps known
6982 to be of a specific size. */
5ff904cd 6983
c7e4ee3a
CB
6984static void
6985ffecom_prepare_let_char_ (ffetargetCharacterSize dest_size, ffebld source)
5ff904cd 6986{
c7e4ee3a
CB
6987 ffecomConcatList_ catlist;
6988 int count;
6989 int i;
6990 tree ltmp;
6991 tree itmp;
6992 tree tempvar = NULL_TREE;
5ff904cd 6993
c7e4ee3a
CB
6994 while (ffebld_op (source) == FFEBLD_opCONVERT)
6995 source = ffebld_left (source);
5ff904cd 6996
c7e4ee3a
CB
6997 catlist = ffecom_concat_list_new_ (source, dest_size);
6998 count = ffecom_concat_list_count_ (catlist);
5ff904cd 6999
c7e4ee3a
CB
7000 if (count >= 2)
7001 {
7002 ltmp
7003 = ffecom_make_tempvar ("let_char_len", ffecom_f2c_ftnlen_type_node,
7004 FFETARGET_charactersizeNONE, count);
7005 itmp
7006 = ffecom_make_tempvar ("let_char_item", ffecom_f2c_address_type_node,
7007 FFETARGET_charactersizeNONE, count);
7008
7009 tempvar = make_tree_vec (2);
7010 TREE_VEC_ELT (tempvar, 0) = ltmp;
7011 TREE_VEC_ELT (tempvar, 1) = itmp;
7012 }
5ff904cd 7013
c7e4ee3a
CB
7014 for (i = 0; i < count; ++i)
7015 ffecom_prepare_arg_ptr_to_expr (ffecom_concat_list_expr_ (catlist, i));
5ff904cd 7016
c7e4ee3a 7017 ffecom_concat_list_kill_ (catlist);
5ff904cd 7018
c7e4ee3a
CB
7019 if (tempvar)
7020 {
7021 ffebld_nonter_set_hook (source, tempvar);
7022 current_binding_level->prep_state = 1;
7023 }
7024}
5ff904cd 7025
c7e4ee3a 7026/* ffecom_push_dummy_decls_ -- Transform dummy args, push parm decls in order
5ff904cd 7027
c7e4ee3a
CB
7028 Ignores STAR (alternate-return) dummies. All other get exec-transitioned
7029 (which generates their trees) and then their trees get push_parm_decl'd.
5ff904cd 7030
c7e4ee3a
CB
7031 The second arg is TRUE if the dummies are for a statement function, in
7032 which case lengths are not pushed for character arguments (since they are
7033 always known by both the caller and the callee, though the code allows
7034 for someday permitting CHAR*(*) stmtfunc dummies). */
5ff904cd 7035
c7e4ee3a
CB
7036static void
7037ffecom_push_dummy_decls_ (ffebld dummy_list, bool stmtfunc)
7038{
7039 ffebld dummy;
7040 ffebld dumlist;
7041 ffesymbol s;
7042 tree parm;
5ff904cd 7043
c7e4ee3a 7044 ffecom_transform_only_dummies_ = TRUE;
5ff904cd 7045
c7e4ee3a 7046 /* First push the parms corresponding to actual dummy "contents". */
5ff904cd 7047
c7e4ee3a
CB
7048 for (dumlist = dummy_list; dumlist != NULL; dumlist = ffebld_trail (dumlist))
7049 {
7050 dummy = ffebld_head (dumlist);
7051 switch (ffebld_op (dummy))
7052 {
7053 case FFEBLD_opSTAR:
7054 case FFEBLD_opANY:
7055 continue; /* Forget alternate returns. */
5ff904cd 7056
c7e4ee3a
CB
7057 default:
7058 break;
7059 }
7060 assert (ffebld_op (dummy) == FFEBLD_opSYMTER);
7061 s = ffebld_symter (dummy);
7062 parm = ffesymbol_hook (s).decl_tree;
7063 if (parm == NULL_TREE)
7064 {
7065 s = ffecom_sym_transform_ (s);
7066 parm = ffesymbol_hook (s).decl_tree;
7067 assert (parm != NULL_TREE);
7068 }
7069 if (parm != error_mark_node)
7070 push_parm_decl (parm);
5ff904cd
JL
7071 }
7072
c7e4ee3a 7073 /* Then, for CHARACTER dummies, push the parms giving their lengths. */
5ff904cd 7074
c7e4ee3a
CB
7075 for (dumlist = dummy_list; dumlist != NULL; dumlist = ffebld_trail (dumlist))
7076 {
7077 dummy = ffebld_head (dumlist);
7078 switch (ffebld_op (dummy))
7079 {
7080 case FFEBLD_opSTAR:
7081 case FFEBLD_opANY:
7082 continue; /* Forget alternate returns, they mean
7083 NOTHING! */
7084
7085 default:
7086 break;
7087 }
7088 s = ffebld_symter (dummy);
7089 if (ffesymbol_basictype (s) != FFEINFO_basictypeCHARACTER)
7090 continue; /* Only looking for CHARACTER arguments. */
7091 if (stmtfunc && (ffesymbol_size (s) != FFETARGET_charactersizeNONE))
7092 continue; /* Stmtfunc arg with known size needs no
7093 length param. */
7094 if (ffesymbol_kind (s) != FFEINFO_kindENTITY)
7095 continue; /* Only looking for variables and arrays. */
7096 parm = ffesymbol_hook (s).length_tree;
7097 assert (parm != NULL_TREE);
7098 if (parm != error_mark_node)
7099 push_parm_decl (parm);
7100 }
7101
7102 ffecom_transform_only_dummies_ = FALSE;
5ff904cd
JL
7103}
7104
c7e4ee3a 7105/* ffecom_start_progunit_ -- Beginning of program unit
5ff904cd 7106
c7e4ee3a
CB
7107 Does GNU back end stuff necessary to teach it about the start of its
7108 equivalent of a Fortran program unit. */
5ff904cd 7109
5ff904cd 7110static void
c7e4ee3a 7111ffecom_start_progunit_ ()
5ff904cd 7112{
c7e4ee3a
CB
7113 ffesymbol fn = ffecom_primary_entry_;
7114 ffebld arglist;
7115 tree id; /* Identifier (name) of function. */
7116 tree type; /* Type of function. */
7117 tree result; /* Result of function. */
7118 ffeinfoBasictype bt;
7119 ffeinfoKindtype kt;
7120 ffeglobal g;
7121 ffeglobalType gt;
7122 ffeglobalType egt = FFEGLOBAL_type;
7123 bool charfunc;
7124 bool cmplxfunc;
7125 bool altentries = (ffecom_num_entrypoints_ != 0);
7126 bool multi
7127 = altentries
7128 && (ffecom_primary_entry_kind_ == FFEINFO_kindFUNCTION)
7129 && (ffecom_master_bt_ == FFEINFO_basictypeNONE);
7130 bool main_program = FALSE;
7131 int old_lineno = lineno;
3b304f5b 7132 const char *old_input_filename = input_filename;
5ff904cd 7133
c7e4ee3a
CB
7134 assert (fn != NULL);
7135 assert (ffesymbol_hook (fn).decl_tree == NULL_TREE);
5ff904cd 7136
c7e4ee3a
CB
7137 input_filename = ffesymbol_where_filename (fn);
7138 lineno = ffesymbol_where_filelinenum (fn);
5ff904cd 7139
c7e4ee3a
CB
7140 switch (ffecom_primary_entry_kind_)
7141 {
7142 case FFEINFO_kindPROGRAM:
7143 main_program = TRUE;
7144 gt = FFEGLOBAL_typeMAIN;
7145 bt = FFEINFO_basictypeNONE;
7146 kt = FFEINFO_kindtypeNONE;
7147 type = ffecom_tree_fun_type_void;
7148 charfunc = FALSE;
7149 cmplxfunc = FALSE;
7150 break;
7151
7152 case FFEINFO_kindBLOCKDATA:
7153 gt = FFEGLOBAL_typeBDATA;
7154 bt = FFEINFO_basictypeNONE;
7155 kt = FFEINFO_kindtypeNONE;
7156 type = ffecom_tree_fun_type_void;
7157 charfunc = FALSE;
7158 cmplxfunc = FALSE;
7159 break;
7160
7161 case FFEINFO_kindFUNCTION:
7162 gt = FFEGLOBAL_typeFUNC;
7163 egt = FFEGLOBAL_typeEXT;
7164 bt = ffesymbol_basictype (fn);
7165 kt = ffesymbol_kindtype (fn);
7166 if (bt == FFEINFO_basictypeNONE)
7167 {
7168 ffeimplic_establish_symbol (fn);
7169 if (ffesymbol_funcresult (fn) != NULL)
7170 ffeimplic_establish_symbol (ffesymbol_funcresult (fn));
7171 bt = ffesymbol_basictype (fn);
7172 kt = ffesymbol_kindtype (fn);
7173 }
7174
7175 if (multi)
7176 charfunc = cmplxfunc = FALSE;
7177 else if (bt == FFEINFO_basictypeCHARACTER)
7178 charfunc = TRUE, cmplxfunc = FALSE;
7179 else if ((bt == FFEINFO_basictypeCOMPLEX)
7180 && ffesymbol_is_f2c (fn)
7181 && !altentries)
7182 charfunc = FALSE, cmplxfunc = TRUE;
7183 else
7184 charfunc = cmplxfunc = FALSE;
7185
7186 if (multi || charfunc)
7187 type = ffecom_tree_fun_type_void;
7188 else if (ffesymbol_is_f2c (fn) && !altentries)
7189 type = ffecom_tree_fun_type[bt][kt];
7190 else
7191 type = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
7192
7193 if ((type == NULL_TREE)
7194 || (TREE_TYPE (type) == NULL_TREE))
7195 type = ffecom_tree_fun_type_void; /* _sym_exec_transition. */
7196 break;
7197
7198 case FFEINFO_kindSUBROUTINE:
7199 gt = FFEGLOBAL_typeSUBR;
7200 egt = FFEGLOBAL_typeEXT;
7201 bt = FFEINFO_basictypeNONE;
7202 kt = FFEINFO_kindtypeNONE;
7203 if (ffecom_is_altreturning_)
7204 type = ffecom_tree_subr_type;
7205 else
7206 type = ffecom_tree_fun_type_void;
7207 charfunc = FALSE;
7208 cmplxfunc = FALSE;
7209 break;
5ff904cd 7210
c7e4ee3a
CB
7211 default:
7212 assert ("say what??" == NULL);
7213 /* Fall through. */
7214 case FFEINFO_kindANY:
7215 gt = FFEGLOBAL_typeANY;
7216 bt = FFEINFO_basictypeNONE;
7217 kt = FFEINFO_kindtypeNONE;
7218 type = error_mark_node;
7219 charfunc = FALSE;
7220 cmplxfunc = FALSE;
7221 break;
7222 }
5ff904cd 7223
c7e4ee3a 7224 if (altentries)
5ff904cd 7225 {
c7e4ee3a 7226 id = ffecom_get_invented_identifier ("__g77_masterfun_%s",
14657de8 7227 ffesymbol_text (fn));
c7e4ee3a
CB
7228 }
7229#if FFETARGET_isENFORCED_MAIN
7230 else if (main_program)
7231 id = get_identifier (FFETARGET_nameENFORCED_MAIN_NAME);
7232#endif
7233 else
7234 id = ffecom_get_external_identifier_ (fn);
5ff904cd 7235
c7e4ee3a
CB
7236 start_function (id,
7237 type,
7238 0, /* nested/inline */
7239 !altentries); /* TREE_PUBLIC */
5ff904cd 7240
c7e4ee3a 7241 TREE_USED (current_function_decl) = 1; /* Avoid spurious warning if altentries. */
5ff904cd 7242
c7e4ee3a
CB
7243 if (!altentries
7244 && ((g = ffesymbol_global (fn)) != NULL)
7245 && ((ffeglobal_type (g) == gt)
7246 || (ffeglobal_type (g) == egt)))
7247 {
7248 ffeglobal_set_hook (g, current_function_decl);
7249 }
5ff904cd 7250
c7e4ee3a
CB
7251 /* Arg handling needs exec-transitioned ffesymbols to work with. But
7252 exec-transitioning needs current_function_decl to be filled in. So we
7253 do these things in two phases. */
5ff904cd 7254
c7e4ee3a
CB
7255 if (altentries)
7256 { /* 1st arg identifies which entrypoint. */
7257 ffecom_which_entrypoint_decl_
7258 = build_decl (PARM_DECL,
7259 ffecom_get_invented_identifier ("__g77_%s",
14657de8 7260 "which_entrypoint"),
c7e4ee3a
CB
7261 integer_type_node);
7262 push_parm_decl (ffecom_which_entrypoint_decl_);
7263 }
5ff904cd 7264
c7e4ee3a
CB
7265 if (charfunc
7266 || cmplxfunc
7267 || multi)
7268 { /* Arg for result (return value). */
7269 tree type;
7270 tree length;
5ff904cd 7271
c7e4ee3a
CB
7272 if (charfunc)
7273 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
7274 else if (cmplxfunc)
7275 type = ffecom_tree_type[FFEINFO_basictypeCOMPLEX][kt];
7276 else
7277 type = ffecom_multi_type_node_;
5ff904cd 7278
14657de8 7279 result = ffecom_get_invented_identifier ("__g77_%s", "result");
5ff904cd 7280
c7e4ee3a 7281 /* Make length arg _and_ enhance type info for CHAR arg itself. */
5ff904cd 7282
c7e4ee3a
CB
7283 if (charfunc)
7284 length = ffecom_char_enhance_arg_ (&type, fn);
7285 else
7286 length = NULL_TREE; /* Not ref'd if !charfunc. */
5ff904cd 7287
c7e4ee3a
CB
7288 type = build_pointer_type (type);
7289 result = build_decl (PARM_DECL, result, type);
5ff904cd 7290
c7e4ee3a
CB
7291 push_parm_decl (result);
7292 if (multi)
7293 ffecom_multi_retval_ = result;
7294 else
7295 ffecom_func_result_ = result;
5ff904cd 7296
c7e4ee3a
CB
7297 if (charfunc)
7298 {
7299 push_parm_decl (length);
7300 ffecom_func_length_ = length;
7301 }
5ff904cd
JL
7302 }
7303
c7e4ee3a
CB
7304 if (ffecom_primary_entry_is_proc_)
7305 {
7306 if (altentries)
7307 arglist = ffecom_master_arglist_;
7308 else
7309 arglist = ffesymbol_dummyargs (fn);
7310 ffecom_push_dummy_decls_ (arglist, FALSE);
7311 }
5ff904cd 7312
c7e4ee3a
CB
7313 if (TREE_CODE (current_function_decl) != ERROR_MARK)
7314 store_parm_decls (main_program ? 1 : 0);
5ff904cd 7315
c7e4ee3a
CB
7316 ffecom_start_compstmt ();
7317 /* Disallow temp vars at this level. */
7318 current_binding_level->prep_state = 2;
5ff904cd 7319
c7e4ee3a
CB
7320 lineno = old_lineno;
7321 input_filename = old_input_filename;
5ff904cd 7322
c7e4ee3a
CB
7323 /* This handles any symbols still untransformed, in case -g specified.
7324 This used to be done in ffecom_finish_progunit, but it turns out to
7325 be necessary to do it here so that statement functions are
7326 expanded before code. But don't bother for BLOCK DATA. */
5ff904cd 7327
c7e4ee3a
CB
7328 if (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA)
7329 ffesymbol_drive (ffecom_finish_symbol_transform_);
5ff904cd
JL
7330}
7331
c7e4ee3a 7332/* ffecom_sym_transform_ -- Transform FFE sym into backend sym
5ff904cd 7333
c7e4ee3a
CB
7334 ffesymbol s;
7335 ffecom_sym_transform_(s);
7336
7337 The ffesymbol_hook info for s is updated with appropriate backend info
7338 on the symbol. */
7339
c7e4ee3a
CB
7340static ffesymbol
7341ffecom_sym_transform_ (ffesymbol s)
7342{
7343 tree t; /* Transformed thingy. */
7344 tree tlen; /* Length if CHAR*(*). */
7345 bool addr; /* Is t the address of the thingy? */
7346 ffeinfoBasictype bt;
7347 ffeinfoKindtype kt;
7348 ffeglobal g;
c7e4ee3a 7349 int old_lineno = lineno;
3b304f5b 7350 const char *old_input_filename = input_filename;
5ff904cd 7351
c7e4ee3a
CB
7352 /* Must ensure special ASSIGN variables are declared at top of outermost
7353 block, else they'll end up in the innermost block when their first
7354 ASSIGN is seen, which leaves them out of scope when they're the
7355 subject of a GOTO or I/O statement.
5ff904cd 7356
c7e4ee3a
CB
7357 We make this variable even if -fugly-assign. Just let it go unused,
7358 in case it turns out there are cases where we really want to use this
7359 variable anyway (e.g. ASSIGN to INTEGER*2 variable). */
5ff904cd 7360
c7e4ee3a
CB
7361 if (! ffecom_transform_only_dummies_
7362 && ffesymbol_assigned (s)
7363 && ! ffesymbol_hook (s).assign_tree)
7364 s = ffecom_sym_transform_assign_ (s);
5ff904cd 7365
c7e4ee3a 7366 if (ffesymbol_sfdummyparent (s) == NULL)
5ff904cd 7367 {
c7e4ee3a
CB
7368 input_filename = ffesymbol_where_filename (s);
7369 lineno = ffesymbol_where_filelinenum (s);
7370 }
7371 else
7372 {
7373 ffesymbol sf = ffesymbol_sfdummyparent (s);
5ff904cd 7374
c7e4ee3a
CB
7375 input_filename = ffesymbol_where_filename (sf);
7376 lineno = ffesymbol_where_filelinenum (sf);
7377 }
6d433196 7378
c7e4ee3a
CB
7379 bt = ffeinfo_basictype (ffebld_info (s));
7380 kt = ffeinfo_kindtype (ffebld_info (s));
5ff904cd 7381
c7e4ee3a
CB
7382 t = NULL_TREE;
7383 tlen = NULL_TREE;
7384 addr = FALSE;
5ff904cd 7385
c7e4ee3a
CB
7386 switch (ffesymbol_kind (s))
7387 {
7388 case FFEINFO_kindNONE:
7389 switch (ffesymbol_where (s))
7390 {
7391 case FFEINFO_whereDUMMY: /* Subroutine or function. */
7392 assert (ffecom_transform_only_dummies_);
5ff904cd 7393
c7e4ee3a
CB
7394 /* Before 0.4, this could be ENTITY/DUMMY, but see
7395 ffestu_sym_end_transition -- no longer true (in particular, if
7396 it could be an ENTITY, it _will_ be made one, so that
7397 possibility won't come through here). So we never make length
7398 arg for CHARACTER type. */
5ff904cd 7399
c7e4ee3a
CB
7400 t = build_decl (PARM_DECL,
7401 ffecom_get_identifier_ (ffesymbol_text (s)),
7402 ffecom_tree_ptr_to_subr_type);
c7e4ee3a 7403 DECL_ARTIFICIAL (t) = 1;
c7e4ee3a
CB
7404 addr = TRUE;
7405 break;
5ff904cd 7406
c7e4ee3a
CB
7407 case FFEINFO_whereGLOBAL: /* Subroutine or function. */
7408 assert (!ffecom_transform_only_dummies_);
5ff904cd 7409
c7e4ee3a
CB
7410 if (((g = ffesymbol_global (s)) != NULL)
7411 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
7412 || (ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
7413 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
7414 && (ffeglobal_hook (g) != NULL_TREE)
7415 && ffe_is_globals ())
7416 {
7417 t = ffeglobal_hook (g);
7418 break;
7419 }
5ff904cd 7420
c7e4ee3a
CB
7421 t = build_decl (FUNCTION_DECL,
7422 ffecom_get_external_identifier_ (s),
7423 ffecom_tree_subr_type); /* Assume subr. */
7424 DECL_EXTERNAL (t) = 1;
7425 TREE_PUBLIC (t) = 1;
5ff904cd 7426
c7e4ee3a
CB
7427 t = start_decl (t, FALSE);
7428 finish_decl (t, NULL_TREE, FALSE);
795232f7 7429
c7e4ee3a
CB
7430 if ((g != NULL)
7431 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
7432 || (ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
7433 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
7434 ffeglobal_set_hook (g, t);
5ff904cd 7435
7189a4b0 7436 ffecom_save_tree_forever (t);
5ff904cd 7437
c7e4ee3a 7438 break;
5ff904cd 7439
c7e4ee3a
CB
7440 default:
7441 assert ("NONE where unexpected" == NULL);
7442 /* Fall through. */
7443 case FFEINFO_whereANY:
7444 break;
7445 }
5ff904cd 7446 break;
5ff904cd 7447
c7e4ee3a
CB
7448 case FFEINFO_kindENTITY:
7449 switch (ffeinfo_where (ffesymbol_info (s)))
7450 {
5ff904cd 7451
c7e4ee3a
CB
7452 case FFEINFO_whereCONSTANT:
7453 /* ~~Debugging info needed? */
7454 assert (!ffecom_transform_only_dummies_);
7455 t = error_mark_node; /* Shouldn't ever see this in expr. */
7456 break;
5ff904cd 7457
c7e4ee3a
CB
7458 case FFEINFO_whereLOCAL:
7459 assert (!ffecom_transform_only_dummies_);
5ff904cd 7460
c7e4ee3a
CB
7461 {
7462 ffestorag st = ffesymbol_storage (s);
7463 tree type;
5ff904cd 7464
c7e4ee3a
CB
7465 if ((st != NULL)
7466 && (ffestorag_size (st) == 0))
7467 {
7468 t = error_mark_node;
7469 break;
7470 }
5ff904cd 7471
c7e4ee3a 7472 type = ffecom_type_localvar_ (s, bt, kt);
5ff904cd 7473
c7e4ee3a
CB
7474 if (type == error_mark_node)
7475 {
7476 t = error_mark_node;
7477 break;
7478 }
5ff904cd 7479
c7e4ee3a
CB
7480 if ((st != NULL)
7481 && (ffestorag_parent (st) != NULL))
7482 { /* Child of EQUIVALENCE parent. */
7483 ffestorag est;
7484 tree et;
c7e4ee3a 7485 ffetargetOffset offset;
5ff904cd 7486
c7e4ee3a
CB
7487 est = ffestorag_parent (st);
7488 ffecom_transform_equiv_ (est);
5ff904cd 7489
c7e4ee3a
CB
7490 et = ffestorag_hook (est);
7491 assert (et != NULL_TREE);
5ff904cd 7492
c7e4ee3a
CB
7493 if (! TREE_STATIC (et))
7494 put_var_into_stack (et);
5ff904cd 7495
c7e4ee3a
CB
7496 offset = ffestorag_modulo (est)
7497 + ffestorag_offset (ffesymbol_storage (s))
7498 - ffestorag_offset (est);
5ff904cd 7499
c7e4ee3a 7500 ffecom_debug_kludge_ (et, "EQUIVALENCE", s, type, offset);
5ff904cd 7501
c7e4ee3a 7502 /* (t_type *) (((char *) &et) + offset) */
5ff904cd 7503
c7e4ee3a
CB
7504 t = convert (string_type_node, /* (char *) */
7505 ffecom_1 (ADDR_EXPR,
7506 build_pointer_type (TREE_TYPE (et)),
7507 et));
7508 t = ffecom_2 (PLUS_EXPR, TREE_TYPE (t),
7509 t,
7510 build_int_2 (offset, 0));
7511 t = convert (build_pointer_type (type),
7512 t);
d50108c7 7513 TREE_CONSTANT (t) = staticp (et);
5ff904cd 7514
c7e4ee3a 7515 addr = TRUE;
c7e4ee3a
CB
7516 }
7517 else
7518 {
7519 tree initexpr;
7520 bool init = ffesymbol_is_init (s);
5ff904cd 7521
c7e4ee3a
CB
7522 t = build_decl (VAR_DECL,
7523 ffecom_get_identifier_ (ffesymbol_text (s)),
7524 type);
5ff904cd 7525
c7e4ee3a
CB
7526 if (init
7527 || ffesymbol_namelisted (s)
7528#ifdef FFECOM_sizeMAXSTACKITEM
7529 || ((st != NULL)
7530 && (ffestorag_size (st) > FFECOM_sizeMAXSTACKITEM))
7531#endif
7532 || ((ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
7533 && (ffecom_primary_entry_kind_
7534 != FFEINFO_kindBLOCKDATA)
7535 && (ffesymbol_is_save (s) || ffe_is_saveall ())))
7536 TREE_STATIC (t) = !ffesymbol_attr (s, FFESYMBOL_attrADJUSTABLE);
7537 else
7538 TREE_STATIC (t) = 0; /* No need to make static. */
5ff904cd 7539
c7e4ee3a
CB
7540 if (init || ffe_is_init_local_zero ())
7541 DECL_INITIAL (t) = error_mark_node;
5ff904cd 7542
c7e4ee3a
CB
7543 /* Keep -Wunused from complaining about var if it
7544 is used as sfunc arg or DATA implied-DO. */
7545 if (ffesymbol_attrs (s) & FFESYMBOL_attrsSFARG)
7546 DECL_IN_SYSTEM_HEADER (t) = 1;
5ff904cd 7547
c7e4ee3a 7548 t = start_decl (t, FALSE);
5ff904cd 7549
c7e4ee3a
CB
7550 if (init)
7551 {
7552 if (ffesymbol_init (s) != NULL)
7553 initexpr = ffecom_expr (ffesymbol_init (s));
7554 else
7555 initexpr = ffecom_init_zero_ (t);
7556 }
7557 else if (ffe_is_init_local_zero ())
7558 initexpr = ffecom_init_zero_ (t);
7559 else
7560 initexpr = NULL_TREE; /* Not ref'd if !init. */
5ff904cd 7561
c7e4ee3a 7562 finish_decl (t, initexpr, FALSE);
5ff904cd 7563
06ceef4e 7564 if (st != NULL && DECL_SIZE (t) != error_mark_node)
c7e4ee3a 7565 {
06ceef4e 7566 assert (TREE_CODE (DECL_SIZE_UNIT (t)) == INTEGER_CST);
05bccae2
RK
7567 assert (0 == compare_tree_int (DECL_SIZE_UNIT (t),
7568 ffestorag_size (st)));
c7e4ee3a 7569 }
c7e4ee3a
CB
7570 }
7571 }
5ff904cd 7572 break;
5ff904cd 7573
c7e4ee3a
CB
7574 case FFEINFO_whereRESULT:
7575 assert (!ffecom_transform_only_dummies_);
5ff904cd 7576
c7e4ee3a
CB
7577 if (bt == FFEINFO_basictypeCHARACTER)
7578 { /* Result is already in list of dummies, use
7579 it (& length). */
7580 t = ffecom_func_result_;
7581 tlen = ffecom_func_length_;
7582 addr = TRUE;
7583 break;
7584 }
7585 if ((ffecom_num_entrypoints_ == 0)
7586 && (bt == FFEINFO_basictypeCOMPLEX)
7587 && (ffesymbol_is_f2c (ffecom_primary_entry_)))
7588 { /* Result is already in list of dummies, use
7589 it. */
7590 t = ffecom_func_result_;
7591 addr = TRUE;
7592 break;
7593 }
7594 if (ffecom_func_result_ != NULL_TREE)
7595 {
7596 t = ffecom_func_result_;
7597 break;
7598 }
7599 if ((ffecom_num_entrypoints_ != 0)
7600 && (ffecom_master_bt_ == FFEINFO_basictypeNONE))
7601 {
c7e4ee3a
CB
7602 assert (ffecom_multi_retval_ != NULL_TREE);
7603 t = ffecom_1 (INDIRECT_REF, ffecom_multi_type_node_,
7604 ffecom_multi_retval_);
7605 t = ffecom_2 (COMPONENT_REF, ffecom_tree_type[bt][kt],
7606 t, ffecom_multi_fields_[bt][kt]);
5ff904cd 7607
c7e4ee3a
CB
7608 break;
7609 }
5ff904cd 7610
c7e4ee3a
CB
7611 t = build_decl (VAR_DECL,
7612 ffecom_get_identifier_ (ffesymbol_text (s)),
7613 ffecom_tree_type[bt][kt]);
7614 TREE_STATIC (t) = 0; /* Put result on stack. */
7615 t = start_decl (t, FALSE);
7616 finish_decl (t, NULL_TREE, FALSE);
5ff904cd 7617
c7e4ee3a 7618 ffecom_func_result_ = t;
5ff904cd 7619
c7e4ee3a 7620 break;
5ff904cd 7621
c7e4ee3a
CB
7622 case FFEINFO_whereDUMMY:
7623 {
7624 tree type;
7625 ffebld dl;
7626 ffebld dim;
7627 tree low;
7628 tree high;
7629 tree old_sizes;
7630 bool adjustable = FALSE; /* Conditionally adjustable? */
5ff904cd 7631
c7e4ee3a
CB
7632 type = ffecom_tree_type[bt][kt];
7633 if (ffesymbol_sfdummyparent (s) != NULL)
7634 {
7635 if (current_function_decl == ffecom_outer_function_decl_)
7636 { /* Exec transition before sfunc
7637 context; get it later. */
7638 break;
7639 }
7640 t = ffecom_get_identifier_ (ffesymbol_text
7641 (ffesymbol_sfdummyparent (s)));
7642 }
7643 else
7644 t = ffecom_get_identifier_ (ffesymbol_text (s));
5ff904cd 7645
c7e4ee3a 7646 assert (ffecom_transform_only_dummies_);
5ff904cd 7647
c7e4ee3a
CB
7648 old_sizes = get_pending_sizes ();
7649 put_pending_sizes (old_sizes);
5ff904cd 7650
c7e4ee3a
CB
7651 if (bt == FFEINFO_basictypeCHARACTER)
7652 tlen = ffecom_char_enhance_arg_ (&type, s);
7653 type = ffecom_check_size_overflow_ (s, type, TRUE);
5ff904cd 7654
c7e4ee3a
CB
7655 for (dl = ffesymbol_dims (s); dl != NULL; dl = ffebld_trail (dl))
7656 {
7657 if (type == error_mark_node)
7658 break;
5ff904cd 7659
c7e4ee3a
CB
7660 dim = ffebld_head (dl);
7661 assert (ffebld_op (dim) == FFEBLD_opBOUNDS);
7662 if ((ffebld_left (dim) == NULL) || ffecom_doing_entry_)
7663 low = ffecom_integer_one_node;
7664 else
7665 low = ffecom_expr (ffebld_left (dim));
7666 assert (ffebld_right (dim) != NULL);
7667 if ((ffebld_op (ffebld_right (dim)) == FFEBLD_opSTAR)
7668 || ffecom_doing_entry_)
7669 {
7670 /* Used to just do high=low. But for ffecom_tree_
7671 canonize_ref_, it probably is important to correctly
7672 assess the size. E.g. given COMPLEX C(*),CFUNC and
7673 C(2)=CFUNC(C), overlap can happen, while it can't
7674 for, say, C(1)=CFUNC(C(2)). */
7675 /* Even more recently used to set to INT_MAX, but that
7676 broke when some overflow checking went into the back
7677 end. Now we just leave the upper bound unspecified. */
7678 high = NULL;
7679 }
7680 else
7681 high = ffecom_expr (ffebld_right (dim));
5ff904cd 7682
c7e4ee3a
CB
7683 /* Determine whether array is conditionally adjustable,
7684 to decide whether back-end magic is needed.
5ff904cd 7685
c7e4ee3a
CB
7686 Normally the front end uses the back-end function
7687 variable_size to wrap SAVE_EXPR's around expressions
7688 affecting the size/shape of an array so that the
7689 size/shape info doesn't change during execution
7690 of the compiled code even though variables and
7691 functions referenced in those expressions might.
5ff904cd 7692
c7e4ee3a
CB
7693 variable_size also makes sure those saved expressions
7694 get evaluated immediately upon entry to the
7695 compiled procedure -- the front end normally doesn't
7696 have to worry about that.
3cf0cea4 7697
c7e4ee3a
CB
7698 However, there is a problem with this that affects
7699 g77's implementation of entry points, and that is
7700 that it is _not_ true that each invocation of the
7701 compiled procedure is permitted to evaluate
7702 array size/shape info -- because it is possible
7703 that, for some invocations, that info is invalid (in
7704 which case it is "promised" -- i.e. a violation of
7705 the Fortran standard -- that the compiled code
7706 won't reference the array or its size/shape
7707 during that particular invocation).
5ff904cd 7708
c7e4ee3a 7709 To phrase this in C terms, consider this gcc function:
5ff904cd 7710
c7e4ee3a
CB
7711 void foo (int *n, float (*a)[*n])
7712 {
7713 // a is "pointer to array ...", fyi.
7714 }
5ff904cd 7715
c7e4ee3a
CB
7716 Suppose that, for some invocations, it is permitted
7717 for a caller of foo to do this:
5ff904cd 7718
c7e4ee3a 7719 foo (NULL, NULL);
5ff904cd 7720
c7e4ee3a
CB
7721 Now the _written_ code for foo can take such a call
7722 into account by either testing explicitly for whether
7723 (a == NULL) || (n == NULL) -- presumably it is
7724 not permitted to reference *a in various fashions
7725 if (n == NULL) I suppose -- or it can avoid it by
7726 looking at other info (other arguments, static/global
7727 data, etc.).
5ff904cd 7728
c7e4ee3a
CB
7729 However, this won't work in gcc 2.5.8 because it'll
7730 automatically emit the code to save the "*n"
7731 expression, which'll yield a NULL dereference for
7732 the "foo (NULL, NULL)" call, something the code
7733 for foo cannot prevent.
5ff904cd 7734
c7e4ee3a
CB
7735 g77 definitely needs to avoid executing such
7736 code anytime the pointer to the adjustable array
7737 is NULL, because even if its bounds expressions
7738 don't have any references to possible "absent"
7739 variables like "*n" -- say all variable references
7740 are to COMMON variables, i.e. global (though in C,
7741 local static could actually make sense) -- the
7742 expressions could yield other run-time problems
7743 for allowably "dead" values in those variables.
5ff904cd 7744
c7e4ee3a
CB
7745 For example, let's consider a more complicated
7746 version of foo:
5ff904cd 7747
c7e4ee3a
CB
7748 extern int i;
7749 extern int j;
5ff904cd 7750
c7e4ee3a
CB
7751 void foo (float (*a)[i/j])
7752 {
7753 ...
7754 }
5ff904cd 7755
c7e4ee3a
CB
7756 The above is (essentially) quite valid for Fortran
7757 but, again, for a call like "foo (NULL);", it is
7758 permitted for i and j to be undefined when the
7759 call is made. If j happened to be zero, for
7760 example, emitting the code to evaluate "i/j"
7761 could result in a run-time error.
5ff904cd 7762
c7e4ee3a
CB
7763 Offhand, though I don't have my F77 or F90
7764 standards handy, it might even be valid for a
7765 bounds expression to contain a function reference,
7766 in which case I doubt it is permitted for an
7767 implementation to invoke that function in the
7768 Fortran case involved here (invocation of an
7769 alternate ENTRY point that doesn't have the adjustable
7770 array as one of its arguments).
5ff904cd 7771
c7e4ee3a
CB
7772 So, the code that the compiler would normally emit
7773 to preevaluate the size/shape info for an
7774 adjustable array _must not_ be executed at run time
7775 in certain cases. Specifically, for Fortran,
7776 the case is when the pointer to the adjustable
7777 array == NULL. (For gnu-ish C, it might be nice
7778 for the source code itself to specify an expression
7779 that, if TRUE, inhibits execution of the code. Or
7780 reverse the sense for elegance.)
5ff904cd 7781
c7e4ee3a
CB
7782 (Note that g77 could use a different test than NULL,
7783 actually, since it happens to always pass an
7784 integer to the called function that specifies which
7785 entry point is being invoked. Hmm, this might
7786 solve the next problem.)
7787
7788 One way a user could, I suppose, write "foo" so
7789 it works is to insert COND_EXPR's for the
7790 size/shape info so the dangerous stuff isn't
7791 actually done, as in:
7792
7793 void foo (int *n, float (*a)[(a == NULL) ? 0 : *n])
7794 {
7795 ...
7796 }
5ff904cd 7797
c7e4ee3a
CB
7798 The next problem is that the front end needs to
7799 be able to tell the back end about the array's
7800 decl _before_ it tells it about the conditional
7801 expression to inhibit evaluation of size/shape info,
7802 as shown above.
5ff904cd 7803
c7e4ee3a
CB
7804 To solve this, the front end needs to be able
7805 to give the back end the expression to inhibit
7806 generation of the preevaluation code _after_
7807 it makes the decl for the adjustable array.
5ff904cd 7808
c7e4ee3a
CB
7809 Until then, the above example using the COND_EXPR
7810 doesn't pass muster with gcc because the "(a == NULL)"
7811 part has a reference to "a", which is still
7812 undefined at that point.
5ff904cd 7813
c7e4ee3a
CB
7814 g77 will therefore use a different mechanism in the
7815 meantime. */
5ff904cd 7816
c7e4ee3a
CB
7817 if (!adjustable
7818 && ((TREE_CODE (low) != INTEGER_CST)
7819 || (high && TREE_CODE (high) != INTEGER_CST)))
7820 adjustable = TRUE;
5ff904cd 7821
c7e4ee3a
CB
7822#if 0 /* Old approach -- see below. */
7823 if (TREE_CODE (low) != INTEGER_CST)
7824 low = ffecom_3 (COND_EXPR, integer_type_node,
7825 ffecom_adjarray_passed_ (s),
7826 low,
7827 ffecom_integer_zero_node);
5ff904cd 7828
c7e4ee3a
CB
7829 if (high && TREE_CODE (high) != INTEGER_CST)
7830 high = ffecom_3 (COND_EXPR, integer_type_node,
7831 ffecom_adjarray_passed_ (s),
7832 high,
7833 ffecom_integer_zero_node);
7834#endif
5ff904cd 7835
c7e4ee3a
CB
7836 /* ~~~gcc/stor-layout.c (layout_type) should do this,
7837 probably. Fixes 950302-1.f. */
5ff904cd 7838
c7e4ee3a
CB
7839 if (TREE_CODE (low) != INTEGER_CST)
7840 low = variable_size (low);
5ff904cd 7841
c7e4ee3a
CB
7842 /* ~~~Similarly, this fixes dumb0.f. The C front end
7843 does this, which is why dumb0.c would work. */
5ff904cd 7844
c7e4ee3a
CB
7845 if (high && TREE_CODE (high) != INTEGER_CST)
7846 high = variable_size (high);
5ff904cd 7847
c7e4ee3a
CB
7848 type
7849 = build_array_type
7850 (type,
7851 build_range_type (ffecom_integer_type_node,
7852 low, high));
7853 type = ffecom_check_size_overflow_ (s, type, TRUE);
7854 }
5ff904cd 7855
c7e4ee3a
CB
7856 if (type == error_mark_node)
7857 {
7858 t = error_mark_node;
7859 break;
7860 }
5ff904cd 7861
c7e4ee3a
CB
7862 if ((ffesymbol_sfdummyparent (s) == NULL)
7863 || (ffesymbol_basictype (s) == FFEINFO_basictypeCHARACTER))
7864 {
7865 type = build_pointer_type (type);
7866 addr = TRUE;
7867 }
5ff904cd 7868
c7e4ee3a 7869 t = build_decl (PARM_DECL, t, type);
c7e4ee3a 7870 DECL_ARTIFICIAL (t) = 1;
5ff904cd 7871
c7e4ee3a
CB
7872 /* If this arg is present in every entry point's list of
7873 dummy args, then we're done. */
5ff904cd 7874
c7e4ee3a
CB
7875 if (ffesymbol_numentries (s)
7876 == (ffecom_num_entrypoints_ + 1))
5ff904cd 7877 break;
5ff904cd 7878
c7e4ee3a 7879#if 1
5ff904cd 7880
c7e4ee3a
CB
7881 /* If variable_size in stor-layout has been called during
7882 the above, then get_pending_sizes should have the
7883 yet-to-be-evaluated saved expressions pending.
7884 Make the whole lot of them get emitted, conditionally
7885 on whether the array decl ("t" above) is not NULL. */
5ff904cd 7886
c7e4ee3a
CB
7887 {
7888 tree sizes = get_pending_sizes ();
7889 tree tem;
5ff904cd 7890
c7e4ee3a
CB
7891 for (tem = sizes;
7892 tem != old_sizes;
7893 tem = TREE_CHAIN (tem))
7894 {
7895 tree temv = TREE_VALUE (tem);
5ff904cd 7896
c7e4ee3a
CB
7897 if (sizes == tem)
7898 sizes = temv;
7899 else
7900 sizes
7901 = ffecom_2 (COMPOUND_EXPR,
7902 TREE_TYPE (sizes),
7903 temv,
7904 sizes);
7905 }
5ff904cd 7906
c7e4ee3a
CB
7907 if (sizes != tem)
7908 {
7909 sizes
7910 = ffecom_3 (COND_EXPR,
7911 TREE_TYPE (sizes),
7912 ffecom_2 (NE_EXPR,
7913 integer_type_node,
7914 t,
7915 null_pointer_node),
7916 sizes,
7917 convert (TREE_TYPE (sizes),
7918 integer_zero_node));
7919 sizes = ffecom_save_tree (sizes);
5ff904cd 7920
c7e4ee3a
CB
7921 sizes
7922 = tree_cons (NULL_TREE, sizes, tem);
7923 }
5ff904cd 7924
c7e4ee3a
CB
7925 if (sizes)
7926 put_pending_sizes (sizes);
7927 }
5ff904cd 7928
c7e4ee3a
CB
7929#else
7930#if 0
7931 if (adjustable
7932 && (ffesymbol_numentries (s)
7933 != ffecom_num_entrypoints_ + 1))
7934 DECL_SOMETHING (t)
7935 = ffecom_2 (NE_EXPR, integer_type_node,
7936 t,
7937 null_pointer_node);
7938#else
7939#if 0
7940 if (adjustable
7941 && (ffesymbol_numentries (s)
7942 != ffecom_num_entrypoints_ + 1))
7943 {
7944 ffebad_start (FFEBAD_MISSING_ADJARRAY_UNSUPPORTED);
7945 ffebad_here (0, ffesymbol_where_line (s),
7946 ffesymbol_where_column (s));
7947 ffebad_string (ffesymbol_text (s));
7948 ffebad_finish ();
7949 }
7950#endif
7951#endif
7952#endif
7953 }
5ff904cd
JL
7954 break;
7955
c7e4ee3a 7956 case FFEINFO_whereCOMMON:
5ff904cd 7957 {
c7e4ee3a
CB
7958 ffesymbol cs;
7959 ffeglobal cg;
7960 tree ct;
5ff904cd
JL
7961 ffestorag st = ffesymbol_storage (s);
7962 tree type;
7963
c7e4ee3a
CB
7964 cs = ffesymbol_common (s); /* The COMMON area itself. */
7965 if (st != NULL) /* Else not laid out. */
5ff904cd 7966 {
c7e4ee3a
CB
7967 ffecom_transform_common_ (cs);
7968 st = ffesymbol_storage (s);
5ff904cd
JL
7969 }
7970
c7e4ee3a 7971 type = ffecom_type_localvar_ (s, bt, kt);
5ff904cd 7972
c7e4ee3a
CB
7973 cg = ffesymbol_global (cs); /* The global COMMON info. */
7974 if ((cg == NULL)
7975 || (ffeglobal_type (cg) != FFEGLOBAL_typeCOMMON))
7976 ct = NULL_TREE;
7977 else
7978 ct = ffeglobal_hook (cg); /* The common area's tree. */
5ff904cd 7979
c7e4ee3a
CB
7980 if ((ct == NULL_TREE)
7981 || (st == NULL)
7982 || (type == error_mark_node))
7983 t = error_mark_node;
7984 else
7985 {
7986 ffetargetOffset offset;
7987 ffestorag cst;
5ff904cd 7988
c7e4ee3a
CB
7989 cst = ffestorag_parent (st);
7990 assert (cst == ffesymbol_storage (cs));
5ff904cd 7991
c7e4ee3a
CB
7992 offset = ffestorag_modulo (cst)
7993 + ffestorag_offset (st)
7994 - ffestorag_offset (cst);
5ff904cd 7995
c7e4ee3a 7996 ffecom_debug_kludge_ (ct, "COMMON", s, type, offset);
5ff904cd 7997
c7e4ee3a 7998 /* (t_type *) (((char *) &ct) + offset) */
5ff904cd
JL
7999
8000 t = convert (string_type_node, /* (char *) */
8001 ffecom_1 (ADDR_EXPR,
c7e4ee3a
CB
8002 build_pointer_type (TREE_TYPE (ct)),
8003 ct));
5ff904cd
JL
8004 t = ffecom_2 (PLUS_EXPR, TREE_TYPE (t),
8005 t,
8006 build_int_2 (offset, 0));
8007 t = convert (build_pointer_type (type),
8008 t);
d50108c7 8009 TREE_CONSTANT (t) = 1;
5ff904cd
JL
8010
8011 addr = TRUE;
5ff904cd 8012 }
c7e4ee3a
CB
8013 }
8014 break;
5ff904cd 8015
c7e4ee3a
CB
8016 case FFEINFO_whereIMMEDIATE:
8017 case FFEINFO_whereGLOBAL:
8018 case FFEINFO_whereFLEETING:
8019 case FFEINFO_whereFLEETING_CADDR:
8020 case FFEINFO_whereFLEETING_IADDR:
8021 case FFEINFO_whereINTRINSIC:
8022 case FFEINFO_whereCONSTANT_SUBOBJECT:
8023 default:
8024 assert ("ENTITY where unheard of" == NULL);
8025 /* Fall through. */
8026 case FFEINFO_whereANY:
8027 t = error_mark_node;
8028 break;
8029 }
8030 break;
5ff904cd 8031
c7e4ee3a
CB
8032 case FFEINFO_kindFUNCTION:
8033 switch (ffeinfo_where (ffesymbol_info (s)))
8034 {
8035 case FFEINFO_whereLOCAL: /* Me. */
8036 assert (!ffecom_transform_only_dummies_);
8037 t = current_function_decl;
5ff904cd
JL
8038 break;
8039
c7e4ee3a 8040 case FFEINFO_whereGLOBAL:
5ff904cd
JL
8041 assert (!ffecom_transform_only_dummies_);
8042
c7e4ee3a
CB
8043 if (((g = ffesymbol_global (s)) != NULL)
8044 && ((ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
8045 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
8046 && (ffeglobal_hook (g) != NULL_TREE)
8047 && ffe_is_globals ())
5ff904cd 8048 {
c7e4ee3a 8049 t = ffeglobal_hook (g);
5ff904cd
JL
8050 break;
8051 }
5ff904cd 8052
c7e4ee3a
CB
8053 if (ffesymbol_is_f2c (s)
8054 && (ffesymbol_where (s) != FFEINFO_whereCONSTANT))
8055 t = ffecom_tree_fun_type[bt][kt];
8056 else
8057 t = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
5ff904cd 8058
c7e4ee3a
CB
8059 t = build_decl (FUNCTION_DECL,
8060 ffecom_get_external_identifier_ (s),
8061 t);
8062 DECL_EXTERNAL (t) = 1;
8063 TREE_PUBLIC (t) = 1;
5ff904cd 8064
5ff904cd
JL
8065 t = start_decl (t, FALSE);
8066 finish_decl (t, NULL_TREE, FALSE);
8067
c7e4ee3a
CB
8068 if ((g != NULL)
8069 && ((ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
8070 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
8071 ffeglobal_set_hook (g, t);
8072
7189a4b0 8073 ffecom_save_tree_forever (t);
5ff904cd 8074
5ff904cd
JL
8075 break;
8076
8077 case FFEINFO_whereDUMMY:
c7e4ee3a 8078 assert (ffecom_transform_only_dummies_);
5ff904cd 8079
c7e4ee3a
CB
8080 if (ffesymbol_is_f2c (s)
8081 && (ffesymbol_where (s) != FFEINFO_whereCONSTANT))
8082 t = ffecom_tree_ptr_to_fun_type[bt][kt];
8083 else
8084 t = build_pointer_type
8085 (build_function_type (ffecom_tree_type[bt][kt], NULL_TREE));
8086
8087 t = build_decl (PARM_DECL,
8088 ffecom_get_identifier_ (ffesymbol_text (s)),
8089 t);
c7e4ee3a 8090 DECL_ARTIFICIAL (t) = 1;
c7e4ee3a
CB
8091 addr = TRUE;
8092 break;
8093
8094 case FFEINFO_whereCONSTANT: /* Statement function. */
8095 assert (!ffecom_transform_only_dummies_);
8096 t = ffecom_gen_sfuncdef_ (s, bt, kt);
8097 break;
8098
8099 case FFEINFO_whereINTRINSIC:
8100 assert (!ffecom_transform_only_dummies_);
8101 break; /* Let actual references generate their
8102 decls. */
8103
8104 default:
8105 assert ("FUNCTION where unheard of" == NULL);
8106 /* Fall through. */
8107 case FFEINFO_whereANY:
8108 t = error_mark_node;
8109 break;
8110 }
8111 break;
8112
8113 case FFEINFO_kindSUBROUTINE:
8114 switch (ffeinfo_where (ffesymbol_info (s)))
8115 {
8116 case FFEINFO_whereLOCAL: /* Me. */
8117 assert (!ffecom_transform_only_dummies_);
8118 t = current_function_decl;
8119 break;
5ff904cd 8120
c7e4ee3a
CB
8121 case FFEINFO_whereGLOBAL:
8122 assert (!ffecom_transform_only_dummies_);
5ff904cd 8123
c7e4ee3a
CB
8124 if (((g = ffesymbol_global (s)) != NULL)
8125 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
8126 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
8127 && (ffeglobal_hook (g) != NULL_TREE)
8128 && ffe_is_globals ())
8129 {
8130 t = ffeglobal_hook (g);
8131 break;
8132 }
5ff904cd 8133
c7e4ee3a
CB
8134 t = build_decl (FUNCTION_DECL,
8135 ffecom_get_external_identifier_ (s),
8136 ffecom_tree_subr_type);
8137 DECL_EXTERNAL (t) = 1;
8138 TREE_PUBLIC (t) = 1;
5ff904cd 8139
c7e4ee3a
CB
8140 t = start_decl (t, FALSE);
8141 finish_decl (t, NULL_TREE, FALSE);
5ff904cd 8142
c7e4ee3a
CB
8143 if ((g != NULL)
8144 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
8145 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
8146 ffeglobal_set_hook (g, t);
5ff904cd 8147
7189a4b0 8148 ffecom_save_tree_forever (t);
5ff904cd 8149
c7e4ee3a 8150 break;
5ff904cd 8151
c7e4ee3a
CB
8152 case FFEINFO_whereDUMMY:
8153 assert (ffecom_transform_only_dummies_);
5ff904cd 8154
c7e4ee3a
CB
8155 t = build_decl (PARM_DECL,
8156 ffecom_get_identifier_ (ffesymbol_text (s)),
8157 ffecom_tree_ptr_to_subr_type);
c7e4ee3a 8158 DECL_ARTIFICIAL (t) = 1;
c7e4ee3a
CB
8159 addr = TRUE;
8160 break;
5ff904cd 8161
c7e4ee3a
CB
8162 case FFEINFO_whereINTRINSIC:
8163 assert (!ffecom_transform_only_dummies_);
8164 break; /* Let actual references generate their
8165 decls. */
5ff904cd 8166
c7e4ee3a
CB
8167 default:
8168 assert ("SUBROUTINE where unheard of" == NULL);
8169 /* Fall through. */
8170 case FFEINFO_whereANY:
8171 t = error_mark_node;
8172 break;
8173 }
8174 break;
5ff904cd 8175
c7e4ee3a
CB
8176 case FFEINFO_kindPROGRAM:
8177 switch (ffeinfo_where (ffesymbol_info (s)))
8178 {
8179 case FFEINFO_whereLOCAL: /* Me. */
8180 assert (!ffecom_transform_only_dummies_);
8181 t = current_function_decl;
8182 break;
5ff904cd 8183
c7e4ee3a
CB
8184 case FFEINFO_whereCOMMON:
8185 case FFEINFO_whereDUMMY:
8186 case FFEINFO_whereGLOBAL:
8187 case FFEINFO_whereRESULT:
8188 case FFEINFO_whereFLEETING:
8189 case FFEINFO_whereFLEETING_CADDR:
8190 case FFEINFO_whereFLEETING_IADDR:
8191 case FFEINFO_whereIMMEDIATE:
8192 case FFEINFO_whereINTRINSIC:
8193 case FFEINFO_whereCONSTANT:
8194 case FFEINFO_whereCONSTANT_SUBOBJECT:
8195 default:
8196 assert ("PROGRAM where unheard of" == NULL);
8197 /* Fall through. */
8198 case FFEINFO_whereANY:
8199 t = error_mark_node;
8200 break;
8201 }
8202 break;
5ff904cd 8203
c7e4ee3a
CB
8204 case FFEINFO_kindBLOCKDATA:
8205 switch (ffeinfo_where (ffesymbol_info (s)))
8206 {
8207 case FFEINFO_whereLOCAL: /* Me. */
8208 assert (!ffecom_transform_only_dummies_);
8209 t = current_function_decl;
8210 break;
5ff904cd 8211
c7e4ee3a
CB
8212 case FFEINFO_whereGLOBAL:
8213 assert (!ffecom_transform_only_dummies_);
5ff904cd 8214
c7e4ee3a
CB
8215 t = build_decl (FUNCTION_DECL,
8216 ffecom_get_external_identifier_ (s),
8217 ffecom_tree_blockdata_type);
8218 DECL_EXTERNAL (t) = 1;
8219 TREE_PUBLIC (t) = 1;
5ff904cd 8220
c7e4ee3a
CB
8221 t = start_decl (t, FALSE);
8222 finish_decl (t, NULL_TREE, FALSE);
5ff904cd 8223
7189a4b0 8224 ffecom_save_tree_forever (t);
5ff904cd 8225
c7e4ee3a 8226 break;
5ff904cd 8227
c7e4ee3a
CB
8228 case FFEINFO_whereCOMMON:
8229 case FFEINFO_whereDUMMY:
8230 case FFEINFO_whereRESULT:
8231 case FFEINFO_whereFLEETING:
8232 case FFEINFO_whereFLEETING_CADDR:
8233 case FFEINFO_whereFLEETING_IADDR:
8234 case FFEINFO_whereIMMEDIATE:
8235 case FFEINFO_whereINTRINSIC:
8236 case FFEINFO_whereCONSTANT:
8237 case FFEINFO_whereCONSTANT_SUBOBJECT:
8238 default:
8239 assert ("BLOCKDATA where unheard of" == NULL);
8240 /* Fall through. */
8241 case FFEINFO_whereANY:
8242 t = error_mark_node;
8243 break;
8244 }
8245 break;
5ff904cd 8246
c7e4ee3a
CB
8247 case FFEINFO_kindCOMMON:
8248 switch (ffeinfo_where (ffesymbol_info (s)))
8249 {
8250 case FFEINFO_whereLOCAL:
8251 assert (!ffecom_transform_only_dummies_);
8252 ffecom_transform_common_ (s);
8253 break;
8254
8255 case FFEINFO_whereNONE:
8256 case FFEINFO_whereCOMMON:
8257 case FFEINFO_whereDUMMY:
8258 case FFEINFO_whereGLOBAL:
8259 case FFEINFO_whereRESULT:
8260 case FFEINFO_whereFLEETING:
8261 case FFEINFO_whereFLEETING_CADDR:
8262 case FFEINFO_whereFLEETING_IADDR:
8263 case FFEINFO_whereIMMEDIATE:
8264 case FFEINFO_whereINTRINSIC:
8265 case FFEINFO_whereCONSTANT:
8266 case FFEINFO_whereCONSTANT_SUBOBJECT:
8267 default:
8268 assert ("COMMON where unheard of" == NULL);
8269 /* Fall through. */
8270 case FFEINFO_whereANY:
8271 t = error_mark_node;
8272 break;
8273 }
8274 break;
5ff904cd 8275
c7e4ee3a
CB
8276 case FFEINFO_kindCONSTRUCT:
8277 switch (ffeinfo_where (ffesymbol_info (s)))
8278 {
8279 case FFEINFO_whereLOCAL:
8280 assert (!ffecom_transform_only_dummies_);
8281 break;
5ff904cd 8282
c7e4ee3a
CB
8283 case FFEINFO_whereNONE:
8284 case FFEINFO_whereCOMMON:
8285 case FFEINFO_whereDUMMY:
8286 case FFEINFO_whereGLOBAL:
8287 case FFEINFO_whereRESULT:
8288 case FFEINFO_whereFLEETING:
8289 case FFEINFO_whereFLEETING_CADDR:
8290 case FFEINFO_whereFLEETING_IADDR:
8291 case FFEINFO_whereIMMEDIATE:
8292 case FFEINFO_whereINTRINSIC:
8293 case FFEINFO_whereCONSTANT:
8294 case FFEINFO_whereCONSTANT_SUBOBJECT:
8295 default:
8296 assert ("CONSTRUCT where unheard of" == NULL);
8297 /* Fall through. */
8298 case FFEINFO_whereANY:
8299 t = error_mark_node;
8300 break;
8301 }
8302 break;
5ff904cd 8303
c7e4ee3a
CB
8304 case FFEINFO_kindNAMELIST:
8305 switch (ffeinfo_where (ffesymbol_info (s)))
8306 {
8307 case FFEINFO_whereLOCAL:
8308 assert (!ffecom_transform_only_dummies_);
8309 t = ffecom_transform_namelist_ (s);
8310 break;
5ff904cd 8311
c7e4ee3a
CB
8312 case FFEINFO_whereNONE:
8313 case FFEINFO_whereCOMMON:
8314 case FFEINFO_whereDUMMY:
8315 case FFEINFO_whereGLOBAL:
8316 case FFEINFO_whereRESULT:
8317 case FFEINFO_whereFLEETING:
8318 case FFEINFO_whereFLEETING_CADDR:
8319 case FFEINFO_whereFLEETING_IADDR:
8320 case FFEINFO_whereIMMEDIATE:
8321 case FFEINFO_whereINTRINSIC:
8322 case FFEINFO_whereCONSTANT:
8323 case FFEINFO_whereCONSTANT_SUBOBJECT:
8324 default:
8325 assert ("NAMELIST where unheard of" == NULL);
8326 /* Fall through. */
8327 case FFEINFO_whereANY:
8328 t = error_mark_node;
8329 break;
8330 }
8331 break;
5ff904cd 8332
c7e4ee3a
CB
8333 default:
8334 assert ("kind unheard of" == NULL);
8335 /* Fall through. */
8336 case FFEINFO_kindANY:
8337 t = error_mark_node;
8338 break;
8339 }
5ff904cd 8340
c7e4ee3a
CB
8341 ffesymbol_hook (s).decl_tree = t;
8342 ffesymbol_hook (s).length_tree = tlen;
8343 ffesymbol_hook (s).addr = addr;
5ff904cd 8344
c7e4ee3a
CB
8345 lineno = old_lineno;
8346 input_filename = old_input_filename;
5ff904cd 8347
c7e4ee3a
CB
8348 return s;
8349}
5ff904cd 8350
c7e4ee3a 8351/* Transform into ASSIGNable symbol.
5ff904cd 8352
c7e4ee3a
CB
8353 Symbol has already been transformed, but for whatever reason, the
8354 resulting decl_tree has been deemed not usable for an ASSIGN target.
8355 (E.g. it isn't wide enough to hold a pointer.) So, here we invent
8356 another local symbol of type void * and stuff that in the assign_tree
8357 argument. The F77/F90 standards allow this implementation. */
5ff904cd 8358
c7e4ee3a
CB
8359static ffesymbol
8360ffecom_sym_transform_assign_ (ffesymbol s)
8361{
8362 tree t; /* Transformed thingy. */
c7e4ee3a 8363 int old_lineno = lineno;
3b304f5b 8364 const char *old_input_filename = input_filename;
5ff904cd 8365
c7e4ee3a
CB
8366 if (ffesymbol_sfdummyparent (s) == NULL)
8367 {
8368 input_filename = ffesymbol_where_filename (s);
8369 lineno = ffesymbol_where_filelinenum (s);
8370 }
8371 else
8372 {
8373 ffesymbol sf = ffesymbol_sfdummyparent (s);
5ff904cd 8374
c7e4ee3a
CB
8375 input_filename = ffesymbol_where_filename (sf);
8376 lineno = ffesymbol_where_filelinenum (sf);
8377 }
5ff904cd 8378
c7e4ee3a 8379 assert (!ffecom_transform_only_dummies_);
5ff904cd 8380
c7e4ee3a
CB
8381 t = build_decl (VAR_DECL,
8382 ffecom_get_invented_identifier ("__g77_ASSIGN_%s",
14657de8 8383 ffesymbol_text (s)),
c7e4ee3a 8384 TREE_TYPE (null_pointer_node));
5ff904cd 8385
c7e4ee3a
CB
8386 switch (ffesymbol_where (s))
8387 {
8388 case FFEINFO_whereLOCAL:
8389 /* Unlike for regular vars, SAVE status is easy to determine for
8390 ASSIGNed vars, since there's no initialization, there's no
8391 effective storage association (so "SAVE J" does not apply to
8392 K even given "EQUIVALENCE (J,K)"), there's no size issue
8393 to worry about, etc. */
8394 if ((ffesymbol_is_save (s) || ffe_is_saveall ())
8395 && (ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
8396 && (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA))
8397 TREE_STATIC (t) = 1; /* SAVEd in proc, make static. */
8398 else
8399 TREE_STATIC (t) = 0; /* No need to make static. */
8400 break;
5ff904cd 8401
c7e4ee3a
CB
8402 case FFEINFO_whereCOMMON:
8403 TREE_STATIC (t) = 1; /* Assume COMMONs always SAVEd. */
8404 break;
5ff904cd 8405
c7e4ee3a
CB
8406 case FFEINFO_whereDUMMY:
8407 /* Note that twinning a DUMMY means the caller won't see
8408 the ASSIGNed value. But both F77 and F90 allow implementations
8409 to do this, i.e. disallow Fortran code that would try and
8410 take advantage of actually putting a label into a variable
8411 via a dummy argument (or any other storage association, for
8412 that matter). */
8413 TREE_STATIC (t) = 0;
8414 break;
5ff904cd 8415
c7e4ee3a
CB
8416 default:
8417 TREE_STATIC (t) = 0;
8418 break;
8419 }
5ff904cd 8420
c7e4ee3a
CB
8421 t = start_decl (t, FALSE);
8422 finish_decl (t, NULL_TREE, FALSE);
5ff904cd 8423
c7e4ee3a 8424 ffesymbol_hook (s).assign_tree = t;
5ff904cd 8425
c7e4ee3a
CB
8426 lineno = old_lineno;
8427 input_filename = old_input_filename;
5ff904cd 8428
c7e4ee3a
CB
8429 return s;
8430}
5ff904cd 8431
c7e4ee3a 8432/* Implement COMMON area in back end.
5ff904cd 8433
c7e4ee3a
CB
8434 Because COMMON-based variables can be referenced in the dimension
8435 expressions of dummy (adjustable) arrays, and because dummies
8436 (in the gcc back end) need to be put in the outer binding level
8437 of a function (which has two binding levels, the outer holding
8438 the dummies and the inner holding the other vars), special care
8439 must be taken to handle COMMON areas.
5ff904cd 8440
c7e4ee3a
CB
8441 The current strategy is basically to always tell the back end about
8442 the COMMON area as a top-level external reference to just a block
8443 of storage of the master type of that area (e.g. integer, real,
8444 character, whatever -- not a structure). As a distinct action,
8445 if initial values are provided, tell the back end about the area
8446 as a top-level non-external (initialized) area and remember not to
8447 allow further initialization or expansion of the area. Meanwhile,
8448 if no initialization happens at all, tell the back end about
8449 the largest size we've seen declared so the space does get reserved.
8450 (This function doesn't handle all that stuff, but it does some
8451 of the important things.)
5ff904cd 8452
c7e4ee3a
CB
8453 Meanwhile, for COMMON variables themselves, just keep creating
8454 references like *((float *) (&common_area + offset)) each time
8455 we reference the variable. In other words, don't make a VAR_DECL
8456 or any kind of component reference (like we used to do before 0.4),
8457 though we might do that as well just for debugging purposes (and
8458 stuff the rtl with the appropriate offset expression). */
5ff904cd 8459
c7e4ee3a
CB
8460static void
8461ffecom_transform_common_ (ffesymbol s)
8462{
8463 ffestorag st = ffesymbol_storage (s);
8464 ffeglobal g = ffesymbol_global (s);
8465 tree cbt;
8466 tree cbtype;
8467 tree init;
8468 tree high;
8469 bool is_init = ffestorag_is_init (st);
5ff904cd 8470
c7e4ee3a 8471 assert (st != NULL);
5ff904cd 8472
c7e4ee3a
CB
8473 if ((g == NULL)
8474 || (ffeglobal_type (g) != FFEGLOBAL_typeCOMMON))
8475 return;
5ff904cd 8476
c7e4ee3a 8477 /* First update the size of the area in global terms. */
5ff904cd 8478
c7e4ee3a 8479 ffeglobal_size_common (s, ffestorag_size (st));
5ff904cd 8480
c7e4ee3a
CB
8481 if (!ffeglobal_common_init (g))
8482 is_init = FALSE; /* No explicit init, don't let erroneous joins init. */
5ff904cd 8483
c7e4ee3a 8484 cbt = ffeglobal_hook (g);
5ff904cd 8485
c7e4ee3a
CB
8486 /* If we already have declared this common block for a previous program
8487 unit, and either we already initialized it or we don't have new
8488 initialization for it, just return what we have without changing it. */
5ff904cd 8489
c7e4ee3a
CB
8490 if ((cbt != NULL_TREE)
8491 && (!is_init
8492 || !DECL_EXTERNAL (cbt)))
b7a80862
AV
8493 {
8494 if (st->hook == NULL) ffestorag_set_hook (st, cbt);
8495 return;
8496 }
5ff904cd 8497
c7e4ee3a 8498 /* Process inits. */
5ff904cd 8499
c7e4ee3a
CB
8500 if (is_init)
8501 {
8502 if (ffestorag_init (st) != NULL)
5ff904cd 8503 {
c7e4ee3a 8504 ffebld sexp;
5ff904cd 8505
c7e4ee3a
CB
8506 /* Set the padding for the expression, so ffecom_expr
8507 knows to insert that many zeros. */
8508 switch (ffebld_op (sexp = ffestorag_init (st)))
5ff904cd 8509 {
c7e4ee3a
CB
8510 case FFEBLD_opCONTER:
8511 ffebld_conter_set_pad (sexp, ffestorag_modulo (st));
5ff904cd 8512 break;
5ff904cd 8513
c7e4ee3a
CB
8514 case FFEBLD_opARRTER:
8515 ffebld_arrter_set_pad (sexp, ffestorag_modulo (st));
8516 break;
5ff904cd 8517
c7e4ee3a
CB
8518 case FFEBLD_opACCTER:
8519 ffebld_accter_set_pad (sexp, ffestorag_modulo (st));
8520 break;
5ff904cd 8521
c7e4ee3a
CB
8522 default:
8523 assert ("bad op for cmn init (pad)" == NULL);
8524 break;
8525 }
5ff904cd 8526
c7e4ee3a
CB
8527 init = ffecom_expr (sexp);
8528 if (init == error_mark_node)
8529 { /* Hopefully the back end complained! */
8530 init = NULL_TREE;
8531 if (cbt != NULL_TREE)
8532 return;
8533 }
8534 }
8535 else
8536 init = error_mark_node;
8537 }
8538 else
8539 init = NULL_TREE;
5ff904cd 8540
c7e4ee3a 8541 /* cbtype must be permanently allocated! */
5ff904cd 8542
c7e4ee3a
CB
8543 /* Allocate the MAX of the areas so far, seen filewide. */
8544 high = build_int_2 ((ffeglobal_common_size (g)
8545 + ffeglobal_common_pad (g)) - 1, 0);
8546 TREE_TYPE (high) = ffecom_integer_type_node;
5ff904cd 8547
c7e4ee3a
CB
8548 if (init)
8549 cbtype = build_array_type (char_type_node,
8550 build_range_type (integer_type_node,
8551 integer_zero_node,
8552 high));
8553 else
8554 cbtype = build_array_type (char_type_node, NULL_TREE);
5ff904cd 8555
c7e4ee3a
CB
8556 if (cbt == NULL_TREE)
8557 {
8558 cbt
8559 = build_decl (VAR_DECL,
8560 ffecom_get_external_identifier_ (s),
8561 cbtype);
8562 TREE_STATIC (cbt) = 1;
8563 TREE_PUBLIC (cbt) = 1;
8564 }
8565 else
8566 {
8567 assert (is_init);
8568 TREE_TYPE (cbt) = cbtype;
8569 }
8570 DECL_EXTERNAL (cbt) = init ? 0 : 1;
8571 DECL_INITIAL (cbt) = init ? error_mark_node : NULL_TREE;
5ff904cd 8572
c7e4ee3a
CB
8573 cbt = start_decl (cbt, TRUE);
8574 if (ffeglobal_hook (g) != NULL)
8575 assert (cbt == ffeglobal_hook (g));
5ff904cd 8576
c7e4ee3a 8577 assert (!init || !DECL_EXTERNAL (cbt));
5ff904cd 8578
c7e4ee3a
CB
8579 /* Make sure that any type can live in COMMON and be referenced
8580 without getting a bus error. We could pick the most restrictive
8581 alignment of all entities actually placed in the COMMON, but
8582 this seems easy enough. */
5ff904cd 8583
c7e4ee3a 8584 DECL_ALIGN (cbt) = BIGGEST_ALIGNMENT;
11cf4d18 8585 DECL_USER_ALIGN (cbt) = 0;
5ff904cd 8586
c7e4ee3a
CB
8587 if (is_init && (ffestorag_init (st) == NULL))
8588 init = ffecom_init_zero_ (cbt);
5ff904cd 8589
c7e4ee3a 8590 finish_decl (cbt, init, TRUE);
5ff904cd 8591
c7e4ee3a
CB
8592 if (is_init)
8593 ffestorag_set_init (st, ffebld_new_any ());
5ff904cd 8594
c7e4ee3a
CB
8595 if (init)
8596 {
06ceef4e
RK
8597 assert (DECL_SIZE_UNIT (cbt) != NULL_TREE);
8598 assert (TREE_CODE (DECL_SIZE_UNIT (cbt)) == INTEGER_CST);
05bccae2
RK
8599 assert (0 == compare_tree_int (DECL_SIZE_UNIT (cbt),
8600 (ffeglobal_common_size (g)
8601 + ffeglobal_common_pad (g))));
c7e4ee3a 8602 }
5ff904cd 8603
c7e4ee3a 8604 ffeglobal_set_hook (g, cbt);
5ff904cd 8605
c7e4ee3a 8606 ffestorag_set_hook (st, cbt);
5ff904cd 8607
7189a4b0 8608 ffecom_save_tree_forever (cbt);
c7e4ee3a 8609}
5ff904cd 8610
c7e4ee3a 8611/* Make master area for local EQUIVALENCE. */
5ff904cd 8612
c7e4ee3a
CB
8613static void
8614ffecom_transform_equiv_ (ffestorag eqst)
8615{
8616 tree eqt;
8617 tree eqtype;
8618 tree init;
8619 tree high;
8620 bool is_init = ffestorag_is_init (eqst);
5ff904cd 8621
c7e4ee3a 8622 assert (eqst != NULL);
5ff904cd 8623
c7e4ee3a 8624 eqt = ffestorag_hook (eqst);
5ff904cd 8625
c7e4ee3a
CB
8626 if (eqt != NULL_TREE)
8627 return;
5ff904cd 8628
c7e4ee3a
CB
8629 /* Process inits. */
8630
8631 if (is_init)
8632 {
8633 if (ffestorag_init (eqst) != NULL)
5ff904cd 8634 {
c7e4ee3a 8635 ffebld sexp;
5ff904cd 8636
c7e4ee3a
CB
8637 /* Set the padding for the expression, so ffecom_expr
8638 knows to insert that many zeros. */
8639 switch (ffebld_op (sexp = ffestorag_init (eqst)))
8640 {
8641 case FFEBLD_opCONTER:
8642 ffebld_conter_set_pad (sexp, ffestorag_modulo (eqst));
8643 break;
5ff904cd 8644
c7e4ee3a
CB
8645 case FFEBLD_opARRTER:
8646 ffebld_arrter_set_pad (sexp, ffestorag_modulo (eqst));
8647 break;
5ff904cd 8648
c7e4ee3a
CB
8649 case FFEBLD_opACCTER:
8650 ffebld_accter_set_pad (sexp, ffestorag_modulo (eqst));
8651 break;
5ff904cd 8652
c7e4ee3a
CB
8653 default:
8654 assert ("bad op for eqv init (pad)" == NULL);
8655 break;
8656 }
5ff904cd 8657
c7e4ee3a
CB
8658 init = ffecom_expr (sexp);
8659 if (init == error_mark_node)
8660 init = NULL_TREE; /* Hopefully the back end complained! */
8661 }
8662 else
8663 init = error_mark_node;
8664 }
8665 else if (ffe_is_init_local_zero ())
8666 init = error_mark_node;
8667 else
8668 init = NULL_TREE;
5ff904cd 8669
c7e4ee3a
CB
8670 ffecom_member_namelisted_ = FALSE;
8671 ffestorag_drive (ffestorag_list_equivs (eqst),
8672 &ffecom_member_phase1_,
8673 eqst);
5ff904cd 8674
c7e4ee3a
CB
8675 high = build_int_2 ((ffestorag_size (eqst)
8676 + ffestorag_modulo (eqst)) - 1, 0);
8677 TREE_TYPE (high) = ffecom_integer_type_node;
5ff904cd 8678
c7e4ee3a
CB
8679 eqtype = build_array_type (char_type_node,
8680 build_range_type (ffecom_integer_type_node,
8681 ffecom_integer_zero_node,
8682 high));
8683
8684 eqt = build_decl (VAR_DECL,
8685 ffecom_get_invented_identifier ("__g77_equiv_%s",
8686 ffesymbol_text
14657de8 8687 (ffestorag_symbol (eqst))),
c7e4ee3a
CB
8688 eqtype);
8689 DECL_EXTERNAL (eqt) = 0;
8690 if (is_init
8691 || ffecom_member_namelisted_
8692#ifdef FFECOM_sizeMAXSTACKITEM
8693 || (ffestorag_size (eqst) > FFECOM_sizeMAXSTACKITEM)
8694#endif
8695 || ((ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
8696 && (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA)
8697 && (ffestorag_is_save (eqst) || ffe_is_saveall ())))
8698 TREE_STATIC (eqt) = 1;
8699 else
8700 TREE_STATIC (eqt) = 0;
8701 TREE_PUBLIC (eqt) = 0;
a8e2bb76 8702 TREE_ADDRESSABLE (eqt) = 1; /* Ensure non-register allocation */
c7e4ee3a
CB
8703 DECL_CONTEXT (eqt) = current_function_decl;
8704 if (init)
8705 DECL_INITIAL (eqt) = error_mark_node;
8706 else
8707 DECL_INITIAL (eqt) = NULL_TREE;
5ff904cd 8708
c7e4ee3a 8709 eqt = start_decl (eqt, FALSE);
5ff904cd 8710
c7e4ee3a
CB
8711 /* Make sure that any type can live in EQUIVALENCE and be referenced
8712 without getting a bus error. We could pick the most restrictive
8713 alignment of all entities actually placed in the EQUIVALENCE, but
8714 this seems easy enough. */
5ff904cd 8715
c7e4ee3a 8716 DECL_ALIGN (eqt) = BIGGEST_ALIGNMENT;
11cf4d18 8717 DECL_USER_ALIGN (eqt) = 0;
5ff904cd 8718
c7e4ee3a
CB
8719 if ((!is_init && ffe_is_init_local_zero ())
8720 || (is_init && (ffestorag_init (eqst) == NULL)))
8721 init = ffecom_init_zero_ (eqt);
5ff904cd 8722
c7e4ee3a 8723 finish_decl (eqt, init, FALSE);
5ff904cd 8724
c7e4ee3a
CB
8725 if (is_init)
8726 ffestorag_set_init (eqst, ffebld_new_any ());
5ff904cd 8727
c7e4ee3a 8728 {
06ceef4e 8729 assert (TREE_CODE (DECL_SIZE_UNIT (eqt)) == INTEGER_CST);
05bccae2
RK
8730 assert (0 == compare_tree_int (DECL_SIZE_UNIT (eqt),
8731 (ffestorag_size (eqst)
8732 + ffestorag_modulo (eqst))));
c7e4ee3a 8733 }
5ff904cd 8734
c7e4ee3a 8735 ffestorag_set_hook (eqst, eqt);
5ff904cd 8736
c7e4ee3a
CB
8737 ffestorag_drive (ffestorag_list_equivs (eqst),
8738 &ffecom_member_phase2_,
8739 eqst);
5ff904cd
JL
8740}
8741
c7e4ee3a 8742/* Implement NAMELIST in back end. See f2c/format.c for more info. */
5ff904cd 8743
c7e4ee3a
CB
8744static tree
8745ffecom_transform_namelist_ (ffesymbol s)
5ff904cd 8746{
c7e4ee3a
CB
8747 tree nmlt;
8748 tree nmltype = ffecom_type_namelist_ ();
8749 tree nmlinits;
8750 tree nameinit;
8751 tree varsinit;
8752 tree nvarsinit;
8753 tree field;
8754 tree high;
c7e4ee3a
CB
8755 int i;
8756 static int mynumber = 0;
5ff904cd 8757
c7e4ee3a
CB
8758 nmlt = build_decl (VAR_DECL,
8759 ffecom_get_invented_identifier ("__g77_namelist_%d",
14657de8 8760 mynumber++),
c7e4ee3a
CB
8761 nmltype);
8762 TREE_STATIC (nmlt) = 1;
8763 DECL_INITIAL (nmlt) = error_mark_node;
5ff904cd 8764
c7e4ee3a 8765 nmlt = start_decl (nmlt, FALSE);
5ff904cd 8766
c7e4ee3a 8767 /* Process inits. */
5ff904cd 8768
c7e4ee3a 8769 i = strlen (ffesymbol_text (s));
5ff904cd 8770
c7e4ee3a
CB
8771 high = build_int_2 (i, 0);
8772 TREE_TYPE (high) = ffecom_f2c_ftnlen_type_node;
8773
8774 nameinit = ffecom_build_f2c_string_ (i + 1,
8775 ffesymbol_text (s));
8776 TREE_TYPE (nameinit)
8777 = build_type_variant
8778 (build_array_type
8779 (char_type_node,
8780 build_range_type (ffecom_f2c_ftnlen_type_node,
8781 ffecom_f2c_ftnlen_one_node,
8782 high)),
8783 1, 0);
8784 TREE_CONSTANT (nameinit) = 1;
8785 TREE_STATIC (nameinit) = 1;
8786 nameinit = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (nameinit)),
8787 nameinit);
8788
8789 varsinit = ffecom_vardesc_array_ (s);
8790 varsinit = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (varsinit)),
8791 varsinit);
8792 TREE_CONSTANT (varsinit) = 1;
8793 TREE_STATIC (varsinit) = 1;
8794
8795 {
8796 ffebld b;
8797
8798 for (i = 0, b = ffesymbol_namelist (s); b != NULL; b = ffebld_trail (b))
8799 ++i;
8800 }
8801 nvarsinit = build_int_2 (i, 0);
8802 TREE_TYPE (nvarsinit) = integer_type_node;
8803 TREE_CONSTANT (nvarsinit) = 1;
8804 TREE_STATIC (nvarsinit) = 1;
8805
8806 nmlinits = build_tree_list ((field = TYPE_FIELDS (nmltype)), nameinit);
8807 TREE_CHAIN (nmlinits) = build_tree_list ((field = TREE_CHAIN (field)),
8808 varsinit);
8809 TREE_CHAIN (TREE_CHAIN (nmlinits))
8810 = build_tree_list ((field = TREE_CHAIN (field)), nvarsinit);
8811
8812 nmlinits = build (CONSTRUCTOR, nmltype, NULL_TREE, nmlinits);
8813 TREE_CONSTANT (nmlinits) = 1;
8814 TREE_STATIC (nmlinits) = 1;
8815
8816 finish_decl (nmlt, nmlinits, FALSE);
8817
8818 nmlt = ffecom_1 (ADDR_EXPR, build_pointer_type (nmltype), nmlt);
8819
c7e4ee3a
CB
8820 return nmlt;
8821}
8822
c7e4ee3a
CB
8823/* A subroutine of ffecom_tree_canonize_ref_. The incoming tree is
8824 analyzed on the assumption it is calculating a pointer to be
8825 indirected through. It must return the proper decl and offset,
8826 taking into account different units of measurements for offsets. */
8827
c7e4ee3a
CB
8828static void
8829ffecom_tree_canonize_ptr_ (tree *decl, tree *offset,
8830 tree t)
8831{
8832 switch (TREE_CODE (t))
8833 {
8834 case NOP_EXPR:
8835 case CONVERT_EXPR:
8836 case NON_LVALUE_EXPR:
8837 ffecom_tree_canonize_ptr_ (decl, offset, TREE_OPERAND (t, 0));
5ff904cd
JL
8838 break;
8839
c7e4ee3a
CB
8840 case PLUS_EXPR:
8841 ffecom_tree_canonize_ptr_ (decl, offset, TREE_OPERAND (t, 0));
8842 if ((*decl == NULL_TREE)
8843 || (*decl == error_mark_node))
8844 break;
8845
8846 if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST)
8847 {
8848 /* An offset into COMMON. */
fed3cef0
RK
8849 *offset = fold (build (PLUS_EXPR, TREE_TYPE (*offset),
8850 *offset, TREE_OPERAND (t, 1)));
c7e4ee3a
CB
8851 /* Convert offset (presumably in bytes) into canonical units
8852 (presumably bits). */
76fa6b3b
ZW
8853 *offset = size_binop (MULT_EXPR,
8854 convert (bitsizetype, *offset),
8855 TYPE_SIZE (TREE_TYPE (TREE_TYPE (t))));
c7e4ee3a
CB
8856 break;
8857 }
8858 /* Not a COMMON reference, so an unrecognized pattern. */
8859 *decl = error_mark_node;
5ff904cd
JL
8860 break;
8861
c7e4ee3a
CB
8862 case PARM_DECL:
8863 *decl = t;
770ae6cc 8864 *offset = bitsize_zero_node;
5ff904cd
JL
8865 break;
8866
c7e4ee3a
CB
8867 case ADDR_EXPR:
8868 if (TREE_CODE (TREE_OPERAND (t, 0)) == VAR_DECL)
8869 {
8870 /* A reference to COMMON. */
8871 *decl = TREE_OPERAND (t, 0);
770ae6cc 8872 *offset = bitsize_zero_node;
c7e4ee3a
CB
8873 break;
8874 }
8875 /* Fall through. */
5ff904cd 8876 default:
c7e4ee3a
CB
8877 /* Not a COMMON reference, so an unrecognized pattern. */
8878 *decl = error_mark_node;
5ff904cd
JL
8879 break;
8880 }
c7e4ee3a 8881}
5ff904cd 8882
c7e4ee3a
CB
8883/* Given a tree that is possibly intended for use as an lvalue, return
8884 information representing a canonical view of that tree as a decl, an
8885 offset into that decl, and a size for the lvalue.
5ff904cd 8886
c7e4ee3a
CB
8887 If there's no applicable decl, NULL_TREE is returned for the decl,
8888 and the other fields are left undefined.
5ff904cd 8889
c7e4ee3a
CB
8890 If the tree doesn't fit the recognizable forms, an ERROR_MARK node
8891 is returned for the decl, and the other fields are left undefined.
5ff904cd 8892
c7e4ee3a
CB
8893 Otherwise, the decl returned currently is either a VAR_DECL or a
8894 PARM_DECL.
5ff904cd 8895
c7e4ee3a
CB
8896 The offset returned is always valid, but of course not necessarily
8897 a constant, and not necessarily converted into the appropriate
8898 type, leaving that up to the caller (so as to avoid that overhead
8899 if the decls being looked at are different anyway).
5ff904cd 8900
c7e4ee3a
CB
8901 If the size cannot be determined (e.g. an adjustable array),
8902 an ERROR_MARK node is returned for the size. Otherwise, the
8903 size returned is valid, not necessarily a constant, and not
8904 necessarily converted into the appropriate type as with the
8905 offset.
5ff904cd 8906
c7e4ee3a
CB
8907 Note that the offset and size expressions are expressed in the
8908 base storage units (usually bits) rather than in the units of
8909 the type of the decl, because two decls with different types
8910 might overlap but with apparently non-overlapping array offsets,
8911 whereas converting the array offsets to consistant offsets will
8912 reveal the overlap. */
5ff904cd 8913
5ff904cd 8914static void
c7e4ee3a
CB
8915ffecom_tree_canonize_ref_ (tree *decl, tree *offset,
8916 tree *size, tree t)
5ff904cd 8917{
c7e4ee3a
CB
8918 /* The default path is to report a nonexistant decl. */
8919 *decl = NULL_TREE;
5ff904cd 8920
c7e4ee3a 8921 if (t == NULL_TREE)
5ff904cd
JL
8922 return;
8923
c7e4ee3a
CB
8924 switch (TREE_CODE (t))
8925 {
8926 case ERROR_MARK:
8927 case IDENTIFIER_NODE:
8928 case INTEGER_CST:
8929 case REAL_CST:
8930 case COMPLEX_CST:
8931 case STRING_CST:
8932 case CONST_DECL:
8933 case PLUS_EXPR:
8934 case MINUS_EXPR:
8935 case MULT_EXPR:
8936 case TRUNC_DIV_EXPR:
8937 case CEIL_DIV_EXPR:
8938 case FLOOR_DIV_EXPR:
8939 case ROUND_DIV_EXPR:
8940 case TRUNC_MOD_EXPR:
8941 case CEIL_MOD_EXPR:
8942 case FLOOR_MOD_EXPR:
8943 case ROUND_MOD_EXPR:
8944 case RDIV_EXPR:
8945 case EXACT_DIV_EXPR:
8946 case FIX_TRUNC_EXPR:
8947 case FIX_CEIL_EXPR:
8948 case FIX_FLOOR_EXPR:
8949 case FIX_ROUND_EXPR:
8950 case FLOAT_EXPR:
c7e4ee3a
CB
8951 case NEGATE_EXPR:
8952 case MIN_EXPR:
8953 case MAX_EXPR:
8954 case ABS_EXPR:
8955 case FFS_EXPR:
8956 case LSHIFT_EXPR:
8957 case RSHIFT_EXPR:
8958 case LROTATE_EXPR:
8959 case RROTATE_EXPR:
8960 case BIT_IOR_EXPR:
8961 case BIT_XOR_EXPR:
8962 case BIT_AND_EXPR:
8963 case BIT_ANDTC_EXPR:
8964 case BIT_NOT_EXPR:
8965 case TRUTH_ANDIF_EXPR:
8966 case TRUTH_ORIF_EXPR:
8967 case TRUTH_AND_EXPR:
8968 case TRUTH_OR_EXPR:
8969 case TRUTH_XOR_EXPR:
8970 case TRUTH_NOT_EXPR:
8971 case LT_EXPR:
8972 case LE_EXPR:
8973 case GT_EXPR:
8974 case GE_EXPR:
8975 case EQ_EXPR:
8976 case NE_EXPR:
8977 case COMPLEX_EXPR:
8978 case CONJ_EXPR:
8979 case REALPART_EXPR:
8980 case IMAGPART_EXPR:
8981 case LABEL_EXPR:
8982 case COMPONENT_REF:
8983 case COMPOUND_EXPR:
8984 case ADDR_EXPR:
8985 return;
5ff904cd 8986
c7e4ee3a
CB
8987 case VAR_DECL:
8988 case PARM_DECL:
8989 *decl = t;
770ae6cc 8990 *offset = bitsize_zero_node;
c7e4ee3a
CB
8991 *size = TYPE_SIZE (TREE_TYPE (t));
8992 return;
5ff904cd 8993
c7e4ee3a
CB
8994 case ARRAY_REF:
8995 {
8996 tree array = TREE_OPERAND (t, 0);
8997 tree element = TREE_OPERAND (t, 1);
8998 tree init_offset;
8999
9000 if ((array == NULL_TREE)
9001 || (element == NULL_TREE))
9002 {
9003 *decl = error_mark_node;
9004 return;
9005 }
9006
9007 ffecom_tree_canonize_ref_ (decl, &init_offset, size,
9008 array);
9009 if ((*decl == NULL_TREE)
9010 || (*decl == error_mark_node))
9011 return;
9012
76fa6b3b
ZW
9013 /* Calculate ((element - base) * NBBY) + init_offset. */
9014 *offset = fold (build (MINUS_EXPR, TREE_TYPE (element),
9015 element,
9016 TYPE_MIN_VALUE (TYPE_DOMAIN
9017 (TREE_TYPE (array)))));
9018
9019 *offset = size_binop (MULT_EXPR,
9020 convert (bitsizetype, *offset),
9021 TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))));
9022
9023 *offset = size_binop (PLUS_EXPR, init_offset, *offset);
c7e4ee3a
CB
9024
9025 *size = TYPE_SIZE (TREE_TYPE (t));
9026 return;
9027 }
9028
9029 case INDIRECT_REF:
9030
9031 /* Most of this code is to handle references to COMMON. And so
9032 far that is useful only for calling library functions, since
9033 external (user) functions might reference common areas. But
9034 even calling an external function, it's worthwhile to decode
9035 COMMON references because if not storing into COMMON, we don't
9036 want COMMON-based arguments to gratuitously force use of a
9037 temporary. */
9038
9039 *size = TYPE_SIZE (TREE_TYPE (t));
5ff904cd 9040
c7e4ee3a
CB
9041 ffecom_tree_canonize_ptr_ (decl, offset,
9042 TREE_OPERAND (t, 0));
5ff904cd 9043
c7e4ee3a 9044 return;
5ff904cd 9045
c7e4ee3a
CB
9046 case CONVERT_EXPR:
9047 case NOP_EXPR:
9048 case MODIFY_EXPR:
9049 case NON_LVALUE_EXPR:
9050 case RESULT_DECL:
9051 case FIELD_DECL:
9052 case COND_EXPR: /* More cases than we can handle. */
9053 case SAVE_EXPR:
9054 case REFERENCE_EXPR:
9055 case PREDECREMENT_EXPR:
9056 case PREINCREMENT_EXPR:
9057 case POSTDECREMENT_EXPR:
9058 case POSTINCREMENT_EXPR:
9059 case CALL_EXPR:
9060 default:
9061 *decl = error_mark_node;
9062 return;
9063 }
9064}
5ff904cd 9065
c7e4ee3a 9066/* Do divide operation appropriate to type of operands. */
5ff904cd 9067
c7e4ee3a
CB
9068static tree
9069ffecom_tree_divide_ (tree tree_type, tree left, tree right,
9070 tree dest_tree, ffebld dest, bool *dest_used,
9071 tree hook)
9072{
9073 if ((left == error_mark_node)
9074 || (right == error_mark_node))
9075 return error_mark_node;
a6fa6420 9076
c7e4ee3a
CB
9077 switch (TREE_CODE (tree_type))
9078 {
9079 case INTEGER_TYPE:
9080 return ffecom_2 (TRUNC_DIV_EXPR, tree_type,
9081 left,
9082 right);
a6fa6420 9083
c7e4ee3a 9084 case COMPLEX_TYPE:
c64f913e
CB
9085 if (! optimize_size)
9086 return ffecom_2 (RDIV_EXPR, tree_type,
9087 left,
9088 right);
c7e4ee3a
CB
9089 {
9090 ffecomGfrt ix;
a6fa6420 9091
c7e4ee3a
CB
9092 if (TREE_TYPE (tree_type)
9093 == ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1])
9094 ix = FFECOM_gfrtDIV_CC; /* Overlapping result okay. */
9095 else
9096 ix = FFECOM_gfrtDIV_ZZ; /* Overlapping result okay. */
a6fa6420 9097
c7e4ee3a
CB
9098 left = ffecom_1 (ADDR_EXPR,
9099 build_pointer_type (TREE_TYPE (left)),
9100 left);
9101 left = build_tree_list (NULL_TREE, left);
9102 right = ffecom_1 (ADDR_EXPR,
9103 build_pointer_type (TREE_TYPE (right)),
9104 right);
9105 right = build_tree_list (NULL_TREE, right);
9106 TREE_CHAIN (left) = right;
a6fa6420 9107
c7e4ee3a
CB
9108 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
9109 ffecom_gfrt_kindtype (ix),
9110 ffe_is_f2c_library (),
9111 tree_type,
9112 left,
9113 dest_tree, dest, dest_used,
9114 NULL_TREE, TRUE, hook);
9115 }
9116 break;
5ff904cd 9117
c7e4ee3a
CB
9118 case RECORD_TYPE:
9119 {
9120 ffecomGfrt ix;
5ff904cd 9121
c7e4ee3a
CB
9122 if (TREE_TYPE (TYPE_FIELDS (tree_type))
9123 == ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1])
9124 ix = FFECOM_gfrtDIV_CC; /* Overlapping result okay. */
9125 else
9126 ix = FFECOM_gfrtDIV_ZZ; /* Overlapping result okay. */
5ff904cd 9127
c7e4ee3a
CB
9128 left = ffecom_1 (ADDR_EXPR,
9129 build_pointer_type (TREE_TYPE (left)),
9130 left);
9131 left = build_tree_list (NULL_TREE, left);
9132 right = ffecom_1 (ADDR_EXPR,
9133 build_pointer_type (TREE_TYPE (right)),
9134 right);
9135 right = build_tree_list (NULL_TREE, right);
9136 TREE_CHAIN (left) = right;
a6fa6420 9137
c7e4ee3a
CB
9138 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
9139 ffecom_gfrt_kindtype (ix),
9140 ffe_is_f2c_library (),
9141 tree_type,
9142 left,
9143 dest_tree, dest, dest_used,
9144 NULL_TREE, TRUE, hook);
9145 }
9146 break;
5ff904cd 9147
c7e4ee3a
CB
9148 default:
9149 return ffecom_2 (RDIV_EXPR, tree_type,
9150 left,
9151 right);
5ff904cd 9152 }
c7e4ee3a 9153}
5ff904cd 9154
c7e4ee3a 9155/* Build type info for non-dummy variable. */
5ff904cd 9156
c7e4ee3a
CB
9157static tree
9158ffecom_type_localvar_ (ffesymbol s, ffeinfoBasictype bt,
9159 ffeinfoKindtype kt)
9160{
9161 tree type;
9162 ffebld dl;
9163 ffebld dim;
9164 tree lowt;
9165 tree hight;
5ff904cd 9166
c7e4ee3a
CB
9167 type = ffecom_tree_type[bt][kt];
9168 if (bt == FFEINFO_basictypeCHARACTER)
9169 {
9170 hight = build_int_2 (ffesymbol_size (s), 0);
9171 TREE_TYPE (hight) = ffecom_f2c_ftnlen_type_node;
5ff904cd 9172
c7e4ee3a
CB
9173 type
9174 = build_array_type
9175 (type,
9176 build_range_type (ffecom_f2c_ftnlen_type_node,
9177 ffecom_f2c_ftnlen_one_node,
9178 hight));
9179 type = ffecom_check_size_overflow_ (s, type, FALSE);
9180 }
5ff904cd 9181
c7e4ee3a
CB
9182 for (dl = ffesymbol_dims (s); dl != NULL; dl = ffebld_trail (dl))
9183 {
9184 if (type == error_mark_node)
9185 break;
5ff904cd 9186
c7e4ee3a
CB
9187 dim = ffebld_head (dl);
9188 assert (ffebld_op (dim) == FFEBLD_opBOUNDS);
5ff904cd 9189
c7e4ee3a
CB
9190 if (ffebld_left (dim) == NULL)
9191 lowt = integer_one_node;
9192 else
9193 lowt = ffecom_expr (ffebld_left (dim));
5ff904cd 9194
c7e4ee3a
CB
9195 if (TREE_CODE (lowt) != INTEGER_CST)
9196 lowt = variable_size (lowt);
5ff904cd 9197
c7e4ee3a
CB
9198 assert (ffebld_right (dim) != NULL);
9199 hight = ffecom_expr (ffebld_right (dim));
5ff904cd 9200
c7e4ee3a
CB
9201 if (TREE_CODE (hight) != INTEGER_CST)
9202 hight = variable_size (hight);
5ff904cd 9203
c7e4ee3a
CB
9204 type = build_array_type (type,
9205 build_range_type (ffecom_integer_type_node,
9206 lowt, hight));
9207 type = ffecom_check_size_overflow_ (s, type, FALSE);
9208 }
5ff904cd 9209
c7e4ee3a 9210 return type;
5ff904cd
JL
9211}
9212
c7e4ee3a 9213/* Build Namelist type. */
5ff904cd 9214
c7e4ee3a
CB
9215static tree
9216ffecom_type_namelist_ ()
9217{
9218 static tree type = NULL_TREE;
5ff904cd 9219
c7e4ee3a
CB
9220 if (type == NULL_TREE)
9221 {
9222 static tree namefield, varsfield, nvarsfield;
9223 tree vardesctype;
5ff904cd 9224
c7e4ee3a 9225 vardesctype = ffecom_type_vardesc_ ();
5ff904cd 9226
c7e4ee3a 9227 type = make_node (RECORD_TYPE);
a6fa6420 9228
c7e4ee3a 9229 vardesctype = build_pointer_type (build_pointer_type (vardesctype));
a6fa6420 9230
c7e4ee3a
CB
9231 namefield = ffecom_decl_field (type, NULL_TREE, "name",
9232 string_type_node);
9233 varsfield = ffecom_decl_field (type, namefield, "vars", vardesctype);
9234 nvarsfield = ffecom_decl_field (type, varsfield, "nvars",
9235 integer_type_node);
a6fa6420 9236
c7e4ee3a
CB
9237 TYPE_FIELDS (type) = namefield;
9238 layout_type (type);
a6fa6420 9239
7189a4b0 9240 ggc_add_tree_root (&type, 1);
5ff904cd 9241 }
5ff904cd 9242
c7e4ee3a
CB
9243 return type;
9244}
5ff904cd 9245
c7e4ee3a 9246/* Build Vardesc type. */
5ff904cd 9247
c7e4ee3a
CB
9248static tree
9249ffecom_type_vardesc_ ()
9250{
9251 static tree type = NULL_TREE;
9252 static tree namefield, addrfield, dimsfield, typefield;
5ff904cd 9253
c7e4ee3a
CB
9254 if (type == NULL_TREE)
9255 {
c7e4ee3a 9256 type = make_node (RECORD_TYPE);
5ff904cd 9257
c7e4ee3a
CB
9258 namefield = ffecom_decl_field (type, NULL_TREE, "name",
9259 string_type_node);
9260 addrfield = ffecom_decl_field (type, namefield, "addr",
9261 string_type_node);
9262 dimsfield = ffecom_decl_field (type, addrfield, "dims",
9263 ffecom_f2c_ptr_to_ftnlen_type_node);
9264 typefield = ffecom_decl_field (type, dimsfield, "type",
9265 integer_type_node);
5ff904cd 9266
c7e4ee3a
CB
9267 TYPE_FIELDS (type) = namefield;
9268 layout_type (type);
9269
7189a4b0 9270 ggc_add_tree_root (&type, 1);
c7e4ee3a
CB
9271 }
9272
9273 return type;
5ff904cd
JL
9274}
9275
5ff904cd 9276static tree
c7e4ee3a 9277ffecom_vardesc_ (ffebld expr)
5ff904cd 9278{
c7e4ee3a 9279 ffesymbol s;
5ff904cd 9280
c7e4ee3a
CB
9281 assert (ffebld_op (expr) == FFEBLD_opSYMTER);
9282 s = ffebld_symter (expr);
5ff904cd 9283
c7e4ee3a
CB
9284 if (ffesymbol_hook (s).vardesc_tree == NULL_TREE)
9285 {
9286 int i;
9287 tree vardesctype = ffecom_type_vardesc_ ();
9288 tree var;
9289 tree nameinit;
9290 tree dimsinit;
9291 tree addrinit;
9292 tree typeinit;
9293 tree field;
9294 tree varinits;
c7e4ee3a 9295 static int mynumber = 0;
5ff904cd 9296
c7e4ee3a
CB
9297 var = build_decl (VAR_DECL,
9298 ffecom_get_invented_identifier ("__g77_vardesc_%d",
14657de8 9299 mynumber++),
c7e4ee3a
CB
9300 vardesctype);
9301 TREE_STATIC (var) = 1;
9302 DECL_INITIAL (var) = error_mark_node;
5ff904cd 9303
c7e4ee3a 9304 var = start_decl (var, FALSE);
5ff904cd 9305
c7e4ee3a 9306 /* Process inits. */
5ff904cd 9307
c7e4ee3a
CB
9308 nameinit = ffecom_build_f2c_string_ ((i = strlen (ffesymbol_text (s)))
9309 + 1,
9310 ffesymbol_text (s));
9311 TREE_TYPE (nameinit)
9312 = build_type_variant
9313 (build_array_type
9314 (char_type_node,
9315 build_range_type (integer_type_node,
9316 integer_one_node,
9317 build_int_2 (i, 0))),
9318 1, 0);
9319 TREE_CONSTANT (nameinit) = 1;
9320 TREE_STATIC (nameinit) = 1;
9321 nameinit = ffecom_1 (ADDR_EXPR,
9322 build_pointer_type (TREE_TYPE (nameinit)),
9323 nameinit);
5ff904cd 9324
c7e4ee3a 9325 addrinit = ffecom_arg_ptr_to_expr (expr, &typeinit);
5ff904cd 9326
c7e4ee3a 9327 dimsinit = ffecom_vardesc_dims_ (s);
5ff904cd 9328
c7e4ee3a
CB
9329 if (typeinit == NULL_TREE)
9330 {
9331 ffeinfoBasictype bt = ffesymbol_basictype (s);
9332 ffeinfoKindtype kt = ffesymbol_kindtype (s);
9333 int tc = ffecom_f2c_typecode (bt, kt);
5ff904cd 9334
c7e4ee3a
CB
9335 assert (tc != -1);
9336 typeinit = build_int_2 (tc, (tc < 0) ? -1 : 0);
9337 }
9338 else
9339 typeinit = ffecom_1 (NEGATE_EXPR, TREE_TYPE (typeinit), typeinit);
5ff904cd 9340
c7e4ee3a
CB
9341 varinits = build_tree_list ((field = TYPE_FIELDS (vardesctype)),
9342 nameinit);
9343 TREE_CHAIN (varinits) = build_tree_list ((field = TREE_CHAIN (field)),
9344 addrinit);
9345 TREE_CHAIN (TREE_CHAIN (varinits))
9346 = build_tree_list ((field = TREE_CHAIN (field)), dimsinit);
9347 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (varinits)))
9348 = build_tree_list ((field = TREE_CHAIN (field)), typeinit);
5ff904cd 9349
c7e4ee3a
CB
9350 varinits = build (CONSTRUCTOR, vardesctype, NULL_TREE, varinits);
9351 TREE_CONSTANT (varinits) = 1;
9352 TREE_STATIC (varinits) = 1;
5ff904cd 9353
c7e4ee3a 9354 finish_decl (var, varinits, FALSE);
5ff904cd 9355
c7e4ee3a 9356 var = ffecom_1 (ADDR_EXPR, build_pointer_type (vardesctype), var);
5ff904cd 9357
c7e4ee3a
CB
9358 ffesymbol_hook (s).vardesc_tree = var;
9359 }
5ff904cd 9360
c7e4ee3a
CB
9361 return ffesymbol_hook (s).vardesc_tree;
9362}
5ff904cd 9363
c7e4ee3a
CB
9364static tree
9365ffecom_vardesc_array_ (ffesymbol s)
5ff904cd 9366{
c7e4ee3a
CB
9367 ffebld b;
9368 tree list;
9369 tree item = NULL_TREE;
9370 tree var;
9371 int i;
c7e4ee3a 9372 static int mynumber = 0;
5ff904cd 9373
c7e4ee3a
CB
9374 for (i = 0, list = NULL_TREE, b = ffesymbol_namelist (s);
9375 b != NULL;
9376 b = ffebld_trail (b), ++i)
9377 {
9378 tree t;
5ff904cd 9379
c7e4ee3a 9380 t = ffecom_vardesc_ (ffebld_head (b));
5ff904cd 9381
c7e4ee3a
CB
9382 if (list == NULL_TREE)
9383 list = item = build_tree_list (NULL_TREE, t);
9384 else
5ff904cd 9385 {
c7e4ee3a
CB
9386 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
9387 item = TREE_CHAIN (item);
5ff904cd 9388 }
5ff904cd 9389 }
5ff904cd 9390
c7e4ee3a
CB
9391 item = build_array_type (build_pointer_type (ffecom_type_vardesc_ ()),
9392 build_range_type (integer_type_node,
9393 integer_one_node,
9394 build_int_2 (i, 0)));
9395 list = build (CONSTRUCTOR, item, NULL_TREE, list);
9396 TREE_CONSTANT (list) = 1;
9397 TREE_STATIC (list) = 1;
5ff904cd 9398
14657de8 9399 var = ffecom_get_invented_identifier ("__g77_vardesc_array_%d", mynumber++);
c7e4ee3a
CB
9400 var = build_decl (VAR_DECL, var, item);
9401 TREE_STATIC (var) = 1;
9402 DECL_INITIAL (var) = error_mark_node;
9403 var = start_decl (var, FALSE);
9404 finish_decl (var, list, FALSE);
5ff904cd 9405
c7e4ee3a
CB
9406 return var;
9407}
5ff904cd 9408
c7e4ee3a
CB
9409static tree
9410ffecom_vardesc_dims_ (ffesymbol s)
9411{
9412 if (ffesymbol_dims (s) == NULL)
9413 return convert (ffecom_f2c_ptr_to_ftnlen_type_node,
9414 integer_zero_node);
5ff904cd 9415
c7e4ee3a
CB
9416 {
9417 ffebld b;
9418 ffebld e;
9419 tree list;
9420 tree backlist;
9421 tree item = NULL_TREE;
9422 tree var;
c7e4ee3a
CB
9423 tree numdim;
9424 tree numelem;
9425 tree baseoff = NULL_TREE;
9426 static int mynumber = 0;
9427
9428 numdim = build_int_2 ((int) ffesymbol_rank (s), 0);
9429 TREE_TYPE (numdim) = ffecom_f2c_ftnlen_type_node;
9430
9431 numelem = ffecom_expr (ffesymbol_arraysize (s));
9432 TREE_TYPE (numelem) = ffecom_f2c_ftnlen_type_node;
9433
9434 list = NULL_TREE;
9435 backlist = NULL_TREE;
9436 for (b = ffesymbol_dims (s), e = ffesymbol_extents (s);
9437 b != NULL;
9438 b = ffebld_trail (b), e = ffebld_trail (e))
5ff904cd 9439 {
c7e4ee3a
CB
9440 tree t;
9441 tree low;
9442 tree back;
5ff904cd 9443
c7e4ee3a
CB
9444 if (ffebld_trail (b) == NULL)
9445 t = NULL_TREE;
9446 else
5ff904cd 9447 {
c7e4ee3a
CB
9448 t = convert (ffecom_f2c_ftnlen_type_node,
9449 ffecom_expr (ffebld_head (e)));
5ff904cd 9450
c7e4ee3a
CB
9451 if (list == NULL_TREE)
9452 list = item = build_tree_list (NULL_TREE, t);
9453 else
9454 {
9455 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
9456 item = TREE_CHAIN (item);
9457 }
9458 }
5ff904cd 9459
c7e4ee3a
CB
9460 if (ffebld_left (ffebld_head (b)) == NULL)
9461 low = ffecom_integer_one_node;
9462 else
9463 low = ffecom_expr (ffebld_left (ffebld_head (b)));
9464 low = convert (ffecom_f2c_ftnlen_type_node, low);
5ff904cd 9465
c7e4ee3a
CB
9466 back = build_tree_list (low, t);
9467 TREE_CHAIN (back) = backlist;
9468 backlist = back;
9469 }
5ff904cd 9470
c7e4ee3a
CB
9471 for (item = backlist; item != NULL_TREE; item = TREE_CHAIN (item))
9472 {
9473 if (TREE_VALUE (item) == NULL_TREE)
9474 baseoff = TREE_PURPOSE (item);
9475 else
9476 baseoff = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
9477 TREE_PURPOSE (item),
9478 ffecom_2 (MULT_EXPR,
9479 ffecom_f2c_ftnlen_type_node,
9480 TREE_VALUE (item),
9481 baseoff));
5ff904cd
JL
9482 }
9483
c7e4ee3a 9484 /* backlist now dead, along with all TREE_PURPOSEs on it. */
5ff904cd 9485
c7e4ee3a
CB
9486 baseoff = build_tree_list (NULL_TREE, baseoff);
9487 TREE_CHAIN (baseoff) = list;
5ff904cd 9488
c7e4ee3a
CB
9489 numelem = build_tree_list (NULL_TREE, numelem);
9490 TREE_CHAIN (numelem) = baseoff;
5ff904cd 9491
c7e4ee3a
CB
9492 numdim = build_tree_list (NULL_TREE, numdim);
9493 TREE_CHAIN (numdim) = numelem;
5ff904cd 9494
c7e4ee3a
CB
9495 item = build_array_type (ffecom_f2c_ftnlen_type_node,
9496 build_range_type (integer_type_node,
9497 integer_zero_node,
9498 build_int_2
9499 ((int) ffesymbol_rank (s)
9500 + 2, 0)));
9501 list = build (CONSTRUCTOR, item, NULL_TREE, numdim);
9502 TREE_CONSTANT (list) = 1;
9503 TREE_STATIC (list) = 1;
9504
14657de8 9505 var = ffecom_get_invented_identifier ("__g77_dims_%d", mynumber++);
c7e4ee3a
CB
9506 var = build_decl (VAR_DECL, var, item);
9507 TREE_STATIC (var) = 1;
9508 DECL_INITIAL (var) = error_mark_node;
9509 var = start_decl (var, FALSE);
9510 finish_decl (var, list, FALSE);
9511
9512 var = ffecom_1 (ADDR_EXPR, build_pointer_type (item), var);
9513
c7e4ee3a
CB
9514 return var;
9515 }
5ff904cd 9516}
c7e4ee3a 9517
c7e4ee3a
CB
9518/* Essentially does a "fold (build1 (code, type, node))" while checking
9519 for certain housekeeping things.
5ff904cd 9520
c7e4ee3a
CB
9521 NOTE: for building an ADDR_EXPR around a FUNCTION_DECL, use
9522 ffecom_1_fn instead. */
5ff904cd 9523
c7e4ee3a
CB
9524tree
9525ffecom_1 (enum tree_code code, tree type, tree node)
5ff904cd 9526{
c7e4ee3a
CB
9527 tree item;
9528
9529 if ((node == error_mark_node)
9530 || (type == error_mark_node))
5ff904cd
JL
9531 return error_mark_node;
9532
c7e4ee3a 9533 if (code == ADDR_EXPR)
5ff904cd 9534 {
dffd7eb6 9535 if (!ffe_mark_addressable (node))
c7e4ee3a
CB
9536 assert ("can't mark_addressable this node!" == NULL);
9537 }
5ff904cd 9538
c7e4ee3a
CB
9539 switch (ffe_is_emulate_complex () ? code : NOP_EXPR)
9540 {
9541 tree realtype;
5ff904cd 9542
c7e4ee3a
CB
9543 case REALPART_EXPR:
9544 item = build (COMPONENT_REF, type, node, TYPE_FIELDS (TREE_TYPE (node)));
5ff904cd
JL
9545 break;
9546
c7e4ee3a
CB
9547 case IMAGPART_EXPR:
9548 item = build (COMPONENT_REF, type, node, TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (node))));
9549 break;
5ff904cd 9550
5ff904cd 9551
c7e4ee3a
CB
9552 case NEGATE_EXPR:
9553 if (TREE_CODE (type) != RECORD_TYPE)
9554 {
9555 item = build1 (code, type, node);
9556 break;
9557 }
9558 node = ffecom_stabilize_aggregate_ (node);
9559 realtype = TREE_TYPE (TYPE_FIELDS (type));
9560 item =
9561 ffecom_2 (COMPLEX_EXPR, type,
9562 ffecom_1 (NEGATE_EXPR, realtype,
9563 ffecom_1 (REALPART_EXPR, realtype,
9564 node)),
9565 ffecom_1 (NEGATE_EXPR, realtype,
9566 ffecom_1 (IMAGPART_EXPR, realtype,
9567 node)));
5ff904cd
JL
9568 break;
9569
9570 default:
c7e4ee3a
CB
9571 item = build1 (code, type, node);
9572 break;
5ff904cd 9573 }
5ff904cd 9574
c7e4ee3a
CB
9575 if (TREE_SIDE_EFFECTS (node))
9576 TREE_SIDE_EFFECTS (item) = 1;
33afb1b7 9577 if (code == ADDR_EXPR && staticp (node))
c7e4ee3a 9578 TREE_CONSTANT (item) = 1;
33afb1b7
RK
9579 else if (code == INDIRECT_REF)
9580 TREE_READONLY (item) = TYPE_READONLY (type);
c7e4ee3a
CB
9581 return fold (item);
9582}
5ff904cd 9583
c7e4ee3a
CB
9584/* Like ffecom_1 (ADDR_EXPR, TREE_TYPE (node), node), except
9585 handles TREE_CODE (node) == FUNCTION_DECL. In particular,
9586 does not set TREE_ADDRESSABLE (because calling an inline
9587 function does not mean the function needs to be separately
9588 compiled). */
5ff904cd 9589
c7e4ee3a
CB
9590tree
9591ffecom_1_fn (tree node)
5ff904cd 9592{
c7e4ee3a 9593 tree item;
5ff904cd 9594 tree type;
5ff904cd 9595
c7e4ee3a
CB
9596 if (node == error_mark_node)
9597 return error_mark_node;
5ff904cd 9598
c7e4ee3a
CB
9599 type = build_type_variant (TREE_TYPE (node),
9600 TREE_READONLY (node),
9601 TREE_THIS_VOLATILE (node));
9602 item = build1 (ADDR_EXPR,
9603 build_pointer_type (type), node);
9604 if (TREE_SIDE_EFFECTS (node))
9605 TREE_SIDE_EFFECTS (item) = 1;
9606 if (staticp (node))
9607 TREE_CONSTANT (item) = 1;
9608 return fold (item);
5ff904cd 9609}
c7e4ee3a
CB
9610
9611/* Essentially does a "fold (build (code, type, node1, node2))" while
9612 checking for certain housekeeping things. */
5ff904cd 9613
c7e4ee3a
CB
9614tree
9615ffecom_2 (enum tree_code code, tree type, tree node1,
9616 tree node2)
5ff904cd 9617{
c7e4ee3a 9618 tree item;
5ff904cd 9619
c7e4ee3a
CB
9620 if ((node1 == error_mark_node)
9621 || (node2 == error_mark_node)
9622 || (type == error_mark_node))
9623 return error_mark_node;
9624
9625 switch (ffe_is_emulate_complex () ? code : NOP_EXPR)
5ff904cd 9626 {
c7e4ee3a 9627 tree a, b, c, d, realtype;
5ff904cd 9628
c7e4ee3a
CB
9629 case CONJ_EXPR:
9630 assert ("no CONJ_EXPR support yet" == NULL);
9631 return error_mark_node;
5ff904cd 9632
c7e4ee3a
CB
9633 case COMPLEX_EXPR:
9634 item = build_tree_list (TYPE_FIELDS (type), node1);
9635 TREE_CHAIN (item) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), node2);
9636 item = build (CONSTRUCTOR, type, NULL_TREE, item);
9637 break;
5ff904cd 9638
c7e4ee3a
CB
9639 case PLUS_EXPR:
9640 if (TREE_CODE (type) != RECORD_TYPE)
9641 {
9642 item = build (code, type, node1, node2);
9643 break;
9644 }
9645 node1 = ffecom_stabilize_aggregate_ (node1);
9646 node2 = ffecom_stabilize_aggregate_ (node2);
9647 realtype = TREE_TYPE (TYPE_FIELDS (type));
9648 item =
9649 ffecom_2 (COMPLEX_EXPR, type,
9650 ffecom_2 (PLUS_EXPR, realtype,
9651 ffecom_1 (REALPART_EXPR, realtype,
9652 node1),
9653 ffecom_1 (REALPART_EXPR, realtype,
9654 node2)),
9655 ffecom_2 (PLUS_EXPR, realtype,
9656 ffecom_1 (IMAGPART_EXPR, realtype,
9657 node1),
9658 ffecom_1 (IMAGPART_EXPR, realtype,
9659 node2)));
9660 break;
5ff904cd 9661
c7e4ee3a
CB
9662 case MINUS_EXPR:
9663 if (TREE_CODE (type) != RECORD_TYPE)
9664 {
9665 item = build (code, type, node1, node2);
9666 break;
9667 }
9668 node1 = ffecom_stabilize_aggregate_ (node1);
9669 node2 = ffecom_stabilize_aggregate_ (node2);
9670 realtype = TREE_TYPE (TYPE_FIELDS (type));
9671 item =
9672 ffecom_2 (COMPLEX_EXPR, type,
9673 ffecom_2 (MINUS_EXPR, realtype,
9674 ffecom_1 (REALPART_EXPR, realtype,
9675 node1),
9676 ffecom_1 (REALPART_EXPR, realtype,
9677 node2)),
9678 ffecom_2 (MINUS_EXPR, realtype,
9679 ffecom_1 (IMAGPART_EXPR, realtype,
9680 node1),
9681 ffecom_1 (IMAGPART_EXPR, realtype,
9682 node2)));
9683 break;
5ff904cd 9684
c7e4ee3a
CB
9685 case MULT_EXPR:
9686 if (TREE_CODE (type) != RECORD_TYPE)
9687 {
9688 item = build (code, type, node1, node2);
9689 break;
9690 }
9691 node1 = ffecom_stabilize_aggregate_ (node1);
9692 node2 = ffecom_stabilize_aggregate_ (node2);
9693 realtype = TREE_TYPE (TYPE_FIELDS (type));
9694 a = save_expr (ffecom_1 (REALPART_EXPR, realtype,
9695 node1));
9696 b = save_expr (ffecom_1 (IMAGPART_EXPR, realtype,
9697 node1));
9698 c = save_expr (ffecom_1 (REALPART_EXPR, realtype,
9699 node2));
9700 d = save_expr (ffecom_1 (IMAGPART_EXPR, realtype,
9701 node2));
9702 item =
9703 ffecom_2 (COMPLEX_EXPR, type,
9704 ffecom_2 (MINUS_EXPR, realtype,
9705 ffecom_2 (MULT_EXPR, realtype,
9706 a,
9707 c),
9708 ffecom_2 (MULT_EXPR, realtype,
9709 b,
9710 d)),
9711 ffecom_2 (PLUS_EXPR, realtype,
9712 ffecom_2 (MULT_EXPR, realtype,
9713 a,
9714 d),
9715 ffecom_2 (MULT_EXPR, realtype,
9716 c,
9717 b)));
9718 break;
5ff904cd 9719
c7e4ee3a
CB
9720 case EQ_EXPR:
9721 if ((TREE_CODE (node1) != RECORD_TYPE)
9722 && (TREE_CODE (node2) != RECORD_TYPE))
9723 {
9724 item = build (code, type, node1, node2);
9725 break;
9726 }
9727 assert (TREE_CODE (node1) == RECORD_TYPE);
9728 assert (TREE_CODE (node2) == RECORD_TYPE);
9729 node1 = ffecom_stabilize_aggregate_ (node1);
9730 node2 = ffecom_stabilize_aggregate_ (node2);
9731 realtype = TREE_TYPE (TYPE_FIELDS (type));
9732 item =
9733 ffecom_2 (TRUTH_ANDIF_EXPR, type,
9734 ffecom_2 (code, type,
9735 ffecom_1 (REALPART_EXPR, realtype,
9736 node1),
9737 ffecom_1 (REALPART_EXPR, realtype,
9738 node2)),
9739 ffecom_2 (code, type,
9740 ffecom_1 (IMAGPART_EXPR, realtype,
9741 node1),
9742 ffecom_1 (IMAGPART_EXPR, realtype,
9743 node2)));
9744 break;
9745
9746 case NE_EXPR:
9747 if ((TREE_CODE (node1) != RECORD_TYPE)
9748 && (TREE_CODE (node2) != RECORD_TYPE))
9749 {
9750 item = build (code, type, node1, node2);
9751 break;
9752 }
9753 assert (TREE_CODE (node1) == RECORD_TYPE);
9754 assert (TREE_CODE (node2) == RECORD_TYPE);
9755 node1 = ffecom_stabilize_aggregate_ (node1);
9756 node2 = ffecom_stabilize_aggregate_ (node2);
9757 realtype = TREE_TYPE (TYPE_FIELDS (type));
9758 item =
9759 ffecom_2 (TRUTH_ORIF_EXPR, type,
9760 ffecom_2 (code, type,
9761 ffecom_1 (REALPART_EXPR, realtype,
9762 node1),
9763 ffecom_1 (REALPART_EXPR, realtype,
9764 node2)),
9765 ffecom_2 (code, type,
9766 ffecom_1 (IMAGPART_EXPR, realtype,
9767 node1),
9768 ffecom_1 (IMAGPART_EXPR, realtype,
9769 node2)));
9770 break;
5ff904cd 9771
c7e4ee3a
CB
9772 default:
9773 item = build (code, type, node1, node2);
9774 break;
5ff904cd
JL
9775 }
9776
c7e4ee3a
CB
9777 if (TREE_SIDE_EFFECTS (node1) || TREE_SIDE_EFFECTS (node2))
9778 TREE_SIDE_EFFECTS (item) = 1;
9779 return fold (item);
5ff904cd
JL
9780}
9781
c7e4ee3a 9782/* ffecom_2pass_advise_entrypoint -- Advise that there's this entrypoint
5ff904cd 9783
c7e4ee3a
CB
9784 ffesymbol s; // the ENTRY point itself
9785 if (ffecom_2pass_advise_entrypoint(s))
9786 // the ENTRY point has been accepted
5ff904cd 9787
c7e4ee3a
CB
9788 Does whatever compiler needs to do when it learns about the entrypoint,
9789 like determine the return type of the master function, count the
9790 number of entrypoints, etc. Returns FALSE if the return type is
9791 not compatible with the return type(s) of other entrypoint(s).
5ff904cd 9792
c7e4ee3a
CB
9793 NOTE: for every call to this fn that returns TRUE, _do_entrypoint must
9794 later (after _finish_progunit) be called with the same entrypoint(s)
9795 as passed to this fn for which TRUE was returned.
5ff904cd 9796
c7e4ee3a
CB
9797 03-Jan-92 JCB 2.0
9798 Return FALSE if the return type conflicts with previous entrypoints. */
5ff904cd 9799
c7e4ee3a
CB
9800bool
9801ffecom_2pass_advise_entrypoint (ffesymbol entry)
5ff904cd 9802{
c7e4ee3a
CB
9803 ffebld list; /* opITEM. */
9804 ffebld mlist; /* opITEM. */
9805 ffebld plist; /* opITEM. */
9806 ffebld arg; /* ffebld_head(opITEM). */
9807 ffebld item; /* opITEM. */
9808 ffesymbol s; /* ffebld_symter(arg). */
9809 ffeinfoBasictype bt = ffesymbol_basictype (entry);
9810 ffeinfoKindtype kt = ffesymbol_kindtype (entry);
9811 ffetargetCharacterSize size = ffesymbol_size (entry);
9812 bool ok;
5ff904cd 9813
c7e4ee3a
CB
9814 if (ffecom_num_entrypoints_ == 0)
9815 { /* First entrypoint, make list of main
9816 arglist's dummies. */
9817 assert (ffecom_primary_entry_ != NULL);
5ff904cd 9818
c7e4ee3a
CB
9819 ffecom_master_bt_ = ffesymbol_basictype (ffecom_primary_entry_);
9820 ffecom_master_kt_ = ffesymbol_kindtype (ffecom_primary_entry_);
9821 ffecom_master_size_ = ffesymbol_size (ffecom_primary_entry_);
5ff904cd 9822
c7e4ee3a
CB
9823 for (plist = NULL, list = ffesymbol_dummyargs (ffecom_primary_entry_);
9824 list != NULL;
9825 list = ffebld_trail (list))
9826 {
9827 arg = ffebld_head (list);
9828 if (ffebld_op (arg) != FFEBLD_opSYMTER)
9829 continue; /* Alternate return or some such thing. */
9830 item = ffebld_new_item (arg, NULL);
9831 if (plist == NULL)
9832 ffecom_master_arglist_ = item;
9833 else
9834 ffebld_set_trail (plist, item);
9835 plist = item;
9836 }
5ff904cd
JL
9837 }
9838
c7e4ee3a
CB
9839 /* If necessary, scan entry arglist for alternate returns. Do this scan
9840 apparently redundantly (it's done below to UNIONize the arglists) so
9841 that we don't complain about RETURN 1 if an offending ENTRY is the only
9842 one with an alternate return. */
5ff904cd 9843
c7e4ee3a 9844 if (!ffecom_is_altreturning_)
5ff904cd 9845 {
c7e4ee3a
CB
9846 for (list = ffesymbol_dummyargs (entry);
9847 list != NULL;
9848 list = ffebld_trail (list))
9849 {
9850 arg = ffebld_head (list);
9851 if (ffebld_op (arg) == FFEBLD_opSTAR)
9852 {
9853 ffecom_is_altreturning_ = TRUE;
9854 break;
9855 }
9856 }
9857 }
5ff904cd 9858
c7e4ee3a 9859 /* Now check type compatibility. */
5ff904cd 9860
c7e4ee3a
CB
9861 switch (ffecom_master_bt_)
9862 {
9863 case FFEINFO_basictypeNONE:
9864 ok = (bt != FFEINFO_basictypeCHARACTER);
9865 break;
5ff904cd 9866
c7e4ee3a
CB
9867 case FFEINFO_basictypeCHARACTER:
9868 ok
9869 = (bt == FFEINFO_basictypeCHARACTER)
9870 && (kt == ffecom_master_kt_)
9871 && (size == ffecom_master_size_);
9872 break;
5ff904cd 9873
c7e4ee3a
CB
9874 case FFEINFO_basictypeANY:
9875 return FALSE; /* Just don't bother. */
5ff904cd 9876
c7e4ee3a
CB
9877 default:
9878 if (bt == FFEINFO_basictypeCHARACTER)
5ff904cd 9879 {
c7e4ee3a
CB
9880 ok = FALSE;
9881 break;
5ff904cd 9882 }
c7e4ee3a
CB
9883 ok = TRUE;
9884 if ((bt != ffecom_master_bt_) || (kt != ffecom_master_kt_))
9885 {
9886 ffecom_master_bt_ = FFEINFO_basictypeNONE;
9887 ffecom_master_kt_ = FFEINFO_kindtypeNONE;
9888 }
9889 break;
9890 }
5ff904cd 9891
c7e4ee3a
CB
9892 if (!ok)
9893 {
9894 ffebad_start (FFEBAD_ENTRY_CONFLICTS);
9895 ffest_ffebad_here_current_stmt (0);
9896 ffebad_finish ();
9897 return FALSE; /* Can't handle entrypoint. */
9898 }
5ff904cd 9899
c7e4ee3a 9900 /* Entrypoint type compatible with previous types. */
5ff904cd 9901
c7e4ee3a 9902 ++ffecom_num_entrypoints_;
5ff904cd 9903
c7e4ee3a
CB
9904 /* Master-arg-list = UNION(Master-arg-list,entry-arg-list). */
9905
9906 for (list = ffesymbol_dummyargs (entry);
9907 list != NULL;
9908 list = ffebld_trail (list))
9909 {
9910 arg = ffebld_head (list);
9911 if (ffebld_op (arg) != FFEBLD_opSYMTER)
9912 continue; /* Alternate return or some such thing. */
9913 s = ffebld_symter (arg);
9914 for (plist = NULL, mlist = ffecom_master_arglist_;
9915 mlist != NULL;
9916 plist = mlist, mlist = ffebld_trail (mlist))
9917 { /* plist points to previous item for easy
9918 appending of arg. */
9919 if (ffebld_symter (ffebld_head (mlist)) == s)
9920 break; /* Already have this arg in the master list. */
9921 }
9922 if (mlist != NULL)
9923 continue; /* Already have this arg in the master list. */
5ff904cd 9924
c7e4ee3a 9925 /* Append this arg to the master list. */
5ff904cd 9926
c7e4ee3a
CB
9927 item = ffebld_new_item (arg, NULL);
9928 if (plist == NULL)
9929 ffecom_master_arglist_ = item;
9930 else
9931 ffebld_set_trail (plist, item);
5ff904cd
JL
9932 }
9933
c7e4ee3a 9934 return TRUE;
5ff904cd
JL
9935}
9936
c7e4ee3a
CB
9937/* ffecom_2pass_do_entrypoint -- Do compilation of entrypoint
9938
9939 ffesymbol s; // the ENTRY point itself
9940 ffecom_2pass_do_entrypoint(s);
9941
9942 Does whatever compiler needs to do to make the entrypoint actually
9943 happen. Must be called for each entrypoint after
9944 ffecom_finish_progunit is called. */
9945
c7e4ee3a
CB
9946void
9947ffecom_2pass_do_entrypoint (ffesymbol entry)
5ff904cd 9948{
c7e4ee3a
CB
9949 static int mfn_num = 0;
9950 static int ent_num;
5ff904cd 9951
c7e4ee3a
CB
9952 if (mfn_num != ffecom_num_fns_)
9953 { /* First entrypoint for this program unit. */
9954 ent_num = 1;
9955 mfn_num = ffecom_num_fns_;
9956 ffecom_do_entry_ (ffecom_primary_entry_, 0);
9957 }
9958 else
9959 ++ent_num;
5ff904cd 9960
c7e4ee3a 9961 --ffecom_num_entrypoints_;
5ff904cd 9962
c7e4ee3a
CB
9963 ffecom_do_entry_ (entry, ent_num);
9964}
5ff904cd 9965
c7e4ee3a
CB
9966/* Essentially does a "fold (build (code, type, node1, node2))" while
9967 checking for certain housekeeping things. Always sets
9968 TREE_SIDE_EFFECTS. */
5ff904cd 9969
c7e4ee3a
CB
9970tree
9971ffecom_2s (enum tree_code code, tree type, tree node1,
9972 tree node2)
9973{
9974 tree item;
5ff904cd 9975
c7e4ee3a
CB
9976 if ((node1 == error_mark_node)
9977 || (node2 == error_mark_node)
9978 || (type == error_mark_node))
9979 return error_mark_node;
5ff904cd 9980
c7e4ee3a
CB
9981 item = build (code, type, node1, node2);
9982 TREE_SIDE_EFFECTS (item) = 1;
9983 return fold (item);
5ff904cd
JL
9984}
9985
c7e4ee3a
CB
9986/* Essentially does a "fold (build (code, type, node1, node2, node3))" while
9987 checking for certain housekeeping things. */
9988
c7e4ee3a
CB
9989tree
9990ffecom_3 (enum tree_code code, tree type, tree node1,
9991 tree node2, tree node3)
5ff904cd 9992{
c7e4ee3a 9993 tree item;
5ff904cd 9994
c7e4ee3a
CB
9995 if ((node1 == error_mark_node)
9996 || (node2 == error_mark_node)
9997 || (node3 == error_mark_node)
9998 || (type == error_mark_node))
9999 return error_mark_node;
5ff904cd 10000
c7e4ee3a
CB
10001 item = build (code, type, node1, node2, node3);
10002 if (TREE_SIDE_EFFECTS (node1) || TREE_SIDE_EFFECTS (node2)
10003 || (node3 != NULL_TREE && TREE_SIDE_EFFECTS (node3)))
10004 TREE_SIDE_EFFECTS (item) = 1;
10005 return fold (item);
10006}
5ff904cd 10007
c7e4ee3a
CB
10008/* Essentially does a "fold (build (code, type, node1, node2, node3))" while
10009 checking for certain housekeeping things. Always sets
10010 TREE_SIDE_EFFECTS. */
5ff904cd 10011
c7e4ee3a
CB
10012tree
10013ffecom_3s (enum tree_code code, tree type, tree node1,
10014 tree node2, tree node3)
10015{
10016 tree item;
5ff904cd 10017
c7e4ee3a
CB
10018 if ((node1 == error_mark_node)
10019 || (node2 == error_mark_node)
10020 || (node3 == error_mark_node)
10021 || (type == error_mark_node))
10022 return error_mark_node;
5ff904cd 10023
c7e4ee3a
CB
10024 item = build (code, type, node1, node2, node3);
10025 TREE_SIDE_EFFECTS (item) = 1;
10026 return fold (item);
10027}
5ff904cd 10028
c7e4ee3a 10029/* ffecom_arg_expr -- Transform argument expr into gcc tree
5ff904cd 10030
c7e4ee3a 10031 See use by ffecom_list_expr.
5ff904cd 10032
c7e4ee3a
CB
10033 If expression is NULL, returns an integer zero tree. If it is not
10034 a CHARACTER expression, returns whatever ffecom_expr
10035 returns and sets the length return value to NULL_TREE. Otherwise
10036 generates code to evaluate the character expression, returns the proper
10037 pointer to the result, but does NOT set the length return value to a tree
10038 that specifies the length of the result. (In other words, the length
10039 variable is always set to NULL_TREE, because a length is never passed.)
5ff904cd 10040
c7e4ee3a
CB
10041 21-Dec-91 JCB 1.1
10042 Don't set returned length, since nobody needs it (yet; someday if
10043 we allow CHARACTER*(*) dummies to statement functions, we'll need
10044 it). */
5ff904cd 10045
c7e4ee3a
CB
10046tree
10047ffecom_arg_expr (ffebld expr, tree *length)
10048{
10049 tree ign;
5ff904cd 10050
c7e4ee3a 10051 *length = NULL_TREE;
5ff904cd 10052
c7e4ee3a
CB
10053 if (expr == NULL)
10054 return integer_zero_node;
5ff904cd 10055
c7e4ee3a
CB
10056 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10057 return ffecom_expr (expr);
5ff904cd 10058
c7e4ee3a
CB
10059 return ffecom_arg_ptr_to_expr (expr, &ign);
10060}
10061
c7e4ee3a
CB
10062/* Transform expression into constant argument-pointer-to-expression tree.
10063
10064 If the expression can be transformed into a argument-pointer-to-expression
10065 tree that is constant, that is done, and the tree returned. Else
10066 NULL_TREE is returned.
5ff904cd 10067
c7e4ee3a
CB
10068 That way, a caller can attempt to provide compile-time initialization
10069 of a variable and, if that fails, *then* choose to start a new block
10070 and resort to using temporaries, as appropriate. */
5ff904cd 10071
c7e4ee3a
CB
10072tree
10073ffecom_arg_ptr_to_const_expr (ffebld expr, tree *length)
10074{
10075 if (! expr)
10076 return integer_zero_node;
5ff904cd 10077
c7e4ee3a
CB
10078 if (ffebld_op (expr) == FFEBLD_opANY)
10079 {
10080 if (length)
10081 *length = error_mark_node;
10082 return error_mark_node;
10083 }
10084
10085 if (ffebld_arity (expr) == 0
10086 && (ffebld_op (expr) != FFEBLD_opSYMTER
10087 || ffebld_where (expr) == FFEINFO_whereCOMMON
10088 || ffebld_where (expr) == FFEINFO_whereGLOBAL
10089 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
10090 {
10091 tree t;
10092
10093 t = ffecom_arg_ptr_to_expr (expr, length);
10094 assert (TREE_CONSTANT (t));
10095 assert (! length || TREE_CONSTANT (*length));
10096 return t;
10097 }
10098
10099 if (length
10100 && ffebld_size (expr) != FFETARGET_charactersizeNONE)
10101 *length = build_int_2 (ffebld_size (expr), 0);
10102 else if (length)
10103 *length = NULL_TREE;
10104 return NULL_TREE;
5ff904cd
JL
10105}
10106
c7e4ee3a 10107/* ffecom_arg_ptr_to_expr -- Transform argument expr into gcc tree
5ff904cd 10108
c7e4ee3a
CB
10109 See use by ffecom_list_ptr_to_expr.
10110
10111 If expression is NULL, returns an integer zero tree. If it is not
10112 a CHARACTER expression, returns whatever ffecom_ptr_to_expr
10113 returns and sets the length return value to NULL_TREE. Otherwise
10114 generates code to evaluate the character expression, returns the proper
10115 pointer to the result, AND sets the length return value to a tree that
10116 specifies the length of the result.
10117
10118 If the length argument is NULL, this is a slightly special
10119 case of building a FORMAT expression, that is, an expression that
10120 will be used at run time without regard to length. For the current
10121 implementation, which uses the libf2c library, this means it is nice
10122 to append a null byte to the end of the expression, where feasible,
10123 to make sure any diagnostic about the FORMAT string terminates at
10124 some useful point.
10125
10126 For now, treat %REF(char-expr) as the same as char-expr with a NULL
10127 length argument. This might even be seen as a feature, if a null
10128 byte can always be appended. */
5ff904cd 10129
5ff904cd 10130tree
c7e4ee3a 10131ffecom_arg_ptr_to_expr (ffebld expr, tree *length)
5ff904cd
JL
10132{
10133 tree item;
c7e4ee3a
CB
10134 tree ign_length;
10135 ffecomConcatList_ catlist;
5ff904cd 10136
c7e4ee3a
CB
10137 if (length != NULL)
10138 *length = NULL_TREE;
5ff904cd 10139
c7e4ee3a
CB
10140 if (expr == NULL)
10141 return integer_zero_node;
5ff904cd 10142
c7e4ee3a 10143 switch (ffebld_op (expr))
5ff904cd 10144 {
c7e4ee3a
CB
10145 case FFEBLD_opPERCENT_VAL:
10146 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10147 return ffecom_expr (ffebld_left (expr));
10148 {
10149 tree temp_exp;
10150 tree temp_length;
5ff904cd 10151
c7e4ee3a
CB
10152 temp_exp = ffecom_arg_ptr_to_expr (ffebld_left (expr), &temp_length);
10153 if (temp_exp == error_mark_node)
10154 return error_mark_node;
5ff904cd 10155
c7e4ee3a
CB
10156 return ffecom_1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (temp_exp)),
10157 temp_exp);
10158 }
5ff904cd 10159
c7e4ee3a
CB
10160 case FFEBLD_opPERCENT_REF:
10161 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10162 return ffecom_ptr_to_expr (ffebld_left (expr));
10163 if (length != NULL)
10164 {
10165 ign_length = NULL_TREE;
10166 length = &ign_length;
10167 }
10168 expr = ffebld_left (expr);
10169 break;
5ff904cd 10170
c7e4ee3a
CB
10171 case FFEBLD_opPERCENT_DESCR:
10172 switch (ffeinfo_basictype (ffebld_info (expr)))
5ff904cd 10173 {
c7e4ee3a
CB
10174#ifdef PASS_HOLLERITH_BY_DESCRIPTOR
10175 case FFEINFO_basictypeHOLLERITH:
10176#endif
10177 case FFEINFO_basictypeCHARACTER:
10178 break; /* Passed by descriptor anyway. */
10179
10180 default:
10181 item = ffecom_ptr_to_expr (expr);
10182 if (item != error_mark_node)
10183 *length = TYPE_SIZE (TREE_TYPE (TREE_TYPE (item)));
5ff904cd
JL
10184 break;
10185 }
5ff904cd
JL
10186 break;
10187
10188 default:
5ff904cd
JL
10189 break;
10190 }
10191
c7e4ee3a
CB
10192#ifdef PASS_HOLLERITH_BY_DESCRIPTOR
10193 if ((ffeinfo_basictype (ffebld_info (expr)) == FFEINFO_basictypeHOLLERITH)
10194 && (length != NULL))
10195 { /* Pass Hollerith by descriptor. */
10196 ffetargetHollerith h;
10197
10198 assert (ffebld_op (expr) == FFEBLD_opCONTER);
10199 h = ffebld_cu_val_hollerith (ffebld_constant_union
10200 (ffebld_conter (expr)));
10201 *length
10202 = build_int_2 (h.length, 0);
10203 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
10204 }
10205#endif
10206
10207 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10208 return ffecom_ptr_to_expr (expr);
10209
10210 assert (ffeinfo_kindtype (ffebld_info (expr))
10211 == FFEINFO_kindtypeCHARACTER1);
10212
47d98fa2
CB
10213 while (ffebld_op (expr) == FFEBLD_opPAREN)
10214 expr = ffebld_left (expr);
10215
c7e4ee3a
CB
10216 catlist = ffecom_concat_list_new_ (expr, FFETARGET_charactersizeNONE);
10217 switch (ffecom_concat_list_count_ (catlist))
10218 {
10219 case 0: /* Shouldn't happen, but in case it does... */
10220 if (length != NULL)
10221 {
10222 *length = ffecom_f2c_ftnlen_zero_node;
10223 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
10224 }
10225 ffecom_concat_list_kill_ (catlist);
10226 return null_pointer_node;
10227
10228 case 1: /* The (fairly) easy case. */
10229 if (length == NULL)
10230 ffecom_char_args_with_null_ (&item, &ign_length,
10231 ffecom_concat_list_expr_ (catlist, 0));
10232 else
10233 ffecom_char_args_ (&item, length,
10234 ffecom_concat_list_expr_ (catlist, 0));
10235 ffecom_concat_list_kill_ (catlist);
10236 assert (item != NULL_TREE);
10237 return item;
10238
10239 default: /* Must actually concatenate things. */
10240 break;
10241 }
10242
10243 {
10244 int count = ffecom_concat_list_count_ (catlist);
10245 int i;
10246 tree lengths;
10247 tree items;
10248 tree length_array;
10249 tree item_array;
10250 tree citem;
10251 tree clength;
10252 tree temporary;
10253 tree num;
10254 tree known_length;
10255 ffetargetCharacterSize sz;
10256
10257 sz = ffecom_concat_list_maxlen_ (catlist);
10258 /* ~~Kludge! */
10259 assert (sz != FFETARGET_charactersizeNONE);
10260
10261#ifdef HOHO
10262 length_array
10263 = lengths
10264 = ffecom_push_tempvar (ffecom_f2c_ftnlen_type_node,
10265 FFETARGET_charactersizeNONE, count, TRUE);
10266 item_array
10267 = items
10268 = ffecom_push_tempvar (ffecom_f2c_address_type_node,
10269 FFETARGET_charactersizeNONE, count, TRUE);
10270 temporary = ffecom_push_tempvar (char_type_node,
10271 sz, -1, TRUE);
10272#else
10273 {
10274 tree hook;
10275
10276 hook = ffebld_nonter_hook (expr);
10277 assert (hook);
10278 assert (TREE_CODE (hook) == TREE_VEC);
10279 assert (TREE_VEC_LENGTH (hook) == 3);
10280 length_array = lengths = TREE_VEC_ELT (hook, 0);
10281 item_array = items = TREE_VEC_ELT (hook, 1);
10282 temporary = TREE_VEC_ELT (hook, 2);
10283 }
10284#endif
10285
10286 known_length = ffecom_f2c_ftnlen_zero_node;
10287
10288 for (i = 0; i < count; ++i)
10289 {
10290 if ((i == count)
10291 && (length == NULL))
10292 ffecom_char_args_with_null_ (&citem, &clength,
10293 ffecom_concat_list_expr_ (catlist, i));
10294 else
10295 ffecom_char_args_ (&citem, &clength,
10296 ffecom_concat_list_expr_ (catlist, i));
10297 if ((citem == error_mark_node)
10298 || (clength == error_mark_node))
10299 {
10300 ffecom_concat_list_kill_ (catlist);
10301 *length = error_mark_node;
10302 return error_mark_node;
10303 }
10304
10305 items
10306 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (items),
10307 ffecom_modify (void_type_node,
10308 ffecom_2 (ARRAY_REF,
10309 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array))),
10310 item_array,
10311 build_int_2 (i, 0)),
10312 citem),
10313 items);
10314 clength = ffecom_save_tree (clength);
10315 if (length != NULL)
10316 known_length
10317 = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
10318 known_length,
10319 clength);
10320 lengths
10321 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (lengths),
10322 ffecom_modify (void_type_node,
10323 ffecom_2 (ARRAY_REF,
10324 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array))),
10325 length_array,
10326 build_int_2 (i, 0)),
10327 clength),
10328 lengths);
10329 }
10330
10331 temporary = ffecom_1 (ADDR_EXPR,
10332 build_pointer_type (TREE_TYPE (temporary)),
10333 temporary);
10334
10335 item = build_tree_list (NULL_TREE, temporary);
10336 TREE_CHAIN (item)
10337 = build_tree_list (NULL_TREE,
10338 ffecom_1 (ADDR_EXPR,
10339 build_pointer_type (TREE_TYPE (items)),
10340 items));
10341 TREE_CHAIN (TREE_CHAIN (item))
10342 = build_tree_list (NULL_TREE,
10343 ffecom_1 (ADDR_EXPR,
10344 build_pointer_type (TREE_TYPE (lengths)),
10345 lengths));
10346 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item)))
10347 = build_tree_list
10348 (NULL_TREE,
10349 ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
10350 convert (ffecom_f2c_ftnlen_type_node,
10351 build_int_2 (count, 0))));
10352 num = build_int_2 (sz, 0);
10353 TREE_TYPE (num) = ffecom_f2c_ftnlen_type_node;
10354 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item))))
10355 = build_tree_list (NULL_TREE, num);
10356
10357 item = ffecom_call_gfrt (FFECOM_gfrtCAT, item, NULL_TREE);
5ff904cd 10358 TREE_SIDE_EFFECTS (item) = 1;
c7e4ee3a
CB
10359 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (temporary),
10360 item,
10361 temporary);
10362
10363 if (length != NULL)
10364 *length = known_length;
10365 }
10366
10367 ffecom_concat_list_kill_ (catlist);
10368 assert (item != NULL_TREE);
10369 return item;
5ff904cd 10370}
c7e4ee3a 10371
c7e4ee3a 10372/* Generate call to run-time function.
5ff904cd 10373
c7e4ee3a
CB
10374 The first arg is the GNU Fortran Run-Time function index, the second
10375 arg is the list of arguments to pass to it. Returned is the expression
10376 (WITHOUT TREE_SIDE_EFFECTS set!) that makes the call and returns the
10377 result (which may be void). */
5ff904cd 10378
5ff904cd 10379tree
c7e4ee3a 10380ffecom_call_gfrt (ffecomGfrt ix, tree args, tree hook)
5ff904cd 10381{
c7e4ee3a
CB
10382 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
10383 ffecom_gfrt_kindtype (ix),
10384 ffe_is_f2c_library () && ffecom_gfrt_complex_[ix],
10385 NULL_TREE, args, NULL_TREE, NULL,
10386 NULL, NULL_TREE, TRUE, hook);
5ff904cd 10387}
5ff904cd 10388
c7e4ee3a 10389/* Transform constant-union to tree. */
5ff904cd 10390
5ff904cd 10391tree
c7e4ee3a
CB
10392ffecom_constantunion (ffebldConstantUnion *cu, ffeinfoBasictype bt,
10393 ffeinfoKindtype kt, tree tree_type)
5ff904cd
JL
10394{
10395 tree item;
10396
c7e4ee3a 10397 switch (bt)
5ff904cd 10398 {
c7e4ee3a
CB
10399 case FFEINFO_basictypeINTEGER:
10400 {
10401 int val;
5ff904cd 10402
c7e4ee3a
CB
10403 switch (kt)
10404 {
10405#if FFETARGET_okINTEGER1
10406 case FFEINFO_kindtypeINTEGER1:
10407 val = ffebld_cu_val_integer1 (*cu);
10408 break;
10409#endif
5ff904cd 10410
c7e4ee3a
CB
10411#if FFETARGET_okINTEGER2
10412 case FFEINFO_kindtypeINTEGER2:
10413 val = ffebld_cu_val_integer2 (*cu);
10414 break;
10415#endif
5ff904cd 10416
c7e4ee3a
CB
10417#if FFETARGET_okINTEGER3
10418 case FFEINFO_kindtypeINTEGER3:
10419 val = ffebld_cu_val_integer3 (*cu);
10420 break;
10421#endif
5ff904cd 10422
c7e4ee3a
CB
10423#if FFETARGET_okINTEGER4
10424 case FFEINFO_kindtypeINTEGER4:
10425 val = ffebld_cu_val_integer4 (*cu);
10426 break;
10427#endif
5ff904cd 10428
c7e4ee3a
CB
10429 default:
10430 assert ("bad INTEGER constant kind type" == NULL);
10431 /* Fall through. */
10432 case FFEINFO_kindtypeANY:
10433 return error_mark_node;
10434 }
10435 item = build_int_2 (val, (val < 0) ? -1 : 0);
10436 TREE_TYPE (item) = tree_type;
10437 }
5ff904cd 10438 break;
5ff904cd 10439
c7e4ee3a
CB
10440 case FFEINFO_basictypeLOGICAL:
10441 {
10442 int val;
5ff904cd 10443
c7e4ee3a
CB
10444 switch (kt)
10445 {
10446#if FFETARGET_okLOGICAL1
10447 case FFEINFO_kindtypeLOGICAL1:
10448 val = ffebld_cu_val_logical1 (*cu);
10449 break;
5ff904cd 10450#endif
5ff904cd 10451
c7e4ee3a
CB
10452#if FFETARGET_okLOGICAL2
10453 case FFEINFO_kindtypeLOGICAL2:
10454 val = ffebld_cu_val_logical2 (*cu);
10455 break;
10456#endif
5ff904cd 10457
c7e4ee3a
CB
10458#if FFETARGET_okLOGICAL3
10459 case FFEINFO_kindtypeLOGICAL3:
10460 val = ffebld_cu_val_logical3 (*cu);
10461 break;
10462#endif
5ff904cd 10463
c7e4ee3a
CB
10464#if FFETARGET_okLOGICAL4
10465 case FFEINFO_kindtypeLOGICAL4:
10466 val = ffebld_cu_val_logical4 (*cu);
10467 break;
10468#endif
5ff904cd 10469
c7e4ee3a
CB
10470 default:
10471 assert ("bad LOGICAL constant kind type" == NULL);
10472 /* Fall through. */
10473 case FFEINFO_kindtypeANY:
10474 return error_mark_node;
10475 }
10476 item = build_int_2 (val, (val < 0) ? -1 : 0);
10477 TREE_TYPE (item) = tree_type;
10478 }
10479 break;
5ff904cd 10480
c7e4ee3a
CB
10481 case FFEINFO_basictypeREAL:
10482 {
10483 REAL_VALUE_TYPE val;
5ff904cd 10484
c7e4ee3a
CB
10485 switch (kt)
10486 {
10487#if FFETARGET_okREAL1
10488 case FFEINFO_kindtypeREAL1:
10489 val = ffetarget_value_real1 (ffebld_cu_val_real1 (*cu));
10490 break;
10491#endif
5ff904cd 10492
c7e4ee3a
CB
10493#if FFETARGET_okREAL2
10494 case FFEINFO_kindtypeREAL2:
10495 val = ffetarget_value_real2 (ffebld_cu_val_real2 (*cu));
10496 break;
10497#endif
5ff904cd 10498
c7e4ee3a
CB
10499#if FFETARGET_okREAL3
10500 case FFEINFO_kindtypeREAL3:
10501 val = ffetarget_value_real3 (ffebld_cu_val_real3 (*cu));
10502 break;
10503#endif
5ff904cd 10504
c7e4ee3a
CB
10505#if FFETARGET_okREAL4
10506 case FFEINFO_kindtypeREAL4:
10507 val = ffetarget_value_real4 (ffebld_cu_val_real4 (*cu));
10508 break;
10509#endif
5ff904cd 10510
c7e4ee3a
CB
10511 default:
10512 assert ("bad REAL constant kind type" == NULL);
10513 /* Fall through. */
10514 case FFEINFO_kindtypeANY:
10515 return error_mark_node;
10516 }
10517 item = build_real (tree_type, val);
10518 }
5ff904cd
JL
10519 break;
10520
c7e4ee3a
CB
10521 case FFEINFO_basictypeCOMPLEX:
10522 {
10523 REAL_VALUE_TYPE real;
10524 REAL_VALUE_TYPE imag;
10525 tree el_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
5ff904cd 10526
c7e4ee3a
CB
10527 switch (kt)
10528 {
10529#if FFETARGET_okCOMPLEX1
10530 case FFEINFO_kindtypeREAL1:
10531 real = ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu).real);
10532 imag = ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu).imaginary);
10533 break;
10534#endif
5ff904cd 10535
c7e4ee3a
CB
10536#if FFETARGET_okCOMPLEX2
10537 case FFEINFO_kindtypeREAL2:
10538 real = ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu).real);
10539 imag = ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu).imaginary);
10540 break;
10541#endif
5ff904cd 10542
c7e4ee3a
CB
10543#if FFETARGET_okCOMPLEX3
10544 case FFEINFO_kindtypeREAL3:
10545 real = ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu).real);
10546 imag = ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu).imaginary);
10547 break;
10548#endif
5ff904cd 10549
c7e4ee3a
CB
10550#if FFETARGET_okCOMPLEX4
10551 case FFEINFO_kindtypeREAL4:
10552 real = ffetarget_value_real4 (ffebld_cu_val_complex4 (*cu).real);
10553 imag = ffetarget_value_real4 (ffebld_cu_val_complex4 (*cu).imaginary);
10554 break;
10555#endif
5ff904cd 10556
c7e4ee3a
CB
10557 default:
10558 assert ("bad REAL constant kind type" == NULL);
10559 /* Fall through. */
10560 case FFEINFO_kindtypeANY:
10561 return error_mark_node;
10562 }
10563 item = ffecom_build_complex_constant_ (tree_type,
10564 build_real (el_type, real),
10565 build_real (el_type, imag));
10566 }
10567 break;
5ff904cd 10568
c7e4ee3a
CB
10569 case FFEINFO_basictypeCHARACTER:
10570 { /* Happens only in DATA and similar contexts. */
10571 ffetargetCharacter1 val;
5ff904cd 10572
c7e4ee3a
CB
10573 switch (kt)
10574 {
10575#if FFETARGET_okCHARACTER1
10576 case FFEINFO_kindtypeLOGICAL1:
10577 val = ffebld_cu_val_character1 (*cu);
10578 break;
10579#endif
10580
10581 default:
10582 assert ("bad CHARACTER constant kind type" == NULL);
10583 /* Fall through. */
10584 case FFEINFO_kindtypeANY:
10585 return error_mark_node;
10586 }
10587 item = build_string (ffetarget_length_character1 (val),
10588 ffetarget_text_character1 (val));
10589 TREE_TYPE (item)
10590 = build_type_variant (build_array_type (char_type_node,
10591 build_range_type
10592 (integer_type_node,
10593 integer_one_node,
10594 build_int_2
10595 (ffetarget_length_character1
10596 (val), 0))),
10597 1, 0);
10598 }
10599 break;
5ff904cd 10600
c7e4ee3a
CB
10601 case FFEINFO_basictypeHOLLERITH:
10602 {
10603 ffetargetHollerith h;
5ff904cd 10604
c7e4ee3a 10605 h = ffebld_cu_val_hollerith (*cu);
5ff904cd 10606
c7e4ee3a
CB
10607 /* If not at least as wide as default INTEGER, widen it. */
10608 if (h.length >= FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE)
10609 item = build_string (h.length, h.text);
10610 else
10611 {
10612 char str[FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE];
5ff904cd 10613
c7e4ee3a
CB
10614 memcpy (str, h.text, h.length);
10615 memset (&str[h.length], ' ',
10616 FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE
10617 - h.length);
10618 item = build_string (FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE,
10619 str);
10620 }
10621 TREE_TYPE (item)
10622 = build_type_variant (build_array_type (char_type_node,
10623 build_range_type
10624 (integer_type_node,
10625 integer_one_node,
10626 build_int_2
10627 (h.length, 0))),
10628 1, 0);
10629 }
10630 break;
5ff904cd 10631
c7e4ee3a
CB
10632 case FFEINFO_basictypeTYPELESS:
10633 {
10634 ffetargetInteger1 ival;
10635 ffetargetTypeless tless;
10636 ffebad error;
5ff904cd 10637
c7e4ee3a
CB
10638 tless = ffebld_cu_val_typeless (*cu);
10639 error = ffetarget_convert_integer1_typeless (&ival, tless);
10640 assert (error == FFEBAD);
5ff904cd 10641
c7e4ee3a
CB
10642 item = build_int_2 ((int) ival, 0);
10643 }
10644 break;
5ff904cd 10645
c7e4ee3a
CB
10646 default:
10647 assert ("not yet on constant type" == NULL);
10648 /* Fall through. */
10649 case FFEINFO_basictypeANY:
10650 return error_mark_node;
5ff904cd 10651 }
5ff904cd 10652
c7e4ee3a 10653 TREE_CONSTANT (item) = 1;
5ff904cd 10654
c7e4ee3a 10655 return item;
5ff904cd
JL
10656}
10657
c7e4ee3a
CB
10658/* Transform expression into constant tree.
10659
10660 If the expression can be transformed into a tree that is constant,
10661 that is done, and the tree returned. Else NULL_TREE is returned.
10662
10663 That way, a caller can attempt to provide compile-time initialization
10664 of a variable and, if that fails, *then* choose to start a new block
10665 and resort to using temporaries, as appropriate. */
5ff904cd 10666
5ff904cd 10667tree
c7e4ee3a 10668ffecom_const_expr (ffebld expr)
5ff904cd 10669{
c7e4ee3a
CB
10670 if (! expr)
10671 return integer_zero_node;
5ff904cd 10672
c7e4ee3a 10673 if (ffebld_op (expr) == FFEBLD_opANY)
5ff904cd
JL
10674 return error_mark_node;
10675
c7e4ee3a
CB
10676 if (ffebld_arity (expr) == 0
10677 && (ffebld_op (expr) != FFEBLD_opSYMTER
10678#if NEWCOMMON
10679 /* ~~Enable once common/equivalence is handled properly? */
10680 || ffebld_where (expr) == FFEINFO_whereCOMMON
5ff904cd 10681#endif
c7e4ee3a
CB
10682 || ffebld_where (expr) == FFEINFO_whereGLOBAL
10683 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
10684 {
10685 tree t;
5ff904cd 10686
c7e4ee3a
CB
10687 t = ffecom_expr (expr);
10688 assert (TREE_CONSTANT (t));
10689 return t;
10690 }
5ff904cd 10691
c7e4ee3a 10692 return NULL_TREE;
5ff904cd
JL
10693}
10694
c7e4ee3a 10695/* Handy way to make a field in a struct/union. */
5ff904cd 10696
5ff904cd 10697tree
c7e4ee3a
CB
10698ffecom_decl_field (tree context, tree prevfield,
10699 const char *name, tree type)
5ff904cd 10700{
c7e4ee3a 10701 tree field;
5ff904cd 10702
c7e4ee3a
CB
10703 field = build_decl (FIELD_DECL, get_identifier (name), type);
10704 DECL_CONTEXT (field) = context;
8ba77681 10705 DECL_ALIGN (field) = 0;
11cf4d18 10706 DECL_USER_ALIGN (field) = 0;
c7e4ee3a
CB
10707 if (prevfield != NULL_TREE)
10708 TREE_CHAIN (prevfield) = field;
5ff904cd 10709
c7e4ee3a 10710 return field;
5ff904cd
JL
10711}
10712
c7e4ee3a
CB
10713void
10714ffecom_close_include (FILE *f)
10715{
c7e4ee3a 10716 ffecom_close_include_ (f);
c7e4ee3a 10717}
5ff904cd 10718
c7e4ee3a
CB
10719int
10720ffecom_decode_include_option (char *spec)
10721{
c7e4ee3a 10722 return ffecom_decode_include_option_ (spec);
c7e4ee3a 10723}
5ff904cd 10724
c7e4ee3a 10725/* End a compound statement (block). */
5ff904cd 10726
5ff904cd 10727tree
c7e4ee3a 10728ffecom_end_compstmt (void)
5ff904cd 10729{
c7e4ee3a
CB
10730 return bison_rule_compstmt_ ();
10731}
5ff904cd 10732
c7e4ee3a 10733/* ffecom_end_transition -- Perform end transition on all symbols
5ff904cd 10734
c7e4ee3a 10735 ffecom_end_transition();
5ff904cd 10736
c7e4ee3a 10737 Calls ffecom_sym_end_transition for each global and local symbol. */
5ff904cd 10738
c7e4ee3a
CB
10739void
10740ffecom_end_transition ()
10741{
c7e4ee3a 10742 ffebld item;
5ff904cd 10743
c7e4ee3a
CB
10744 if (ffe_is_ffedebug ())
10745 fprintf (dmpout, "; end_stmt_transition\n");
86fc7a6c 10746
c7e4ee3a
CB
10747 ffecom_list_blockdata_ = NULL;
10748 ffecom_list_common_ = NULL;
86fc7a6c 10749
c7e4ee3a
CB
10750 ffesymbol_drive (ffecom_sym_end_transition);
10751 if (ffe_is_ffedebug ())
10752 {
10753 ffestorag_report ();
c7e4ee3a 10754 }
5ff904cd 10755
c7e4ee3a
CB
10756 ffecom_start_progunit_ ();
10757
10758 for (item = ffecom_list_blockdata_;
10759 item != NULL;
10760 item = ffebld_trail (item))
10761 {
10762 ffebld callee;
10763 ffesymbol s;
10764 tree dt;
10765 tree t;
10766 tree var;
c7e4ee3a
CB
10767 static int number = 0;
10768
10769 callee = ffebld_head (item);
10770 s = ffebld_symter (callee);
10771 t = ffesymbol_hook (s).decl_tree;
10772 if (t == NULL_TREE)
10773 {
10774 s = ffecom_sym_transform_ (s);
10775 t = ffesymbol_hook (s).decl_tree;
10776 }
5ff904cd 10777
c7e4ee3a 10778 dt = build_pointer_type (TREE_TYPE (t));
5ff904cd 10779
c7e4ee3a
CB
10780 var = build_decl (VAR_DECL,
10781 ffecom_get_invented_identifier ("__g77_forceload_%d",
14657de8 10782 number++),
c7e4ee3a
CB
10783 dt);
10784 DECL_EXTERNAL (var) = 0;
10785 TREE_STATIC (var) = 1;
10786 TREE_PUBLIC (var) = 0;
10787 DECL_INITIAL (var) = error_mark_node;
10788 TREE_USED (var) = 1;
5ff904cd 10789
c7e4ee3a 10790 var = start_decl (var, FALSE);
702edf1d 10791
c7e4ee3a 10792 t = ffecom_1 (ADDR_EXPR, dt, t);
5ff904cd 10793
c7e4ee3a 10794 finish_decl (var, t, FALSE);
c7e4ee3a
CB
10795 }
10796
10797 /* This handles any COMMON areas that weren't referenced but have, for
10798 example, important initial data. */
10799
10800 for (item = ffecom_list_common_;
10801 item != NULL;
10802 item = ffebld_trail (item))
10803 ffecom_transform_common_ (ffebld_symter (ffebld_head (item)));
10804
10805 ffecom_list_common_ = NULL;
c7e4ee3a 10806}
5ff904cd 10807
c7e4ee3a 10808/* ffecom_exec_transition -- Perform exec transition on all symbols
5ff904cd 10809
c7e4ee3a 10810 ffecom_exec_transition();
5ff904cd 10811
c7e4ee3a
CB
10812 Calls ffecom_sym_exec_transition for each global and local symbol.
10813 Make sure error updating not inhibited. */
5ff904cd 10814
c7e4ee3a
CB
10815void
10816ffecom_exec_transition ()
10817{
10818 bool inhibited;
5ff904cd 10819
c7e4ee3a
CB
10820 if (ffe_is_ffedebug ())
10821 fprintf (dmpout, "; exec_stmt_transition\n");
5ff904cd 10822
c7e4ee3a
CB
10823 inhibited = ffebad_inhibit ();
10824 ffebad_set_inhibit (FALSE);
5ff904cd 10825
c7e4ee3a
CB
10826 ffesymbol_drive (ffecom_sym_exec_transition); /* Don't retract! */
10827 ffeequiv_exec_transition (); /* Handle all pending EQUIVALENCEs. */
10828 if (ffe_is_ffedebug ())
5ff904cd 10829 {
c7e4ee3a 10830 ffestorag_report ();
c7e4ee3a 10831 }
5ff904cd 10832
c7e4ee3a
CB
10833 if (inhibited)
10834 ffebad_set_inhibit (TRUE);
10835}
5ff904cd 10836
c7e4ee3a 10837/* Handle assignment statement.
5ff904cd 10838
c7e4ee3a
CB
10839 Convert dest and source using ffecom_expr, then join them
10840 with an ASSIGN op and pass the whole thing to expand_expr_stmt. */
5ff904cd 10841
c7e4ee3a
CB
10842void
10843ffecom_expand_let_stmt (ffebld dest, ffebld source)
10844{
10845 tree dest_tree;
10846 tree dest_length;
10847 tree source_tree;
10848 tree expr_tree;
5ff904cd 10849
c7e4ee3a
CB
10850 if (ffeinfo_basictype (ffebld_info (dest)) != FFEINFO_basictypeCHARACTER)
10851 {
10852 bool dest_used;
d6cd84e0 10853 tree assign_temp;
5ff904cd 10854
c7e4ee3a
CB
10855 /* This attempts to replicate the test below, but must not be
10856 true when the test below is false. (Always err on the side
10857 of creating unused temporaries, to avoid ICEs.) */
10858 if (ffebld_op (dest) != FFEBLD_opSYMTER
10859 || ((dest_tree = ffesymbol_hook (ffebld_symter (dest)).decl_tree)
10860 && (TREE_CODE (dest_tree) != VAR_DECL
10861 || TREE_ADDRESSABLE (dest_tree))))
10862 {
10863 ffecom_prepare_expr_ (source, dest);
10864 dest_used = TRUE;
10865 }
10866 else
10867 {
10868 ffecom_prepare_expr_ (source, NULL);
10869 dest_used = FALSE;
10870 }
5ff904cd 10871
c7e4ee3a 10872 ffecom_prepare_expr_w (NULL_TREE, dest);
5ff904cd 10873
d6cd84e0
CB
10874 /* For COMPLEX assignment like C1=C2, if partial overlap is possible,
10875 create a temporary through which the assignment is to take place,
10876 since MODIFY_EXPR doesn't handle partial overlap properly. */
10877 if (ffebld_basictype (dest) == FFEINFO_basictypeCOMPLEX
10878 && ffecom_possible_partial_overlap_ (dest, source))
10879 {
10880 assign_temp = ffecom_make_tempvar ("complex_let",
10881 ffecom_tree_type
10882 [ffebld_basictype (dest)]
10883 [ffebld_kindtype (dest)],
10884 FFETARGET_charactersizeNONE,
10885 -1);
10886 }
10887 else
10888 assign_temp = NULL_TREE;
10889
c7e4ee3a 10890 ffecom_prepare_end ();
5ff904cd 10891
c7e4ee3a
CB
10892 dest_tree = ffecom_expr_w (NULL_TREE, dest);
10893 if (dest_tree == error_mark_node)
10894 return;
5ff904cd 10895
c7e4ee3a
CB
10896 if ((TREE_CODE (dest_tree) != VAR_DECL)
10897 || TREE_ADDRESSABLE (dest_tree))
10898 source_tree = ffecom_expr_ (source, dest_tree, dest, &dest_used,
10899 FALSE, FALSE);
10900 else
10901 {
10902 assert (! dest_used);
10903 dest_used = FALSE;
10904 source_tree = ffecom_expr (source);
10905 }
10906 if (source_tree == error_mark_node)
10907 return;
5ff904cd 10908
c7e4ee3a
CB
10909 if (dest_used)
10910 expr_tree = source_tree;
d6cd84e0
CB
10911 else if (assign_temp)
10912 {
10913#ifdef MOVE_EXPR
10914 /* The back end understands a conceptual move (evaluate source;
10915 store into dest), so use that, in case it can determine
10916 that it is going to use, say, two registers as temporaries
10917 anyway. So don't use the temp (and someday avoid generating
10918 it, once this code starts triggering regularly). */
10919 expr_tree = ffecom_2s (MOVE_EXPR, void_type_node,
10920 dest_tree,
10921 source_tree);
10922#else
10923 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
10924 assign_temp,
10925 source_tree);
10926 expand_expr_stmt (expr_tree);
10927 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
10928 dest_tree,
10929 assign_temp);
10930#endif
10931 }
c7e4ee3a
CB
10932 else
10933 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
10934 dest_tree,
10935 source_tree);
5ff904cd 10936
c7e4ee3a
CB
10937 expand_expr_stmt (expr_tree);
10938 return;
10939 }
5ff904cd 10940
c7e4ee3a
CB
10941 ffecom_prepare_let_char_ (ffebld_size_known (dest), source);
10942 ffecom_prepare_expr_w (NULL_TREE, dest);
10943
10944 ffecom_prepare_end ();
10945
10946 ffecom_char_args_ (&dest_tree, &dest_length, dest);
10947 ffecom_let_char_ (dest_tree, dest_length, ffebld_size_known (dest),
10948 source);
5ff904cd
JL
10949}
10950
c7e4ee3a 10951/* ffecom_expr -- Transform expr into gcc tree
5ff904cd 10952
c7e4ee3a
CB
10953 tree t;
10954 ffebld expr; // FFE expression.
10955 tree = ffecom_expr(expr);
5ff904cd 10956
c7e4ee3a
CB
10957 Recursive descent on expr while making corresponding tree nodes and
10958 attaching type info and such. */
5ff904cd 10959
5ff904cd 10960tree
c7e4ee3a 10961ffecom_expr (ffebld expr)
5ff904cd 10962{
c7e4ee3a 10963 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, FALSE, FALSE);
5ff904cd 10964}
c7e4ee3a 10965
c7e4ee3a 10966/* Like ffecom_expr, but return tree usable for assigned GOTO or FORMAT. */
5ff904cd 10967
c7e4ee3a
CB
10968tree
10969ffecom_expr_assign (ffebld expr)
10970{
10971 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, TRUE, FALSE);
10972}
5ff904cd 10973
c7e4ee3a 10974/* Like ffecom_expr_rw, but return tree usable for ASSIGN. */
5ff904cd 10975
5ff904cd 10976tree
c7e4ee3a 10977ffecom_expr_assign_w (ffebld expr)
5ff904cd 10978{
c7e4ee3a
CB
10979 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, TRUE, FALSE);
10980}
5ff904cd 10981
c7e4ee3a
CB
10982/* Transform expr for use as into read/write tree and stabilize the
10983 reference. Not for use on CHARACTER expressions.
5ff904cd 10984
c7e4ee3a
CB
10985 Recursive descent on expr while making corresponding tree nodes and
10986 attaching type info and such. */
5ff904cd 10987
c7e4ee3a
CB
10988tree
10989ffecom_expr_rw (tree type, ffebld expr)
10990{
10991 assert (expr != NULL);
10992 /* Different target types not yet supported. */
10993 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
10994
10995 return stabilize_reference (ffecom_expr (expr));
10996}
5ff904cd 10997
c7e4ee3a
CB
10998/* Transform expr for use as into write tree and stabilize the
10999 reference. Not for use on CHARACTER expressions.
5ff904cd 11000
c7e4ee3a
CB
11001 Recursive descent on expr while making corresponding tree nodes and
11002 attaching type info and such. */
5ff904cd 11003
c7e4ee3a
CB
11004tree
11005ffecom_expr_w (tree type, ffebld expr)
11006{
11007 assert (expr != NULL);
11008 /* Different target types not yet supported. */
11009 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
11010
11011 return stabilize_reference (ffecom_expr (expr));
11012}
5ff904cd 11013
c7e4ee3a
CB
11014/* Do global stuff. */
11015
c7e4ee3a
CB
11016void
11017ffecom_finish_compile ()
11018{
11019 assert (ffecom_outer_function_decl_ == NULL_TREE);
11020 assert (current_function_decl == NULL_TREE);
11021
11022 ffeglobal_drive (ffecom_finish_global_);
11023}
5ff904cd 11024
c7e4ee3a
CB
11025/* Public entry point for front end to access finish_decl. */
11026
c7e4ee3a
CB
11027void
11028ffecom_finish_decl (tree decl, tree init, bool is_top_level)
11029{
11030 assert (!is_top_level);
11031 finish_decl (decl, init, FALSE);
11032}
5ff904cd 11033
c7e4ee3a
CB
11034/* Finish a program unit. */
11035
c7e4ee3a
CB
11036void
11037ffecom_finish_progunit ()
11038{
11039 ffecom_end_compstmt ();
11040
11041 ffecom_previous_function_decl_ = current_function_decl;
11042 ffecom_which_entrypoint_decl_ = NULL_TREE;
11043
11044 finish_function (0);
11045}
5ff904cd 11046
14657de8 11047/* Wrapper for get_identifier. pattern is sprintf-like. */
c7e4ee3a 11048
c7e4ee3a 11049tree
14657de8 11050ffecom_get_invented_identifier (const char *pattern, ...)
c7e4ee3a
CB
11051{
11052 tree decl;
11053 char *nam;
14657de8 11054 va_list ap;
c7e4ee3a 11055
14657de8
KG
11056 va_start (ap, pattern);
11057 if (vasprintf (&nam, pattern, ap) == 0)
11058 abort ();
11059 va_end (ap);
c7e4ee3a 11060 decl = get_identifier (nam);
14657de8 11061 free (nam);
c7e4ee3a 11062 IDENTIFIER_INVENTED (decl) = 1;
c7e4ee3a
CB
11063 return decl;
11064}
11065
11066ffeinfoBasictype
11067ffecom_gfrt_basictype (ffecomGfrt gfrt)
11068{
11069 assert (gfrt < FFECOM_gfrt);
11070
11071 switch (ffecom_gfrt_type_[gfrt])
11072 {
11073 case FFECOM_rttypeVOID_:
11074 case FFECOM_rttypeVOIDSTAR_:
11075 return FFEINFO_basictypeNONE;
11076
11077 case FFECOM_rttypeFTNINT_:
11078 return FFEINFO_basictypeINTEGER;
11079
11080 case FFECOM_rttypeINTEGER_:
11081 return FFEINFO_basictypeINTEGER;
11082
11083 case FFECOM_rttypeLONGINT_:
11084 return FFEINFO_basictypeINTEGER;
11085
11086 case FFECOM_rttypeLOGICAL_:
11087 return FFEINFO_basictypeLOGICAL;
11088
11089 case FFECOM_rttypeREAL_F2C_:
11090 case FFECOM_rttypeREAL_GNU_:
11091 return FFEINFO_basictypeREAL;
11092
11093 case FFECOM_rttypeCOMPLEX_F2C_:
11094 case FFECOM_rttypeCOMPLEX_GNU_:
11095 return FFEINFO_basictypeCOMPLEX;
11096
11097 case FFECOM_rttypeDOUBLE_:
11098 case FFECOM_rttypeDOUBLEREAL_:
11099 return FFEINFO_basictypeREAL;
11100
11101 case FFECOM_rttypeDBLCMPLX_F2C_:
11102 case FFECOM_rttypeDBLCMPLX_GNU_:
11103 return FFEINFO_basictypeCOMPLEX;
11104
11105 case FFECOM_rttypeCHARACTER_:
11106 return FFEINFO_basictypeCHARACTER;
11107
11108 default:
11109 return FFEINFO_basictypeANY;
11110 }
11111}
11112
11113ffeinfoKindtype
11114ffecom_gfrt_kindtype (ffecomGfrt gfrt)
11115{
11116 assert (gfrt < FFECOM_gfrt);
11117
11118 switch (ffecom_gfrt_type_[gfrt])
11119 {
11120 case FFECOM_rttypeVOID_:
11121 case FFECOM_rttypeVOIDSTAR_:
11122 return FFEINFO_kindtypeNONE;
5ff904cd 11123
c7e4ee3a
CB
11124 case FFECOM_rttypeFTNINT_:
11125 return FFEINFO_kindtypeINTEGER1;
5ff904cd 11126
c7e4ee3a
CB
11127 case FFECOM_rttypeINTEGER_:
11128 return FFEINFO_kindtypeINTEGER1;
5ff904cd 11129
c7e4ee3a
CB
11130 case FFECOM_rttypeLONGINT_:
11131 return FFEINFO_kindtypeINTEGER4;
5ff904cd 11132
c7e4ee3a
CB
11133 case FFECOM_rttypeLOGICAL_:
11134 return FFEINFO_kindtypeLOGICAL1;
5ff904cd 11135
c7e4ee3a
CB
11136 case FFECOM_rttypeREAL_F2C_:
11137 case FFECOM_rttypeREAL_GNU_:
11138 return FFEINFO_kindtypeREAL1;
5ff904cd 11139
c7e4ee3a
CB
11140 case FFECOM_rttypeCOMPLEX_F2C_:
11141 case FFECOM_rttypeCOMPLEX_GNU_:
11142 return FFEINFO_kindtypeREAL1;
5ff904cd 11143
c7e4ee3a
CB
11144 case FFECOM_rttypeDOUBLE_:
11145 case FFECOM_rttypeDOUBLEREAL_:
11146 return FFEINFO_kindtypeREAL2;
5ff904cd 11147
c7e4ee3a
CB
11148 case FFECOM_rttypeDBLCMPLX_F2C_:
11149 case FFECOM_rttypeDBLCMPLX_GNU_:
11150 return FFEINFO_kindtypeREAL2;
5ff904cd 11151
c7e4ee3a
CB
11152 case FFECOM_rttypeCHARACTER_:
11153 return FFEINFO_kindtypeCHARACTER1;
5ff904cd 11154
c7e4ee3a
CB
11155 default:
11156 return FFEINFO_kindtypeANY;
11157 }
11158}
5ff904cd 11159
c7e4ee3a
CB
11160void
11161ffecom_init_0 ()
11162{
11163 tree endlink;
11164 int i;
11165 int j;
11166 tree t;
11167 tree field;
11168 ffetype type;
11169 ffetype base_type;
7189a4b0
GK
11170 tree double_ftype_double;
11171 tree float_ftype_float;
11172 tree ldouble_ftype_ldouble;
11173 tree ffecom_tree_ptr_to_fun_type_void;
5ff904cd 11174
c7e4ee3a
CB
11175 /* This block of code comes from the now-obsolete cktyps.c. It checks
11176 whether the compiler environment is buggy in known ways, some of which
11177 would, if not explicitly checked here, result in subtle bugs in g77. */
5ff904cd 11178
c7e4ee3a
CB
11179 if (ffe_is_do_internal_checks ())
11180 {
8b60264b 11181 static const char names[][12]
c7e4ee3a
CB
11182 =
11183 {"bar", "bletch", "foo", "foobar"};
8b60264b 11184 const char *name;
c7e4ee3a
CB
11185 unsigned long ul;
11186 double fl;
5ff904cd 11187
c7e4ee3a 11188 name = bsearch ("foo", &names[0], ARRAY_SIZE (names), sizeof (names[0]),
b0791fa9 11189 (int (*)(const void *, const void *)) strcmp);
8b60264b 11190 if (name != &names[0][2])
c7e4ee3a
CB
11191 {
11192 assert ("bsearch doesn't work, #define FFEPROJ_BSEARCH 0 in proj.h"
11193 == NULL);
11194 abort ();
11195 }
5ff904cd 11196
c7e4ee3a
CB
11197 ul = strtoul ("123456789", NULL, 10);
11198 if (ul != 123456789L)
11199 {
11200 assert ("strtoul doesn't have enough range, #define FFEPROJ_STRTOUL 0\
11201 in proj.h" == NULL);
11202 abort ();
11203 }
5ff904cd 11204
c7e4ee3a
CB
11205 fl = atof ("56.789");
11206 if ((fl < 56.788) || (fl > 56.79))
11207 {
11208 assert ("atof not type double, fix your #include <stdio.h>"
11209 == NULL);
11210 abort ();
11211 }
11212 }
5ff904cd 11213
c7e4ee3a
CB
11214 ffecom_outer_function_decl_ = NULL_TREE;
11215 current_function_decl = NULL_TREE;
11216 named_labels = NULL_TREE;
11217 current_binding_level = NULL_BINDING_LEVEL;
11218 free_binding_level = NULL_BINDING_LEVEL;
11219 /* Make the binding_level structure for global names. */
11220 pushlevel (0);
11221 global_binding_level = current_binding_level;
11222 current_binding_level->prep_state = 2;
5ff904cd 11223
81b3411c 11224 build_common_tree_nodes (1);
5ff904cd 11225
81b3411c 11226 /* Define `int' and `char' first so that dbx will output them first. */
c7e4ee3a
CB
11227 pushdecl (build_decl (TYPE_DECL, get_identifier ("int"),
11228 integer_type_node));
a49bedaa
TM
11229 /* CHARACTER*1 is unsigned in ICHAR contexts. */
11230 char_type_node = make_unsigned_type (CHAR_TYPE_SIZE);
c7e4ee3a
CB
11231 pushdecl (build_decl (TYPE_DECL, get_identifier ("char"),
11232 char_type_node));
c7e4ee3a
CB
11233 pushdecl (build_decl (TYPE_DECL, get_identifier ("long int"),
11234 long_integer_type_node));
c7e4ee3a
CB
11235 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned int"),
11236 unsigned_type_node));
c7e4ee3a
CB
11237 pushdecl (build_decl (TYPE_DECL, get_identifier ("long unsigned int"),
11238 long_unsigned_type_node));
c7e4ee3a
CB
11239 pushdecl (build_decl (TYPE_DECL, get_identifier ("long long int"),
11240 long_long_integer_type_node));
c7e4ee3a
CB
11241 pushdecl (build_decl (TYPE_DECL, get_identifier ("long long unsigned int"),
11242 long_long_unsigned_type_node));
c7e4ee3a
CB
11243 pushdecl (build_decl (TYPE_DECL, get_identifier ("short int"),
11244 short_integer_type_node));
c7e4ee3a
CB
11245 pushdecl (build_decl (TYPE_DECL, get_identifier ("short unsigned int"),
11246 short_unsigned_type_node));
5ff904cd 11247
ff852b44
CB
11248 /* Set the sizetype before we make other types. This *should* be the
11249 first type we create. */
11250
11251 set_sizetype
11252 (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE))));
11253 ffecom_typesize_pointer_
11254 = TREE_INT_CST_LOW (TYPE_SIZE (sizetype)) / BITS_PER_UNIT;
11255
81b3411c 11256 build_common_tree_nodes_2 (0);
ff852b44 11257
c7e4ee3a 11258 /* Define both `signed char' and `unsigned char'. */
c7e4ee3a
CB
11259 pushdecl (build_decl (TYPE_DECL, get_identifier ("signed char"),
11260 signed_char_type_node));
5ff904cd 11261
c7e4ee3a
CB
11262 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned char"),
11263 unsigned_char_type_node));
5ff904cd 11264
c7e4ee3a
CB
11265 pushdecl (build_decl (TYPE_DECL, get_identifier ("float"),
11266 float_type_node));
c7e4ee3a
CB
11267 pushdecl (build_decl (TYPE_DECL, get_identifier ("double"),
11268 double_type_node));
c7e4ee3a
CB
11269 pushdecl (build_decl (TYPE_DECL, get_identifier ("long double"),
11270 long_double_type_node));
5ff904cd 11271
81b3411c 11272 /* For now, override what build_common_tree_nodes has done. */
c7e4ee3a 11273 complex_integer_type_node = ffecom_make_complex_type_ (integer_type_node);
81b3411c
BS
11274 complex_float_type_node = ffecom_make_complex_type_ (float_type_node);
11275 complex_double_type_node = ffecom_make_complex_type_ (double_type_node);
11276 complex_long_double_type_node
11277 = ffecom_make_complex_type_ (long_double_type_node);
11278
c7e4ee3a
CB
11279 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex int"),
11280 complex_integer_type_node));
c7e4ee3a
CB
11281 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex float"),
11282 complex_float_type_node));
c7e4ee3a
CB
11283 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex double"),
11284 complex_double_type_node));
c7e4ee3a
CB
11285 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex long double"),
11286 complex_long_double_type_node));
5ff904cd 11287
c7e4ee3a
CB
11288 pushdecl (build_decl (TYPE_DECL, get_identifier ("void"),
11289 void_type_node));
c7e4ee3a
CB
11290 /* We are not going to have real types in C with less than byte alignment,
11291 so we might as well not have any types that claim to have it. */
11292 TYPE_ALIGN (void_type_node) = BITS_PER_UNIT;
11cf4d18 11293 TYPE_USER_ALIGN (void_type_node) = 0;
5ff904cd 11294
c7e4ee3a 11295 string_type_node = build_pointer_type (char_type_node);
5ff904cd 11296
c7e4ee3a
CB
11297 ffecom_tree_fun_type_void
11298 = build_function_type (void_type_node, NULL_TREE);
5ff904cd 11299
c7e4ee3a
CB
11300 ffecom_tree_ptr_to_fun_type_void
11301 = build_pointer_type (ffecom_tree_fun_type_void);
5ff904cd 11302
c7e4ee3a 11303 endlink = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
5ff904cd 11304
c7e4ee3a
CB
11305 float_ftype_float
11306 = build_function_type (float_type_node,
11307 tree_cons (NULL_TREE, float_type_node, endlink));
5ff904cd 11308
c7e4ee3a
CB
11309 double_ftype_double
11310 = build_function_type (double_type_node,
11311 tree_cons (NULL_TREE, double_type_node, endlink));
5ff904cd 11312
c7e4ee3a
CB
11313 ldouble_ftype_ldouble
11314 = build_function_type (long_double_type_node,
11315 tree_cons (NULL_TREE, long_double_type_node,
11316 endlink));
5ff904cd 11317
c7e4ee3a
CB
11318 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11319 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11320 {
11321 ffecom_tree_type[i][j] = NULL_TREE;
11322 ffecom_tree_fun_type[i][j] = NULL_TREE;
11323 ffecom_tree_ptr_to_fun_type[i][j] = NULL_TREE;
11324 ffecom_f2c_typecode_[i][j] = -1;
11325 }
5ff904cd 11326
c7e4ee3a
CB
11327 /* Set up standard g77 types. Note that INTEGER and LOGICAL are set
11328 to size FLOAT_TYPE_SIZE because they have to be the same size as
11329 REAL, which also is FLOAT_TYPE_SIZE, according to the standard.
11330 Compiler options and other such stuff that change the ways these
11331 types are set should not affect this particular setup. */
5ff904cd 11332
c7e4ee3a
CB
11333 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER1]
11334 = t = make_signed_type (FLOAT_TYPE_SIZE);
11335 pushdecl (build_decl (TYPE_DECL, get_identifier ("integer"),
11336 t));
11337 type = ffetype_new ();
11338 base_type = type;
11339 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER1,
11340 type);
11341 ffetype_set_ams (type,
11342 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11343 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11344 ffetype_set_star (base_type,
11345 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11346 type);
11347 ffetype_set_kind (base_type, 1, type);
ff852b44 11348 ffecom_typesize_integer1_ = ffetype_size (type);
c7e4ee3a 11349 assert (ffetype_size (type) == sizeof (ffetargetInteger1));
5ff904cd 11350
c7e4ee3a
CB
11351 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER1]
11352 = t = make_unsigned_type (FLOAT_TYPE_SIZE); /* HOLLERITH means unsigned. */
11353 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned"),
11354 t));
5ff904cd 11355
c7e4ee3a
CB
11356 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER2]
11357 = t = make_signed_type (CHAR_TYPE_SIZE);
11358 pushdecl (build_decl (TYPE_DECL, get_identifier ("byte"),
11359 t));
11360 type = ffetype_new ();
11361 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER2,
11362 type);
11363 ffetype_set_ams (type,
11364 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11365 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11366 ffetype_set_star (base_type,
11367 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11368 type);
11369 ffetype_set_kind (base_type, 3, type);
11370 assert (ffetype_size (type) == sizeof (ffetargetInteger2));
5ff904cd 11371
c7e4ee3a
CB
11372 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER2]
11373 = t = make_unsigned_type (CHAR_TYPE_SIZE);
11374 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned byte"),
11375 t));
11376
11377 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER3]
11378 = t = make_signed_type (CHAR_TYPE_SIZE * 2);
11379 pushdecl (build_decl (TYPE_DECL, get_identifier ("word"),
11380 t));
11381 type = ffetype_new ();
11382 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER3,
11383 type);
11384 ffetype_set_ams (type,
11385 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11386 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11387 ffetype_set_star (base_type,
11388 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11389 type);
11390 ffetype_set_kind (base_type, 6, type);
11391 assert (ffetype_size (type) == sizeof (ffetargetInteger3));
5ff904cd 11392
c7e4ee3a
CB
11393 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER3]
11394 = t = make_unsigned_type (CHAR_TYPE_SIZE * 2);
11395 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned word"),
11396 t));
5ff904cd 11397
c7e4ee3a
CB
11398 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER4]
11399 = t = make_signed_type (FLOAT_TYPE_SIZE * 2);
11400 pushdecl (build_decl (TYPE_DECL, get_identifier ("integer4"),
11401 t));
11402 type = ffetype_new ();
11403 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER4,
11404 type);
11405 ffetype_set_ams (type,
11406 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11407 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11408 ffetype_set_star (base_type,
11409 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11410 type);
11411 ffetype_set_kind (base_type, 2, type);
11412 assert (ffetype_size (type) == sizeof (ffetargetInteger4));
5ff904cd 11413
c7e4ee3a
CB
11414 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER4]
11415 = t = make_unsigned_type (FLOAT_TYPE_SIZE * 2);
11416 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned4"),
11417 t));
5ff904cd 11418
c7e4ee3a
CB
11419#if 0
11420 if (ffe_is_do_internal_checks ()
11421 && LONG_TYPE_SIZE != FLOAT_TYPE_SIZE
11422 && LONG_TYPE_SIZE != CHAR_TYPE_SIZE
11423 && LONG_TYPE_SIZE != SHORT_TYPE_SIZE
11424 && LONG_TYPE_SIZE != LONG_LONG_TYPE_SIZE)
5ff904cd 11425 {
c7e4ee3a
CB
11426 fprintf (stderr, "Sorry, no g77 support for LONG_TYPE_SIZE (%d bits) yet.\n",
11427 LONG_TYPE_SIZE);
5ff904cd 11428 }
c7e4ee3a 11429#endif
5ff904cd 11430
c7e4ee3a
CB
11431 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL1]
11432 = t = make_signed_type (FLOAT_TYPE_SIZE);
11433 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical"),
11434 t));
11435 type = ffetype_new ();
11436 base_type = type;
11437 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL1,
11438 type);
11439 ffetype_set_ams (type,
11440 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11441 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11442 ffetype_set_star (base_type,
11443 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11444 type);
11445 ffetype_set_kind (base_type, 1, type);
11446 assert (ffetype_size (type) == sizeof (ffetargetLogical1));
5ff904cd 11447
c7e4ee3a
CB
11448 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL2]
11449 = t = make_signed_type (CHAR_TYPE_SIZE);
11450 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical2"),
11451 t));
11452 type = ffetype_new ();
11453 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL2,
11454 type);
11455 ffetype_set_ams (type,
11456 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11457 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11458 ffetype_set_star (base_type,
11459 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11460 type);
11461 ffetype_set_kind (base_type, 3, type);
11462 assert (ffetype_size (type) == sizeof (ffetargetLogical2));
5ff904cd 11463
c7e4ee3a
CB
11464 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL3]
11465 = t = make_signed_type (CHAR_TYPE_SIZE * 2);
11466 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical3"),
11467 t));
11468 type = ffetype_new ();
11469 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL3,
11470 type);
11471 ffetype_set_ams (type,
11472 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11473 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11474 ffetype_set_star (base_type,
11475 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11476 type);
11477 ffetype_set_kind (base_type, 6, type);
11478 assert (ffetype_size (type) == sizeof (ffetargetLogical3));
5ff904cd 11479
c7e4ee3a
CB
11480 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL4]
11481 = t = make_signed_type (FLOAT_TYPE_SIZE * 2);
11482 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical4"),
11483 t));
11484 type = ffetype_new ();
11485 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL4,
11486 type);
11487 ffetype_set_ams (type,
11488 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11489 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11490 ffetype_set_star (base_type,
11491 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11492 type);
11493 ffetype_set_kind (base_type, 2, type);
11494 assert (ffetype_size (type) == sizeof (ffetargetLogical4));
5ff904cd 11495
c7e4ee3a
CB
11496 ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]
11497 = t = make_node (REAL_TYPE);
11498 TYPE_PRECISION (t) = FLOAT_TYPE_SIZE;
11499 pushdecl (build_decl (TYPE_DECL, get_identifier ("real"),
11500 t));
11501 layout_type (t);
11502 type = ffetype_new ();
11503 base_type = type;
11504 ffeinfo_set_type (FFEINFO_basictypeREAL, FFEINFO_kindtypeREAL1,
11505 type);
11506 ffetype_set_ams (type,
11507 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11508 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11509 ffetype_set_star (base_type,
11510 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11511 type);
11512 ffetype_set_kind (base_type, 1, type);
11513 ffecom_f2c_typecode_[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]
11514 = FFETARGET_f2cTYREAL;
11515 assert (ffetype_size (type) == sizeof (ffetargetReal1));
5ff904cd 11516
c7e4ee3a
CB
11517 ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREALDOUBLE]
11518 = t = make_node (REAL_TYPE);
11519 TYPE_PRECISION (t) = FLOAT_TYPE_SIZE * 2; /* Always twice REAL. */
11520 pushdecl (build_decl (TYPE_DECL, get_identifier ("double precision"),
11521 t));
11522 layout_type (t);
11523 type = ffetype_new ();
11524 ffeinfo_set_type (FFEINFO_basictypeREAL, FFEINFO_kindtypeREALDOUBLE,
11525 type);
11526 ffetype_set_ams (type,
11527 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11528 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11529 ffetype_set_star (base_type,
11530 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11531 type);
11532 ffetype_set_kind (base_type, 2, type);
11533 ffecom_f2c_typecode_[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2]
11534 = FFETARGET_f2cTYDREAL;
11535 assert (ffetype_size (type) == sizeof (ffetargetReal2));
5ff904cd 11536
c7e4ee3a
CB
11537 ffecom_tree_type[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL1]
11538 = t = ffecom_make_complex_type_ (ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]);
11539 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex"),
11540 t));
11541 type = ffetype_new ();
11542 base_type = type;
11543 ffeinfo_set_type (FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREAL1,
11544 type);
11545 ffetype_set_ams (type,
11546 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11547 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11548 ffetype_set_star (base_type,
11549 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11550 type);
11551 ffetype_set_kind (base_type, 1, type);
11552 ffecom_f2c_typecode_[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL1]
11553 = FFETARGET_f2cTYCOMPLEX;
11554 assert (ffetype_size (type) == sizeof (ffetargetComplex1));
5ff904cd 11555
c7e4ee3a
CB
11556 ffecom_tree_type[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREALDOUBLE]
11557 = t = ffecom_make_complex_type_ (ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2]);
11558 pushdecl (build_decl (TYPE_DECL, get_identifier ("double complex"),
11559 t));
11560 type = ffetype_new ();
11561 ffeinfo_set_type (FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREALDOUBLE,
11562 type);
11563 ffetype_set_ams (type,
11564 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11565 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11566 ffetype_set_star (base_type,
11567 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11568 type);
11569 ffetype_set_kind (base_type, 2,
11570 type);
11571 ffecom_f2c_typecode_[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL2]
11572 = FFETARGET_f2cTYDCOMPLEX;
11573 assert (ffetype_size (type) == sizeof (ffetargetComplex2));
5ff904cd 11574
c7e4ee3a 11575 /* Make function and ptr-to-function types for non-CHARACTER types. */
5ff904cd 11576
c7e4ee3a
CB
11577 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11578 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11579 {
11580 if ((t = ffecom_tree_type[i][j]) != NULL_TREE)
11581 {
11582 if (i == FFEINFO_basictypeINTEGER)
11583 {
11584 /* Figure out the smallest INTEGER type that can hold
11585 a pointer on this machine. */
11586 if (GET_MODE_SIZE (TYPE_MODE (t))
11587 >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
11588 {
11589 if ((ffecom_pointer_kind_ == FFEINFO_kindtypeNONE)
11590 || (GET_MODE_SIZE (TYPE_MODE (ffecom_tree_type[i][ffecom_pointer_kind_]))
11591 > GET_MODE_SIZE (TYPE_MODE (t))))
11592 ffecom_pointer_kind_ = j;
11593 }
11594 }
11595 else if (i == FFEINFO_basictypeCOMPLEX)
11596 t = void_type_node;
11597 /* For f2c compatibility, REAL functions are really
11598 implemented as DOUBLE PRECISION. */
11599 else if ((i == FFEINFO_basictypeREAL)
11600 && (j == FFEINFO_kindtypeREAL1))
11601 t = ffecom_tree_type
11602 [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2];
5ff904cd 11603
c7e4ee3a
CB
11604 t = ffecom_tree_fun_type[i][j] = build_function_type (t,
11605 NULL_TREE);
11606 ffecom_tree_ptr_to_fun_type[i][j] = build_pointer_type (t);
11607 }
11608 }
5ff904cd 11609
c7e4ee3a 11610 /* Set up pointer types. */
5ff904cd 11611
c7e4ee3a 11612 if (ffecom_pointer_kind_ == FFEINFO_basictypeNONE)
400500c4 11613 fatal_error ("no INTEGER type can hold a pointer on this configuration");
c7e4ee3a
CB
11614 else if (0 && ffe_is_do_internal_checks ())
11615 fprintf (stderr, "Pointer type kt=%d\n", ffecom_pointer_kind_);
11616 ffetype_set_kind (ffeinfo_type (FFEINFO_basictypeINTEGER,
11617 FFEINFO_kindtypeINTEGERDEFAULT),
11618 7,
11619 ffeinfo_type (FFEINFO_basictypeINTEGER,
11620 ffecom_pointer_kind_));
5ff904cd 11621
c7e4ee3a
CB
11622 if (ffe_is_ugly_assign ())
11623 ffecom_label_kind_ = ffecom_pointer_kind_; /* Require ASSIGN etc to this. */
11624 else
11625 ffecom_label_kind_ = FFEINFO_kindtypeINTEGERDEFAULT;
11626 if (0 && ffe_is_do_internal_checks ())
11627 fprintf (stderr, "Label type kt=%d\n", ffecom_label_kind_);
5ff904cd 11628
c7e4ee3a
CB
11629 ffecom_integer_type_node
11630 = ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER1];
11631 ffecom_integer_zero_node = convert (ffecom_integer_type_node,
11632 integer_zero_node);
11633 ffecom_integer_one_node = convert (ffecom_integer_type_node,
11634 integer_one_node);
5ff904cd 11635
c7e4ee3a
CB
11636 /* Yes, the "FLOAT_TYPE_SIZE" references below are intentional.
11637 Turns out that by TYLONG, runtime/libI77/lio.h really means
11638 "whatever size an ftnint is". For consistency and sanity,
11639 com.h and runtime/f2c.h.in agree that flag, ftnint, and ftlen
11640 all are INTEGER, which we also make out of whatever back-end
11641 integer type is FLOAT_TYPE_SIZE bits wide. This change, from
11642 LONG_TYPE_SIZE, for TYLONG and TYLOGICAL, was necessary to
11643 accommodate machines like the Alpha. Note that this suggests
11644 f2c and libf2c are missing a distinction perhaps needed on
11645 some machines between "int" and "long int". -- burley 0.5.5 950215 */
5ff904cd 11646
c7e4ee3a
CB
11647 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, FLOAT_TYPE_SIZE,
11648 FFETARGET_f2cTYLONG);
11649 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, SHORT_TYPE_SIZE,
11650 FFETARGET_f2cTYSHORT);
11651 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, CHAR_TYPE_SIZE,
11652 FFETARGET_f2cTYINT1);
11653 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, LONG_LONG_TYPE_SIZE,
11654 FFETARGET_f2cTYQUAD);
11655 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, FLOAT_TYPE_SIZE,
11656 FFETARGET_f2cTYLOGICAL);
11657 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, SHORT_TYPE_SIZE,
11658 FFETARGET_f2cTYLOGICAL2);
11659 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, CHAR_TYPE_SIZE,
11660 FFETARGET_f2cTYLOGICAL1);
11661 /* ~~~Not really such a type in libf2c, e.g. I/O support? */
11662 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, LONG_LONG_TYPE_SIZE,
11663 FFETARGET_f2cTYQUAD);
5ff904cd 11664
c7e4ee3a
CB
11665 /* CHARACTER stuff is all special-cased, so it is not handled in the above
11666 loop. CHARACTER items are built as arrays of unsigned char. */
5ff904cd 11667
c7e4ee3a
CB
11668 ffecom_tree_type[FFEINFO_basictypeCHARACTER]
11669 [FFEINFO_kindtypeCHARACTER1] = t = char_type_node;
11670 type = ffetype_new ();
11671 base_type = type;
11672 ffeinfo_set_type (FFEINFO_basictypeCHARACTER,
11673 FFEINFO_kindtypeCHARACTER1,
11674 type);
11675 ffetype_set_ams (type,
11676 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11677 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11678 ffetype_set_kind (base_type, 1, type);
11679 assert (ffetype_size (type)
11680 == sizeof (((ffetargetCharacter1) { 0, NULL }).text[0]));
5ff904cd 11681
c7e4ee3a
CB
11682 ffecom_tree_fun_type[FFEINFO_basictypeCHARACTER]
11683 [FFEINFO_kindtypeCHARACTER1] = ffecom_tree_fun_type_void;
11684 ffecom_tree_ptr_to_fun_type[FFEINFO_basictypeCHARACTER]
11685 [FFEINFO_kindtypeCHARACTER1]
11686 = ffecom_tree_ptr_to_fun_type_void;
11687 ffecom_f2c_typecode_[FFEINFO_basictypeCHARACTER][FFEINFO_kindtypeCHARACTER1]
11688 = FFETARGET_f2cTYCHAR;
5ff904cd 11689
c7e4ee3a
CB
11690 ffecom_f2c_typecode_[FFEINFO_basictypeANY][FFEINFO_kindtypeANY]
11691 = 0;
5ff904cd 11692
c7e4ee3a 11693 /* Make multi-return-value type and fields. */
5ff904cd 11694
c7e4ee3a 11695 ffecom_multi_type_node_ = make_node (UNION_TYPE);
5ff904cd 11696
c7e4ee3a 11697 field = NULL_TREE;
5ff904cd 11698
c7e4ee3a
CB
11699 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11700 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11701 {
11702 char name[30];
5ff904cd 11703
c7e4ee3a
CB
11704 if (ffecom_tree_type[i][j] == NULL_TREE)
11705 continue; /* Not supported. */
11706 sprintf (&name[0], "bt_%s_kt_%s",
11707 ffeinfo_basictype_string ((ffeinfoBasictype) i),
11708 ffeinfo_kindtype_string ((ffeinfoKindtype) j));
11709 ffecom_multi_fields_[i][j] = build_decl (FIELD_DECL,
11710 get_identifier (name),
11711 ffecom_tree_type[i][j]);
11712 DECL_CONTEXT (ffecom_multi_fields_[i][j])
11713 = ffecom_multi_type_node_;
8ba77681 11714 DECL_ALIGN (ffecom_multi_fields_[i][j]) = 0;
11cf4d18 11715 DECL_USER_ALIGN (ffecom_multi_fields_[i][j]) = 0;
c7e4ee3a
CB
11716 TREE_CHAIN (ffecom_multi_fields_[i][j]) = field;
11717 field = ffecom_multi_fields_[i][j];
11718 }
5ff904cd 11719
c7e4ee3a
CB
11720 TYPE_FIELDS (ffecom_multi_type_node_) = field;
11721 layout_type (ffecom_multi_type_node_);
5ff904cd 11722
c7e4ee3a
CB
11723 /* Subroutines usually return integer because they might have alternate
11724 returns. */
5ff904cd 11725
c7e4ee3a
CB
11726 ffecom_tree_subr_type
11727 = build_function_type (integer_type_node, NULL_TREE);
11728 ffecom_tree_ptr_to_subr_type
11729 = build_pointer_type (ffecom_tree_subr_type);
11730 ffecom_tree_blockdata_type
11731 = build_function_type (void_type_node, NULL_TREE);
5ff904cd 11732
c7e4ee3a 11733 builtin_function ("__builtin_sqrtf", float_ftype_float,
dc6f4158
AJ
11734 BUILT_IN_SQRTF, BUILT_IN_NORMAL, "sqrtf");
11735 builtin_function ("__builtin_sqrt", double_ftype_double,
11736 BUILT_IN_SQRT, BUILT_IN_NORMAL, "sqrt");
c7e4ee3a 11737 builtin_function ("__builtin_sqrtl", ldouble_ftype_ldouble,
dc6f4158 11738 BUILT_IN_SQRTL, BUILT_IN_NORMAL, "sqrtl");
c7e4ee3a 11739 builtin_function ("__builtin_sinf", float_ftype_float,
dc6f4158 11740 BUILT_IN_SINF, BUILT_IN_NORMAL, "sinf");
c7e4ee3a 11741 builtin_function ("__builtin_sin", double_ftype_double,
26db82d8 11742 BUILT_IN_SIN, BUILT_IN_NORMAL, "sin");
c7e4ee3a 11743 builtin_function ("__builtin_sinl", ldouble_ftype_ldouble,
dc6f4158 11744 BUILT_IN_SINL, BUILT_IN_NORMAL, "sinl");
c7e4ee3a 11745 builtin_function ("__builtin_cosf", float_ftype_float,
dc6f4158 11746 BUILT_IN_COSF, BUILT_IN_NORMAL, "cosf");
c7e4ee3a 11747 builtin_function ("__builtin_cos", double_ftype_double,
26db82d8 11748 BUILT_IN_COS, BUILT_IN_NORMAL, "cos");
c7e4ee3a 11749 builtin_function ("__builtin_cosl", ldouble_ftype_ldouble,
dc6f4158 11750 BUILT_IN_COSL, BUILT_IN_NORMAL, "cosl");
5ff904cd 11751
c7e4ee3a 11752 pedantic_lvalues = FALSE;
5ff904cd 11753
c7e4ee3a
CB
11754 ffecom_f2c_make_type_ (&ffecom_f2c_integer_type_node,
11755 FFECOM_f2cINTEGER,
11756 "integer");
11757 ffecom_f2c_make_type_ (&ffecom_f2c_address_type_node,
11758 FFECOM_f2cADDRESS,
11759 "address");
11760 ffecom_f2c_make_type_ (&ffecom_f2c_real_type_node,
11761 FFECOM_f2cREAL,
11762 "real");
11763 ffecom_f2c_make_type_ (&ffecom_f2c_doublereal_type_node,
11764 FFECOM_f2cDOUBLEREAL,
11765 "doublereal");
11766 ffecom_f2c_make_type_ (&ffecom_f2c_complex_type_node,
11767 FFECOM_f2cCOMPLEX,
11768 "complex");
11769 ffecom_f2c_make_type_ (&ffecom_f2c_doublecomplex_type_node,
11770 FFECOM_f2cDOUBLECOMPLEX,
11771 "doublecomplex");
11772 ffecom_f2c_make_type_ (&ffecom_f2c_longint_type_node,
11773 FFECOM_f2cLONGINT,
11774 "longint");
11775 ffecom_f2c_make_type_ (&ffecom_f2c_logical_type_node,
11776 FFECOM_f2cLOGICAL,
11777 "logical");
11778 ffecom_f2c_make_type_ (&ffecom_f2c_flag_type_node,
11779 FFECOM_f2cFLAG,
11780 "flag");
11781 ffecom_f2c_make_type_ (&ffecom_f2c_ftnlen_type_node,
11782 FFECOM_f2cFTNLEN,
11783 "ftnlen");
11784 ffecom_f2c_make_type_ (&ffecom_f2c_ftnint_type_node,
11785 FFECOM_f2cFTNINT,
11786 "ftnint");
5ff904cd 11787
c7e4ee3a
CB
11788 ffecom_f2c_ftnlen_zero_node
11789 = convert (ffecom_f2c_ftnlen_type_node, integer_zero_node);
5ff904cd 11790
c7e4ee3a
CB
11791 ffecom_f2c_ftnlen_one_node
11792 = convert (ffecom_f2c_ftnlen_type_node, integer_one_node);
5ff904cd 11793
c7e4ee3a
CB
11794 ffecom_f2c_ftnlen_two_node = build_int_2 (2, 0);
11795 TREE_TYPE (ffecom_f2c_ftnlen_two_node) = ffecom_integer_type_node;
5ff904cd 11796
c7e4ee3a
CB
11797 ffecom_f2c_ptr_to_ftnlen_type_node
11798 = build_pointer_type (ffecom_f2c_ftnlen_type_node);
5ff904cd 11799
c7e4ee3a
CB
11800 ffecom_f2c_ptr_to_ftnint_type_node
11801 = build_pointer_type (ffecom_f2c_ftnint_type_node);
5ff904cd 11802
c7e4ee3a
CB
11803 ffecom_f2c_ptr_to_integer_type_node
11804 = build_pointer_type (ffecom_f2c_integer_type_node);
5ff904cd 11805
c7e4ee3a
CB
11806 ffecom_f2c_ptr_to_real_type_node
11807 = build_pointer_type (ffecom_f2c_real_type_node);
5ff904cd 11808
c7e4ee3a
CB
11809 ffecom_float_zero_ = build_real (float_type_node, dconst0);
11810 ffecom_double_zero_ = build_real (double_type_node, dconst0);
11811 {
11812 REAL_VALUE_TYPE point_5;
5ff904cd 11813
c7e4ee3a 11814 REAL_ARITHMETIC (point_5, RDIV_EXPR, dconst1, dconst2);
c7e4ee3a
CB
11815 ffecom_float_half_ = build_real (float_type_node, point_5);
11816 ffecom_double_half_ = build_real (double_type_node, point_5);
11817 }
5ff904cd 11818
c7e4ee3a 11819 /* Do "extern int xargc;". */
5ff904cd 11820
c7e4ee3a
CB
11821 ffecom_tree_xargc_ = build_decl (VAR_DECL,
11822 get_identifier ("f__xargc"),
11823 integer_type_node);
11824 DECL_EXTERNAL (ffecom_tree_xargc_) = 1;
11825 TREE_STATIC (ffecom_tree_xargc_) = 1;
11826 TREE_PUBLIC (ffecom_tree_xargc_) = 1;
11827 ffecom_tree_xargc_ = start_decl (ffecom_tree_xargc_, FALSE);
11828 finish_decl (ffecom_tree_xargc_, NULL_TREE, FALSE);
5ff904cd 11829
c7e4ee3a
CB
11830#if 0 /* This is being fixed, and seems to be working now. */
11831 if ((FLOAT_TYPE_SIZE != 32)
11832 || (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node))) != 32))
5ff904cd 11833 {
c7e4ee3a
CB
11834 warning ("configuration: REAL, INTEGER, and LOGICAL are %d bits wide,",
11835 (int) FLOAT_TYPE_SIZE);
11836 warning ("and pointers are %d bits wide, but g77 doesn't yet work",
11837 (int) TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node))));
c725bd79 11838 warning ("properly unless they all are 32 bits wide");
0aa00c7f 11839 warning ("Please keep this in mind before you report bugs.");
c7e4ee3a
CB
11840 }
11841#endif
5ff904cd 11842
c7e4ee3a
CB
11843#if 0 /* Code in ste.c that would crash has been commented out. */
11844 if (TYPE_PRECISION (ffecom_f2c_ftnlen_type_node)
11845 < TYPE_PRECISION (string_type_node))
11846 /* I/O will probably crash. */
11847 warning ("configuration: char * holds %d bits, but ftnlen only %d",
11848 TYPE_PRECISION (string_type_node),
11849 TYPE_PRECISION (ffecom_f2c_ftnlen_type_node));
11850#endif
5ff904cd 11851
c7e4ee3a
CB
11852#if 0 /* ASSIGN-related stuff has been changed to accommodate this. */
11853 if (TYPE_PRECISION (ffecom_integer_type_node)
11854 < TYPE_PRECISION (string_type_node))
11855 /* ASSIGN 10 TO I will crash. */
11856 warning ("configuration: char * holds %d bits, but INTEGER only %d --\n\
11857 ASSIGN statement might fail",
11858 TYPE_PRECISION (string_type_node),
11859 TYPE_PRECISION (ffecom_integer_type_node));
11860#endif
11861}
5ff904cd 11862
c7e4ee3a 11863/* ffecom_init_2 -- Initialize
5ff904cd 11864
c7e4ee3a 11865 ffecom_init_2(); */
5ff904cd 11866
c7e4ee3a
CB
11867void
11868ffecom_init_2 ()
11869{
11870 assert (ffecom_outer_function_decl_ == NULL_TREE);
11871 assert (current_function_decl == NULL_TREE);
11872 assert (ffecom_which_entrypoint_decl_ == NULL_TREE);
5ff904cd 11873
c7e4ee3a
CB
11874 ffecom_master_arglist_ = NULL;
11875 ++ffecom_num_fns_;
11876 ffecom_primary_entry_ = NULL;
11877 ffecom_is_altreturning_ = FALSE;
11878 ffecom_func_result_ = NULL_TREE;
11879 ffecom_multi_retval_ = NULL_TREE;
11880}
5ff904cd 11881
c7e4ee3a 11882/* ffecom_list_expr -- Transform list of exprs into gcc tree
5ff904cd 11883
c7e4ee3a
CB
11884 tree t;
11885 ffebld expr; // FFE opITEM list.
11886 tree = ffecom_list_expr(expr);
5ff904cd 11887
c7e4ee3a 11888 List of actual args is transformed into corresponding gcc backend list. */
5ff904cd 11889
c7e4ee3a
CB
11890tree
11891ffecom_list_expr (ffebld expr)
5ff904cd 11892{
c7e4ee3a
CB
11893 tree list;
11894 tree *plist = &list;
11895 tree trail = NULL_TREE; /* Append char length args here. */
11896 tree *ptrail = &trail;
11897 tree length;
5ff904cd 11898
c7e4ee3a 11899 while (expr != NULL)
5ff904cd 11900 {
c7e4ee3a 11901 tree texpr = ffecom_arg_expr (ffebld_head (expr), &length);
5ff904cd 11902
c7e4ee3a
CB
11903 if (texpr == error_mark_node)
11904 return error_mark_node;
5ff904cd 11905
c7e4ee3a
CB
11906 *plist = build_tree_list (NULL_TREE, texpr);
11907 plist = &TREE_CHAIN (*plist);
11908 expr = ffebld_trail (expr);
11909 if (length != NULL_TREE)
5ff904cd 11910 {
c7e4ee3a
CB
11911 *ptrail = build_tree_list (NULL_TREE, length);
11912 ptrail = &TREE_CHAIN (*ptrail);
5ff904cd
JL
11913 }
11914 }
11915
c7e4ee3a 11916 *plist = trail;
5ff904cd 11917
c7e4ee3a
CB
11918 return list;
11919}
5ff904cd 11920
c7e4ee3a 11921/* ffecom_list_ptr_to_expr -- Transform list of exprs into gcc tree
5ff904cd 11922
c7e4ee3a
CB
11923 tree t;
11924 ffebld expr; // FFE opITEM list.
11925 tree = ffecom_list_ptr_to_expr(expr);
5ff904cd 11926
c7e4ee3a
CB
11927 List of actual args is transformed into corresponding gcc backend list for
11928 use in calling an external procedure (vs. a statement function). */
5ff904cd 11929
c7e4ee3a
CB
11930tree
11931ffecom_list_ptr_to_expr (ffebld expr)
11932{
11933 tree list;
11934 tree *plist = &list;
11935 tree trail = NULL_TREE; /* Append char length args here. */
11936 tree *ptrail = &trail;
11937 tree length;
5ff904cd 11938
c7e4ee3a
CB
11939 while (expr != NULL)
11940 {
11941 tree texpr = ffecom_arg_ptr_to_expr (ffebld_head (expr), &length);
5ff904cd 11942
c7e4ee3a
CB
11943 if (texpr == error_mark_node)
11944 return error_mark_node;
5ff904cd 11945
c7e4ee3a
CB
11946 *plist = build_tree_list (NULL_TREE, texpr);
11947 plist = &TREE_CHAIN (*plist);
11948 expr = ffebld_trail (expr);
11949 if (length != NULL_TREE)
11950 {
11951 *ptrail = build_tree_list (NULL_TREE, length);
11952 ptrail = &TREE_CHAIN (*ptrail);
11953 }
11954 }
5ff904cd 11955
c7e4ee3a 11956 *plist = trail;
5ff904cd 11957
c7e4ee3a
CB
11958 return list;
11959}
5ff904cd 11960
c7e4ee3a 11961/* Obtain gcc's LABEL_DECL tree for label. */
5ff904cd 11962
c7e4ee3a
CB
11963tree
11964ffecom_lookup_label (ffelab label)
11965{
11966 tree glabel;
5ff904cd 11967
c7e4ee3a
CB
11968 if (ffelab_hook (label) == NULL_TREE)
11969 {
11970 char labelname[16];
5ff904cd 11971
c7e4ee3a
CB
11972 switch (ffelab_type (label))
11973 {
11974 case FFELAB_typeLOOPEND:
11975 case FFELAB_typeNOTLOOP:
11976 case FFELAB_typeENDIF:
11977 sprintf (labelname, "%" ffelabValue_f "u", ffelab_value (label));
11978 glabel = build_decl (LABEL_DECL, get_identifier (labelname),
11979 void_type_node);
11980 DECL_CONTEXT (glabel) = current_function_decl;
11981 DECL_MODE (glabel) = VOIDmode;
11982 break;
5ff904cd 11983
c7e4ee3a 11984 case FFELAB_typeFORMAT:
c7e4ee3a
CB
11985 glabel = build_decl (VAR_DECL,
11986 ffecom_get_invented_identifier
14657de8 11987 ("__g77_format_%d", (int) ffelab_value (label)),
c7e4ee3a
CB
11988 build_type_variant (build_array_type
11989 (char_type_node,
11990 NULL_TREE),
11991 1, 0));
11992 TREE_CONSTANT (glabel) = 1;
11993 TREE_STATIC (glabel) = 1;
611081b2 11994 DECL_CONTEXT (glabel) = current_function_decl;
c7e4ee3a 11995 DECL_INITIAL (glabel) = NULL;
6c418184 11996 make_decl_rtl (glabel, NULL);
c7e4ee3a 11997 expand_decl (glabel);
5ff904cd 11998
7189a4b0 11999 ffecom_save_tree_forever (glabel);
5ff904cd 12000
c7e4ee3a 12001 break;
5ff904cd 12002
c7e4ee3a
CB
12003 case FFELAB_typeANY:
12004 glabel = error_mark_node;
12005 break;
5ff904cd 12006
c7e4ee3a
CB
12007 default:
12008 assert ("bad label type" == NULL);
12009 glabel = NULL;
12010 break;
12011 }
12012 ffelab_set_hook (label, glabel);
12013 }
12014 else
12015 {
12016 glabel = ffelab_hook (label);
12017 }
5ff904cd 12018
c7e4ee3a
CB
12019 return glabel;
12020}
5ff904cd 12021
c7e4ee3a
CB
12022/* Stabilizes the arguments. Don't use this if the lhs and rhs come from
12023 a single source specification (as in the fourth argument of MVBITS).
12024 If the type is NULL_TREE, the type of lhs is used to make the type of
12025 the MODIFY_EXPR. */
5ff904cd 12026
c7e4ee3a
CB
12027tree
12028ffecom_modify (tree newtype, tree lhs,
12029 tree rhs)
12030{
12031 if (lhs == error_mark_node || rhs == error_mark_node)
12032 return error_mark_node;
5ff904cd 12033
c7e4ee3a
CB
12034 if (newtype == NULL_TREE)
12035 newtype = TREE_TYPE (lhs);
5ff904cd 12036
c7e4ee3a
CB
12037 if (TREE_SIDE_EFFECTS (lhs))
12038 lhs = stabilize_reference (lhs);
5ff904cd 12039
c7e4ee3a
CB
12040 return ffecom_2s (MODIFY_EXPR, newtype, lhs, rhs);
12041}
5ff904cd 12042
c7e4ee3a 12043/* Register source file name. */
5ff904cd 12044
c7e4ee3a 12045void
b0791fa9 12046ffecom_file (const char *name)
c7e4ee3a 12047{
c7e4ee3a 12048 ffecom_file_ (name);
c7e4ee3a 12049}
5ff904cd 12050
c7e4ee3a 12051/* ffecom_notify_init_storage -- An aggregate storage is now fully init'ed
5ff904cd 12052
c7e4ee3a
CB
12053 ffestorag st;
12054 ffecom_notify_init_storage(st);
5ff904cd 12055
c7e4ee3a
CB
12056 Gets called when all possible units in an aggregate storage area (a LOCAL
12057 with equivalences or a COMMON) have been initialized. The initialization
12058 info either is in ffestorag_init or, if that is NULL,
12059 ffestorag_accretion:
5ff904cd 12060
c7e4ee3a
CB
12061 ffestorag_init may contain an opCONTER or opARRTER. opCONTER may occur
12062 even for an array if the array is one element in length!
5ff904cd 12063
c7e4ee3a
CB
12064 ffestorag_accretion will contain an opACCTER. It is much like an
12065 opARRTER except it has an ffebit object in it instead of just a size.
12066 The back end can use the info in the ffebit object, if it wants, to
12067 reduce the amount of actual initialization, but in any case it should
12068 kill the ffebit object when done. Also, set accretion to NULL but
12069 init to a non-NULL value.
5ff904cd 12070
c7e4ee3a
CB
12071 After performing initialization, DO NOT set init to NULL, because that'll
12072 tell the front end it is ok for more initialization to happen. Instead,
12073 set init to an opANY expression or some such thing that you can use to
12074 tell that you've already initialized the object.
5ff904cd 12075
c7e4ee3a
CB
12076 27-Oct-91 JCB 1.1
12077 Support two-pass FFE. */
5ff904cd 12078
c7e4ee3a
CB
12079void
12080ffecom_notify_init_storage (ffestorag st)
12081{
12082 ffebld init; /* The initialization expression. */
c7e4ee3a
CB
12083
12084 if (ffestorag_init (st) == NULL)
5ff904cd 12085 {
c7e4ee3a
CB
12086 init = ffestorag_accretion (st);
12087 assert (init != NULL);
12088 ffestorag_set_accretion (st, NULL);
12089 ffestorag_set_accretes (st, 0);
c7e4ee3a 12090 ffestorag_set_init (st, init);
5ff904cd 12091 }
c7e4ee3a 12092}
5ff904cd 12093
c7e4ee3a 12094/* ffecom_notify_init_symbol -- A symbol is now fully init'ed
5ff904cd 12095
c7e4ee3a
CB
12096 ffesymbol s;
12097 ffecom_notify_init_symbol(s);
5ff904cd 12098
c7e4ee3a
CB
12099 Gets called when all possible units in a symbol (not placed in COMMON
12100 or involved in EQUIVALENCE, unless it as yet has no ffestorag object)
12101 have been initialized. The initialization info either is in
12102 ffesymbol_init or, if that is NULL, ffesymbol_accretion:
5ff904cd 12103
c7e4ee3a
CB
12104 ffesymbol_init may contain an opCONTER or opARRTER. opCONTER may occur
12105 even for an array if the array is one element in length!
5ff904cd 12106
c7e4ee3a
CB
12107 ffesymbol_accretion will contain an opACCTER. It is much like an
12108 opARRTER except it has an ffebit object in it instead of just a size.
12109 The back end can use the info in the ffebit object, if it wants, to
12110 reduce the amount of actual initialization, but in any case it should
12111 kill the ffebit object when done. Also, set accretion to NULL but
12112 init to a non-NULL value.
5ff904cd 12113
c7e4ee3a
CB
12114 After performing initialization, DO NOT set init to NULL, because that'll
12115 tell the front end it is ok for more initialization to happen. Instead,
12116 set init to an opANY expression or some such thing that you can use to
12117 tell that you've already initialized the object.
5ff904cd 12118
c7e4ee3a
CB
12119 27-Oct-91 JCB 1.1
12120 Support two-pass FFE. */
5ff904cd 12121
c7e4ee3a
CB
12122void
12123ffecom_notify_init_symbol (ffesymbol s)
12124{
12125 ffebld init; /* The initialization expression. */
5ff904cd 12126
c7e4ee3a
CB
12127 if (ffesymbol_storage (s) == NULL)
12128 return; /* Do nothing until COMMON/EQUIVALENCE
12129 possibilities checked. */
5ff904cd 12130
c7e4ee3a
CB
12131 if ((ffesymbol_init (s) == NULL)
12132 && ((init = ffesymbol_accretion (s)) != NULL))
12133 {
12134 ffesymbol_set_accretion (s, NULL);
12135 ffesymbol_set_accretes (s, 0);
c7e4ee3a 12136 ffesymbol_set_init (s, init);
c7e4ee3a 12137 }
c7e4ee3a 12138}
5ff904cd 12139
c7e4ee3a 12140/* ffecom_notify_primary_entry -- Learn which is the primary entry point
5ff904cd 12141
c7e4ee3a
CB
12142 ffesymbol s;
12143 ffecom_notify_primary_entry(s);
5ff904cd 12144
c7e4ee3a
CB
12145 Gets called when implicit or explicit PROGRAM statement seen or when
12146 FUNCTION, SUBROUTINE, or BLOCK DATA statement seen, with the primary
12147 global symbol that serves as the entry point. */
5ff904cd 12148
c7e4ee3a
CB
12149void
12150ffecom_notify_primary_entry (ffesymbol s)
12151{
12152 ffecom_primary_entry_ = s;
12153 ffecom_primary_entry_kind_ = ffesymbol_kind (s);
5ff904cd 12154
c7e4ee3a
CB
12155 if ((ffecom_primary_entry_kind_ == FFEINFO_kindFUNCTION)
12156 || (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE))
12157 ffecom_primary_entry_is_proc_ = TRUE;
12158 else
12159 ffecom_primary_entry_is_proc_ = FALSE;
5ff904cd 12160
c7e4ee3a
CB
12161 if (!ffe_is_silent ())
12162 {
12163 if (ffecom_primary_entry_kind_ == FFEINFO_kindPROGRAM)
12164 fprintf (stderr, "%s:\n", ffesymbol_text (s));
12165 else
12166 fprintf (stderr, " %s:\n", ffesymbol_text (s));
12167 }
5ff904cd 12168
c7e4ee3a
CB
12169 if (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE)
12170 {
12171 ffebld list;
12172 ffebld arg;
5ff904cd 12173
c7e4ee3a
CB
12174 for (list = ffesymbol_dummyargs (s);
12175 list != NULL;
12176 list = ffebld_trail (list))
12177 {
12178 arg = ffebld_head (list);
12179 if (ffebld_op (arg) == FFEBLD_opSTAR)
12180 {
12181 ffecom_is_altreturning_ = TRUE;
12182 break;
12183 }
12184 }
12185 }
c7e4ee3a 12186}
5ff904cd 12187
c7e4ee3a
CB
12188FILE *
12189ffecom_open_include (char *name, ffewhereLine l, ffewhereColumn c)
12190{
c7e4ee3a 12191 return ffecom_open_include_ (name, l, c);
c7e4ee3a 12192}
5ff904cd 12193
c7e4ee3a 12194/* ffecom_ptr_to_expr -- Transform expr into gcc tree with & in front
5ff904cd 12195
c7e4ee3a
CB
12196 tree t;
12197 ffebld expr; // FFE expression.
12198 tree = ffecom_ptr_to_expr(expr);
5ff904cd 12199
c7e4ee3a 12200 Like ffecom_expr, but sticks address-of in front of most things. */
5ff904cd 12201
c7e4ee3a
CB
12202tree
12203ffecom_ptr_to_expr (ffebld expr)
12204{
12205 tree item;
12206 ffeinfoBasictype bt;
12207 ffeinfoKindtype kt;
12208 ffesymbol s;
5ff904cd 12209
c7e4ee3a 12210 assert (expr != NULL);
5ff904cd 12211
c7e4ee3a
CB
12212 switch (ffebld_op (expr))
12213 {
12214 case FFEBLD_opSYMTER:
12215 s = ffebld_symter (expr);
12216 if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC)
12217 {
12218 ffecomGfrt ix;
5ff904cd 12219
c7e4ee3a
CB
12220 ix = ffeintrin_gfrt_indirect (ffebld_symter_implementation (expr));
12221 assert (ix != FFECOM_gfrt);
12222 if ((item = ffecom_gfrt_[ix]) == NULL_TREE)
12223 {
12224 ffecom_make_gfrt_ (ix);
12225 item = ffecom_gfrt_[ix];
12226 }
12227 }
12228 else
12229 {
12230 item = ffesymbol_hook (s).decl_tree;
12231 if (item == NULL_TREE)
12232 {
12233 s = ffecom_sym_transform_ (s);
12234 item = ffesymbol_hook (s).decl_tree;
12235 }
12236 }
12237 assert (item != NULL);
12238 if (item == error_mark_node)
12239 return item;
12240 if (!ffesymbol_hook (s).addr)
12241 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12242 item);
12243 return item;
5ff904cd 12244
c7e4ee3a 12245 case FFEBLD_opARRAYREF:
ff852b44 12246 return ffecom_arrayref_ (NULL_TREE, expr, 1);
5ff904cd 12247
c7e4ee3a 12248 case FFEBLD_opCONTER:
5ff904cd 12249
c7e4ee3a
CB
12250 bt = ffeinfo_basictype (ffebld_info (expr));
12251 kt = ffeinfo_kindtype (ffebld_info (expr));
5ff904cd 12252
c7e4ee3a
CB
12253 item = ffecom_constantunion (&ffebld_constant_union
12254 (ffebld_conter (expr)), bt, kt,
12255 ffecom_tree_type[bt][kt]);
12256 if (item == error_mark_node)
12257 return error_mark_node;
12258 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12259 item);
12260 return item;
5ff904cd 12261
c7e4ee3a
CB
12262 case FFEBLD_opANY:
12263 return error_mark_node;
5ff904cd 12264
c7e4ee3a
CB
12265 default:
12266 bt = ffeinfo_basictype (ffebld_info (expr));
12267 kt = ffeinfo_kindtype (ffebld_info (expr));
12268
12269 item = ffecom_expr (expr);
12270 if (item == error_mark_node)
12271 return error_mark_node;
12272
12273 /* The back end currently optimizes a bit too zealously for us, in that
12274 we fail JCB001 if the following block of code is omitted. It checks
12275 to see if the transformed expression is a symbol or array reference,
12276 and encloses it in a SAVE_EXPR if that is the case. */
12277
12278 STRIP_NOPS (item);
12279 if ((TREE_CODE (item) == VAR_DECL)
12280 || (TREE_CODE (item) == PARM_DECL)
12281 || (TREE_CODE (item) == RESULT_DECL)
12282 || (TREE_CODE (item) == INDIRECT_REF)
12283 || (TREE_CODE (item) == ARRAY_REF)
12284 || (TREE_CODE (item) == COMPONENT_REF)
12285#ifdef OFFSET_REF
12286 || (TREE_CODE (item) == OFFSET_REF)
12287#endif
12288 || (TREE_CODE (item) == BUFFER_REF)
12289 || (TREE_CODE (item) == REALPART_EXPR)
12290 || (TREE_CODE (item) == IMAGPART_EXPR))
12291 {
12292 item = ffecom_save_tree (item);
12293 }
12294
12295 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12296 item);
12297 return item;
12298 }
12299
12300 assert ("fall-through error" == NULL);
12301 return error_mark_node;
5ff904cd
JL
12302}
12303
c7e4ee3a 12304/* Obtain a temp var with given data type.
5ff904cd 12305
c7e4ee3a
CB
12306 size is FFETARGET_charactersizeNONE for a non-CHARACTER type
12307 or >= 0 for a CHARACTER type.
5ff904cd 12308
c7e4ee3a 12309 elements is -1 for a scalar or > 0 for an array of type. */
5ff904cd 12310
5ff904cd 12311tree
c7e4ee3a
CB
12312ffecom_make_tempvar (const char *commentary, tree type,
12313 ffetargetCharacterSize size, int elements)
5ff904cd 12314{
c7e4ee3a
CB
12315 tree t;
12316 static int mynumber;
5ff904cd 12317
c7e4ee3a 12318 assert (current_binding_level->prep_state < 2);
702edf1d 12319
c7e4ee3a
CB
12320 if (type == error_mark_node)
12321 return error_mark_node;
702edf1d 12322
c7e4ee3a
CB
12323 if (size != FFETARGET_charactersizeNONE)
12324 type = build_array_type (type,
12325 build_range_type (ffecom_f2c_ftnlen_type_node,
12326 ffecom_f2c_ftnlen_one_node,
12327 build_int_2 (size, 0)));
12328 if (elements != -1)
12329 type = build_array_type (type,
12330 build_range_type (integer_type_node,
12331 integer_zero_node,
12332 build_int_2 (elements - 1,
12333 0)));
12334 t = build_decl (VAR_DECL,
12335 ffecom_get_invented_identifier ("__g77_%s_%d",
12336 commentary,
12337 mynumber++),
12338 type);
5ff904cd 12339
c7e4ee3a
CB
12340 t = start_decl (t, FALSE);
12341 finish_decl (t, NULL_TREE, FALSE);
12342
c7e4ee3a
CB
12343 return t;
12344}
5ff904cd 12345
c7e4ee3a 12346/* Prepare argument pointer to expression.
5ff904cd 12347
c7e4ee3a
CB
12348 Like ffecom_prepare_expr, except for expressions to be evaluated
12349 via ffecom_arg_ptr_to_expr. */
5ff904cd 12350
c7e4ee3a
CB
12351void
12352ffecom_prepare_arg_ptr_to_expr (ffebld expr)
5ff904cd 12353{
c7e4ee3a
CB
12354 /* ~~For now, it seems to be the same thing. */
12355 ffecom_prepare_expr (expr);
12356 return;
12357}
702edf1d 12358
c7e4ee3a 12359/* End of preparations. */
702edf1d 12360
c7e4ee3a
CB
12361bool
12362ffecom_prepare_end (void)
12363{
12364 int prep_state = current_binding_level->prep_state;
5ff904cd 12365
c7e4ee3a
CB
12366 assert (prep_state < 2);
12367 current_binding_level->prep_state = 2;
5ff904cd 12368
c7e4ee3a 12369 return (prep_state == 1) ? TRUE : FALSE;
5ff904cd
JL
12370}
12371
c7e4ee3a 12372/* Prepare expression.
5ff904cd 12373
c7e4ee3a
CB
12374 This is called before any code is generated for the current block.
12375 It scans the expression, declares any temporaries that might be needed
12376 during evaluation of the expression, and stores those temporaries in
12377 the appropriate "hook" fields of the expression. `dest', if not NULL,
12378 specifies the destination that ffecom_expr_ will see, in case that
12379 helps avoid generating unused temporaries.
12380
12381 ~~Improve to avoid allocating unused temporaries by taking `dest'
12382 into account vis-a-vis aliasing requirements of complex/character
12383 functions. */
12384
12385void
12386ffecom_prepare_expr_ (ffebld expr, ffebld dest UNUSED)
5ff904cd 12387{
c7e4ee3a
CB
12388 ffeinfoBasictype bt;
12389 ffeinfoKindtype kt;
12390 ffetargetCharacterSize sz;
12391 tree tempvar = NULL_TREE;
5ff904cd 12392
c7e4ee3a
CB
12393 assert (current_binding_level->prep_state < 2);
12394
12395 if (! expr)
12396 return;
12397
12398 bt = ffeinfo_basictype (ffebld_info (expr));
12399 kt = ffeinfo_kindtype (ffebld_info (expr));
12400 sz = ffeinfo_size (ffebld_info (expr));
12401
12402 /* Generate whatever temporaries are needed to represent the result
12403 of the expression. */
12404
47d98fa2
CB
12405 if (bt == FFEINFO_basictypeCHARACTER)
12406 {
12407 while (ffebld_op (expr) == FFEBLD_opPAREN)
12408 expr = ffebld_left (expr);
12409 }
12410
c7e4ee3a 12411 switch (ffebld_op (expr))
5ff904cd 12412 {
c7e4ee3a
CB
12413 default:
12414 /* Don't make temps for SYMTER, CONTER, etc. */
12415 if (ffebld_arity (expr) == 0)
12416 break;
5ff904cd 12417
c7e4ee3a 12418 switch (bt)
5ff904cd 12419 {
c7e4ee3a
CB
12420 case FFEINFO_basictypeCOMPLEX:
12421 if (ffebld_op (expr) == FFEBLD_opFUNCREF)
12422 {
12423 ffesymbol s;
5ff904cd 12424
c7e4ee3a
CB
12425 if (ffebld_op (ffebld_left (expr)) != FFEBLD_opSYMTER)
12426 break;
5ff904cd 12427
c7e4ee3a
CB
12428 s = ffebld_symter (ffebld_left (expr));
12429 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT
68779408
CB
12430 || (ffesymbol_where (s) != FFEINFO_whereINTRINSIC
12431 && ! ffesymbol_is_f2c (s))
12432 || (ffesymbol_where (s) == FFEINFO_whereINTRINSIC
12433 && ! ffe_is_f2c_library ()))
c7e4ee3a
CB
12434 break;
12435 }
12436 else if (ffebld_op (expr) == FFEBLD_opPOWER)
12437 {
12438 /* Requires special treatment. There's no POW_CC function
12439 in libg2c, so POW_ZZ is used, which means we always
12440 need a double-complex temp, not a single-complex. */
12441 kt = FFEINFO_kindtypeREAL2;
12442 }
12443 else if (ffebld_op (expr) != FFEBLD_opDIVIDE)
12444 /* The other ops don't need temps for complex operands. */
12445 break;
5ff904cd 12446
c7e4ee3a
CB
12447 /* ~~~Avoid making temps for some intrinsics, such as AIMAG(C),
12448 REAL(C). See 19990325-0.f, routine `check', for cases. */
12449 tempvar = ffecom_make_tempvar ("complex",
12450 ffecom_tree_type
12451 [FFEINFO_basictypeCOMPLEX][kt],
12452 FFETARGET_charactersizeNONE,
12453 -1);
5ff904cd
JL
12454 break;
12455
c7e4ee3a
CB
12456 case FFEINFO_basictypeCHARACTER:
12457 if (ffebld_op (expr) != FFEBLD_opFUNCREF)
12458 break;
12459
12460 if (sz == FFETARGET_charactersizeNONE)
12461 /* ~~Kludge alert! This should someday be fixed. */
12462 sz = 24;
12463
12464 tempvar = ffecom_make_tempvar ("char", char_type_node, sz, -1);
5ff904cd
JL
12465 break;
12466
12467 default:
5ff904cd
JL
12468 break;
12469 }
c7e4ee3a 12470 break;
5ff904cd 12471
c7e4ee3a
CB
12472#ifdef HAHA
12473 case FFEBLD_opPOWER:
12474 {
12475 tree rtype, ltype;
12476 tree rtmp, ltmp, result;
5ff904cd 12477
c7e4ee3a
CB
12478 ltype = ffecom_type_expr (ffebld_left (expr));
12479 rtype = ffecom_type_expr (ffebld_right (expr));
5ff904cd 12480
c7e4ee3a
CB
12481 rtmp = ffecom_make_tempvar (rtype, FFETARGET_charactersizeNONE, -1);
12482 ltmp = ffecom_make_tempvar (ltype, FFETARGET_charactersizeNONE, -1);
12483 result = ffecom_make_tempvar (ltype, FFETARGET_charactersizeNONE, -1);
5ff904cd 12484
c7e4ee3a
CB
12485 tempvar = make_tree_vec (3);
12486 TREE_VEC_ELT (tempvar, 0) = rtmp;
12487 TREE_VEC_ELT (tempvar, 1) = ltmp;
12488 TREE_VEC_ELT (tempvar, 2) = result;
12489 }
12490 break;
12491#endif /* HAHA */
5ff904cd 12492
c7e4ee3a
CB
12493 case FFEBLD_opCONCATENATE:
12494 {
12495 /* This gets special handling, because only one set of temps
12496 is needed for a tree of these -- the tree is treated as
12497 a flattened list of concatenations when generating code. */
5ff904cd 12498
c7e4ee3a
CB
12499 ffecomConcatList_ catlist;
12500 tree ltmp, itmp, result;
12501 int count;
12502 int i;
5ff904cd 12503
c7e4ee3a
CB
12504 catlist = ffecom_concat_list_new_ (expr, FFETARGET_charactersizeNONE);
12505 count = ffecom_concat_list_count_ (catlist);
5ff904cd 12506
c7e4ee3a
CB
12507 if (count >= 2)
12508 {
12509 ltmp
12510 = ffecom_make_tempvar ("concat_len",
12511 ffecom_f2c_ftnlen_type_node,
12512 FFETARGET_charactersizeNONE, count);
12513 itmp
12514 = ffecom_make_tempvar ("concat_item",
12515 ffecom_f2c_address_type_node,
12516 FFETARGET_charactersizeNONE, count);
12517 result
12518 = ffecom_make_tempvar ("concat_res",
12519 char_type_node,
12520 ffecom_concat_list_maxlen_ (catlist),
12521 -1);
12522
12523 tempvar = make_tree_vec (3);
12524 TREE_VEC_ELT (tempvar, 0) = ltmp;
12525 TREE_VEC_ELT (tempvar, 1) = itmp;
12526 TREE_VEC_ELT (tempvar, 2) = result;
12527 }
5ff904cd 12528
c7e4ee3a
CB
12529 for (i = 0; i < count; ++i)
12530 ffecom_prepare_arg_ptr_to_expr (ffecom_concat_list_expr_ (catlist,
12531 i));
5ff904cd 12532
c7e4ee3a 12533 ffecom_concat_list_kill_ (catlist);
5ff904cd 12534
c7e4ee3a
CB
12535 if (tempvar)
12536 {
12537 ffebld_nonter_set_hook (expr, tempvar);
12538 current_binding_level->prep_state = 1;
12539 }
12540 }
12541 return;
5ff904cd 12542
c7e4ee3a
CB
12543 case FFEBLD_opCONVERT:
12544 if (bt == FFEINFO_basictypeCHARACTER
12545 && ((ffebld_size_known (ffebld_left (expr))
12546 == FFETARGET_charactersizeNONE)
12547 || (ffebld_size_known (ffebld_left (expr)) >= sz)))
12548 tempvar = ffecom_make_tempvar ("convert", char_type_node, sz, -1);
12549 break;
12550 }
5ff904cd 12551
c7e4ee3a
CB
12552 if (tempvar)
12553 {
12554 ffebld_nonter_set_hook (expr, tempvar);
12555 current_binding_level->prep_state = 1;
12556 }
5ff904cd 12557
c7e4ee3a 12558 /* Prepare subexpressions for this expr. */
5ff904cd 12559
c7e4ee3a 12560 switch (ffebld_op (expr))
5ff904cd 12561 {
c7e4ee3a
CB
12562 case FFEBLD_opPERCENT_LOC:
12563 ffecom_prepare_ptr_to_expr (ffebld_left (expr));
12564 break;
5ff904cd 12565
c7e4ee3a
CB
12566 case FFEBLD_opPERCENT_VAL:
12567 case FFEBLD_opPERCENT_REF:
12568 ffecom_prepare_expr (ffebld_left (expr));
12569 break;
5ff904cd 12570
c7e4ee3a
CB
12571 case FFEBLD_opPERCENT_DESCR:
12572 ffecom_prepare_arg_ptr_to_expr (ffebld_left (expr));
12573 break;
5ff904cd 12574
c7e4ee3a
CB
12575 case FFEBLD_opITEM:
12576 {
12577 ffebld item;
5ff904cd 12578
c7e4ee3a
CB
12579 for (item = expr;
12580 item != NULL;
12581 item = ffebld_trail (item))
12582 if (ffebld_head (item) != NULL)
12583 ffecom_prepare_expr (ffebld_head (item));
12584 }
12585 break;
5ff904cd 12586
c7e4ee3a
CB
12587 default:
12588 /* Need to handle character conversion specially. */
12589 switch (ffebld_arity (expr))
12590 {
12591 case 2:
12592 ffecom_prepare_expr (ffebld_left (expr));
12593 ffecom_prepare_expr (ffebld_right (expr));
12594 break;
5ff904cd 12595
c7e4ee3a
CB
12596 case 1:
12597 ffecom_prepare_expr (ffebld_left (expr));
12598 break;
5ff904cd 12599
c7e4ee3a
CB
12600 default:
12601 break;
12602 }
12603 }
5ff904cd 12604
c7e4ee3a 12605 return;
5ff904cd
JL
12606}
12607
c7e4ee3a 12608/* Prepare expression for reading and writing.
5ff904cd 12609
c7e4ee3a
CB
12610 Like ffecom_prepare_expr, except for expressions to be evaluated
12611 via ffecom_expr_rw. */
5ff904cd 12612
c7e4ee3a
CB
12613void
12614ffecom_prepare_expr_rw (tree type, ffebld expr)
12615{
12616 /* This is all we support for now. */
12617 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
5ff904cd 12618
c7e4ee3a
CB
12619 /* ~~For now, it seems to be the same thing. */
12620 ffecom_prepare_expr (expr);
12621 return;
12622}
5ff904cd 12623
c7e4ee3a 12624/* Prepare expression for writing.
5ff904cd 12625
c7e4ee3a
CB
12626 Like ffecom_prepare_expr, except for expressions to be evaluated
12627 via ffecom_expr_w. */
5ff904cd
JL
12628
12629void
c7e4ee3a 12630ffecom_prepare_expr_w (tree type, ffebld expr)
5ff904cd 12631{
c7e4ee3a
CB
12632 /* This is all we support for now. */
12633 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
5ff904cd 12634
c7e4ee3a
CB
12635 /* ~~For now, it seems to be the same thing. */
12636 ffecom_prepare_expr (expr);
12637 return;
12638}
5ff904cd 12639
c7e4ee3a 12640/* Prepare expression for returning.
5ff904cd 12641
c7e4ee3a
CB
12642 Like ffecom_prepare_expr, except for expressions to be evaluated
12643 via ffecom_return_expr. */
5ff904cd 12644
c7e4ee3a
CB
12645void
12646ffecom_prepare_return_expr (ffebld expr)
12647{
12648 assert (current_binding_level->prep_state < 2);
5ff904cd 12649
c7e4ee3a
CB
12650 if (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE
12651 && ffecom_is_altreturning_
12652 && expr != NULL)
12653 ffecom_prepare_expr (expr);
12654}
5ff904cd 12655
c7e4ee3a 12656/* Prepare pointer to expression.
5ff904cd 12657
c7e4ee3a
CB
12658 Like ffecom_prepare_expr, except for expressions to be evaluated
12659 via ffecom_ptr_to_expr. */
5ff904cd 12660
c7e4ee3a
CB
12661void
12662ffecom_prepare_ptr_to_expr (ffebld expr)
12663{
12664 /* ~~For now, it seems to be the same thing. */
12665 ffecom_prepare_expr (expr);
12666 return;
5ff904cd
JL
12667}
12668
c7e4ee3a 12669/* Transform expression into constant pointer-to-expression tree.
5ff904cd 12670
c7e4ee3a
CB
12671 If the expression can be transformed into a pointer-to-expression tree
12672 that is constant, that is done, and the tree returned. Else NULL_TREE
12673 is returned.
5ff904cd 12674
c7e4ee3a
CB
12675 That way, a caller can attempt to provide compile-time initialization
12676 of a variable and, if that fails, *then* choose to start a new block
12677 and resort to using temporaries, as appropriate. */
5ff904cd 12678
c7e4ee3a
CB
12679tree
12680ffecom_ptr_to_const_expr (ffebld expr)
5ff904cd 12681{
c7e4ee3a
CB
12682 if (! expr)
12683 return integer_zero_node;
5ff904cd 12684
c7e4ee3a
CB
12685 if (ffebld_op (expr) == FFEBLD_opANY)
12686 return error_mark_node;
5ff904cd 12687
c7e4ee3a
CB
12688 if (ffebld_arity (expr) == 0
12689 && (ffebld_op (expr) != FFEBLD_opSYMTER
12690 || ffebld_where (expr) == FFEINFO_whereCOMMON
12691 || ffebld_where (expr) == FFEINFO_whereGLOBAL
12692 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
5ff904cd 12693 {
c7e4ee3a
CB
12694 tree t;
12695
12696 t = ffecom_ptr_to_expr (expr);
12697 assert (TREE_CONSTANT (t));
12698 return t;
5ff904cd
JL
12699 }
12700
c7e4ee3a
CB
12701 return NULL_TREE;
12702}
12703
12704/* ffecom_return_expr -- Returns return-value expr given alt return expr
12705
12706 tree rtn; // NULL_TREE means use expand_null_return()
12707 ffebld expr; // NULL if no alt return expr to RETURN stmt
12708 rtn = ffecom_return_expr(expr);
12709
12710 Based on the program unit type and other info (like return function
12711 type, return master function type when alternate ENTRY points,
12712 whether subroutine has any alternate RETURN points, etc), returns the
12713 appropriate expression to be returned to the caller, or NULL_TREE
12714 meaning no return value or the caller expects it to be returned somewhere
12715 else (which is handled by other parts of this module). */
12716
c7e4ee3a
CB
12717tree
12718ffecom_return_expr (ffebld expr)
12719{
12720 tree rtn;
12721
12722 switch (ffecom_primary_entry_kind_)
5ff904cd 12723 {
c7e4ee3a
CB
12724 case FFEINFO_kindPROGRAM:
12725 case FFEINFO_kindBLOCKDATA:
12726 rtn = NULL_TREE;
12727 break;
5ff904cd 12728
c7e4ee3a
CB
12729 case FFEINFO_kindSUBROUTINE:
12730 if (!ffecom_is_altreturning_)
12731 rtn = NULL_TREE; /* No alt returns, never an expr. */
12732 else if (expr == NULL)
12733 rtn = integer_zero_node;
12734 else
12735 rtn = ffecom_expr (expr);
12736 break;
12737
12738 case FFEINFO_kindFUNCTION:
12739 if ((ffecom_multi_retval_ != NULL_TREE)
12740 || (ffesymbol_basictype (ffecom_primary_entry_)
12741 == FFEINFO_basictypeCHARACTER)
12742 || ((ffesymbol_basictype (ffecom_primary_entry_)
12743 == FFEINFO_basictypeCOMPLEX)
12744 && (ffecom_num_entrypoints_ == 0)
12745 && ffesymbol_is_f2c (ffecom_primary_entry_)))
12746 { /* Value is returned by direct assignment
12747 into (implicit) dummy. */
12748 rtn = NULL_TREE;
12749 break;
5ff904cd 12750 }
c7e4ee3a
CB
12751 rtn = ffecom_func_result_;
12752#if 0
12753 /* Spurious error if RETURN happens before first reference! So elide
12754 this code. In particular, for debugging registry, rtn should always
12755 be non-null after all, but TREE_USED won't be set until we encounter
12756 a reference in the code. Perfectly okay (but weird) code that,
12757 e.g., has "GOTO 20;10 RETURN;20 RTN=0;GOTO 10", would result in
12758 this diagnostic for no reason. Have people use -O -Wuninitialized
12759 and leave it to the back end to find obviously weird cases. */
5ff904cd 12760
c7e4ee3a
CB
12761 /* Used to "assert(rtn != NULL_TREE);" here, but it's kind of a valid
12762 situation; if the return value has never been referenced, it won't
12763 have a tree under 2pass mode. */
12764 if ((rtn == NULL_TREE)
12765 || !TREE_USED (rtn))
12766 {
12767 ffebad_start (FFEBAD_RETURN_VALUE_UNSET);
12768 ffebad_here (0, ffesymbol_where_line (ffecom_primary_entry_),
12769 ffesymbol_where_column (ffecom_primary_entry_));
12770 ffebad_string (ffesymbol_text (ffesymbol_funcresult
12771 (ffecom_primary_entry_)));
12772 ffebad_finish ();
12773 }
5ff904cd 12774#endif
c7e4ee3a 12775 break;
5ff904cd 12776
c7e4ee3a
CB
12777 default:
12778 assert ("bad unit kind" == NULL);
12779 case FFEINFO_kindANY:
12780 rtn = error_mark_node;
12781 break;
12782 }
5ff904cd 12783
c7e4ee3a
CB
12784 return rtn;
12785}
5ff904cd 12786
c7e4ee3a 12787/* Do save_expr only if tree is not error_mark_node. */
5ff904cd 12788
c7e4ee3a
CB
12789tree
12790ffecom_save_tree (tree t)
5ff904cd 12791{
c7e4ee3a 12792 return save_expr (t);
5ff904cd 12793}
c7e4ee3a
CB
12794
12795/* Start a compound statement (block). */
5ff904cd 12796
5ff904cd 12797void
c7e4ee3a 12798ffecom_start_compstmt (void)
5ff904cd 12799{
c7e4ee3a 12800 bison_rule_pushlevel_ ();
5ff904cd
JL
12801}
12802
c7e4ee3a 12803/* Public entry point for front end to access start_decl. */
5ff904cd 12804
5ff904cd 12805tree
c7e4ee3a 12806ffecom_start_decl (tree decl, bool is_initialized)
5ff904cd 12807{
c7e4ee3a
CB
12808 DECL_INITIAL (decl) = is_initialized ? error_mark_node : NULL_TREE;
12809 return start_decl (decl, FALSE);
12810}
5ff904cd 12811
c7e4ee3a 12812/* ffecom_sym_commit -- Symbol's state being committed to reality
5ff904cd 12813
c7e4ee3a
CB
12814 ffesymbol s;
12815 ffecom_sym_commit(s);
5ff904cd 12816
c7e4ee3a
CB
12817 Does whatever the backend needs when a symbol is committed after having
12818 been backtrackable for a period of time. */
5ff904cd 12819
c7e4ee3a
CB
12820void
12821ffecom_sym_commit (ffesymbol s UNUSED)
12822{
12823 assert (!ffesymbol_retractable ());
12824}
5ff904cd 12825
c7e4ee3a 12826/* ffecom_sym_end_transition -- Perform end transition on all symbols
5ff904cd 12827
c7e4ee3a 12828 ffecom_sym_end_transition();
5ff904cd 12829
c7e4ee3a
CB
12830 Does backend-specific stuff and also calls ffest_sym_end_transition
12831 to do the necessary FFE stuff.
5ff904cd 12832
c7e4ee3a
CB
12833 Backtracking is never enabled when this fn is called, so don't worry
12834 about it. */
5ff904cd 12835
c7e4ee3a
CB
12836ffesymbol
12837ffecom_sym_end_transition (ffesymbol s)
12838{
12839 ffestorag st;
5ff904cd 12840
c7e4ee3a 12841 assert (!ffesymbol_retractable ());
5ff904cd 12842
c7e4ee3a 12843 s = ffest_sym_end_transition (s);
5ff904cd 12844
c7e4ee3a
CB
12845 if ((ffesymbol_kind (s) == FFEINFO_kindBLOCKDATA)
12846 && (ffesymbol_where (s) == FFEINFO_whereGLOBAL))
12847 {
12848 ffecom_list_blockdata_
12849 = ffebld_new_item (ffebld_new_symter (s, FFEINTRIN_genNONE,
12850 FFEINTRIN_specNONE,
12851 FFEINTRIN_impNONE),
12852 ffecom_list_blockdata_);
5ff904cd 12853 }
5ff904cd 12854
c7e4ee3a
CB
12855 /* This is where we finally notice that a symbol has partial initialization
12856 and finalize it. */
5ff904cd 12857
c7e4ee3a
CB
12858 if (ffesymbol_accretion (s) != NULL)
12859 {
12860 assert (ffesymbol_init (s) == NULL);
12861 ffecom_notify_init_symbol (s);
12862 }
12863 else if (((st = ffesymbol_storage (s)) != NULL)
12864 && ((st = ffestorag_parent (st)) != NULL)
12865 && (ffestorag_accretion (st) != NULL))
12866 {
12867 assert (ffestorag_init (st) == NULL);
12868 ffecom_notify_init_storage (st);
12869 }
5ff904cd 12870
c7e4ee3a
CB
12871 if ((ffesymbol_kind (s) == FFEINFO_kindCOMMON)
12872 && (ffesymbol_where (s) == FFEINFO_whereLOCAL)
12873 && (ffesymbol_storage (s) != NULL))
12874 {
12875 ffecom_list_common_
12876 = ffebld_new_item (ffebld_new_symter (s, FFEINTRIN_genNONE,
12877 FFEINTRIN_specNONE,
12878 FFEINTRIN_impNONE),
12879 ffecom_list_common_);
12880 }
5ff904cd 12881
c7e4ee3a
CB
12882 return s;
12883}
5ff904cd 12884
c7e4ee3a 12885/* ffecom_sym_exec_transition -- Perform exec transition on all symbols
5ff904cd 12886
c7e4ee3a 12887 ffecom_sym_exec_transition();
5ff904cd 12888
c7e4ee3a
CB
12889 Does backend-specific stuff and also calls ffest_sym_exec_transition
12890 to do the necessary FFE stuff.
5ff904cd 12891
c7e4ee3a
CB
12892 See the long-winded description in ffecom_sym_learned for info
12893 on handling the situation where backtracking is inhibited. */
5ff904cd 12894
c7e4ee3a
CB
12895ffesymbol
12896ffecom_sym_exec_transition (ffesymbol s)
12897{
12898 s = ffest_sym_exec_transition (s);
5ff904cd 12899
c7e4ee3a
CB
12900 return s;
12901}
5ff904cd 12902
c7e4ee3a 12903/* ffecom_sym_learned -- Initial or more info gained on symbol after exec
5ff904cd 12904
c7e4ee3a
CB
12905 ffesymbol s;
12906 s = ffecom_sym_learned(s);
5ff904cd 12907
c7e4ee3a
CB
12908 Called when a new symbol is seen after the exec transition or when more
12909 info (perhaps) is gained for an UNCERTAIN symbol. The symbol state when
12910 it arrives here is that all its latest info is updated already, so its
12911 state may be UNCERTAIN or UNDERSTOOD, it might already have the hook
12912 field filled in if its gone through here or exec_transition first, and
12913 so on.
5ff904cd 12914
c7e4ee3a
CB
12915 The backend probably wants to check ffesymbol_retractable() to see if
12916 backtracking is in effect. If so, the FFE's changes to the symbol may
12917 be retracted (undone) or committed (ratified), at which time the
12918 appropriate ffecom_sym_retract or _commit function will be called
12919 for that function.
5ff904cd 12920
c7e4ee3a
CB
12921 If the backend has its own backtracking mechanism, great, use it so that
12922 committal is a simple operation. Though it doesn't make much difference,
12923 I suppose: the reason for tentative symbol evolution in the FFE is to
12924 enable error detection in weird incorrect statements early and to disable
12925 incorrect error detection on a correct statement. The backend is not
12926 likely to introduce any information that'll get involved in these
12927 considerations, so it is probably just fine that the implementation
12928 model for this fn and for _exec_transition is to not do anything
12929 (besides the required FFE stuff) if ffesymbol_retractable() returns TRUE
12930 and instead wait until ffecom_sym_commit is called (which it never
12931 will be as long as we're using ambiguity-detecting statement analysis in
12932 the FFE, which we are initially to shake out the code, but don't depend
12933 on this), otherwise go ahead and do whatever is needed.
5ff904cd 12934
c7e4ee3a
CB
12935 In essence, then, when this fn and _exec_transition get called while
12936 backtracking is enabled, a general mechanism would be to flag which (or
12937 both) of these were called (and in what order? neat question as to what
12938 might happen that I'm too lame to think through right now) and then when
12939 _commit is called reproduce the original calling sequence, if any, for
12940 the two fns (at which point backtracking will, of course, be disabled). */
5ff904cd 12941
c7e4ee3a
CB
12942ffesymbol
12943ffecom_sym_learned (ffesymbol s)
12944{
12945 ffestorag_exec_layout (s);
5ff904cd 12946
c7e4ee3a 12947 return s;
5ff904cd
JL
12948}
12949
c7e4ee3a 12950/* ffecom_sym_retract -- Symbol's state being retracted from reality
5ff904cd 12951
c7e4ee3a
CB
12952 ffesymbol s;
12953 ffecom_sym_retract(s);
5ff904cd 12954
c7e4ee3a
CB
12955 Does whatever the backend needs when a symbol is retracted after having
12956 been backtrackable for a period of time. */
5ff904cd 12957
c7e4ee3a
CB
12958void
12959ffecom_sym_retract (ffesymbol s UNUSED)
5ff904cd 12960{
c7e4ee3a 12961 assert (!ffesymbol_retractable ());
5ff904cd 12962
c7e4ee3a
CB
12963#if 0 /* GCC doesn't commit any backtrackable sins,
12964 so nothing needed here. */
12965 switch (ffesymbol_hook (s).state)
5ff904cd 12966 {
c7e4ee3a 12967 case 0: /* nothing happened yet. */
5ff904cd
JL
12968 break;
12969
c7e4ee3a 12970 case 1: /* exec transition happened. */
5ff904cd
JL
12971 break;
12972
c7e4ee3a
CB
12973 case 2: /* learned happened. */
12974 break;
5ff904cd 12975
c7e4ee3a
CB
12976 case 3: /* learned then exec. */
12977 break;
12978
12979 case 4: /* exec then learned. */
5ff904cd
JL
12980 break;
12981
12982 default:
c7e4ee3a 12983 assert ("bad hook state" == NULL);
5ff904cd
JL
12984 break;
12985 }
c7e4ee3a
CB
12986#endif
12987}
5ff904cd 12988
c7e4ee3a
CB
12989/* Create temporary gcc label. */
12990
c7e4ee3a
CB
12991tree
12992ffecom_temp_label ()
12993{
12994 tree glabel;
12995 static int mynumber = 0;
12996
12997 glabel = build_decl (LABEL_DECL,
12998 ffecom_get_invented_identifier ("__g77_label_%d",
c7e4ee3a
CB
12999 mynumber++),
13000 void_type_node);
13001 DECL_CONTEXT (glabel) = current_function_decl;
13002 DECL_MODE (glabel) = VOIDmode;
13003
13004 return glabel;
5ff904cd
JL
13005}
13006
c7e4ee3a
CB
13007/* Return an expression that is usable as an arg in a conditional context
13008 (IF, DO WHILE, .NOT., and so on).
13009
13010 Use the one provided for the back end as of >2.6.0. */
5ff904cd 13011
a2977d2d 13012tree
c7e4ee3a 13013ffecom_truth_value (tree expr)
5ff904cd 13014{
c7e4ee3a 13015 return truthvalue_conversion (expr);
5ff904cd 13016}
c7e4ee3a 13017
c7e4ee3a
CB
13018/* Return the inversion of a truth value (the inversion of what
13019 ffecom_truth_value builds).
5ff904cd 13020
c7e4ee3a
CB
13021 Apparently invert_truthvalue, which is properly in the back end, is
13022 enough for now, so just use it. */
5ff904cd 13023
5ff904cd 13024tree
c7e4ee3a 13025ffecom_truth_value_invert (tree expr)
5ff904cd 13026{
c7e4ee3a 13027 return invert_truthvalue (ffecom_truth_value (expr));
5ff904cd
JL
13028}
13029
c7e4ee3a
CB
13030/* Return the tree that is the type of the expression, as would be
13031 returned in TREE_TYPE(ffecom_expr(expr)), without otherwise
13032 transforming the expression, generating temporaries, etc. */
5ff904cd 13033
c7e4ee3a
CB
13034tree
13035ffecom_type_expr (ffebld expr)
13036{
13037 ffeinfoBasictype bt;
13038 ffeinfoKindtype kt;
13039 tree tree_type;
13040
13041 assert (expr != NULL);
13042
13043 bt = ffeinfo_basictype (ffebld_info (expr));
13044 kt = ffeinfo_kindtype (ffebld_info (expr));
13045 tree_type = ffecom_tree_type[bt][kt];
13046
13047 switch (ffebld_op (expr))
13048 {
13049 case FFEBLD_opCONTER:
13050 case FFEBLD_opSYMTER:
13051 case FFEBLD_opARRAYREF:
13052 case FFEBLD_opUPLUS:
13053 case FFEBLD_opPAREN:
13054 case FFEBLD_opUMINUS:
13055 case FFEBLD_opADD:
13056 case FFEBLD_opSUBTRACT:
13057 case FFEBLD_opMULTIPLY:
13058 case FFEBLD_opDIVIDE:
13059 case FFEBLD_opPOWER:
13060 case FFEBLD_opNOT:
13061 case FFEBLD_opFUNCREF:
13062 case FFEBLD_opSUBRREF:
13063 case FFEBLD_opAND:
13064 case FFEBLD_opOR:
13065 case FFEBLD_opXOR:
13066 case FFEBLD_opNEQV:
13067 case FFEBLD_opEQV:
13068 case FFEBLD_opCONVERT:
13069 case FFEBLD_opLT:
13070 case FFEBLD_opLE:
13071 case FFEBLD_opEQ:
13072 case FFEBLD_opNE:
13073 case FFEBLD_opGT:
13074 case FFEBLD_opGE:
13075 case FFEBLD_opPERCENT_LOC:
13076 return tree_type;
13077
13078 case FFEBLD_opACCTER:
13079 case FFEBLD_opARRTER:
13080 case FFEBLD_opITEM:
13081 case FFEBLD_opSTAR:
13082 case FFEBLD_opBOUNDS:
13083 case FFEBLD_opREPEAT:
13084 case FFEBLD_opLABTER:
13085 case FFEBLD_opLABTOK:
13086 case FFEBLD_opIMPDO:
13087 case FFEBLD_opCONCATENATE:
13088 case FFEBLD_opSUBSTR:
13089 default:
13090 assert ("bad op for ffecom_type_expr" == NULL);
13091 /* Fall through. */
13092 case FFEBLD_opANY:
13093 return error_mark_node;
13094 }
13095}
13096
13097/* Return PARM_DECL for arg#1 of master fn containing alternate ENTRY points
13098
13099 If the PARM_DECL already exists, return it, else create it. It's an
13100 integer_type_node argument for the master function that implements a
13101 subroutine or function with more than one entrypoint and is bound at
13102 run time with the entrypoint number (0 for SUBROUTINE/FUNCTION, 1 for
13103 first ENTRY statement, and so on). */
5ff904cd 13104
c7e4ee3a
CB
13105tree
13106ffecom_which_entrypoint_decl ()
5ff904cd 13107{
c7e4ee3a
CB
13108 assert (ffecom_which_entrypoint_decl_ != NULL_TREE);
13109
13110 return ffecom_which_entrypoint_decl_;
5ff904cd 13111}
c7e4ee3a
CB
13112\f
13113/* The following sections consists of private and public functions
13114 that have the same names and perform roughly the same functions
13115 as counterparts in the C front end. Changes in the C front end
13116 might affect how things should be done here. Only functions
13117 needed by the back end should be public here; the rest should
13118 be private (static in the C sense). Functions needed by other
13119 g77 front-end modules should be accessed by them via public
13120 ffecom_* names, which should themselves call private versions
13121 in this section so the private versions are easy to recognize
13122 when upgrading to a new gcc and finding interesting changes
13123 in the front end.
5ff904cd 13124
c7e4ee3a
CB
13125 Functions named after rule "foo:" in c-parse.y are named
13126 "bison_rule_foo_" so they are easy to find. */
5ff904cd 13127
c7e4ee3a
CB
13128static void
13129bison_rule_pushlevel_ ()
13130{
13131 emit_line_note (input_filename, lineno);
13132 pushlevel (0);
13133 clear_last_expr ();
c7e4ee3a
CB
13134 expand_start_bindings (0);
13135}
5ff904cd 13136
c7e4ee3a
CB
13137static tree
13138bison_rule_compstmt_ ()
5ff904cd 13139{
c7e4ee3a
CB
13140 tree t;
13141 int keep = kept_level_p ();
5ff904cd 13142
c7e4ee3a
CB
13143 /* Make the temps go away. */
13144 if (! keep)
13145 current_binding_level->names = NULL_TREE;
5ff904cd 13146
c7e4ee3a
CB
13147 emit_line_note (input_filename, lineno);
13148 expand_end_bindings (getdecls (), keep, 0);
13149 t = poplevel (keep, 1, 0);
5ff904cd 13150
c7e4ee3a
CB
13151 return t;
13152}
5ff904cd 13153
c7e4ee3a
CB
13154/* Return a definition for a builtin function named NAME and whose data type
13155 is TYPE. TYPE should be a function type with argument types.
13156 FUNCTION_CODE tells later passes how to compile calls to this function.
13157 See tree.h for its possible values.
5ff904cd 13158
c7e4ee3a
CB
13159 If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME,
13160 the name to be called if we can't opencode the function. */
5ff904cd 13161
26db82d8
BS
13162tree
13163builtin_function (const char *name, tree type, int function_code,
13164 enum built_in_class class,
c7e4ee3a
CB
13165 const char *library_name)
13166{
13167 tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
13168 DECL_EXTERNAL (decl) = 1;
13169 TREE_PUBLIC (decl) = 1;
13170 if (library_name)
92643fea 13171 SET_DECL_ASSEMBLER_NAME (decl, get_identifier (library_name));
3e411c3f 13172 make_decl_rtl (decl, NULL);
c7e4ee3a 13173 pushdecl (decl);
26db82d8
BS
13174 DECL_BUILT_IN_CLASS (decl) = class;
13175 DECL_FUNCTION_CODE (decl) = function_code;
5ff904cd 13176
c7e4ee3a 13177 return decl;
5ff904cd
JL
13178}
13179
c7e4ee3a
CB
13180/* Handle when a new declaration NEWDECL
13181 has the same name as an old one OLDDECL
13182 in the same binding contour.
13183 Prints an error message if appropriate.
5ff904cd 13184
c7e4ee3a
CB
13185 If safely possible, alter OLDDECL to look like NEWDECL, and return 1.
13186 Otherwise, return 0. */
5ff904cd 13187
c7e4ee3a
CB
13188static int
13189duplicate_decls (tree newdecl, tree olddecl)
5ff904cd 13190{
c7e4ee3a
CB
13191 int types_match = 1;
13192 int new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL
13193 && DECL_INITIAL (newdecl) != 0);
13194 tree oldtype = TREE_TYPE (olddecl);
13195 tree newtype = TREE_TYPE (newdecl);
5ff904cd 13196
c7e4ee3a
CB
13197 if (olddecl == newdecl)
13198 return 1;
5ff904cd 13199
c7e4ee3a
CB
13200 if (TREE_CODE (newtype) == ERROR_MARK
13201 || TREE_CODE (oldtype) == ERROR_MARK)
13202 types_match = 0;
5ff904cd 13203
c7e4ee3a
CB
13204 /* New decl is completely inconsistent with the old one =>
13205 tell caller to replace the old one.
13206 This is always an error except in the case of shadowing a builtin. */
13207 if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
13208 return 0;
5ff904cd 13209
c7e4ee3a
CB
13210 /* For real parm decl following a forward decl,
13211 return 1 so old decl will be reused. */
13212 if (types_match && TREE_CODE (newdecl) == PARM_DECL
13213 && TREE_ASM_WRITTEN (olddecl) && ! TREE_ASM_WRITTEN (newdecl))
13214 return 1;
5ff904cd 13215
c7e4ee3a
CB
13216 /* The new declaration is the same kind of object as the old one.
13217 The declarations may partially match. Print warnings if they don't
13218 match enough. Ultimately, copy most of the information from the new
13219 decl to the old one, and keep using the old one. */
5ff904cd 13220
c7e4ee3a
CB
13221 if (TREE_CODE (olddecl) == FUNCTION_DECL
13222 && DECL_BUILT_IN (olddecl))
13223 {
13224 /* A function declaration for a built-in function. */
13225 if (!TREE_PUBLIC (newdecl))
13226 return 0;
13227 else if (!types_match)
13228 {
13229 /* Accept the return type of the new declaration if same modes. */
13230 tree oldreturntype = TREE_TYPE (TREE_TYPE (olddecl));
13231 tree newreturntype = TREE_TYPE (TREE_TYPE (newdecl));
5ff904cd 13232
c7e4ee3a
CB
13233 if (TYPE_MODE (oldreturntype) == TYPE_MODE (newreturntype))
13234 {
13235 /* Function types may be shared, so we can't just modify
13236 the return type of olddecl's function type. */
13237 tree newtype
13238 = build_function_type (newreturntype,
13239 TYPE_ARG_TYPES (TREE_TYPE (olddecl)));
5ff904cd 13240
c7e4ee3a
CB
13241 types_match = 1;
13242 if (types_match)
13243 TREE_TYPE (olddecl) = newtype;
13244 }
c7e4ee3a
CB
13245 }
13246 if (!types_match)
13247 return 0;
13248 }
13249 else if (TREE_CODE (olddecl) == FUNCTION_DECL
13250 && DECL_SOURCE_LINE (olddecl) == 0)
5ff904cd 13251 {
c7e4ee3a
CB
13252 /* A function declaration for a predeclared function
13253 that isn't actually built in. */
13254 if (!TREE_PUBLIC (newdecl))
13255 return 0;
13256 else if (!types_match)
13257 {
13258 /* If the types don't match, preserve volatility indication.
13259 Later on, we will discard everything else about the
13260 default declaration. */
13261 TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
13262 }
13263 }
5ff904cd 13264
c7e4ee3a
CB
13265 /* Copy all the DECL_... slots specified in the new decl
13266 except for any that we copy here from the old type.
5ff904cd 13267
c7e4ee3a
CB
13268 Past this point, we don't change OLDTYPE and NEWTYPE
13269 even if we change the types of NEWDECL and OLDDECL. */
5ff904cd 13270
c7e4ee3a
CB
13271 if (types_match)
13272 {
c7e4ee3a
CB
13273 /* Merge the data types specified in the two decls. */
13274 if (TREE_CODE (newdecl) != FUNCTION_DECL || !DECL_BUILT_IN (olddecl))
13275 TREE_TYPE (newdecl)
13276 = TREE_TYPE (olddecl)
13277 = TREE_TYPE (newdecl);
5ff904cd 13278
c7e4ee3a
CB
13279 /* Lay the type out, unless already done. */
13280 if (oldtype != TREE_TYPE (newdecl))
13281 {
13282 if (TREE_TYPE (newdecl) != error_mark_node)
13283 layout_type (TREE_TYPE (newdecl));
13284 if (TREE_CODE (newdecl) != FUNCTION_DECL
13285 && TREE_CODE (newdecl) != TYPE_DECL
13286 && TREE_CODE (newdecl) != CONST_DECL)
13287 layout_decl (newdecl, 0);
13288 }
13289 else
13290 {
13291 /* Since the type is OLDDECL's, make OLDDECL's size go with. */
13292 DECL_SIZE (newdecl) = DECL_SIZE (olddecl);
06ceef4e 13293 DECL_SIZE_UNIT (newdecl) = DECL_SIZE_UNIT (olddecl);
c7e4ee3a
CB
13294 if (TREE_CODE (olddecl) != FUNCTION_DECL)
13295 if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl))
11cf4d18
JJ
13296 {
13297 DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl);
13298 DECL_USER_ALIGN (newdecl) |= DECL_USER_ALIGN (olddecl);
13299 }
c7e4ee3a 13300 }
5ff904cd 13301
c7e4ee3a 13302 /* Keep the old rtl since we can safely use it. */
fe01b88e 13303 COPY_DECL_RTL (olddecl, newdecl);
5ff904cd 13304
c7e4ee3a
CB
13305 /* Merge the type qualifiers. */
13306 if (DECL_BUILT_IN_NONANSI (olddecl) && TREE_THIS_VOLATILE (olddecl)
13307 && !TREE_THIS_VOLATILE (newdecl))
13308 TREE_THIS_VOLATILE (olddecl) = 0;
13309 if (TREE_READONLY (newdecl))
13310 TREE_READONLY (olddecl) = 1;
13311 if (TREE_THIS_VOLATILE (newdecl))
13312 {
13313 TREE_THIS_VOLATILE (olddecl) = 1;
13314 if (TREE_CODE (newdecl) == VAR_DECL)
13315 make_var_volatile (newdecl);
13316 }
5ff904cd 13317
c7e4ee3a
CB
13318 /* Keep source location of definition rather than declaration.
13319 Likewise, keep decl at outer scope. */
13320 if ((DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0)
13321 || (DECL_CONTEXT (newdecl) != 0 && DECL_CONTEXT (olddecl) == 0))
13322 {
13323 DECL_SOURCE_LINE (newdecl) = DECL_SOURCE_LINE (olddecl);
13324 DECL_SOURCE_FILE (newdecl) = DECL_SOURCE_FILE (olddecl);
5ff904cd 13325
c7e4ee3a
CB
13326 if (DECL_CONTEXT (olddecl) == 0
13327 && TREE_CODE (newdecl) != FUNCTION_DECL)
13328 DECL_CONTEXT (newdecl) = 0;
13329 }
5ff904cd 13330
c7e4ee3a
CB
13331 /* Merge the unused-warning information. */
13332 if (DECL_IN_SYSTEM_HEADER (olddecl))
13333 DECL_IN_SYSTEM_HEADER (newdecl) = 1;
13334 else if (DECL_IN_SYSTEM_HEADER (newdecl))
13335 DECL_IN_SYSTEM_HEADER (olddecl) = 1;
5ff904cd 13336
c7e4ee3a
CB
13337 /* Merge the initialization information. */
13338 if (DECL_INITIAL (newdecl) == 0)
13339 DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
5ff904cd 13340
c7e4ee3a
CB
13341 /* Merge the section attribute.
13342 We want to issue an error if the sections conflict but that must be
13343 done later in decl_attributes since we are called before attributes
13344 are assigned. */
13345 if (DECL_SECTION_NAME (newdecl) == NULL_TREE)
13346 DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl);
5ff904cd 13347
c7e4ee3a
CB
13348 if (TREE_CODE (newdecl) == FUNCTION_DECL)
13349 {
13350 DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl);
13351 DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
13352 }
c7e4ee3a
CB
13353 }
13354 /* If cannot merge, then use the new type and qualifiers,
13355 and don't preserve the old rtl. */
13356 else
13357 {
13358 TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
13359 TREE_READONLY (olddecl) = TREE_READONLY (newdecl);
13360 TREE_THIS_VOLATILE (olddecl) = TREE_THIS_VOLATILE (newdecl);
13361 TREE_SIDE_EFFECTS (olddecl) = TREE_SIDE_EFFECTS (newdecl);
13362 }
5ff904cd 13363
c7e4ee3a
CB
13364 /* Merge the storage class information. */
13365 /* For functions, static overrides non-static. */
13366 if (TREE_CODE (newdecl) == FUNCTION_DECL)
13367 {
13368 TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl);
13369 /* This is since we don't automatically
13370 copy the attributes of NEWDECL into OLDDECL. */
13371 TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
13372 /* If this clears `static', clear it in the identifier too. */
13373 if (! TREE_PUBLIC (olddecl))
13374 TREE_PUBLIC (DECL_NAME (olddecl)) = 0;
13375 }
13376 if (DECL_EXTERNAL (newdecl))
13377 {
13378 TREE_STATIC (newdecl) = TREE_STATIC (olddecl);
13379 DECL_EXTERNAL (newdecl) = DECL_EXTERNAL (olddecl);
13380 /* An extern decl does not override previous storage class. */
13381 TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
13382 }
13383 else
13384 {
13385 TREE_STATIC (olddecl) = TREE_STATIC (newdecl);
13386 TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
13387 }
5ff904cd 13388
c7e4ee3a
CB
13389 /* If either decl says `inline', this fn is inline,
13390 unless its definition was passed already. */
13391 if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == 0)
13392 DECL_INLINE (olddecl) = 1;
13393 DECL_INLINE (newdecl) = DECL_INLINE (olddecl);
5ff904cd 13394
c7e4ee3a
CB
13395 /* Get rid of any built-in function if new arg types don't match it
13396 or if we have a function definition. */
13397 if (TREE_CODE (newdecl) == FUNCTION_DECL
13398 && DECL_BUILT_IN (olddecl)
13399 && (!types_match || new_is_definition))
13400 {
13401 TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
26db82d8 13402 DECL_BUILT_IN_CLASS (olddecl) = NOT_BUILT_IN;
c7e4ee3a 13403 }
5ff904cd 13404
c7e4ee3a
CB
13405 /* If redeclaring a builtin function, and not a definition,
13406 it stays built in.
13407 Also preserve various other info from the definition. */
13408 if (TREE_CODE (newdecl) == FUNCTION_DECL && !new_is_definition)
13409 {
13410 if (DECL_BUILT_IN (olddecl))
13411 {
26db82d8 13412 DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl);
c7e4ee3a
CB
13413 DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
13414 }
5ff904cd 13415
c7e4ee3a
CB
13416 DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
13417 DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
13418 DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl);
13419 DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
13420 }
5ff904cd 13421
c7e4ee3a
CB
13422 /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
13423 But preserve olddecl's DECL_UID. */
13424 {
13425 register unsigned olddecl_uid = DECL_UID (olddecl);
5ff904cd 13426
c7e4ee3a
CB
13427 memcpy ((char *) olddecl + sizeof (struct tree_common),
13428 (char *) newdecl + sizeof (struct tree_common),
13429 sizeof (struct tree_decl) - sizeof (struct tree_common));
13430 DECL_UID (olddecl) = olddecl_uid;
13431 }
5ff904cd 13432
c7e4ee3a 13433 return 1;
5ff904cd
JL
13434}
13435
c7e4ee3a
CB
13436/* Finish processing of a declaration;
13437 install its initial value.
13438 If the length of an array type is not known before,
13439 it must be determined now, from the initial value, or it is an error. */
13440
5ff904cd 13441static void
c7e4ee3a 13442finish_decl (tree decl, tree init, bool is_top_level)
5ff904cd 13443{
c7e4ee3a
CB
13444 register tree type = TREE_TYPE (decl);
13445 int was_incomplete = (DECL_SIZE (decl) == 0);
c7e4ee3a
CB
13446 bool at_top_level = (current_binding_level == global_binding_level);
13447 bool top_level = is_top_level || at_top_level;
5ff904cd 13448
c7e4ee3a
CB
13449 /* Caller should pass TRUE for is_top_level only if we wouldn't be at top
13450 level anyway. */
13451 assert (!is_top_level || !at_top_level);
5ff904cd 13452
c7e4ee3a
CB
13453 if (TREE_CODE (decl) == PARM_DECL)
13454 assert (init == NULL_TREE);
13455 /* Remember that PARM_DECL doesn't have a DECL_INITIAL field per se -- it
13456 overlaps DECL_ARG_TYPE. */
13457 else if (init == NULL_TREE)
13458 assert (DECL_INITIAL (decl) == NULL_TREE);
13459 else
13460 assert (DECL_INITIAL (decl) == error_mark_node);
5ff904cd 13461
c7e4ee3a 13462 if (init != NULL_TREE)
5ff904cd 13463 {
c7e4ee3a
CB
13464 if (TREE_CODE (decl) != TYPE_DECL)
13465 DECL_INITIAL (decl) = init;
13466 else
13467 {
13468 /* typedef foo = bar; store the type of bar as the type of foo. */
13469 TREE_TYPE (decl) = TREE_TYPE (init);
13470 DECL_INITIAL (decl) = init = 0;
13471 }
5ff904cd
JL
13472 }
13473
c7e4ee3a 13474 /* Deduce size of array from initialization, if not already known */
5ff904cd 13475
c7e4ee3a
CB
13476 if (TREE_CODE (type) == ARRAY_TYPE
13477 && TYPE_DOMAIN (type) == 0
13478 && TREE_CODE (decl) != TYPE_DECL)
13479 {
13480 assert (top_level);
13481 assert (was_incomplete);
5ff904cd 13482
c7e4ee3a
CB
13483 layout_decl (decl, 0);
13484 }
5ff904cd 13485
c7e4ee3a
CB
13486 if (TREE_CODE (decl) == VAR_DECL)
13487 {
13488 if (DECL_SIZE (decl) == NULL_TREE
13489 && TYPE_SIZE (TREE_TYPE (decl)) != NULL_TREE)
13490 layout_decl (decl, 0);
5ff904cd 13491
c7e4ee3a
CB
13492 if (DECL_SIZE (decl) == NULL_TREE
13493 && (TREE_STATIC (decl)
13494 ?
13495 /* A static variable with an incomplete type is an error if it is
13496 initialized. Also if it is not file scope. Otherwise, let it
13497 through, but if it is not `extern' then it may cause an error
13498 message later. */
13499 (DECL_INITIAL (decl) != 0 || DECL_CONTEXT (decl) != 0)
13500 :
13501 /* An automatic variable with an incomplete type is an error. */
13502 !DECL_EXTERNAL (decl)))
13503 {
13504 assert ("storage size not known" == NULL);
13505 abort ();
13506 }
5ff904cd 13507
c7e4ee3a
CB
13508 if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl))
13509 && (DECL_SIZE (decl) != 0)
13510 && (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST))
13511 {
13512 assert ("storage size not constant" == NULL);
13513 abort ();
13514 }
13515 }
5ff904cd 13516
c7e4ee3a
CB
13517 /* Output the assembler code and/or RTL code for variables and functions,
13518 unless the type is an undefined structure or union. If not, it will get
13519 done when the type is completed. */
5ff904cd 13520
c7e4ee3a 13521 if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)
5ff904cd 13522 {
c7e4ee3a
CB
13523 rest_of_decl_compilation (decl, NULL,
13524 DECL_CONTEXT (decl) == 0,
13525 0);
5ff904cd 13526
c7e4ee3a
CB
13527 if (DECL_CONTEXT (decl) != 0)
13528 {
13529 /* Recompute the RTL of a local array now if it used to be an
13530 incomplete type. */
13531 if (was_incomplete
13532 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
5ff904cd 13533 {
c7e4ee3a
CB
13534 /* If we used it already as memory, it must stay in memory. */
13535 TREE_ADDRESSABLE (decl) = TREE_USED (decl);
13536 /* If it's still incomplete now, no init will save it. */
13537 if (DECL_SIZE (decl) == 0)
13538 DECL_INITIAL (decl) = 0;
13539 expand_decl (decl);
5ff904cd 13540 }
c7e4ee3a
CB
13541 /* Compute and store the initial value. */
13542 if (TREE_CODE (decl) != FUNCTION_DECL)
13543 expand_decl_init (decl);
13544 }
13545 }
13546 else if (TREE_CODE (decl) == TYPE_DECL)
13547 {
3e411c3f 13548 rest_of_decl_compilation (decl, NULL,
c7e4ee3a
CB
13549 DECL_CONTEXT (decl) == 0,
13550 0);
13551 }
5ff904cd 13552
c7e4ee3a
CB
13553 /* At the end of a declaration, throw away any variable type sizes of types
13554 defined inside that declaration. There is no use computing them in the
13555 following function definition. */
13556 if (current_binding_level == global_binding_level)
13557 get_pending_sizes ();
13558}
5ff904cd 13559
c7e4ee3a
CB
13560/* Finish up a function declaration and compile that function
13561 all the way to assembler language output. The free the storage
13562 for the function definition.
5ff904cd 13563
c7e4ee3a 13564 This is called after parsing the body of the function definition.
5ff904cd 13565
c7e4ee3a
CB
13566 NESTED is nonzero if the function being finished is nested in another. */
13567
13568static void
13569finish_function (int nested)
13570{
13571 register tree fndecl = current_function_decl;
13572
13573 assert (fndecl != NULL_TREE);
13574 if (TREE_CODE (fndecl) != ERROR_MARK)
13575 {
13576 if (nested)
13577 assert (DECL_CONTEXT (fndecl) != NULL_TREE);
5ff904cd 13578 else
c7e4ee3a
CB
13579 assert (DECL_CONTEXT (fndecl) == NULL_TREE);
13580 }
5ff904cd 13581
c7e4ee3a
CB
13582/* TREE_READONLY (fndecl) = 1;
13583 This caused &foo to be of type ptr-to-const-function
13584 which then got a warning when stored in a ptr-to-function variable. */
5ff904cd 13585
c7e4ee3a 13586 poplevel (1, 0, 1);
5ff904cd 13587
c7e4ee3a
CB
13588 if (TREE_CODE (fndecl) != ERROR_MARK)
13589 {
13590 BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
5ff904cd 13591
c7e4ee3a 13592 /* Must mark the RESULT_DECL as being in this function. */
5ff904cd 13593
c7e4ee3a 13594 DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;
5ff904cd 13595
c7e4ee3a
CB
13596 /* Obey `register' declarations if `setjmp' is called in this fn. */
13597 /* Generate rtl for function exit. */
13598 expand_function_end (input_filename, lineno, 0);
5ff904cd 13599
7189a4b0
GK
13600 /* If this is a nested function, protect the local variables in the stack
13601 above us from being collected while we're compiling this function. */
1f8f4a0b 13602 if (nested)
7189a4b0
GK
13603 ggc_push_context ();
13604
c7e4ee3a
CB
13605 /* Run the optimizers and output the assembler code for this function. */
13606 rest_of_compilation (fndecl);
7189a4b0
GK
13607
13608 /* Undo the GC context switch. */
1f8f4a0b 13609 if (nested)
7189a4b0 13610 ggc_pop_context ();
c7e4ee3a 13611 }
5ff904cd 13612
c7e4ee3a
CB
13613 if (TREE_CODE (fndecl) != ERROR_MARK
13614 && !nested
13615 && DECL_SAVED_INSNS (fndecl) == 0)
13616 {
13617 /* Stop pointing to the local nodes about to be freed. */
13618 /* But DECL_INITIAL must remain nonzero so we know this was an actual
13619 function definition. */
13620 /* For a nested function, this is done in pop_f_function_context. */
13621 /* If rest_of_compilation set this to 0, leave it 0. */
13622 if (DECL_INITIAL (fndecl) != 0)
13623 DECL_INITIAL (fndecl) = error_mark_node;
13624 DECL_ARGUMENTS (fndecl) = 0;
5ff904cd 13625 }
c7e4ee3a
CB
13626
13627 if (!nested)
5ff904cd 13628 {
c7e4ee3a
CB
13629 /* Let the error reporting routines know that we're outside a function.
13630 For a nested function, this value is used in pop_c_function_context
13631 and then reset via pop_function_context. */
13632 ffecom_outer_function_decl_ = current_function_decl = NULL;
5ff904cd 13633 }
c7e4ee3a 13634}
5ff904cd 13635
c7e4ee3a
CB
13636/* Plug-in replacement for identifying the name of a decl and, for a
13637 function, what we call it in diagnostics. For now, "program unit"
13638 should suffice, since it's a bit of a hassle to figure out which
13639 of several kinds of things it is. Note that it could conceivably
13640 be a statement function, which probably isn't really a program unit
13641 per se, but if that comes up, it should be easy to check (being a
13642 nested function and all). */
13643
4b731ffa 13644static const char *
7afff7cf 13645ffe_printable_name (tree decl, int v)
c7e4ee3a
CB
13646{
13647 /* Just to keep GCC quiet about the unused variable.
13648 In theory, differing values of V should produce different
13649 output. */
13650 switch (v)
5ff904cd 13651 {
c7e4ee3a
CB
13652 default:
13653 if (TREE_CODE (decl) == ERROR_MARK)
13654 return "erroneous code";
13655 return IDENTIFIER_POINTER (DECL_NAME (decl));
5ff904cd 13656 }
c7e4ee3a
CB
13657}
13658
13659/* g77's function to print out name of current function that caused
13660 an error. */
13661
b0791fa9 13662static void
7cb32822
NB
13663ffe_print_error_function (diagnostic_context *context __attribute__((unused)),
13664 const char *file)
c7e4ee3a
CB
13665{
13666 static ffeglobal last_g = NULL;
13667 static ffesymbol last_s = NULL;
13668 ffeglobal g;
13669 ffesymbol s;
13670 const char *kind;
13671
13672 if ((ffecom_primary_entry_ == NULL)
13673 || (ffesymbol_global (ffecom_primary_entry_) == NULL))
5ff904cd 13674 {
c7e4ee3a
CB
13675 g = NULL;
13676 s = NULL;
13677 kind = NULL;
5ff904cd
JL
13678 }
13679 else
13680 {
c7e4ee3a
CB
13681 g = ffesymbol_global (ffecom_primary_entry_);
13682 if (ffecom_nested_entry_ == NULL)
13683 {
13684 s = ffecom_primary_entry_;
f1685b7c 13685 kind = _(ffeinfo_kind_message (ffesymbol_kind (s)));
c7e4ee3a
CB
13686 }
13687 else
13688 {
13689 s = ffecom_nested_entry_;
f1685b7c 13690 kind = _("In statement function");
c7e4ee3a 13691 }
5ff904cd
JL
13692 }
13693
c7e4ee3a 13694 if ((last_g != g) || (last_s != s))
5ff904cd 13695 {
c7e4ee3a
CB
13696 if (file)
13697 fprintf (stderr, "%s: ", file);
13698
13699 if (s == NULL)
f1685b7c 13700 fprintf (stderr, _("Outside of any program unit:\n"));
c7e4ee3a 13701 else
5ff904cd 13702 {
c7e4ee3a
CB
13703 const char *name = ffesymbol_text (s);
13704
f1685b7c 13705 fprintf (stderr, "%s `%s':\n", kind, name);
5ff904cd 13706 }
5ff904cd 13707
c7e4ee3a
CB
13708 last_g = g;
13709 last_s = s;
5ff904cd 13710 }
c7e4ee3a 13711}
5ff904cd 13712
c7e4ee3a 13713/* Similar to `lookup_name' but look only at current binding level. */
5ff904cd 13714
c7e4ee3a
CB
13715static tree
13716lookup_name_current_level (tree name)
13717{
13718 register tree t;
5ff904cd 13719
c7e4ee3a
CB
13720 if (current_binding_level == global_binding_level)
13721 return IDENTIFIER_GLOBAL_VALUE (name);
13722
13723 if (IDENTIFIER_LOCAL_VALUE (name) == 0)
13724 return 0;
13725
13726 for (t = current_binding_level->names; t; t = TREE_CHAIN (t))
13727 if (DECL_NAME (t) == name)
13728 break;
13729
13730 return t;
5ff904cd
JL
13731}
13732
c7e4ee3a 13733/* Create a new `struct binding_level'. */
5ff904cd 13734
c7e4ee3a
CB
13735static struct binding_level *
13736make_binding_level ()
5ff904cd 13737{
c7e4ee3a
CB
13738 /* NOSTRICT */
13739 return (struct binding_level *) xmalloc (sizeof (struct binding_level));
13740}
5ff904cd 13741
c7e4ee3a
CB
13742/* Save and restore the variables in this file and elsewhere
13743 that keep track of the progress of compilation of the current function.
13744 Used for nested functions. */
5ff904cd 13745
c7e4ee3a
CB
13746struct f_function
13747{
13748 struct f_function *next;
13749 tree named_labels;
13750 tree shadowed_labels;
13751 struct binding_level *binding_level;
13752};
5ff904cd 13753
c7e4ee3a 13754struct f_function *f_function_chain;
5ff904cd 13755
c7e4ee3a 13756/* Restore the variables used during compilation of a C function. */
5ff904cd 13757
c7e4ee3a
CB
13758static void
13759pop_f_function_context ()
13760{
13761 struct f_function *p = f_function_chain;
13762 tree link;
5ff904cd 13763
c7e4ee3a
CB
13764 /* Bring back all the labels that were shadowed. */
13765 for (link = shadowed_labels; link; link = TREE_CHAIN (link))
13766 if (DECL_NAME (TREE_VALUE (link)) != 0)
13767 IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link)))
13768 = TREE_VALUE (link);
5ff904cd 13769
c7e4ee3a
CB
13770 if (current_function_decl != error_mark_node
13771 && DECL_SAVED_INSNS (current_function_decl) == 0)
13772 {
13773 /* Stop pointing to the local nodes about to be freed. */
13774 /* But DECL_INITIAL must remain nonzero so we know this was an actual
13775 function definition. */
13776 DECL_INITIAL (current_function_decl) = error_mark_node;
13777 DECL_ARGUMENTS (current_function_decl) = 0;
5ff904cd
JL
13778 }
13779
c7e4ee3a 13780 pop_function_context ();
5ff904cd 13781
c7e4ee3a 13782 f_function_chain = p->next;
5ff904cd 13783
c7e4ee3a
CB
13784 named_labels = p->named_labels;
13785 shadowed_labels = p->shadowed_labels;
13786 current_binding_level = p->binding_level;
5ff904cd 13787
c7e4ee3a
CB
13788 free (p);
13789}
5ff904cd 13790
c7e4ee3a
CB
13791/* Save and reinitialize the variables
13792 used during compilation of a C function. */
5ff904cd 13793
c7e4ee3a
CB
13794static void
13795push_f_function_context ()
13796{
13797 struct f_function *p
13798 = (struct f_function *) xmalloc (sizeof (struct f_function));
5ff904cd 13799
c7e4ee3a
CB
13800 push_function_context ();
13801
13802 p->next = f_function_chain;
13803 f_function_chain = p;
13804
13805 p->named_labels = named_labels;
13806 p->shadowed_labels = shadowed_labels;
13807 p->binding_level = current_binding_level;
13808}
5ff904cd 13809
c7e4ee3a
CB
13810static void
13811push_parm_decl (tree parm)
13812{
13813 int old_immediate_size_expand = immediate_size_expand;
5ff904cd 13814
c7e4ee3a 13815 /* Don't try computing parm sizes now -- wait till fn is called. */
5ff904cd 13816
c7e4ee3a 13817 immediate_size_expand = 0;
5ff904cd 13818
c7e4ee3a 13819 /* Fill in arg stuff. */
5ff904cd 13820
c7e4ee3a
CB
13821 DECL_ARG_TYPE (parm) = TREE_TYPE (parm);
13822 DECL_ARG_TYPE_AS_WRITTEN (parm) = TREE_TYPE (parm);
13823 TREE_READONLY (parm) = 1; /* All implementation args are read-only. */
5ff904cd 13824
c7e4ee3a
CB
13825 parm = pushdecl (parm);
13826
13827 immediate_size_expand = old_immediate_size_expand;
13828
13829 finish_decl (parm, NULL_TREE, FALSE);
5ff904cd
JL
13830}
13831
c7e4ee3a 13832/* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL, if appropriate. */
5ff904cd 13833
c7e4ee3a
CB
13834static tree
13835pushdecl_top_level (x)
13836 tree x;
13837{
13838 register tree t;
13839 register struct binding_level *b = current_binding_level;
13840 register tree f = current_function_decl;
5ff904cd 13841
c7e4ee3a
CB
13842 current_binding_level = global_binding_level;
13843 current_function_decl = NULL_TREE;
13844 t = pushdecl (x);
13845 current_binding_level = b;
13846 current_function_decl = f;
13847 return t;
13848}
13849
13850/* Store the list of declarations of the current level.
13851 This is done for the parameter declarations of a function being defined,
13852 after they are modified in the light of any missing parameters. */
13853
13854static tree
13855storedecls (decls)
13856 tree decls;
13857{
13858 return current_binding_level->names = decls;
13859}
13860
13861/* Store the parameter declarations into the current function declaration.
13862 This is called after parsing the parameter declarations, before
13863 digesting the body of the function.
13864
13865 For an old-style definition, modify the function's type
13866 to specify at least the number of arguments. */
5ff904cd
JL
13867
13868static void
c7e4ee3a 13869store_parm_decls (int is_main_program UNUSED)
5ff904cd
JL
13870{
13871 register tree fndecl = current_function_decl;
13872
c7e4ee3a
CB
13873 if (fndecl == error_mark_node)
13874 return;
5ff904cd 13875
c7e4ee3a
CB
13876 /* This is a chain of PARM_DECLs from old-style parm declarations. */
13877 DECL_ARGUMENTS (fndecl) = storedecls (nreverse (getdecls ()));
5ff904cd 13878
c7e4ee3a 13879 /* Initialize the RTL code for the function. */
5ff904cd 13880
c7e4ee3a 13881 init_function_start (fndecl, input_filename, lineno);
56a0044b 13882
c7e4ee3a 13883 /* Set up parameters and prepare for return, for the function. */
5ff904cd 13884
c7e4ee3a
CB
13885 expand_function_start (fndecl, 0);
13886}
5ff904cd 13887
c7e4ee3a
CB
13888static tree
13889start_decl (tree decl, bool is_top_level)
13890{
13891 register tree tem;
13892 bool at_top_level = (current_binding_level == global_binding_level);
13893 bool top_level = is_top_level || at_top_level;
5ff904cd 13894
c7e4ee3a
CB
13895 /* Caller should pass TRUE for is_top_level only if we wouldn't be at top
13896 level anyway. */
13897 assert (!is_top_level || !at_top_level);
5ff904cd 13898
c7e4ee3a
CB
13899 if (DECL_INITIAL (decl) != NULL_TREE)
13900 {
13901 assert (DECL_INITIAL (decl) == error_mark_node);
13902 assert (!DECL_EXTERNAL (decl));
56a0044b 13903 }
c7e4ee3a
CB
13904 else if (top_level)
13905 assert ((TREE_STATIC (decl) == 1) || DECL_EXTERNAL (decl) == 1);
5ff904cd 13906
c7e4ee3a
CB
13907 /* For Fortran, we by default put things in .common when possible. */
13908 DECL_COMMON (decl) = 1;
5ff904cd 13909
c7e4ee3a
CB
13910 /* Add this decl to the current binding level. TEM may equal DECL or it may
13911 be a previous decl of the same name. */
13912 if (is_top_level)
13913 tem = pushdecl_top_level (decl);
13914 else
13915 tem = pushdecl (decl);
13916
13917 /* For a local variable, define the RTL now. */
13918 if (!top_level
13919 /* But not if this is a duplicate decl and we preserved the rtl from the
13920 previous one (which may or may not happen). */
19e7881c 13921 && !DECL_RTL_SET_P (tem))
5ff904cd 13922 {
c7e4ee3a
CB
13923 if (TYPE_SIZE (TREE_TYPE (tem)) != 0)
13924 expand_decl (tem);
13925 else if (TREE_CODE (TREE_TYPE (tem)) == ARRAY_TYPE
13926 && DECL_INITIAL (tem) != 0)
13927 expand_decl (tem);
5ff904cd
JL
13928 }
13929
c7e4ee3a 13930 return tem;
5ff904cd
JL
13931}
13932
c7e4ee3a
CB
13933/* Create the FUNCTION_DECL for a function definition.
13934 DECLSPECS and DECLARATOR are the parts of the declaration;
13935 they describe the function's name and the type it returns,
13936 but twisted together in a fashion that parallels the syntax of C.
5ff904cd 13937
c7e4ee3a
CB
13938 This function creates a binding context for the function body
13939 as well as setting up the FUNCTION_DECL in current_function_decl.
5ff904cd 13940
c7e4ee3a
CB
13941 Returns 1 on success. If the DECLARATOR is not suitable for a function
13942 (it defines a datum instead), we return 0, which tells
52dabb6c 13943 ffe_parse_file to report a parse error.
5ff904cd 13944
c7e4ee3a
CB
13945 NESTED is nonzero for a function nested within another function. */
13946
13947static void
13948start_function (tree name, tree type, int nested, int public)
5ff904cd 13949{
c7e4ee3a
CB
13950 tree decl1;
13951 tree restype;
13952 int old_immediate_size_expand = immediate_size_expand;
5ff904cd 13953
c7e4ee3a
CB
13954 named_labels = 0;
13955 shadowed_labels = 0;
13956
13957 /* Don't expand any sizes in the return type of the function. */
13958 immediate_size_expand = 0;
13959
13960 if (nested)
5ff904cd 13961 {
c7e4ee3a
CB
13962 assert (!public);
13963 assert (current_function_decl != NULL_TREE);
13964 assert (DECL_CONTEXT (current_function_decl) == NULL_TREE);
13965 }
13966 else
13967 {
13968 assert (current_function_decl == NULL_TREE);
5ff904cd 13969 }
c7e4ee3a
CB
13970
13971 if (TREE_CODE (type) == ERROR_MARK)
13972 decl1 = current_function_decl = error_mark_node;
56a0044b 13973 else
5ff904cd 13974 {
c7e4ee3a
CB
13975 decl1 = build_decl (FUNCTION_DECL,
13976 name,
13977 type);
13978 TREE_PUBLIC (decl1) = public ? 1 : 0;
13979 if (nested)
13980 DECL_INLINE (decl1) = 1;
13981 TREE_STATIC (decl1) = 1;
13982 DECL_EXTERNAL (decl1) = 0;
5ff904cd 13983
c7e4ee3a 13984 announce_function (decl1);
5ff904cd 13985
c7e4ee3a
CB
13986 /* Make the init_value nonzero so pushdecl knows this is not tentative.
13987 error_mark_node is replaced below (in poplevel) with the BLOCK. */
13988 DECL_INITIAL (decl1) = error_mark_node;
5ff904cd 13989
c7e4ee3a
CB
13990 /* Record the decl so that the function name is defined. If we already have
13991 a decl for this name, and it is a FUNCTION_DECL, use the old decl. */
5ff904cd 13992
c7e4ee3a 13993 current_function_decl = pushdecl (decl1);
5ff904cd
JL
13994 }
13995
c7e4ee3a
CB
13996 if (!nested)
13997 ffecom_outer_function_decl_ = current_function_decl;
5ff904cd 13998
c7e4ee3a
CB
13999 pushlevel (0);
14000 current_binding_level->prep_state = 2;
5ff904cd 14001
c7e4ee3a
CB
14002 if (TREE_CODE (current_function_decl) != ERROR_MARK)
14003 {
6c418184 14004 make_decl_rtl (current_function_decl, NULL);
5ff904cd 14005
c7e4ee3a
CB
14006 restype = TREE_TYPE (TREE_TYPE (current_function_decl));
14007 DECL_RESULT (current_function_decl)
14008 = build_decl (RESULT_DECL, NULL_TREE, restype);
5ff904cd 14009 }
5ff904cd 14010
c7e4ee3a
CB
14011 if (!nested && (TREE_CODE (current_function_decl) != ERROR_MARK))
14012 TREE_ADDRESSABLE (current_function_decl) = 1;
14013
14014 immediate_size_expand = old_immediate_size_expand;
14015}
14016\f
14017/* Here are the public functions the GNU back end needs. */
14018
14019tree
14020convert (type, expr)
14021 tree type, expr;
5ff904cd 14022{
c7e4ee3a
CB
14023 register tree e = expr;
14024 register enum tree_code code = TREE_CODE (type);
5ff904cd 14025
c7e4ee3a
CB
14026 if (type == TREE_TYPE (e)
14027 || TREE_CODE (e) == ERROR_MARK)
14028 return e;
14029 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
14030 return fold (build1 (NOP_EXPR, type, e));
14031 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
14032 || code == ERROR_MARK)
14033 return error_mark_node;
14034 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
14035 {
14036 assert ("void value not ignored as it ought to be" == NULL);
14037 return error_mark_node;
14038 }
14039 if (code == VOID_TYPE)
14040 return build1 (CONVERT_EXPR, type, e);
14041 if ((code != RECORD_TYPE)
14042 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
14043 e = ffecom_1 (REALPART_EXPR, TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e))),
14044 e);
14045 if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)
14046 return fold (convert_to_integer (type, e));
14047 if (code == POINTER_TYPE)
14048 return fold (convert_to_pointer (type, e));
14049 if (code == REAL_TYPE)
14050 return fold (convert_to_real (type, e));
14051 if (code == COMPLEX_TYPE)
14052 return fold (convert_to_complex (type, e));
14053 if (code == RECORD_TYPE)
14054 return fold (ffecom_convert_to_complex_ (type, e));
5ff904cd 14055
c7e4ee3a
CB
14056 assert ("conversion to non-scalar type requested" == NULL);
14057 return error_mark_node;
14058}
5ff904cd 14059
c7e4ee3a
CB
14060/* Return the list of declarations of the current level.
14061 Note that this list is in reverse order unless/until
14062 you nreverse it; and when you do nreverse it, you must
14063 store the result back using `storedecls' or you will lose. */
5ff904cd 14064
c7e4ee3a
CB
14065tree
14066getdecls ()
5ff904cd 14067{
c7e4ee3a 14068 return current_binding_level->names;
5ff904cd
JL
14069}
14070
c7e4ee3a 14071/* Nonzero if we are currently in the global binding level. */
5ff904cd 14072
c7e4ee3a
CB
14073int
14074global_bindings_p ()
5ff904cd 14075{
c7e4ee3a
CB
14076 return current_binding_level == global_binding_level;
14077}
5ff904cd 14078
c7e4ee3a
CB
14079/* Print an error message for invalid use of an incomplete type.
14080 VALUE is the expression that was used (or 0 if that isn't known)
14081 and TYPE is the type that was invalid. */
5ff904cd 14082
c7e4ee3a
CB
14083void
14084incomplete_type_error (value, type)
14085 tree value UNUSED;
14086 tree type;
14087{
14088 if (TREE_CODE (type) == ERROR_MARK)
14089 return;
5ff904cd 14090
c7e4ee3a
CB
14091 assert ("incomplete type?!?" == NULL);
14092}
14093
7189a4b0 14094/* Mark ARG for GC. */
516b69ff 14095static void
54551044 14096mark_binding_level (void *arg)
7189a4b0
GK
14097{
14098 struct binding_level *level = *(struct binding_level **) arg;
14099
14100 while (level)
14101 {
14102 ggc_mark_tree (level->names);
14103 ggc_mark_tree (level->blocks);
14104 ggc_mark_tree (level->this_block);
14105 level = level->level_chain;
14106 }
14107}
14108
f5e99456
NB
14109static void
14110ffecom_init_decl_processing ()
5ff904cd 14111{
7189a4b0
GK
14112 static tree *const tree_roots[] = {
14113 &current_function_decl,
14114 &string_type_node,
14115 &ffecom_tree_fun_type_void,
14116 &ffecom_integer_zero_node,
14117 &ffecom_integer_one_node,
14118 &ffecom_tree_subr_type,
14119 &ffecom_tree_ptr_to_subr_type,
14120 &ffecom_tree_blockdata_type,
14121 &ffecom_tree_xargc_,
14122 &ffecom_f2c_integer_type_node,
14123 &ffecom_f2c_ptr_to_integer_type_node,
14124 &ffecom_f2c_address_type_node,
14125 &ffecom_f2c_real_type_node,
14126 &ffecom_f2c_ptr_to_real_type_node,
14127 &ffecom_f2c_doublereal_type_node,
14128 &ffecom_f2c_complex_type_node,
14129 &ffecom_f2c_doublecomplex_type_node,
14130 &ffecom_f2c_longint_type_node,
14131 &ffecom_f2c_logical_type_node,
14132 &ffecom_f2c_flag_type_node,
14133 &ffecom_f2c_ftnlen_type_node,
14134 &ffecom_f2c_ftnlen_zero_node,
14135 &ffecom_f2c_ftnlen_one_node,
14136 &ffecom_f2c_ftnlen_two_node,
14137 &ffecom_f2c_ptr_to_ftnlen_type_node,
14138 &ffecom_f2c_ftnint_type_node,
14139 &ffecom_f2c_ptr_to_ftnint_type_node,
14140 &ffecom_outer_function_decl_,
14141 &ffecom_previous_function_decl_,
14142 &ffecom_which_entrypoint_decl_,
14143 &ffecom_float_zero_,
14144 &ffecom_float_half_,
14145 &ffecom_double_zero_,
14146 &ffecom_double_half_,
14147 &ffecom_func_result_,
14148 &ffecom_func_length_,
14149 &ffecom_multi_type_node_,
14150 &ffecom_multi_retval_,
14151 &named_labels,
14152 &shadowed_labels
14153 };
14154 size_t i;
14155
c7e4ee3a 14156 malloc_init ();
7189a4b0
GK
14157
14158 /* Record our roots. */
75ff2ca7 14159 for (i = 0; i < ARRAY_SIZE (tree_roots); i++)
7189a4b0 14160 ggc_add_tree_root (tree_roots[i], 1);
516b69ff 14161 ggc_add_tree_root (&ffecom_tree_type[0][0],
7189a4b0 14162 FFEINFO_basictype*FFEINFO_kindtype);
516b69ff 14163 ggc_add_tree_root (&ffecom_tree_fun_type[0][0],
7189a4b0 14164 FFEINFO_basictype*FFEINFO_kindtype);
516b69ff 14165 ggc_add_tree_root (&ffecom_tree_ptr_to_fun_type[0][0],
7189a4b0
GK
14166 FFEINFO_basictype*FFEINFO_kindtype);
14167 ggc_add_tree_root (ffecom_gfrt_, FFECOM_gfrt);
14168 ggc_add_root (&current_binding_level, 1, sizeof current_binding_level,
14169 mark_binding_level);
14170 ggc_add_root (&free_binding_level, 1, sizeof current_binding_level,
14171 mark_binding_level);
14172 ggc_add_root (&tracker_head, 1, sizeof tracker_head, mark_tracker_head);
14173
c7e4ee3a
CB
14174 ffe_init_0 ();
14175}
5ff904cd 14176
c7e4ee3a
CB
14177/* Delete the node BLOCK from the current binding level.
14178 This is used for the block inside a stmt expr ({...})
14179 so that the block can be reinserted where appropriate. */
14180
14181static void
14182delete_block (block)
14183 tree block;
14184{
14185 tree t;
14186 if (current_binding_level->blocks == block)
14187 current_binding_level->blocks = TREE_CHAIN (block);
14188 for (t = current_binding_level->blocks; t;)
14189 {
14190 if (TREE_CHAIN (t) == block)
14191 TREE_CHAIN (t) = TREE_CHAIN (block);
14192 else
14193 t = TREE_CHAIN (t);
14194 }
14195 TREE_CHAIN (block) = NULL;
14196 /* Clear TREE_USED which is always set by poplevel.
14197 The flag is set again if insert_block is called. */
14198 TREE_USED (block) = 0;
14199}
14200
14201void
14202insert_block (block)
14203 tree block;
14204{
14205 TREE_USED (block) = 1;
14206 current_binding_level->blocks
14207 = chainon (current_binding_level->blocks, block);
14208}
14209
cd2a3ba2 14210/* Each front end provides its own. */
f5e99456 14211static const char *ffe_init PARAMS ((const char *));
ee811cfd
NB
14212static void ffe_finish PARAMS ((void));
14213static void ffe_init_options PARAMS ((void));
5d69f816 14214static void ffe_print_identifier PARAMS ((FILE *, tree, int));
4f0ade92 14215static void ffe_mark_tree (tree);
ee811cfd 14216
3ac88239
NB
14217#undef LANG_HOOKS_NAME
14218#define LANG_HOOKS_NAME "GNU F77"
17ed6335
RH
14219#undef LANG_HOOKS_INIT
14220#define LANG_HOOKS_INIT ffe_init
14221#undef LANG_HOOKS_FINISH
14222#define LANG_HOOKS_FINISH ffe_finish
14223#undef LANG_HOOKS_INIT_OPTIONS
14224#define LANG_HOOKS_INIT_OPTIONS ffe_init_options
14225#undef LANG_HOOKS_DECODE_OPTION
14226#define LANG_HOOKS_DECODE_OPTION ffe_decode_option
52dabb6c
NB
14227#undef LANG_HOOKS_PARSE_FILE
14228#define LANG_HOOKS_PARSE_FILE ffe_parse_file
4f0ade92
NB
14229#undef LANG_HOOKS_MARK_TREE
14230#define LANG_HOOKS_MARK_TREE ffe_mark_tree
dffd7eb6
NB
14231#undef LANG_HOOKS_MARK_ADDRESSABLE
14232#define LANG_HOOKS_MARK_ADDRESSABLE ffe_mark_addressable
5d69f816
NB
14233#undef LANG_HOOKS_PRINT_IDENTIFIER
14234#define LANG_HOOKS_PRINT_IDENTIFIER ffe_print_identifier
7afff7cf
NB
14235#undef LANG_HOOKS_DECL_PRINTABLE_NAME
14236#define LANG_HOOKS_DECL_PRINTABLE_NAME ffe_printable_name
7cb32822
NB
14237#undef LANG_HOOKS_PRINT_ERROR_FUNCTION
14238#define LANG_HOOKS_PRINT_ERROR_FUNCTION ffe_print_error_function
ceef8ce4 14239
b0c48229
NB
14240#undef LANG_HOOKS_TYPE_FOR_MODE
14241#define LANG_HOOKS_TYPE_FOR_MODE ffe_type_for_mode
14242#undef LANG_HOOKS_TYPE_FOR_SIZE
14243#define LANG_HOOKS_TYPE_FOR_SIZE ffe_type_for_size
ceef8ce4
NB
14244#undef LANG_HOOKS_SIGNED_TYPE
14245#define LANG_HOOKS_SIGNED_TYPE ffe_signed_type
14246#undef LANG_HOOKS_UNSIGNED_TYPE
14247#define LANG_HOOKS_UNSIGNED_TYPE ffe_unsigned_type
14248#undef LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE
14249#define LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE ffe_signed_or_unsigned_type
17ed6335 14250
8ac61af7
RK
14251/* We do not wish to use alias-set based aliasing at all. Used in the
14252 extreme (every object with its own set, with equivalences recorded) it
14253 might be helpful, but there are problems when it comes to inlining. We
14254 get on ok with flag_argument_noalias, and alias-set aliasing does
14255 currently limit how stack slots can be reused, which is a lose. */
14256#undef LANG_HOOKS_GET_ALIAS_SET
14257#define LANG_HOOKS_GET_ALIAS_SET hook_get_alias_set_0
14258
3ac88239 14259const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
cd2a3ba2 14260
2f9834e8
KG
14261/* Table indexed by tree code giving a string containing a character
14262 classifying the tree code. Possibilities are
14263 t, d, s, c, r, <, 1, 2 and e. See tree.def for details. */
14264
14265#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
14266
14267const char tree_code_type[] = {
14268#include "tree.def"
14269};
14270#undef DEFTREECODE
14271
14272/* Table indexed by tree code giving number of expression
14273 operands beyond the fixed part of the node structure.
14274 Not used for types or decls. */
14275
14276#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
14277
14278const unsigned char tree_code_length[] = {
14279#include "tree.def"
14280};
14281#undef DEFTREECODE
14282
14283/* Names of tree components.
14284 Used for printing out the tree and error messages. */
14285#define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
14286
14287const char *const tree_code_name[] = {
14288#include "tree.def"
14289};
14290#undef DEFTREECODE
14291
f5e99456
NB
14292static const char *
14293ffe_init (filename)
14294 const char *filename;
14295{
14296 /* Open input file. */
14297 if (filename == 0 || !strcmp (filename, "-"))
14298 {
14299 finput = stdin;
14300 filename = "stdin";
14301 }
14302 else
14303 finput = fopen (filename, "r");
14304 if (finput == 0)
14305 fatal_io_error ("can't open %s", filename);
14306
14307#ifdef IO_BUFFER_SIZE
14308 setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
14309#endif
14310
14311 ffecom_init_decl_processing ();
f5e99456
NB
14312
14313 /* If the file is output from cpp, it should contain a first line
14314 `# 1 "real-filename"', and the current design of gcc (toplev.c
14315 in particular and the way it sets up information relied on by
14316 INCLUDE) requires that we read this now, and store the
14317 "real-filename" info in master_input_filename. Ask the lexer
14318 to try doing this. */
14319 ffelex_hash_kludge (finput);
14320
14321 /* FIXME: The ffelex_hash_kludge code needs to be cleaned up to
14322 return the new file name. */
14323 if (main_input_filename)
14324 filename = main_input_filename;
14325
14326 return filename;
14327}
14328
13c61421 14329static void
ee811cfd 14330ffe_finish ()
c7e4ee3a
CB
14331{
14332 ffe_terminate_0 ();
5ff904cd 14333
c7e4ee3a
CB
14334 if (ffe_is_ffedebug ())
14335 malloc_pool_display (malloc_pool_image ());
22703ccc
NB
14336
14337 fclose (finput);
5ff904cd
JL
14338}
14339
ee811cfd
NB
14340static void
14341ffe_init_options ()
c7e4ee3a
CB
14342{
14343 /* Set default options for Fortran. */
14344 flag_move_all_movables = 1;
14345 flag_reduce_all_givs = 1;
14346 flag_argument_noalias = 2;
201556f0 14347 flag_merge_constants = 2;
41af162c 14348 flag_errno_math = 0;
c64f913e 14349 flag_complex_divide_method = 1;
c7e4ee3a 14350}
5ff904cd 14351
dffd7eb6
NB
14352static bool
14353ffe_mark_addressable (exp)
c7e4ee3a
CB
14354 tree exp;
14355{
14356 register tree x = exp;
14357 while (1)
14358 switch (TREE_CODE (x))
14359 {
14360 case ADDR_EXPR:
14361 case COMPONENT_REF:
14362 case ARRAY_REF:
14363 x = TREE_OPERAND (x, 0);
14364 break;
5ff904cd 14365
c7e4ee3a
CB
14366 case CONSTRUCTOR:
14367 TREE_ADDRESSABLE (x) = 1;
dffd7eb6 14368 return true;
5ff904cd 14369
c7e4ee3a
CB
14370 case VAR_DECL:
14371 case CONST_DECL:
14372 case PARM_DECL:
14373 case RESULT_DECL:
14374 if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
14375 && DECL_NONLOCAL (x))
14376 {
14377 if (TREE_PUBLIC (x))
14378 {
14379 assert ("address of global register var requested" == NULL);
dffd7eb6 14380 return false;
c7e4ee3a
CB
14381 }
14382 assert ("address of register variable requested" == NULL);
14383 }
14384 else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x))
14385 {
14386 if (TREE_PUBLIC (x))
14387 {
14388 assert ("address of global register var requested" == NULL);
dffd7eb6 14389 return false;
c7e4ee3a
CB
14390 }
14391 assert ("address of register var requested" == NULL);
14392 }
14393 put_var_into_stack (x);
5ff904cd 14394
c7e4ee3a
CB
14395 /* drops in */
14396 case FUNCTION_DECL:
14397 TREE_ADDRESSABLE (x) = 1;
14398#if 0 /* poplevel deals with this now. */
14399 if (DECL_CONTEXT (x) == 0)
14400 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (x)) = 1;
14401#endif
5ff904cd 14402
c7e4ee3a 14403 default:
dffd7eb6 14404 return true;
c7e4ee3a 14405 }
5ff904cd
JL
14406}
14407
c7e4ee3a
CB
14408/* Exit a binding level.
14409 Pop the level off, and restore the state of the identifier-decl mappings
14410 that were in effect when this level was entered.
5ff904cd 14411
c7e4ee3a
CB
14412 If KEEP is nonzero, this level had explicit declarations, so
14413 and create a "block" (a BLOCK node) for the level
14414 to record its declarations and subblocks for symbol table output.
5ff904cd 14415
c7e4ee3a
CB
14416 If FUNCTIONBODY is nonzero, this level is the body of a function,
14417 so create a block as if KEEP were set and also clear out all
14418 label names.
5ff904cd 14419
c7e4ee3a
CB
14420 If REVERSE is nonzero, reverse the order of decls before putting
14421 them into the BLOCK. */
5ff904cd 14422
c7e4ee3a
CB
14423tree
14424poplevel (keep, reverse, functionbody)
14425 int keep;
14426 int reverse;
14427 int functionbody;
5ff904cd 14428{
c7e4ee3a
CB
14429 register tree link;
14430 /* The chain of decls was accumulated in reverse order.
14431 Put it into forward order, just for cleanliness. */
14432 tree decls;
14433 tree subblocks = current_binding_level->blocks;
14434 tree block = 0;
14435 tree decl;
14436 int block_previously_created;
5ff904cd 14437
c7e4ee3a
CB
14438 /* Get the decls in the order they were written.
14439 Usually current_binding_level->names is in reverse order.
14440 But parameter decls were previously put in forward order. */
702edf1d 14441
c7e4ee3a
CB
14442 if (reverse)
14443 current_binding_level->names
14444 = decls = nreverse (current_binding_level->names);
14445 else
14446 decls = current_binding_level->names;
5ff904cd 14447
c7e4ee3a
CB
14448 /* Output any nested inline functions within this block
14449 if they weren't already output. */
5ff904cd 14450
c7e4ee3a
CB
14451 for (decl = decls; decl; decl = TREE_CHAIN (decl))
14452 if (TREE_CODE (decl) == FUNCTION_DECL
14453 && ! TREE_ASM_WRITTEN (decl)
14454 && DECL_INITIAL (decl) != 0
14455 && TREE_ADDRESSABLE (decl))
14456 {
14457 /* If this decl was copied from a file-scope decl
14458 on account of a block-scope extern decl,
14459 propagate TREE_ADDRESSABLE to the file-scope decl.
14460
14461 DECL_ABSTRACT_ORIGIN can be set to itself if warn_return_type is
14462 true, since then the decl goes through save_for_inline_copying. */
14463 if (DECL_ABSTRACT_ORIGIN (decl) != 0
14464 && DECL_ABSTRACT_ORIGIN (decl) != decl)
14465 TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1;
14466 else if (DECL_SAVED_INSNS (decl) != 0)
14467 {
14468 push_function_context ();
14469 output_inline_function (decl);
14470 pop_function_context ();
14471 }
14472 }
5ff904cd 14473
c7e4ee3a
CB
14474 /* If there were any declarations or structure tags in that level,
14475 or if this level is a function body,
14476 create a BLOCK to record them for the life of this function. */
5ff904cd 14477
c7e4ee3a
CB
14478 block = 0;
14479 block_previously_created = (current_binding_level->this_block != 0);
14480 if (block_previously_created)
14481 block = current_binding_level->this_block;
14482 else if (keep || functionbody)
14483 block = make_node (BLOCK);
14484 if (block != 0)
14485 {
14486 BLOCK_VARS (block) = decls;
14487 BLOCK_SUBBLOCKS (block) = subblocks;
c7e4ee3a 14488 }
5ff904cd 14489
c7e4ee3a 14490 /* In each subblock, record that this is its superior. */
5ff904cd 14491
c7e4ee3a
CB
14492 for (link = subblocks; link; link = TREE_CHAIN (link))
14493 BLOCK_SUPERCONTEXT (link) = block;
5ff904cd 14494
c7e4ee3a 14495 /* Clear out the meanings of the local variables of this level. */
5ff904cd 14496
c7e4ee3a 14497 for (link = decls; link; link = TREE_CHAIN (link))
5ff904cd 14498 {
c7e4ee3a
CB
14499 if (DECL_NAME (link) != 0)
14500 {
14501 /* If the ident. was used or addressed via a local extern decl,
14502 don't forget that fact. */
14503 if (DECL_EXTERNAL (link))
14504 {
14505 if (TREE_USED (link))
14506 TREE_USED (DECL_NAME (link)) = 1;
14507 if (TREE_ADDRESSABLE (link))
14508 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (link)) = 1;
14509 }
14510 IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = 0;
14511 }
5ff904cd 14512 }
5ff904cd 14513
c7e4ee3a
CB
14514 /* If the level being exited is the top level of a function,
14515 check over all the labels, and clear out the current
14516 (function local) meanings of their names. */
5ff904cd 14517
c7e4ee3a 14518 if (functionbody)
5ff904cd 14519 {
c7e4ee3a
CB
14520 /* If this is the top level block of a function,
14521 the vars are the function's parameters.
14522 Don't leave them in the BLOCK because they are
14523 found in the FUNCTION_DECL instead. */
14524
14525 BLOCK_VARS (block) = 0;
5ff904cd
JL
14526 }
14527
c7e4ee3a
CB
14528 /* Pop the current level, and free the structure for reuse. */
14529
14530 {
14531 register struct binding_level *level = current_binding_level;
14532 current_binding_level = current_binding_level->level_chain;
14533
14534 level->level_chain = free_binding_level;
14535 free_binding_level = level;
14536 }
14537
14538 /* Dispose of the block that we just made inside some higher level. */
14539 if (functionbody
14540 && current_function_decl != error_mark_node)
14541 DECL_INITIAL (current_function_decl) = block;
14542 else if (block)
5ff904cd 14543 {
c7e4ee3a
CB
14544 if (!block_previously_created)
14545 current_binding_level->blocks
14546 = chainon (current_binding_level->blocks, block);
5ff904cd 14547 }
c7e4ee3a
CB
14548 /* If we did not make a block for the level just exited,
14549 any blocks made for inner levels
14550 (since they cannot be recorded as subblocks in that level)
14551 must be carried forward so they will later become subblocks
14552 of something else. */
14553 else if (subblocks)
14554 current_binding_level->blocks
14555 = chainon (current_binding_level->blocks, subblocks);
5ff904cd 14556
c7e4ee3a
CB
14557 if (block)
14558 TREE_USED (block) = 1;
14559 return block;
5ff904cd
JL
14560}
14561
5d69f816
NB
14562static void
14563ffe_print_identifier (file, node, indent)
c7e4ee3a
CB
14564 FILE *file;
14565 tree node;
14566 int indent;
14567{
14568 print_node (file, "global", IDENTIFIER_GLOBAL_VALUE (node), indent + 4);
14569 print_node (file, "local", IDENTIFIER_LOCAL_VALUE (node), indent + 4);
14570}
5ff904cd 14571
c7e4ee3a
CB
14572/* Record a decl-node X as belonging to the current lexical scope.
14573 Check for errors (such as an incompatible declaration for the same
14574 name already seen in the same scope).
5ff904cd 14575
c7e4ee3a
CB
14576 Returns either X or an old decl for the same name.
14577 If an old decl is returned, it may have been smashed
14578 to agree with what X says. */
5ff904cd 14579
c7e4ee3a
CB
14580tree
14581pushdecl (x)
14582 tree x;
14583{
14584 register tree t;
14585 register tree name = DECL_NAME (x);
14586 register struct binding_level *b = current_binding_level;
5ff904cd 14587
c7e4ee3a
CB
14588 if ((TREE_CODE (x) == FUNCTION_DECL)
14589 && (DECL_INITIAL (x) == 0)
14590 && DECL_EXTERNAL (x))
14591 DECL_CONTEXT (x) = NULL_TREE;
56a0044b 14592 else
c7e4ee3a
CB
14593 DECL_CONTEXT (x) = current_function_decl;
14594
14595 if (name)
56a0044b 14596 {
c7e4ee3a
CB
14597 if (IDENTIFIER_INVENTED (name))
14598 {
c7e4ee3a 14599 DECL_ARTIFICIAL (x) = 1;
c7e4ee3a
CB
14600 DECL_IN_SYSTEM_HEADER (x) = 1;
14601 }
5ff904cd 14602
c7e4ee3a 14603 t = lookup_name_current_level (name);
5ff904cd 14604
c7e4ee3a 14605 assert ((t == NULL_TREE) || (DECL_CONTEXT (x) == NULL_TREE));
5ff904cd 14606
c7e4ee3a
CB
14607 /* Don't push non-parms onto list for parms until we understand
14608 why we're doing this and whether it works. */
56a0044b 14609
c7e4ee3a
CB
14610 assert ((b == global_binding_level)
14611 || !ffecom_transform_only_dummies_
14612 || TREE_CODE (x) == PARM_DECL);
5ff904cd 14613
c7e4ee3a
CB
14614 if ((t != NULL_TREE) && duplicate_decls (x, t))
14615 return t;
5ff904cd 14616
c7e4ee3a
CB
14617 /* If we are processing a typedef statement, generate a whole new
14618 ..._TYPE node (which will be just an variant of the existing
14619 ..._TYPE node with identical properties) and then install the
14620 TYPE_DECL node generated to represent the typedef name as the
14621 TYPE_NAME of this brand new (duplicate) ..._TYPE node.
5ff904cd 14622
c7e4ee3a
CB
14623 The whole point here is to end up with a situation where each and every
14624 ..._TYPE node the compiler creates will be uniquely associated with
14625 AT MOST one node representing a typedef name. This way, even though
14626 the compiler substitutes corresponding ..._TYPE nodes for TYPE_DECL
14627 (i.e. "typedef name") nodes very early on, later parts of the
14628 compiler can always do the reverse translation and get back the
14629 corresponding typedef name. For example, given:
5ff904cd 14630
c7e4ee3a 14631 typedef struct S MY_TYPE; MY_TYPE object;
5ff904cd 14632
c7e4ee3a
CB
14633 Later parts of the compiler might only know that `object' was of type
14634 `struct S' if it were not for code just below. With this code
14635 however, later parts of the compiler see something like:
5ff904cd 14636
c7e4ee3a 14637 struct S' == struct S typedef struct S' MY_TYPE; struct S' object;
5ff904cd 14638
c7e4ee3a
CB
14639 And they can then deduce (from the node for type struct S') that the
14640 original object declaration was:
5ff904cd 14641
c7e4ee3a 14642 MY_TYPE object;
5ff904cd 14643
c7e4ee3a
CB
14644 Being able to do this is important for proper support of protoize, and
14645 also for generating precise symbolic debugging information which
14646 takes full account of the programmer's (typedef) vocabulary.
5ff904cd 14647
c7e4ee3a
CB
14648 Obviously, we don't want to generate a duplicate ..._TYPE node if the
14649 TYPE_DECL node that we are now processing really represents a
14650 standard built-in type.
5ff904cd 14651
c7e4ee3a
CB
14652 Since all standard types are effectively declared at line zero in the
14653 source file, we can easily check to see if we are working on a
14654 standard type by checking the current value of lineno. */
14655
14656 if (TREE_CODE (x) == TYPE_DECL)
14657 {
14658 if (DECL_SOURCE_LINE (x) == 0)
14659 {
14660 if (TYPE_NAME (TREE_TYPE (x)) == 0)
14661 TYPE_NAME (TREE_TYPE (x)) = x;
14662 }
14663 else if (TREE_TYPE (x) != error_mark_node)
14664 {
14665 tree tt = TREE_TYPE (x);
14666
14667 tt = build_type_copy (tt);
14668 TYPE_NAME (tt) = x;
14669 TREE_TYPE (x) = tt;
14670 }
14671 }
5ff904cd 14672
c7e4ee3a
CB
14673 /* This name is new in its binding level. Install the new declaration
14674 and return it. */
14675 if (b == global_binding_level)
14676 IDENTIFIER_GLOBAL_VALUE (name) = x;
14677 else
14678 IDENTIFIER_LOCAL_VALUE (name) = x;
14679 }
5ff904cd 14680
c7e4ee3a
CB
14681 /* Put decls on list in reverse order. We will reverse them later if
14682 necessary. */
14683 TREE_CHAIN (x) = b->names;
14684 b->names = x;
5ff904cd 14685
c7e4ee3a 14686 return x;
5ff904cd
JL
14687}
14688
c7e4ee3a 14689/* Nonzero if the current level needs to have a BLOCK made. */
5ff904cd 14690
c7e4ee3a
CB
14691static int
14692kept_level_p ()
5ff904cd 14693{
c7e4ee3a
CB
14694 tree decl;
14695
14696 for (decl = current_binding_level->names;
14697 decl;
14698 decl = TREE_CHAIN (decl))
14699 {
14700 if (TREE_USED (decl) || TREE_CODE (decl) != VAR_DECL
14701 || (DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl)))
14702 /* Currently, there aren't supposed to be non-artificial names
14703 at other than the top block for a function -- they're
14704 believed to always be temps. But it's wise to check anyway. */
14705 return 1;
14706 }
14707 return 0;
5ff904cd
JL
14708}
14709
c7e4ee3a
CB
14710/* Enter a new binding level.
14711 If TAG_TRANSPARENT is nonzero, do so only for the name space of variables,
14712 not for that of tags. */
5ff904cd
JL
14713
14714void
c7e4ee3a
CB
14715pushlevel (tag_transparent)
14716 int tag_transparent;
5ff904cd 14717{
c7e4ee3a 14718 register struct binding_level *newlevel = NULL_BINDING_LEVEL;
5ff904cd 14719
c7e4ee3a 14720 assert (! tag_transparent);
5ff904cd 14721
c7e4ee3a
CB
14722 if (current_binding_level == global_binding_level)
14723 {
14724 named_labels = 0;
14725 }
5ff904cd 14726
c7e4ee3a 14727 /* Reuse or create a struct for this binding level. */
5ff904cd 14728
c7e4ee3a 14729 if (free_binding_level)
77f77701 14730 {
c7e4ee3a
CB
14731 newlevel = free_binding_level;
14732 free_binding_level = free_binding_level->level_chain;
77f77701
DB
14733 }
14734 else
c7e4ee3a
CB
14735 {
14736 newlevel = make_binding_level ();
14737 }
77f77701 14738
c7e4ee3a
CB
14739 /* Add this level to the front of the chain (stack) of levels that
14740 are active. */
71b5e532 14741
c7e4ee3a
CB
14742 *newlevel = clear_binding_level;
14743 newlevel->level_chain = current_binding_level;
14744 current_binding_level = newlevel;
5ff904cd
JL
14745}
14746
c7e4ee3a
CB
14747/* Set the BLOCK node for the innermost scope
14748 (the one we are currently in). */
77f77701 14749
5ff904cd 14750void
c7e4ee3a
CB
14751set_block (block)
14752 register tree block;
5ff904cd 14753{
c7e4ee3a 14754 current_binding_level->this_block = block;
9b58f739
RK
14755 current_binding_level->names = chainon (current_binding_level->names,
14756 BLOCK_VARS (block));
14757 current_binding_level->blocks = chainon (current_binding_level->blocks,
14758 BLOCK_SUBBLOCKS (block));
5ff904cd
JL
14759}
14760
ceef8ce4
NB
14761static tree
14762ffe_signed_or_unsigned_type (unsignedp, type)
c7e4ee3a
CB
14763 int unsignedp;
14764 tree type;
5ff904cd 14765{
c7e4ee3a 14766 tree type2;
5ff904cd 14767
c7e4ee3a
CB
14768 if (! INTEGRAL_TYPE_P (type))
14769 return type;
14770 if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node))
14771 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
14772 if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
14773 return unsignedp ? unsigned_type_node : integer_type_node;
14774 if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node))
14775 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
14776 if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node))
14777 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
14778 if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node))
14779 return (unsignedp ? long_long_unsigned_type_node
14780 : long_long_integer_type_node);
5ff904cd 14781
b0c48229 14782 type2 = ffe_type_for_size (TYPE_PRECISION (type), unsignedp);
c7e4ee3a
CB
14783 if (type2 == NULL_TREE)
14784 return type;
f84639ba 14785
c7e4ee3a 14786 return type2;
5ff904cd
JL
14787}
14788
ceef8ce4
NB
14789static tree
14790ffe_signed_type (type)
c7e4ee3a 14791 tree type;
5ff904cd 14792{
c7e4ee3a
CB
14793 tree type1 = TYPE_MAIN_VARIANT (type);
14794 ffeinfoKindtype kt;
14795 tree type2;
5ff904cd 14796
c7e4ee3a
CB
14797 if (type1 == unsigned_char_type_node || type1 == char_type_node)
14798 return signed_char_type_node;
14799 if (type1 == unsigned_type_node)
14800 return integer_type_node;
14801 if (type1 == short_unsigned_type_node)
14802 return short_integer_type_node;
14803 if (type1 == long_unsigned_type_node)
14804 return long_integer_type_node;
14805 if (type1 == long_long_unsigned_type_node)
14806 return long_long_integer_type_node;
14807#if 0 /* gcc/c-* files only */
14808 if (type1 == unsigned_intDI_type_node)
14809 return intDI_type_node;
14810 if (type1 == unsigned_intSI_type_node)
14811 return intSI_type_node;
14812 if (type1 == unsigned_intHI_type_node)
14813 return intHI_type_node;
14814 if (type1 == unsigned_intQI_type_node)
14815 return intQI_type_node;
14816#endif
5ff904cd 14817
b0c48229 14818 type2 = ffe_type_for_size (TYPE_PRECISION (type1), 0);
c7e4ee3a
CB
14819 if (type2 != NULL_TREE)
14820 return type2;
5ff904cd 14821
c7e4ee3a
CB
14822 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
14823 {
14824 type2 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
5ff904cd 14825
c7e4ee3a
CB
14826 if (type1 == type2)
14827 return ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
14828 }
14829
14830 return type;
5ff904cd
JL
14831}
14832
c7e4ee3a
CB
14833/* Prepare expr to be an argument of a TRUTH_NOT_EXPR,
14834 or validate its data type for an `if' or `while' statement or ?..: exp.
14835
14836 This preparation consists of taking the ordinary
14837 representation of an expression expr and producing a valid tree
14838 boolean expression describing whether expr is nonzero. We could
14839 simply always do build_binary_op (NE_EXPR, expr, integer_zero_node, 1),
14840 but we optimize comparisons, &&, ||, and !.
14841
14842 The resulting type should always be `integer_type_node'. */
5ff904cd
JL
14843
14844tree
c7e4ee3a
CB
14845truthvalue_conversion (expr)
14846 tree expr;
5ff904cd 14847{
c7e4ee3a
CB
14848 if (TREE_CODE (expr) == ERROR_MARK)
14849 return expr;
5ff904cd 14850
c7e4ee3a
CB
14851#if 0 /* This appears to be wrong for C++. */
14852 /* These really should return error_mark_node after 2.4 is stable.
14853 But not all callers handle ERROR_MARK properly. */
14854 switch (TREE_CODE (TREE_TYPE (expr)))
14855 {
14856 case RECORD_TYPE:
14857 error ("struct type value used where scalar is required");
14858 return integer_zero_node;
5ff904cd 14859
c7e4ee3a
CB
14860 case UNION_TYPE:
14861 error ("union type value used where scalar is required");
14862 return integer_zero_node;
5ff904cd 14863
c7e4ee3a
CB
14864 case ARRAY_TYPE:
14865 error ("array type value used where scalar is required");
14866 return integer_zero_node;
5ff904cd 14867
c7e4ee3a
CB
14868 default:
14869 break;
14870 }
14871#endif /* 0 */
5ff904cd 14872
c7e4ee3a
CB
14873 switch (TREE_CODE (expr))
14874 {
14875 /* It is simpler and generates better code to have only TRUTH_*_EXPR
14876 or comparison expressions as truth values at this level. */
14877#if 0
14878 case COMPONENT_REF:
14879 /* A one-bit unsigned bit-field is already acceptable. */
14880 if (1 == TREE_INT_CST_LOW (DECL_SIZE (TREE_OPERAND (expr, 1)))
14881 && TREE_UNSIGNED (TREE_OPERAND (expr, 1)))
14882 return expr;
14883 break;
14884#endif
14885
14886 case EQ_EXPR:
14887 /* It is simpler and generates better code to have only TRUTH_*_EXPR
14888 or comparison expressions as truth values at this level. */
14889#if 0
14890 if (integer_zerop (TREE_OPERAND (expr, 1)))
14891 return build_unary_op (TRUTH_NOT_EXPR, TREE_OPERAND (expr, 0), 0);
14892#endif
14893 case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
14894 case TRUTH_ANDIF_EXPR:
14895 case TRUTH_ORIF_EXPR:
14896 case TRUTH_AND_EXPR:
14897 case TRUTH_OR_EXPR:
14898 case TRUTH_XOR_EXPR:
14899 TREE_TYPE (expr) = integer_type_node;
14900 return expr;
5ff904cd 14901
c7e4ee3a
CB
14902 case ERROR_MARK:
14903 return expr;
5ff904cd 14904
c7e4ee3a
CB
14905 case INTEGER_CST:
14906 return integer_zerop (expr) ? integer_zero_node : integer_one_node;
5ff904cd 14907
c7e4ee3a
CB
14908 case REAL_CST:
14909 return real_zerop (expr) ? integer_zero_node : integer_one_node;
5ff904cd 14910
c7e4ee3a
CB
14911 case ADDR_EXPR:
14912 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 0)))
14913 return build (COMPOUND_EXPR, integer_type_node,
14914 TREE_OPERAND (expr, 0), integer_one_node);
14915 else
14916 return integer_one_node;
5ff904cd 14917
c7e4ee3a
CB
14918 case COMPLEX_EXPR:
14919 return ffecom_2 ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))
14920 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
14921 integer_type_node,
14922 truthvalue_conversion (TREE_OPERAND (expr, 0)),
14923 truthvalue_conversion (TREE_OPERAND (expr, 1)));
5ff904cd 14924
c7e4ee3a
CB
14925 case NEGATE_EXPR:
14926 case ABS_EXPR:
14927 case FLOAT_EXPR:
14928 case FFS_EXPR:
14929 /* These don't change whether an object is non-zero or zero. */
14930 return truthvalue_conversion (TREE_OPERAND (expr, 0));
5ff904cd 14931
c7e4ee3a
CB
14932 case LROTATE_EXPR:
14933 case RROTATE_EXPR:
14934 /* These don't change whether an object is zero or non-zero, but
14935 we can't ignore them if their second arg has side-effects. */
14936 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)))
14937 return build (COMPOUND_EXPR, integer_type_node, TREE_OPERAND (expr, 1),
14938 truthvalue_conversion (TREE_OPERAND (expr, 0)));
14939 else
14940 return truthvalue_conversion (TREE_OPERAND (expr, 0));
5ff904cd 14941
c7e4ee3a
CB
14942 case COND_EXPR:
14943 /* Distribute the conversion into the arms of a COND_EXPR. */
14944 return fold (build (COND_EXPR, integer_type_node, TREE_OPERAND (expr, 0),
14945 truthvalue_conversion (TREE_OPERAND (expr, 1)),
14946 truthvalue_conversion (TREE_OPERAND (expr, 2))));
5ff904cd 14947
c7e4ee3a
CB
14948 case CONVERT_EXPR:
14949 /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
14950 since that affects how `default_conversion' will behave. */
14951 if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE
14952 || TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)
14953 break;
14954 /* fall through... */
14955 case NOP_EXPR:
14956 /* If this is widening the argument, we can ignore it. */
14957 if (TYPE_PRECISION (TREE_TYPE (expr))
14958 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
14959 return truthvalue_conversion (TREE_OPERAND (expr, 0));
14960 break;
5ff904cd 14961
c7e4ee3a
CB
14962 case MINUS_EXPR:
14963 /* With IEEE arithmetic, x - x may not equal 0, so we can't optimize
14964 this case. */
14965 if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
14966 && TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE)
14967 break;
14968 /* fall through... */
14969 case BIT_XOR_EXPR:
14970 /* This and MINUS_EXPR can be changed into a comparison of the
14971 two objects. */
14972 if (TREE_TYPE (TREE_OPERAND (expr, 0))
14973 == TREE_TYPE (TREE_OPERAND (expr, 1)))
14974 return ffecom_2 (NE_EXPR, integer_type_node,
14975 TREE_OPERAND (expr, 0),
14976 TREE_OPERAND (expr, 1));
14977 return ffecom_2 (NE_EXPR, integer_type_node,
14978 TREE_OPERAND (expr, 0),
14979 fold (build1 (NOP_EXPR,
14980 TREE_TYPE (TREE_OPERAND (expr, 0)),
14981 TREE_OPERAND (expr, 1))));
14982
14983 case BIT_AND_EXPR:
14984 if (integer_onep (TREE_OPERAND (expr, 1)))
14985 return expr;
14986 break;
14987
14988 case MODIFY_EXPR:
14989#if 0 /* No such thing in Fortran. */
14990 if (warn_parentheses && C_EXP_ORIGINAL_CODE (expr) == MODIFY_EXPR)
14991 warning ("suggest parentheses around assignment used as truth value");
14992#endif
14993 break;
14994
14995 default:
14996 break;
5ff904cd
JL
14997 }
14998
c7e4ee3a
CB
14999 if (TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE)
15000 return (ffecom_2
15001 ((TREE_SIDE_EFFECTS (expr)
15002 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
15003 integer_type_node,
15004 truthvalue_conversion (ffecom_1 (REALPART_EXPR,
15005 TREE_TYPE (TREE_TYPE (expr)),
15006 expr)),
15007 truthvalue_conversion (ffecom_1 (IMAGPART_EXPR,
15008 TREE_TYPE (TREE_TYPE (expr)),
15009 expr))));
15010
15011 return ffecom_2 (NE_EXPR, integer_type_node,
15012 expr,
15013 convert (TREE_TYPE (expr), integer_zero_node));
15014}
15015
b0c48229
NB
15016static tree
15017ffe_type_for_mode (mode, unsignedp)
c7e4ee3a
CB
15018 enum machine_mode mode;
15019 int unsignedp;
15020{
15021 int i;
15022 int j;
15023 tree t;
5ff904cd 15024
c7e4ee3a
CB
15025 if (mode == TYPE_MODE (integer_type_node))
15026 return unsignedp ? unsigned_type_node : integer_type_node;
5ff904cd 15027
c7e4ee3a
CB
15028 if (mode == TYPE_MODE (signed_char_type_node))
15029 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
5ff904cd 15030
c7e4ee3a
CB
15031 if (mode == TYPE_MODE (short_integer_type_node))
15032 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
5ff904cd 15033
c7e4ee3a
CB
15034 if (mode == TYPE_MODE (long_integer_type_node))
15035 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
5ff904cd 15036
c7e4ee3a
CB
15037 if (mode == TYPE_MODE (long_long_integer_type_node))
15038 return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node;
5ff904cd 15039
fed3cef0
RK
15040#if HOST_BITS_PER_WIDE_INT >= 64
15041 if (mode == TYPE_MODE (intTI_type_node))
15042 return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
15043#endif
15044
c7e4ee3a
CB
15045 if (mode == TYPE_MODE (float_type_node))
15046 return float_type_node;
5ff904cd 15047
c7e4ee3a
CB
15048 if (mode == TYPE_MODE (double_type_node))
15049 return double_type_node;
5ff904cd 15050
c7e4ee3a
CB
15051 if (mode == TYPE_MODE (build_pointer_type (char_type_node)))
15052 return build_pointer_type (char_type_node);
5ff904cd 15053
c7e4ee3a
CB
15054 if (mode == TYPE_MODE (build_pointer_type (integer_type_node)))
15055 return build_pointer_type (integer_type_node);
5ff904cd 15056
c7e4ee3a
CB
15057 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
15058 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
15059 {
15060 if (((t = ffecom_tree_type[i][j]) != NULL_TREE)
15061 && (mode == TYPE_MODE (t)))
15062 {
15063 if ((i == FFEINFO_basictypeINTEGER) && unsignedp)
15064 return ffecom_tree_type[FFEINFO_basictypeHOLLERITH][j];
15065 else
15066 return t;
15067 }
15068 }
5ff904cd 15069
c7e4ee3a 15070 return 0;
5ff904cd
JL
15071}
15072
b0c48229
NB
15073static tree
15074ffe_type_for_size (bits, unsignedp)
c7e4ee3a
CB
15075 unsigned bits;
15076 int unsignedp;
5ff904cd 15077{
c7e4ee3a
CB
15078 ffeinfoKindtype kt;
15079 tree type_node;
5ff904cd 15080
c7e4ee3a
CB
15081 if (bits == TYPE_PRECISION (integer_type_node))
15082 return unsignedp ? unsigned_type_node : integer_type_node;
5ff904cd 15083
c7e4ee3a
CB
15084 if (bits == TYPE_PRECISION (signed_char_type_node))
15085 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
5ff904cd 15086
c7e4ee3a
CB
15087 if (bits == TYPE_PRECISION (short_integer_type_node))
15088 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
5ff904cd 15089
c7e4ee3a
CB
15090 if (bits == TYPE_PRECISION (long_integer_type_node))
15091 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
5ff904cd 15092
c7e4ee3a
CB
15093 if (bits == TYPE_PRECISION (long_long_integer_type_node))
15094 return (unsignedp ? long_long_unsigned_type_node
15095 : long_long_integer_type_node);
5ff904cd 15096
c7e4ee3a 15097 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
5ff904cd 15098 {
c7e4ee3a 15099 type_node = ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
5ff904cd 15100
c7e4ee3a
CB
15101 if ((type_node != NULL_TREE) && (bits == TYPE_PRECISION (type_node)))
15102 return unsignedp ? ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt]
15103 : type_node;
15104 }
5ff904cd 15105
c7e4ee3a
CB
15106 return 0;
15107}
5ff904cd 15108
ceef8ce4
NB
15109static tree
15110ffe_unsigned_type (type)
c7e4ee3a
CB
15111 tree type;
15112{
15113 tree type1 = TYPE_MAIN_VARIANT (type);
15114 ffeinfoKindtype kt;
15115 tree type2;
5ff904cd 15116
c7e4ee3a
CB
15117 if (type1 == signed_char_type_node || type1 == char_type_node)
15118 return unsigned_char_type_node;
15119 if (type1 == integer_type_node)
15120 return unsigned_type_node;
15121 if (type1 == short_integer_type_node)
15122 return short_unsigned_type_node;
15123 if (type1 == long_integer_type_node)
15124 return long_unsigned_type_node;
15125 if (type1 == long_long_integer_type_node)
15126 return long_long_unsigned_type_node;
15127#if 0 /* gcc/c-* files only */
15128 if (type1 == intDI_type_node)
15129 return unsigned_intDI_type_node;
15130 if (type1 == intSI_type_node)
15131 return unsigned_intSI_type_node;
15132 if (type1 == intHI_type_node)
15133 return unsigned_intHI_type_node;
15134 if (type1 == intQI_type_node)
15135 return unsigned_intQI_type_node;
15136#endif
5ff904cd 15137
b0c48229 15138 type2 = ffe_type_for_size (TYPE_PRECISION (type1), 1);
c7e4ee3a
CB
15139 if (type2 != NULL_TREE)
15140 return type2;
5ff904cd 15141
c7e4ee3a
CB
15142 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
15143 {
15144 type2 = ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
5ff904cd 15145
c7e4ee3a
CB
15146 if (type1 == type2)
15147 return ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
15148 }
5ff904cd 15149
c7e4ee3a
CB
15150 return type;
15151}
5ff904cd 15152
4f0ade92
NB
15153static void
15154ffe_mark_tree (t)
15155 tree t;
7189a4b0
GK
15156{
15157 if (TREE_CODE (t) == IDENTIFIER_NODE)
15158 {
15159 struct lang_identifier *i = (struct lang_identifier *) t;
15160 ggc_mark_tree (IDENTIFIER_GLOBAL_VALUE (i));
15161 ggc_mark_tree (IDENTIFIER_LOCAL_VALUE (i));
15162 ggc_mark_tree (IDENTIFIER_LABEL_VALUE (i));
15163 }
15164 else if (TYPE_P (t) && TYPE_LANG_SPECIFIC (t))
15165 ggc_mark (TYPE_LANG_SPECIFIC (t));
15166}
c7e4ee3a 15167\f
c7e4ee3a 15168/* From gcc/cccp.c, the code to handle -I. */
5ff904cd 15169
c7e4ee3a
CB
15170/* Skip leading "./" from a directory name.
15171 This may yield the empty string, which represents the current directory. */
5ff904cd 15172
c7e4ee3a
CB
15173static const char *
15174skip_redundant_dir_prefix (const char *dir)
15175{
15176 while (dir[0] == '.' && dir[1] == '/')
15177 for (dir += 2; *dir == '/'; dir++)
15178 continue;
15179 if (dir[0] == '.' && !dir[1])
15180 dir++;
15181 return dir;
15182}
5ff904cd 15183
c7e4ee3a
CB
15184/* The file_name_map structure holds a mapping of file names for a
15185 particular directory. This mapping is read from the file named
15186 FILE_NAME_MAP_FILE in that directory. Such a file can be used to
15187 map filenames on a file system with severe filename restrictions,
15188 such as DOS. The format of the file name map file is just a series
15189 of lines with two tokens on each line. The first token is the name
15190 to map, and the second token is the actual name to use. */
5ff904cd 15191
c7e4ee3a
CB
15192struct file_name_map
15193{
15194 struct file_name_map *map_next;
15195 char *map_from;
15196 char *map_to;
15197};
5ff904cd 15198
c7e4ee3a 15199#define FILE_NAME_MAP_FILE "header.gcc"
5ff904cd 15200
c7e4ee3a
CB
15201/* Current maximum length of directory names in the search path
15202 for include files. (Altered as we get more of them.) */
5ff904cd 15203
c7e4ee3a 15204static int max_include_len = 0;
5ff904cd 15205
c7e4ee3a
CB
15206struct file_name_list
15207 {
15208 struct file_name_list *next;
15209 char *fname;
15210 /* Mapping of file names for this directory. */
15211 struct file_name_map *name_map;
15212 /* Non-zero if name_map is valid. */
15213 int got_name_map;
15214 };
5ff904cd 15215
c7e4ee3a
CB
15216static struct file_name_list *include = NULL; /* First dir to search */
15217static struct file_name_list *last_include = NULL; /* Last in chain */
5ff904cd 15218
c7e4ee3a
CB
15219/* I/O buffer structure.
15220 The `fname' field is nonzero for source files and #include files
15221 and for the dummy text used for -D and -U.
15222 It is zero for rescanning results of macro expansion
15223 and for expanding macro arguments. */
15224#define INPUT_STACK_MAX 400
15225static struct file_buf {
b0791fa9 15226 const char *fname;
c7e4ee3a 15227 /* Filename specified with #line command. */
b0791fa9 15228 const char *nominal_fname;
c7e4ee3a
CB
15229 /* Record where in the search path this file was found.
15230 For #include_next. */
15231 struct file_name_list *dir;
15232 ffewhereLine line;
15233 ffewhereColumn column;
15234} instack[INPUT_STACK_MAX];
5ff904cd 15235
c7e4ee3a
CB
15236static int last_error_tick = 0; /* Incremented each time we print it. */
15237static int input_file_stack_tick = 0; /* Incremented when status changes. */
5ff904cd 15238
c7e4ee3a
CB
15239/* Current nesting level of input sources.
15240 `instack[indepth]' is the level currently being read. */
15241static int indepth = -1;
5ff904cd 15242
c7e4ee3a 15243typedef struct file_buf FILE_BUF;
5ff904cd 15244
c7e4ee3a
CB
15245/* Nonzero means -I- has been seen,
15246 so don't look for #include "foo" the source-file directory. */
15247static int ignore_srcdir;
5ff904cd 15248
c7e4ee3a
CB
15249#ifndef INCLUDE_LEN_FUDGE
15250#define INCLUDE_LEN_FUDGE 0
15251#endif
5ff904cd 15252
c7e4ee3a
CB
15253static void append_include_chain (struct file_name_list *first,
15254 struct file_name_list *last);
15255static FILE *open_include_file (char *filename,
15256 struct file_name_list *searchptr);
15257static void print_containing_files (ffebadSeverity sev);
c7e4ee3a
CB
15258static char *read_filename_string (int ch, FILE *f);
15259static struct file_name_map *read_name_map (const char *dirname);
5ff904cd 15260
c7e4ee3a
CB
15261/* Append a chain of `struct file_name_list's
15262 to the end of the main include chain.
15263 FIRST is the beginning of the chain to append, and LAST is the end. */
5ff904cd 15264
c7e4ee3a
CB
15265static void
15266append_include_chain (first, last)
15267 struct file_name_list *first, *last;
5ff904cd 15268{
c7e4ee3a 15269 struct file_name_list *dir;
5ff904cd 15270
c7e4ee3a
CB
15271 if (!first || !last)
15272 return;
5ff904cd 15273
c7e4ee3a
CB
15274 if (include == 0)
15275 include = first;
15276 else
15277 last_include->next = first;
5ff904cd 15278
c7e4ee3a
CB
15279 for (dir = first; ; dir = dir->next) {
15280 int len = strlen (dir->fname) + INCLUDE_LEN_FUDGE;
15281 if (len > max_include_len)
15282 max_include_len = len;
15283 if (dir == last)
15284 break;
15285 }
15286
15287 last->next = NULL;
15288 last_include = last;
5ff904cd
JL
15289}
15290
c7e4ee3a
CB
15291/* Try to open include file FILENAME. SEARCHPTR is the directory
15292 being tried from the include file search path. This function maps
15293 filenames on file systems based on information read by
15294 read_name_map. */
15295
15296static FILE *
15297open_include_file (filename, searchptr)
15298 char *filename;
15299 struct file_name_list *searchptr;
5ff904cd 15300{
c7e4ee3a
CB
15301 register struct file_name_map *map;
15302 register char *from;
15303 char *p, *dir;
5ff904cd 15304
c7e4ee3a
CB
15305 if (searchptr && ! searchptr->got_name_map)
15306 {
15307 searchptr->name_map = read_name_map (searchptr->fname
15308 ? searchptr->fname : ".");
15309 searchptr->got_name_map = 1;
15310 }
5ff904cd 15311
c7e4ee3a
CB
15312 /* First check the mapping for the directory we are using. */
15313 if (searchptr && searchptr->name_map)
15314 {
15315 from = filename;
15316 if (searchptr->fname)
15317 from += strlen (searchptr->fname) + 1;
15318 for (map = searchptr->name_map; map; map = map->map_next)
15319 {
15320 if (! strcmp (map->map_from, from))
15321 {
15322 /* Found a match. */
15323 return fopen (map->map_to, "r");
15324 }
15325 }
15326 }
5ff904cd 15327
c7e4ee3a
CB
15328 /* Try to find a mapping file for the particular directory we are
15329 looking in. Thus #include <sys/types.h> will look up sys/types.h
15330 in /usr/include/header.gcc and look up types.h in
15331 /usr/include/sys/header.gcc. */
9473c522 15332 p = strrchr (filename, '/');
c7e4ee3a 15333#ifdef DIR_SEPARATOR
9473c522 15334 if (! p) p = strrchr (filename, DIR_SEPARATOR);
c7e4ee3a 15335 else {
9473c522 15336 char *tmp = strrchr (filename, DIR_SEPARATOR);
c7e4ee3a
CB
15337 if (tmp != NULL && tmp > p) p = tmp;
15338 }
15339#endif
15340 if (! p)
15341 p = filename;
15342 if (searchptr
15343 && searchptr->fname
15344 && strlen (searchptr->fname) == (size_t) (p - filename)
15345 && ! strncmp (searchptr->fname, filename, (int) (p - filename)))
15346 {
15347 /* FILENAME is in SEARCHPTR, which we've already checked. */
15348 return fopen (filename, "r");
15349 }
15350
15351 if (p == filename)
15352 {
15353 from = filename;
15354 map = read_name_map (".");
15355 }
15356 else
5ff904cd 15357 {
c7e4ee3a
CB
15358 dir = (char *) xmalloc (p - filename + 1);
15359 memcpy (dir, filename, p - filename);
15360 dir[p - filename] = '\0';
15361 from = p + 1;
15362 map = read_name_map (dir);
15363 free (dir);
5ff904cd 15364 }
c7e4ee3a
CB
15365 for (; map; map = map->map_next)
15366 if (! strcmp (map->map_from, from))
15367 return fopen (map->map_to, "r");
5ff904cd 15368
c7e4ee3a 15369 return fopen (filename, "r");
5ff904cd
JL
15370}
15371
c7e4ee3a
CB
15372/* Print the file names and line numbers of the #include
15373 commands which led to the current file. */
5ff904cd 15374
c7e4ee3a
CB
15375static void
15376print_containing_files (ffebadSeverity sev)
15377{
15378 FILE_BUF *ip = NULL;
15379 int i;
15380 int first = 1;
15381 const char *str1;
15382 const char *str2;
5ff904cd 15383
c7e4ee3a
CB
15384 /* If stack of files hasn't changed since we last printed
15385 this info, don't repeat it. */
15386 if (last_error_tick == input_file_stack_tick)
15387 return;
5ff904cd 15388
c7e4ee3a
CB
15389 for (i = indepth; i >= 0; i--)
15390 if (instack[i].fname != NULL) {
15391 ip = &instack[i];
15392 break;
15393 }
5ff904cd 15394
c7e4ee3a
CB
15395 /* Give up if we don't find a source file. */
15396 if (ip == NULL)
15397 return;
5ff904cd 15398
c7e4ee3a
CB
15399 /* Find the other, outer source files. */
15400 for (i--; i >= 0; i--)
15401 if (instack[i].fname != NULL)
15402 {
15403 ip = &instack[i];
15404 if (first)
15405 {
15406 first = 0;
15407 str1 = "In file included";
15408 }
15409 else
15410 {
15411 str1 = "... ...";
15412 }
5ff904cd 15413
c7e4ee3a
CB
15414 if (i == 1)
15415 str2 = ":";
15416 else
15417 str2 = "";
5ff904cd 15418
5987ca1c 15419 /* xgettext:no-c-format */
c7e4ee3a
CB
15420 ffebad_start_msg ("%A from %B at %0%C", sev);
15421 ffebad_here (0, ip->line, ip->column);
15422 ffebad_string (str1);
15423 ffebad_string (ip->nominal_fname);
15424 ffebad_string (str2);
15425 ffebad_finish ();
15426 }
5ff904cd 15427
c7e4ee3a
CB
15428 /* Record we have printed the status as of this time. */
15429 last_error_tick = input_file_stack_tick;
15430}
5ff904cd 15431
c7e4ee3a
CB
15432/* Read a space delimited string of unlimited length from a stdio
15433 file. */
5ff904cd 15434
c7e4ee3a
CB
15435static char *
15436read_filename_string (ch, f)
15437 int ch;
15438 FILE *f;
15439{
15440 char *alloc, *set;
15441 int len;
5ff904cd 15442
c7e4ee3a
CB
15443 len = 20;
15444 set = alloc = xmalloc (len + 1);
93a787dc 15445 if (! ISSPACE (ch))
c7e4ee3a
CB
15446 {
15447 *set++ = ch;
93a787dc 15448 while ((ch = getc (f)) != EOF && ! ISSPACE (ch))
c7e4ee3a
CB
15449 {
15450 if (set - alloc == len)
15451 {
15452 len *= 2;
15453 alloc = xrealloc (alloc, len + 1);
15454 set = alloc + len / 2;
15455 }
15456 *set++ = ch;
15457 }
15458 }
15459 *set = '\0';
15460 ungetc (ch, f);
15461 return alloc;
15462}
5ff904cd 15463
c7e4ee3a 15464/* Read the file name map file for DIRNAME. */
5ff904cd 15465
c7e4ee3a
CB
15466static struct file_name_map *
15467read_name_map (dirname)
15468 const char *dirname;
15469{
15470 /* This structure holds a linked list of file name maps, one per
15471 directory. */
15472 struct file_name_map_list
15473 {
15474 struct file_name_map_list *map_list_next;
15475 char *map_list_name;
15476 struct file_name_map *map_list_map;
15477 };
15478 static struct file_name_map_list *map_list;
15479 register struct file_name_map_list *map_list_ptr;
15480 char *name;
15481 FILE *f;
15482 size_t dirlen;
15483 int separator_needed;
5ff904cd 15484
c7e4ee3a 15485 dirname = skip_redundant_dir_prefix (dirname);
5ff904cd 15486
c7e4ee3a
CB
15487 for (map_list_ptr = map_list; map_list_ptr;
15488 map_list_ptr = map_list_ptr->map_list_next)
15489 if (! strcmp (map_list_ptr->map_list_name, dirname))
15490 return map_list_ptr->map_list_map;
5ff904cd 15491
c7e4ee3a
CB
15492 map_list_ptr = ((struct file_name_map_list *)
15493 xmalloc (sizeof (struct file_name_map_list)));
15494 map_list_ptr->map_list_name = xstrdup (dirname);
15495 map_list_ptr->map_list_map = NULL;
5ff904cd 15496
c7e4ee3a
CB
15497 dirlen = strlen (dirname);
15498 separator_needed = dirlen != 0 && dirname[dirlen - 1] != '/';
15499 name = (char *) xmalloc (dirlen + strlen (FILE_NAME_MAP_FILE) + 2);
15500 strcpy (name, dirname);
15501 name[dirlen] = '/';
15502 strcpy (name + dirlen + separator_needed, FILE_NAME_MAP_FILE);
15503 f = fopen (name, "r");
15504 free (name);
15505 if (!f)
15506 map_list_ptr->map_list_map = NULL;
15507 else
15508 {
15509 int ch;
5ff904cd 15510
c7e4ee3a
CB
15511 while ((ch = getc (f)) != EOF)
15512 {
15513 char *from, *to;
15514 struct file_name_map *ptr;
15515
93a787dc 15516 if (ISSPACE (ch))
c7e4ee3a
CB
15517 continue;
15518 from = read_filename_string (ch, f);
93a787dc 15519 while ((ch = getc (f)) != EOF && ISSPACE (ch) && ch != '\n')
c7e4ee3a
CB
15520 ;
15521 to = read_filename_string (ch, f);
5ff904cd 15522
c7e4ee3a
CB
15523 ptr = ((struct file_name_map *)
15524 xmalloc (sizeof (struct file_name_map)));
15525 ptr->map_from = from;
5ff904cd 15526
c7e4ee3a
CB
15527 /* Make the real filename absolute. */
15528 if (*to == '/')
15529 ptr->map_to = to;
15530 else
15531 {
15532 ptr->map_to = xmalloc (dirlen + strlen (to) + 2);
15533 strcpy (ptr->map_to, dirname);
15534 ptr->map_to[dirlen] = '/';
15535 strcpy (ptr->map_to + dirlen + separator_needed, to);
15536 free (to);
15537 }
5ff904cd 15538
c7e4ee3a
CB
15539 ptr->map_next = map_list_ptr->map_list_map;
15540 map_list_ptr->map_list_map = ptr;
5ff904cd 15541
c7e4ee3a
CB
15542 while ((ch = getc (f)) != '\n')
15543 if (ch == EOF)
15544 break;
15545 }
15546 fclose (f);
5ff904cd
JL
15547 }
15548
c7e4ee3a
CB
15549 map_list_ptr->map_list_next = map_list;
15550 map_list = map_list_ptr;
5ff904cd 15551
c7e4ee3a 15552 return map_list_ptr->map_list_map;
5ff904cd
JL
15553}
15554
c7e4ee3a 15555static void
b0791fa9 15556ffecom_file_ (const char *name)
5ff904cd 15557{
c7e4ee3a 15558 FILE_BUF *fp;
5ff904cd 15559
c7e4ee3a
CB
15560 /* Do partial setup of input buffer for the sake of generating
15561 early #line directives (when -g is in effect). */
5ff904cd 15562
c7e4ee3a
CB
15563 fp = &instack[++indepth];
15564 memset ((char *) fp, 0, sizeof (FILE_BUF));
15565 if (name == NULL)
15566 name = "";
15567 fp->nominal_fname = fp->fname = name;
15568}
5ff904cd 15569
c7e4ee3a
CB
15570static void
15571ffecom_close_include_ (FILE *f)
15572{
15573 fclose (f);
5ff904cd 15574
c7e4ee3a
CB
15575 indepth--;
15576 input_file_stack_tick++;
5ff904cd 15577
c7e4ee3a
CB
15578 ffewhere_line_kill (instack[indepth].line);
15579 ffewhere_column_kill (instack[indepth].column);
15580}
5ff904cd 15581
c7e4ee3a
CB
15582static int
15583ffecom_decode_include_option_ (char *spec)
15584{
15585 struct file_name_list *dirtmp;
15586
15587 if (! ignore_srcdir && !strcmp (spec, "-"))
15588 ignore_srcdir = 1;
15589 else
15590 {
15591 dirtmp = (struct file_name_list *)
15592 xmalloc (sizeof (struct file_name_list));
15593 dirtmp->next = 0; /* New one goes on the end */
400500c4 15594 dirtmp->fname = spec;
c7e4ee3a 15595 dirtmp->got_name_map = 0;
400500c4 15596 if (spec[0] == 0)
c725bd79 15597 error ("directory name must immediately follow -I");
400500c4
RK
15598 else
15599 append_include_chain (dirtmp, dirtmp);
c7e4ee3a
CB
15600 }
15601 return 1;
5ff904cd
JL
15602}
15603
c7e4ee3a
CB
15604/* Open INCLUDEd file. */
15605
15606static FILE *
15607ffecom_open_include_ (char *name, ffewhereLine l, ffewhereColumn c)
5ff904cd 15608{
c7e4ee3a
CB
15609 char *fbeg = name;
15610 size_t flen = strlen (fbeg);
15611 struct file_name_list *search_start = include; /* Chain of dirs to search */
15612 struct file_name_list dsp[1]; /* First in chain, if #include "..." */
15613 struct file_name_list *searchptr = 0;
15614 char *fname; /* Dynamically allocated fname buffer */
15615 FILE *f;
15616 FILE_BUF *fp;
5ff904cd 15617
c7e4ee3a
CB
15618 if (flen == 0)
15619 return NULL;
5ff904cd 15620
c7e4ee3a 15621 dsp[0].fname = NULL;
5ff904cd 15622
c7e4ee3a
CB
15623 /* If -I- was specified, don't search current dir, only spec'd ones. */
15624 if (!ignore_srcdir)
15625 {
15626 for (fp = &instack[indepth]; fp >= instack; fp--)
15627 {
15628 int n;
15629 char *ep;
b0791fa9 15630 const char *nam;
5ff904cd 15631
c7e4ee3a
CB
15632 if ((nam = fp->nominal_fname) != NULL)
15633 {
15634 /* Found a named file. Figure out dir of the file,
15635 and put it in front of the search list. */
15636 dsp[0].next = search_start;
15637 search_start = dsp;
15638#ifndef VMS
9473c522 15639 ep = strrchr (nam, '/');
c7e4ee3a 15640#ifdef DIR_SEPARATOR
9473c522 15641 if (ep == NULL) ep = strrchr (nam, DIR_SEPARATOR);
c7e4ee3a 15642 else {
9473c522 15643 char *tmp = strrchr (nam, DIR_SEPARATOR);
c7e4ee3a
CB
15644 if (tmp != NULL && tmp > ep) ep = tmp;
15645 }
15646#endif
15647#else /* VMS */
9473c522
JM
15648 ep = strrchr (nam, ']');
15649 if (ep == NULL) ep = strrchr (nam, '>');
15650 if (ep == NULL) ep = strrchr (nam, ':');
c7e4ee3a
CB
15651 if (ep != NULL) ep++;
15652#endif /* VMS */
15653 if (ep != NULL)
15654 {
15655 n = ep - nam;
15656 dsp[0].fname = (char *) xmalloc (n + 1);
15657 strncpy (dsp[0].fname, nam, n);
15658 dsp[0].fname[n] = '\0';
15659 if (n + INCLUDE_LEN_FUDGE > max_include_len)
15660 max_include_len = n + INCLUDE_LEN_FUDGE;
15661 }
15662 else
15663 dsp[0].fname = NULL; /* Current directory */
15664 dsp[0].got_name_map = 0;
15665 break;
15666 }
15667 }
15668 }
5ff904cd 15669
c7e4ee3a
CB
15670 /* Allocate this permanently, because it gets stored in the definitions
15671 of macros. */
15672 fname = xmalloc (max_include_len + flen + 4);
15673 /* + 2 above for slash and terminating null. */
15674 /* + 2 added for '.h' on VMS (to support '#include filename') (NOT USED
15675 for g77 yet). */
5ff904cd 15676
c7e4ee3a 15677 /* If specified file name is absolute, just open it. */
5ff904cd 15678
c7e4ee3a
CB
15679 if (*fbeg == '/'
15680#ifdef DIR_SEPARATOR
15681 || *fbeg == DIR_SEPARATOR
15682#endif
15683 )
15684 {
15685 strncpy (fname, (char *) fbeg, flen);
15686 fname[flen] = 0;
3e411c3f 15687 f = open_include_file (fname, NULL);
5ff904cd 15688 }
c7e4ee3a
CB
15689 else
15690 {
15691 f = NULL;
5ff904cd 15692
c7e4ee3a
CB
15693 /* Search directory path, trying to open the file.
15694 Copy each filename tried into FNAME. */
5ff904cd 15695
c7e4ee3a
CB
15696 for (searchptr = search_start; searchptr; searchptr = searchptr->next)
15697 {
15698 if (searchptr->fname)
15699 {
15700 /* The empty string in a search path is ignored.
15701 This makes it possible to turn off entirely
15702 a standard piece of the list. */
15703 if (searchptr->fname[0] == 0)
15704 continue;
15705 strcpy (fname, skip_redundant_dir_prefix (searchptr->fname));
15706 if (fname[0] && fname[strlen (fname) - 1] != '/')
15707 strcat (fname, "/");
15708 fname[strlen (fname) + flen] = 0;
15709 }
15710 else
15711 fname[0] = 0;
5ff904cd 15712
c7e4ee3a
CB
15713 strncat (fname, fbeg, flen);
15714#ifdef VMS
15715 /* Change this 1/2 Unix 1/2 VMS file specification into a
15716 full VMS file specification */
15717 if (searchptr->fname && (searchptr->fname[0] != 0))
15718 {
15719 /* Fix up the filename */
15720 hack_vms_include_specification (fname);
15721 }
15722 else
15723 {
15724 /* This is a normal VMS filespec, so use it unchanged. */
15725 strncpy (fname, (char *) fbeg, flen);
15726 fname[flen] = 0;
15727#if 0 /* Not for g77. */
15728 /* if it's '#include filename', add the missing .h */
9473c522 15729 if (strchr (fname, '.') == NULL)
c7e4ee3a 15730 strcat (fname, ".h");
5ff904cd 15731#endif
c7e4ee3a
CB
15732 }
15733#endif /* VMS */
15734 f = open_include_file (fname, searchptr);
15735#ifdef EACCES
15736 if (f == NULL && errno == EACCES)
15737 {
15738 print_containing_files (FFEBAD_severityWARNING);
5987ca1c 15739 /* xgettext:no-c-format */
c7e4ee3a
CB
15740 ffebad_start_msg ("At %0, INCLUDE file %A exists, but is not readable",
15741 FFEBAD_severityWARNING);
15742 ffebad_string (fname);
15743 ffebad_here (0, l, c);
15744 ffebad_finish ();
15745 }
15746#endif
15747 if (f != NULL)
15748 break;
15749 }
15750 }
5ff904cd 15751
c7e4ee3a 15752 if (f == NULL)
5ff904cd 15753 {
c7e4ee3a 15754 /* A file that was not found. */
5ff904cd 15755
c7e4ee3a
CB
15756 strncpy (fname, (char *) fbeg, flen);
15757 fname[flen] = 0;
15758 print_containing_files (ffebad_severity (FFEBAD_OPEN_INCLUDE));
15759 ffebad_start (FFEBAD_OPEN_INCLUDE);
15760 ffebad_here (0, l, c);
15761 ffebad_string (fname);
15762 ffebad_finish ();
5ff904cd
JL
15763 }
15764
c7e4ee3a
CB
15765 if (dsp[0].fname != NULL)
15766 free (dsp[0].fname);
5ff904cd 15767
c7e4ee3a
CB
15768 if (f == NULL)
15769 return NULL;
5ff904cd 15770
c7e4ee3a
CB
15771 if (indepth >= (INPUT_STACK_MAX - 1))
15772 {
15773 print_containing_files (FFEBAD_severityFATAL);
5987ca1c 15774 /* xgettext:no-c-format */
c7e4ee3a
CB
15775 ffebad_start_msg ("At %0, INCLUDE nesting too deep",
15776 FFEBAD_severityFATAL);
15777 ffebad_string (fname);
15778 ffebad_here (0, l, c);
15779 ffebad_finish ();
15780 return NULL;
15781 }
5ff904cd 15782
c7e4ee3a
CB
15783 instack[indepth].line = ffewhere_line_use (l);
15784 instack[indepth].column = ffewhere_column_use (c);
5ff904cd 15785
c7e4ee3a
CB
15786 fp = &instack[indepth + 1];
15787 memset ((char *) fp, 0, sizeof (FILE_BUF));
15788 fp->nominal_fname = fp->fname = fname;
15789 fp->dir = searchptr;
5ff904cd 15790
c7e4ee3a
CB
15791 indepth++;
15792 input_file_stack_tick++;
5ff904cd 15793
c7e4ee3a
CB
15794 return f;
15795}
5ff904cd 15796
c7e4ee3a
CB
15797/**INDENT* (Do not reformat this comment even with -fca option.)
15798 Data-gathering files: Given the source file listed below, compiled with
15799 f2c I obtained the output file listed after that, and from the output
15800 file I derived the above code.
5ff904cd 15801
c7e4ee3a
CB
15802-------- (begin input file to f2c)
15803 implicit none
15804 character*10 A1,A2
15805 complex C1,C2
15806 integer I1,I2
15807 real R1,R2
15808 double precision D1,D2
15809C
15810 call getem(A1,A2,C1,C2,I1,I2,R1,R2,D1,D2)
15811c /
15812 call fooI(I1/I2)
15813 call fooR(R1/I1)
15814 call fooD(D1/I1)
15815 call fooC(C1/I1)
15816 call fooR(R1/R2)
15817 call fooD(R1/D1)
15818 call fooD(D1/D2)
15819 call fooD(D1/R1)
15820 call fooC(C1/C2)
15821 call fooC(C1/R1)
15822 call fooZ(C1/D1)
15823c **
15824 call fooI(I1**I2)
15825 call fooR(R1**I1)
15826 call fooD(D1**I1)
15827 call fooC(C1**I1)
15828 call fooR(R1**R2)
15829 call fooD(R1**D1)
15830 call fooD(D1**D2)
15831 call fooD(D1**R1)
15832 call fooC(C1**C2)
15833 call fooC(C1**R1)
15834 call fooZ(C1**D1)
15835c FFEINTRIN_impABS
15836 call fooR(ABS(R1))
15837c FFEINTRIN_impACOS
15838 call fooR(ACOS(R1))
15839c FFEINTRIN_impAIMAG
15840 call fooR(AIMAG(C1))
15841c FFEINTRIN_impAINT
15842 call fooR(AINT(R1))
15843c FFEINTRIN_impALOG
15844 call fooR(ALOG(R1))
15845c FFEINTRIN_impALOG10
15846 call fooR(ALOG10(R1))
15847c FFEINTRIN_impAMAX0
15848 call fooR(AMAX0(I1,I2))
15849c FFEINTRIN_impAMAX1
15850 call fooR(AMAX1(R1,R2))
15851c FFEINTRIN_impAMIN0
15852 call fooR(AMIN0(I1,I2))
15853c FFEINTRIN_impAMIN1
15854 call fooR(AMIN1(R1,R2))
15855c FFEINTRIN_impAMOD
15856 call fooR(AMOD(R1,R2))
15857c FFEINTRIN_impANINT
15858 call fooR(ANINT(R1))
15859c FFEINTRIN_impASIN
15860 call fooR(ASIN(R1))
15861c FFEINTRIN_impATAN
15862 call fooR(ATAN(R1))
15863c FFEINTRIN_impATAN2
15864 call fooR(ATAN2(R1,R2))
15865c FFEINTRIN_impCABS
15866 call fooR(CABS(C1))
15867c FFEINTRIN_impCCOS
15868 call fooC(CCOS(C1))
15869c FFEINTRIN_impCEXP
15870 call fooC(CEXP(C1))
15871c FFEINTRIN_impCHAR
15872 call fooA(CHAR(I1))
15873c FFEINTRIN_impCLOG
15874 call fooC(CLOG(C1))
15875c FFEINTRIN_impCONJG
15876 call fooC(CONJG(C1))
15877c FFEINTRIN_impCOS
15878 call fooR(COS(R1))
15879c FFEINTRIN_impCOSH
15880 call fooR(COSH(R1))
15881c FFEINTRIN_impCSIN
15882 call fooC(CSIN(C1))
15883c FFEINTRIN_impCSQRT
15884 call fooC(CSQRT(C1))
15885c FFEINTRIN_impDABS
15886 call fooD(DABS(D1))
15887c FFEINTRIN_impDACOS
15888 call fooD(DACOS(D1))
15889c FFEINTRIN_impDASIN
15890 call fooD(DASIN(D1))
15891c FFEINTRIN_impDATAN
15892 call fooD(DATAN(D1))
15893c FFEINTRIN_impDATAN2
15894 call fooD(DATAN2(D1,D2))
15895c FFEINTRIN_impDCOS
15896 call fooD(DCOS(D1))
15897c FFEINTRIN_impDCOSH
15898 call fooD(DCOSH(D1))
15899c FFEINTRIN_impDDIM
15900 call fooD(DDIM(D1,D2))
15901c FFEINTRIN_impDEXP
15902 call fooD(DEXP(D1))
15903c FFEINTRIN_impDIM
15904 call fooR(DIM(R1,R2))
15905c FFEINTRIN_impDINT
15906 call fooD(DINT(D1))
15907c FFEINTRIN_impDLOG
15908 call fooD(DLOG(D1))
15909c FFEINTRIN_impDLOG10
15910 call fooD(DLOG10(D1))
15911c FFEINTRIN_impDMAX1
15912 call fooD(DMAX1(D1,D2))
15913c FFEINTRIN_impDMIN1
15914 call fooD(DMIN1(D1,D2))
15915c FFEINTRIN_impDMOD
15916 call fooD(DMOD(D1,D2))
15917c FFEINTRIN_impDNINT
15918 call fooD(DNINT(D1))
15919c FFEINTRIN_impDPROD
15920 call fooD(DPROD(R1,R2))
15921c FFEINTRIN_impDSIGN
15922 call fooD(DSIGN(D1,D2))
15923c FFEINTRIN_impDSIN
15924 call fooD(DSIN(D1))
15925c FFEINTRIN_impDSINH
15926 call fooD(DSINH(D1))
15927c FFEINTRIN_impDSQRT
15928 call fooD(DSQRT(D1))
15929c FFEINTRIN_impDTAN
15930 call fooD(DTAN(D1))
15931c FFEINTRIN_impDTANH
15932 call fooD(DTANH(D1))
15933c FFEINTRIN_impEXP
15934 call fooR(EXP(R1))
15935c FFEINTRIN_impIABS
15936 call fooI(IABS(I1))
15937c FFEINTRIN_impICHAR
15938 call fooI(ICHAR(A1))
15939c FFEINTRIN_impIDIM
15940 call fooI(IDIM(I1,I2))
15941c FFEINTRIN_impIDNINT
15942 call fooI(IDNINT(D1))
15943c FFEINTRIN_impINDEX
15944 call fooI(INDEX(A1,A2))
15945c FFEINTRIN_impISIGN
15946 call fooI(ISIGN(I1,I2))
15947c FFEINTRIN_impLEN
15948 call fooI(LEN(A1))
15949c FFEINTRIN_impLGE
15950 call fooL(LGE(A1,A2))
15951c FFEINTRIN_impLGT
15952 call fooL(LGT(A1,A2))
15953c FFEINTRIN_impLLE
15954 call fooL(LLE(A1,A2))
15955c FFEINTRIN_impLLT
15956 call fooL(LLT(A1,A2))
15957c FFEINTRIN_impMAX0
15958 call fooI(MAX0(I1,I2))
15959c FFEINTRIN_impMAX1
15960 call fooI(MAX1(R1,R2))
15961c FFEINTRIN_impMIN0
15962 call fooI(MIN0(I1,I2))
15963c FFEINTRIN_impMIN1
15964 call fooI(MIN1(R1,R2))
15965c FFEINTRIN_impMOD
15966 call fooI(MOD(I1,I2))
15967c FFEINTRIN_impNINT
15968 call fooI(NINT(R1))
15969c FFEINTRIN_impSIGN
15970 call fooR(SIGN(R1,R2))
15971c FFEINTRIN_impSIN
15972 call fooR(SIN(R1))
15973c FFEINTRIN_impSINH
15974 call fooR(SINH(R1))
15975c FFEINTRIN_impSQRT
15976 call fooR(SQRT(R1))
15977c FFEINTRIN_impTAN
15978 call fooR(TAN(R1))
15979c FFEINTRIN_impTANH
15980 call fooR(TANH(R1))
15981c FFEINTRIN_imp_CMPLX_C
15982 call fooC(cmplx(C1,C2))
15983c FFEINTRIN_imp_CMPLX_D
15984 call fooZ(cmplx(D1,D2))
15985c FFEINTRIN_imp_CMPLX_I
15986 call fooC(cmplx(I1,I2))
15987c FFEINTRIN_imp_CMPLX_R
15988 call fooC(cmplx(R1,R2))
15989c FFEINTRIN_imp_DBLE_C
15990 call fooD(dble(C1))
15991c FFEINTRIN_imp_DBLE_D
15992 call fooD(dble(D1))
15993c FFEINTRIN_imp_DBLE_I
15994 call fooD(dble(I1))
15995c FFEINTRIN_imp_DBLE_R
15996 call fooD(dble(R1))
15997c FFEINTRIN_imp_INT_C
15998 call fooI(int(C1))
15999c FFEINTRIN_imp_INT_D
16000 call fooI(int(D1))
16001c FFEINTRIN_imp_INT_I
16002 call fooI(int(I1))
16003c FFEINTRIN_imp_INT_R
16004 call fooI(int(R1))
16005c FFEINTRIN_imp_REAL_C
16006 call fooR(real(C1))
16007c FFEINTRIN_imp_REAL_D
16008 call fooR(real(D1))
16009c FFEINTRIN_imp_REAL_I
16010 call fooR(real(I1))
16011c FFEINTRIN_imp_REAL_R
16012 call fooR(real(R1))
16013c
16014c FFEINTRIN_imp_INT_D:
16015c
16016c FFEINTRIN_specIDINT
16017 call fooI(IDINT(D1))
16018c
16019c FFEINTRIN_imp_INT_R:
16020c
16021c FFEINTRIN_specIFIX
16022 call fooI(IFIX(R1))
16023c FFEINTRIN_specINT
16024 call fooI(INT(R1))
16025c
16026c FFEINTRIN_imp_REAL_D:
16027c
16028c FFEINTRIN_specSNGL
16029 call fooR(SNGL(D1))
16030c
16031c FFEINTRIN_imp_REAL_I:
16032c
16033c FFEINTRIN_specFLOAT
16034 call fooR(FLOAT(I1))
16035c FFEINTRIN_specREAL
16036 call fooR(REAL(I1))
16037c
16038 end
16039-------- (end input file to f2c)
5ff904cd 16040
c7e4ee3a
CB
16041-------- (begin output from providing above input file as input to:
16042-------- `f2c | gcc -E -C - | sed -e "s:/[*]*://:g" -e "s:[*]*[/]://:g" \
16043-------- -e "s:^#.*$::g"')
5ff904cd 16044
c7e4ee3a
CB
16045// -- translated by f2c (version 19950223).
16046 You must link the resulting object file with the libraries:
16047 -lf2c -lm (in that order)
16048//
5ff904cd 16049
5ff904cd 16050
c7e4ee3a 16051// f2c.h -- Standard Fortran to C header file //
5ff904cd 16052
c7e4ee3a 16053/// barf [ba:rf] 2. "He suggested using FORTRAN, and everybody barfed."
5ff904cd 16054
c7e4ee3a 16055 - From The Shogakukan DICTIONARY OF NEW ENGLISH (Second edition) //
5ff904cd 16056
5ff904cd 16057
5ff904cd 16058
5ff904cd 16059
c7e4ee3a
CB
16060// F2C_INTEGER will normally be `int' but would be `long' on 16-bit systems //
16061// we assume short, float are OK //
16062typedef long int // long int // integer;
16063typedef char *address;
16064typedef short int shortint;
16065typedef float real;
16066typedef double doublereal;
16067typedef struct { real r, i; } complex;
16068typedef struct { doublereal r, i; } doublecomplex;
16069typedef long int // long int // logical;
16070typedef short int shortlogical;
16071typedef char logical1;
16072typedef char integer1;
16073// typedef long long longint; // // system-dependent //
5ff904cd 16074
5ff904cd 16075
5ff904cd 16076
5ff904cd 16077
c7e4ee3a 16078// Extern is for use with -E //
5ff904cd 16079
5ff904cd 16080
5ff904cd 16081
5ff904cd 16082
c7e4ee3a 16083// I/O stuff //
5ff904cd 16084
5ff904cd 16085
5ff904cd 16086
5ff904cd 16087
5ff904cd 16088
5ff904cd 16089
5ff904cd 16090
5ff904cd 16091
c7e4ee3a
CB
16092typedef long int // int or long int // flag;
16093typedef long int // int or long int // ftnlen;
16094typedef long int // int or long int // ftnint;
5ff904cd 16095
5ff904cd 16096
c7e4ee3a
CB
16097//external read, write//
16098typedef struct
16099{ flag cierr;
16100 ftnint ciunit;
16101 flag ciend;
16102 char *cifmt;
16103 ftnint cirec;
16104} cilist;
5ff904cd 16105
c7e4ee3a
CB
16106//internal read, write//
16107typedef struct
16108{ flag icierr;
16109 char *iciunit;
16110 flag iciend;
16111 char *icifmt;
16112 ftnint icirlen;
16113 ftnint icirnum;
16114} icilist;
5ff904cd 16115
c7e4ee3a
CB
16116//open//
16117typedef struct
16118{ flag oerr;
16119 ftnint ounit;
16120 char *ofnm;
16121 ftnlen ofnmlen;
16122 char *osta;
16123 char *oacc;
16124 char *ofm;
16125 ftnint orl;
16126 char *oblnk;
16127} olist;
5ff904cd 16128
c7e4ee3a
CB
16129//close//
16130typedef struct
16131{ flag cerr;
16132 ftnint cunit;
16133 char *csta;
16134} cllist;
5ff904cd 16135
c7e4ee3a
CB
16136//rewind, backspace, endfile//
16137typedef struct
16138{ flag aerr;
16139 ftnint aunit;
16140} alist;
5ff904cd 16141
c7e4ee3a
CB
16142// inquire //
16143typedef struct
16144{ flag inerr;
16145 ftnint inunit;
16146 char *infile;
16147 ftnlen infilen;
16148 ftnint *inex; //parameters in standard's order//
16149 ftnint *inopen;
16150 ftnint *innum;
16151 ftnint *innamed;
16152 char *inname;
16153 ftnlen innamlen;
16154 char *inacc;
16155 ftnlen inacclen;
16156 char *inseq;
16157 ftnlen inseqlen;
16158 char *indir;
16159 ftnlen indirlen;
16160 char *infmt;
16161 ftnlen infmtlen;
16162 char *inform;
16163 ftnint informlen;
16164 char *inunf;
16165 ftnlen inunflen;
16166 ftnint *inrecl;
16167 ftnint *innrec;
16168 char *inblank;
16169 ftnlen inblanklen;
16170} inlist;
5ff904cd 16171
5ff904cd 16172
5ff904cd 16173
c7e4ee3a
CB
16174union Multitype { // for multiple entry points //
16175 integer1 g;
16176 shortint h;
16177 integer i;
16178 // longint j; //
16179 real r;
16180 doublereal d;
16181 complex c;
16182 doublecomplex z;
16183 };
16184
16185typedef union Multitype Multitype;
5ff904cd 16186
c7e4ee3a 16187typedef long Long; // No longer used; formerly in Namelist //
5ff904cd 16188
c7e4ee3a
CB
16189struct Vardesc { // for Namelist //
16190 char *name;
16191 char *addr;
16192 ftnlen *dims;
16193 int type;
16194 };
16195typedef struct Vardesc Vardesc;
5ff904cd 16196
c7e4ee3a
CB
16197struct Namelist {
16198 char *name;
16199 Vardesc **vars;
16200 int nvars;
16201 };
16202typedef struct Namelist Namelist;
5ff904cd 16203
5ff904cd 16204
5ff904cd 16205
5ff904cd 16206
5ff904cd 16207
5ff904cd 16208
5ff904cd 16209
5ff904cd 16210
c7e4ee3a 16211// procedure parameter types for -A and -C++ //
5ff904cd 16212
5ff904cd 16213
5ff904cd 16214
5ff904cd 16215
c7e4ee3a
CB
16216typedef int // Unknown procedure type // (*U_fp)();
16217typedef shortint (*J_fp)();
16218typedef integer (*I_fp)();
16219typedef real (*R_fp)();
16220typedef doublereal (*D_fp)(), (*E_fp)();
16221typedef // Complex // void (*C_fp)();
16222typedef // Double Complex // void (*Z_fp)();
16223typedef logical (*L_fp)();
16224typedef shortlogical (*K_fp)();
16225typedef // Character // void (*H_fp)();
16226typedef // Subroutine // int (*S_fp)();
5ff904cd 16227
c7e4ee3a
CB
16228// E_fp is for real functions when -R is not specified //
16229typedef void C_f; // complex function //
16230typedef void H_f; // character function //
16231typedef void Z_f; // double complex function //
16232typedef doublereal E_f; // real function with -R not specified //
5ff904cd 16233
c7e4ee3a 16234// undef any lower-case symbols that your C compiler predefines, e.g.: //
5ff904cd 16235
5ff904cd 16236
c7e4ee3a
CB
16237// (No such symbols should be defined in a strict ANSI C compiler.
16238 We can avoid trouble with f2c-translated code by using
f458d1d5 16239 gcc -ansi.) //
c7e4ee3a 16240
5ff904cd 16241
5ff904cd 16242
5ff904cd 16243
5ff904cd 16244
5ff904cd 16245
5ff904cd 16246
5ff904cd 16247
5ff904cd 16248
5ff904cd 16249
5ff904cd 16250
5ff904cd 16251
5ff904cd 16252
5ff904cd 16253
5ff904cd 16254
5ff904cd 16255
5ff904cd 16256
5ff904cd 16257
5ff904cd 16258
5ff904cd 16259
5ff904cd 16260
5ff904cd 16261
5ff904cd 16262
c7e4ee3a
CB
16263// Main program // MAIN__()
16264{
16265 // System generated locals //
16266 integer i__1;
16267 real r__1, r__2;
16268 doublereal d__1, d__2;
16269 complex q__1;
16270 doublecomplex z__1, z__2, z__3;
16271 logical L__1;
16272 char ch__1[1];
16273
16274 // Builtin functions //
16275 void c_div();
16276 integer pow_ii();
16277 double pow_ri(), pow_di();
16278 void pow_ci();
16279 double pow_dd();
16280 void pow_zz();
516b69ff 16281 double acos(), r_imag(), r_int(), log(), r_lg10(), r_mod(), r_nint(),
c7e4ee3a
CB
16282 asin(), atan(), atan2(), c_abs();
16283 void c_cos(), c_exp(), c_log(), r_cnjg();
16284 double cos(), cosh();
16285 void c_sin(), c_sqrt();
516b69ff 16286 double d_dim(), exp(), r_dim(), d_int(), d_lg10(), d_mod(), d_nint(),
c7e4ee3a
CB
16287 d_sign(), sin(), sinh(), sqrt(), tan(), tanh();
16288 integer i_dim(), i_dnnt(), i_indx(), i_sign(), i_len();
16289 logical l_ge(), l_gt(), l_le(), l_lt();
16290 integer i_nint();
16291 double r_sign();
16292
16293 // Local variables //
516b69ff 16294 extern // Subroutine // int fooa_(), fooc_(), food_(), fooi_(), foor_(),
c7e4ee3a
CB
16295 fool_(), fooz_(), getem_();
16296 static char a1[10], a2[10];
16297 static complex c1, c2;
16298 static doublereal d1, d2;
16299 static integer i1, i2;
16300 static real r1, r2;
16301
16302
16303 getem_(a1, a2, &c1, &c2, &i1, &i2, &r1, &r2, &d1, &d2, 10L, 10L);
16304// / //
16305 i__1 = i1 / i2;
16306 fooi_(&i__1);
16307 r__1 = r1 / i1;
16308 foor_(&r__1);
16309 d__1 = d1 / i1;
16310 food_(&d__1);
16311 d__1 = (doublereal) i1;
16312 q__1.r = c1.r / d__1, q__1.i = c1.i / d__1;
16313 fooc_(&q__1);
16314 r__1 = r1 / r2;
16315 foor_(&r__1);
16316 d__1 = r1 / d1;
16317 food_(&d__1);
16318 d__1 = d1 / d2;
16319 food_(&d__1);
16320 d__1 = d1 / r1;
16321 food_(&d__1);
16322 c_div(&q__1, &c1, &c2);
16323 fooc_(&q__1);
16324 q__1.r = c1.r / r1, q__1.i = c1.i / r1;
16325 fooc_(&q__1);
16326 z__1.r = c1.r / d1, z__1.i = c1.i / d1;
16327 fooz_(&z__1);
16328// ** //
16329 i__1 = pow_ii(&i1, &i2);
16330 fooi_(&i__1);
16331 r__1 = pow_ri(&r1, &i1);
16332 foor_(&r__1);
16333 d__1 = pow_di(&d1, &i1);
16334 food_(&d__1);
16335 pow_ci(&q__1, &c1, &i1);
16336 fooc_(&q__1);
16337 d__1 = (doublereal) r1;
16338 d__2 = (doublereal) r2;
16339 r__1 = pow_dd(&d__1, &d__2);
16340 foor_(&r__1);
16341 d__2 = (doublereal) r1;
16342 d__1 = pow_dd(&d__2, &d1);
16343 food_(&d__1);
16344 d__1 = pow_dd(&d1, &d2);
16345 food_(&d__1);
16346 d__2 = (doublereal) r1;
16347 d__1 = pow_dd(&d1, &d__2);
16348 food_(&d__1);
16349 z__2.r = c1.r, z__2.i = c1.i;
16350 z__3.r = c2.r, z__3.i = c2.i;
16351 pow_zz(&z__1, &z__2, &z__3);
16352 q__1.r = z__1.r, q__1.i = z__1.i;
16353 fooc_(&q__1);
16354 z__2.r = c1.r, z__2.i = c1.i;
16355 z__3.r = r1, z__3.i = 0.;
16356 pow_zz(&z__1, &z__2, &z__3);
16357 q__1.r = z__1.r, q__1.i = z__1.i;
16358 fooc_(&q__1);
16359 z__2.r = c1.r, z__2.i = c1.i;
16360 z__3.r = d1, z__3.i = 0.;
16361 pow_zz(&z__1, &z__2, &z__3);
16362 fooz_(&z__1);
16363// FFEINTRIN_impABS //
16364 r__1 = (doublereal)(( r1 ) >= 0 ? ( r1 ) : -( r1 )) ;
16365 foor_(&r__1);
16366// FFEINTRIN_impACOS //
16367 r__1 = acos(r1);
16368 foor_(&r__1);
16369// FFEINTRIN_impAIMAG //
16370 r__1 = r_imag(&c1);
16371 foor_(&r__1);
16372// FFEINTRIN_impAINT //
16373 r__1 = r_int(&r1);
16374 foor_(&r__1);
16375// FFEINTRIN_impALOG //
16376 r__1 = log(r1);
16377 foor_(&r__1);
16378// FFEINTRIN_impALOG10 //
16379 r__1 = r_lg10(&r1);
16380 foor_(&r__1);
16381// FFEINTRIN_impAMAX0 //
16382 r__1 = (real) (( i1 ) >= ( i2 ) ? ( i1 ) : ( i2 )) ;
16383 foor_(&r__1);
16384// FFEINTRIN_impAMAX1 //
16385 r__1 = (doublereal)(( r1 ) >= ( r2 ) ? ( r1 ) : ( r2 )) ;
16386 foor_(&r__1);
16387// FFEINTRIN_impAMIN0 //
16388 r__1 = (real) (( i1 ) <= ( i2 ) ? ( i1 ) : ( i2 )) ;
16389 foor_(&r__1);
16390// FFEINTRIN_impAMIN1 //
16391 r__1 = (doublereal)(( r1 ) <= ( r2 ) ? ( r1 ) : ( r2 )) ;
16392 foor_(&r__1);
16393// FFEINTRIN_impAMOD //
16394 r__1 = r_mod(&r1, &r2);
16395 foor_(&r__1);
16396// FFEINTRIN_impANINT //
16397 r__1 = r_nint(&r1);
16398 foor_(&r__1);
16399// FFEINTRIN_impASIN //
16400 r__1 = asin(r1);
16401 foor_(&r__1);
16402// FFEINTRIN_impATAN //
16403 r__1 = atan(r1);
16404 foor_(&r__1);
16405// FFEINTRIN_impATAN2 //
16406 r__1 = atan2(r1, r2);
16407 foor_(&r__1);
16408// FFEINTRIN_impCABS //
16409 r__1 = c_abs(&c1);
16410 foor_(&r__1);
16411// FFEINTRIN_impCCOS //
16412 c_cos(&q__1, &c1);
16413 fooc_(&q__1);
16414// FFEINTRIN_impCEXP //
16415 c_exp(&q__1, &c1);
16416 fooc_(&q__1);
16417// FFEINTRIN_impCHAR //
16418 *(unsigned char *)&ch__1[0] = i1;
16419 fooa_(ch__1, 1L);
16420// FFEINTRIN_impCLOG //
16421 c_log(&q__1, &c1);
16422 fooc_(&q__1);
16423// FFEINTRIN_impCONJG //
16424 r_cnjg(&q__1, &c1);
16425 fooc_(&q__1);
16426// FFEINTRIN_impCOS //
16427 r__1 = cos(r1);
16428 foor_(&r__1);
16429// FFEINTRIN_impCOSH //
16430 r__1 = cosh(r1);
16431 foor_(&r__1);
16432// FFEINTRIN_impCSIN //
16433 c_sin(&q__1, &c1);
16434 fooc_(&q__1);
16435// FFEINTRIN_impCSQRT //
16436 c_sqrt(&q__1, &c1);
16437 fooc_(&q__1);
16438// FFEINTRIN_impDABS //
16439 d__1 = (( d1 ) >= 0 ? ( d1 ) : -( d1 )) ;
16440 food_(&d__1);
16441// FFEINTRIN_impDACOS //
16442 d__1 = acos(d1);
16443 food_(&d__1);
16444// FFEINTRIN_impDASIN //
16445 d__1 = asin(d1);
16446 food_(&d__1);
16447// FFEINTRIN_impDATAN //
16448 d__1 = atan(d1);
16449 food_(&d__1);
16450// FFEINTRIN_impDATAN2 //
16451 d__1 = atan2(d1, d2);
16452 food_(&d__1);
16453// FFEINTRIN_impDCOS //
16454 d__1 = cos(d1);
16455 food_(&d__1);
16456// FFEINTRIN_impDCOSH //
16457 d__1 = cosh(d1);
16458 food_(&d__1);
16459// FFEINTRIN_impDDIM //
16460 d__1 = d_dim(&d1, &d2);
16461 food_(&d__1);
16462// FFEINTRIN_impDEXP //
16463 d__1 = exp(d1);
16464 food_(&d__1);
16465// FFEINTRIN_impDIM //
16466 r__1 = r_dim(&r1, &r2);
16467 foor_(&r__1);
16468// FFEINTRIN_impDINT //
16469 d__1 = d_int(&d1);
16470 food_(&d__1);
16471// FFEINTRIN_impDLOG //
16472 d__1 = log(d1);
16473 food_(&d__1);
16474// FFEINTRIN_impDLOG10 //
16475 d__1 = d_lg10(&d1);
16476 food_(&d__1);
16477// FFEINTRIN_impDMAX1 //
16478 d__1 = (( d1 ) >= ( d2 ) ? ( d1 ) : ( d2 )) ;
16479 food_(&d__1);
16480// FFEINTRIN_impDMIN1 //
16481 d__1 = (( d1 ) <= ( d2 ) ? ( d1 ) : ( d2 )) ;
16482 food_(&d__1);
16483// FFEINTRIN_impDMOD //
16484 d__1 = d_mod(&d1, &d2);
16485 food_(&d__1);
16486// FFEINTRIN_impDNINT //
16487 d__1 = d_nint(&d1);
16488 food_(&d__1);
16489// FFEINTRIN_impDPROD //
16490 d__1 = (doublereal) r1 * r2;
16491 food_(&d__1);
16492// FFEINTRIN_impDSIGN //
16493 d__1 = d_sign(&d1, &d2);
16494 food_(&d__1);
16495// FFEINTRIN_impDSIN //
16496 d__1 = sin(d1);
16497 food_(&d__1);
16498// FFEINTRIN_impDSINH //
16499 d__1 = sinh(d1);
16500 food_(&d__1);
16501// FFEINTRIN_impDSQRT //
16502 d__1 = sqrt(d1);
16503 food_(&d__1);
16504// FFEINTRIN_impDTAN //
16505 d__1 = tan(d1);
16506 food_(&d__1);
16507// FFEINTRIN_impDTANH //
16508 d__1 = tanh(d1);
16509 food_(&d__1);
16510// FFEINTRIN_impEXP //
16511 r__1 = exp(r1);
16512 foor_(&r__1);
16513// FFEINTRIN_impIABS //
16514 i__1 = (( i1 ) >= 0 ? ( i1 ) : -( i1 )) ;
16515 fooi_(&i__1);
16516// FFEINTRIN_impICHAR //
16517 i__1 = *(unsigned char *)a1;
16518 fooi_(&i__1);
16519// FFEINTRIN_impIDIM //
16520 i__1 = i_dim(&i1, &i2);
16521 fooi_(&i__1);
16522// FFEINTRIN_impIDNINT //
16523 i__1 = i_dnnt(&d1);
16524 fooi_(&i__1);
16525// FFEINTRIN_impINDEX //
16526 i__1 = i_indx(a1, a2, 10L, 10L);
16527 fooi_(&i__1);
16528// FFEINTRIN_impISIGN //
16529 i__1 = i_sign(&i1, &i2);
16530 fooi_(&i__1);
16531// FFEINTRIN_impLEN //
16532 i__1 = i_len(a1, 10L);
16533 fooi_(&i__1);
16534// FFEINTRIN_impLGE //
16535 L__1 = l_ge(a1, a2, 10L, 10L);
16536 fool_(&L__1);
16537// FFEINTRIN_impLGT //
16538 L__1 = l_gt(a1, a2, 10L, 10L);
16539 fool_(&L__1);
16540// FFEINTRIN_impLLE //
16541 L__1 = l_le(a1, a2, 10L, 10L);
16542 fool_(&L__1);
16543// FFEINTRIN_impLLT //
16544 L__1 = l_lt(a1, a2, 10L, 10L);
16545 fool_(&L__1);
16546// FFEINTRIN_impMAX0 //
16547 i__1 = (( i1 ) >= ( i2 ) ? ( i1 ) : ( i2 )) ;
16548 fooi_(&i__1);
16549// FFEINTRIN_impMAX1 //
16550 i__1 = (integer) (doublereal)(( r1 ) >= ( r2 ) ? ( r1 ) : ( r2 )) ;
16551 fooi_(&i__1);
16552// FFEINTRIN_impMIN0 //
16553 i__1 = (( i1 ) <= ( i2 ) ? ( i1 ) : ( i2 )) ;
16554 fooi_(&i__1);
16555// FFEINTRIN_impMIN1 //
16556 i__1 = (integer) (doublereal)(( r1 ) <= ( r2 ) ? ( r1 ) : ( r2 )) ;
16557 fooi_(&i__1);
16558// FFEINTRIN_impMOD //
16559 i__1 = i1 % i2;
16560 fooi_(&i__1);
16561// FFEINTRIN_impNINT //
16562 i__1 = i_nint(&r1);
16563 fooi_(&i__1);
16564// FFEINTRIN_impSIGN //
16565 r__1 = r_sign(&r1, &r2);
16566 foor_(&r__1);
16567// FFEINTRIN_impSIN //
16568 r__1 = sin(r1);
16569 foor_(&r__1);
16570// FFEINTRIN_impSINH //
16571 r__1 = sinh(r1);
16572 foor_(&r__1);
16573// FFEINTRIN_impSQRT //
16574 r__1 = sqrt(r1);
16575 foor_(&r__1);
16576// FFEINTRIN_impTAN //
16577 r__1 = tan(r1);
16578 foor_(&r__1);
16579// FFEINTRIN_impTANH //
16580 r__1 = tanh(r1);
16581 foor_(&r__1);
16582// FFEINTRIN_imp_CMPLX_C //
16583 r__1 = c1.r;
16584 r__2 = c2.r;
16585 q__1.r = r__1, q__1.i = r__2;
16586 fooc_(&q__1);
16587// FFEINTRIN_imp_CMPLX_D //
16588 z__1.r = d1, z__1.i = d2;
16589 fooz_(&z__1);
16590// FFEINTRIN_imp_CMPLX_I //
16591 r__1 = (real) i1;
16592 r__2 = (real) i2;
16593 q__1.r = r__1, q__1.i = r__2;
16594 fooc_(&q__1);
16595// FFEINTRIN_imp_CMPLX_R //
16596 q__1.r = r1, q__1.i = r2;
16597 fooc_(&q__1);
16598// FFEINTRIN_imp_DBLE_C //
16599 d__1 = (doublereal) c1.r;
16600 food_(&d__1);
16601// FFEINTRIN_imp_DBLE_D //
16602 d__1 = d1;
16603 food_(&d__1);
16604// FFEINTRIN_imp_DBLE_I //
16605 d__1 = (doublereal) i1;
16606 food_(&d__1);
16607// FFEINTRIN_imp_DBLE_R //
16608 d__1 = (doublereal) r1;
16609 food_(&d__1);
16610// FFEINTRIN_imp_INT_C //
16611 i__1 = (integer) c1.r;
16612 fooi_(&i__1);
16613// FFEINTRIN_imp_INT_D //
16614 i__1 = (integer) d1;
16615 fooi_(&i__1);
16616// FFEINTRIN_imp_INT_I //
16617 i__1 = i1;
16618 fooi_(&i__1);
16619// FFEINTRIN_imp_INT_R //
16620 i__1 = (integer) r1;
16621 fooi_(&i__1);
16622// FFEINTRIN_imp_REAL_C //
16623 r__1 = c1.r;
16624 foor_(&r__1);
16625// FFEINTRIN_imp_REAL_D //
16626 r__1 = (real) d1;
16627 foor_(&r__1);
16628// FFEINTRIN_imp_REAL_I //
16629 r__1 = (real) i1;
16630 foor_(&r__1);
16631// FFEINTRIN_imp_REAL_R //
16632 r__1 = r1;
16633 foor_(&r__1);
16634
16635// FFEINTRIN_imp_INT_D: //
16636
16637// FFEINTRIN_specIDINT //
16638 i__1 = (integer) d1;
16639 fooi_(&i__1);
16640
16641// FFEINTRIN_imp_INT_R: //
16642
16643// FFEINTRIN_specIFIX //
16644 i__1 = (integer) r1;
16645 fooi_(&i__1);
16646// FFEINTRIN_specINT //
16647 i__1 = (integer) r1;
16648 fooi_(&i__1);
16649
16650// FFEINTRIN_imp_REAL_D: //
5ff904cd 16651
c7e4ee3a
CB
16652// FFEINTRIN_specSNGL //
16653 r__1 = (real) d1;
16654 foor_(&r__1);
5ff904cd 16655
c7e4ee3a 16656// FFEINTRIN_imp_REAL_I: //
5ff904cd 16657
c7e4ee3a
CB
16658// FFEINTRIN_specFLOAT //
16659 r__1 = (real) i1;
16660 foor_(&r__1);
16661// FFEINTRIN_specREAL //
16662 r__1 = (real) i1;
16663 foor_(&r__1);
5ff904cd 16664
c7e4ee3a 16665} // MAIN__ //
5ff904cd 16666
c7e4ee3a 16667-------- (end output file from f2c)
5ff904cd 16668
c7e4ee3a 16669*/
This page took 3.251059 seconds and 5 git commands to generate.