]> gcc.gnu.org Git - gcc.git/blame - gcc/f/com.c
* pt.c (unify): Handle SCOPE_REF.
[gcc.git] / gcc / f / com.c
CommitLineData
5ff904cd 1/* com.c -- Implementation File (module.c template V1.0)
0d5d970b 2 Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001
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"
17ed6335 92#include "langhooks.h"
5ff904cd 93
5ff904cd
JL
94/* VMS-specific definitions */
95#ifdef VMS
96#include <descrip.h>
97#define O_RDONLY 0 /* Open arg for Read/Only */
98#define O_WRONLY 1 /* Open arg for Write/Only */
99#define read(fd,buf,size) VMS_read (fd,buf,size)
100#define write(fd,buf,size) VMS_write (fd,buf,size)
101#define open(fname,mode,prot) VMS_open (fname,mode,prot)
102#define fopen(fname,mode) VMS_fopen (fname,mode)
103#define freopen(fname,mode,ofile) VMS_freopen (fname,mode,ofile)
104#define strncat(dst,src,cnt) VMS_strncat (dst,src,cnt)
105#define fstat(fd,stbuf) VMS_fstat (fd,stbuf)
106static int VMS_fstat (), VMS_stat ();
107static char * VMS_strncat ();
108static int VMS_read ();
109static int VMS_write ();
110static int VMS_open ();
111static FILE * VMS_fopen ();
112static FILE * VMS_freopen ();
113static void hack_vms_include_specification ();
114typedef struct { unsigned :16, :16, :16; } vms_ino_t;
115#define ino_t vms_ino_t
116#define INCLUDE_LEN_FUDGE 10 /* leave room for VMS syntax conversion */
5ff904cd
JL
117#endif /* VMS */
118
5ff904cd
JL
119#define FFECOM_DETERMINE_TYPES 1 /* for com.h */
120#include "com.h"
121#include "bad.h"
122#include "bld.h"
123#include "equiv.h"
124#include "expr.h"
125#include "implic.h"
126#include "info.h"
127#include "malloc.h"
128#include "src.h"
129#include "st.h"
130#include "storag.h"
131#include "symbol.h"
132#include "target.h"
133#include "top.h"
134#include "type.h"
135
136/* Externals defined here. */
137
c7e4ee3a
CB
138/* ~~gcc/tree.h *should* declare this, because toplev.c and dwarfout.c
139 reference it. */
5ff904cd 140
f425a887 141const char * const language_string = "GNU F77";
5ff904cd 142
77f77701
DB
143/* Stream for reading from the input file. */
144FILE *finput;
145
5ff904cd
JL
146/* These definitions parallel those in c-decl.c so that code from that
147 module can be used pretty much as is. Much of these defs aren't
148 otherwise used, i.e. by g77 code per se, except some of them are used
149 to build some of them that are. The ones that are global (i.e. not
150 "static") are those that ste.c and such might use (directly
151 or by using com macros that reference them in their definitions). */
152
5ff904cd
JL
153tree string_type_node;
154
5ff904cd
JL
155/* The rest of these are inventions for g77, though there might be
156 similar things in the C front end. As they are found, these
157 inventions should be renamed to be canonical. Note that only
158 the ones currently required to be global are so. */
159
160static tree ffecom_tree_fun_type_void;
5ff904cd
JL
161
162tree ffecom_integer_type_node; /* Abbrev for _tree_type[blah][blah]. */
163tree ffecom_integer_zero_node; /* Like *_*_* with g77's integer type. */
164tree ffecom_integer_one_node; /* " */
165tree ffecom_tree_type[FFEINFO_basictype][FFEINFO_kindtype];
166
167/* _fun_type things are the f2c-specific versions. For -fno-f2c,
168 just use build_function_type and build_pointer_type on the
169 appropriate _tree_type array element. */
170
171static tree ffecom_tree_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
172static tree ffecom_tree_ptr_to_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
173static tree ffecom_tree_subr_type;
174static tree ffecom_tree_ptr_to_subr_type;
175static tree ffecom_tree_blockdata_type;
176
177static tree ffecom_tree_xargc_;
178
179ffecomSymbol ffecom_symbol_null_
180=
181{
182 NULL_TREE,
183 NULL_TREE,
184 NULL_TREE,
0816ebdd
KG
185 NULL_TREE,
186 false
5ff904cd
JL
187};
188ffeinfoKindtype ffecom_pointer_kind_ = FFEINFO_basictypeNONE;
189ffeinfoKindtype ffecom_label_kind_ = FFEINFO_basictypeNONE;
190
191int ffecom_f2c_typecode_[FFEINFO_basictype][FFEINFO_kindtype];
192tree ffecom_f2c_integer_type_node;
193tree ffecom_f2c_ptr_to_integer_type_node;
194tree ffecom_f2c_address_type_node;
195tree ffecom_f2c_real_type_node;
196tree ffecom_f2c_ptr_to_real_type_node;
197tree ffecom_f2c_doublereal_type_node;
198tree ffecom_f2c_complex_type_node;
199tree ffecom_f2c_doublecomplex_type_node;
200tree ffecom_f2c_longint_type_node;
201tree ffecom_f2c_logical_type_node;
202tree ffecom_f2c_flag_type_node;
203tree ffecom_f2c_ftnlen_type_node;
204tree ffecom_f2c_ftnlen_zero_node;
205tree ffecom_f2c_ftnlen_one_node;
206tree ffecom_f2c_ftnlen_two_node;
207tree ffecom_f2c_ptr_to_ftnlen_type_node;
208tree ffecom_f2c_ftnint_type_node;
209tree ffecom_f2c_ptr_to_ftnint_type_node;
5ff904cd
JL
210
211/* Simple definitions and enumerations. */
212
213#ifndef FFECOM_sizeMAXSTACKITEM
214#define FFECOM_sizeMAXSTACKITEM 32*1024 /* Keep user-declared things
215 larger than this # bytes
216 off stack if possible. */
217#endif
218
219/* For systems that have large enough stacks, they should define
220 this to 0, and here, for ease of use later on, we just undefine
221 it if it is 0. */
222
223#if FFECOM_sizeMAXSTACKITEM == 0
224#undef FFECOM_sizeMAXSTACKITEM
225#endif
226
227typedef enum
228 {
229 FFECOM_rttypeVOID_,
6d433196 230 FFECOM_rttypeVOIDSTAR_, /* C's `void *' type. */
795232f7
JL
231 FFECOM_rttypeFTNINT_, /* f2c's `ftnint' type. */
232 FFECOM_rttypeINTEGER_, /* f2c's `integer' type. */
233 FFECOM_rttypeLONGINT_, /* f2c's `longint' type. */
234 FFECOM_rttypeLOGICAL_, /* f2c's `logical' type. */
235 FFECOM_rttypeREAL_F2C_, /* f2c's `real' returned as `double'. */
236 FFECOM_rttypeREAL_GNU_, /* `real' returned as such. */
5ff904cd 237 FFECOM_rttypeCOMPLEX_F2C_, /* f2c's `complex' returned via 1st arg. */
795232f7 238 FFECOM_rttypeCOMPLEX_GNU_, /* f2c's `complex' returned directly. */
5ff904cd 239 FFECOM_rttypeDOUBLE_, /* C's `double' type. */
795232f7 240 FFECOM_rttypeDOUBLEREAL_, /* f2c's `doublereal' type. */
5ff904cd 241 FFECOM_rttypeDBLCMPLX_F2C_, /* f2c's `doublecomplex' returned via 1st arg. */
795232f7 242 FFECOM_rttypeDBLCMPLX_GNU_, /* f2c's `doublecomplex' returned directly. */
5ff904cd
JL
243 FFECOM_rttypeCHARACTER_, /* f2c `char *'/`ftnlen' pair. */
244 FFECOM_rttype_
245 } ffecomRttype_;
246
247/* Internal typedefs. */
248
5ff904cd 249typedef struct _ffecom_concat_list_ ffecomConcatList_;
5ff904cd
JL
250
251/* Private include files. */
252
253
254/* Internal structure definitions. */
255
5ff904cd
JL
256struct _ffecom_concat_list_
257 {
258 ffebld *exprs;
259 int count;
260 int max;
261 ffetargetCharacterSize minlen;
262 ffetargetCharacterSize maxlen;
263 };
5ff904cd
JL
264
265/* Static functions (internal). */
266
26f096f9 267static tree ffecom_arglist_expr_ (const char *argstring, ffebld args);
5ff904cd
JL
268static tree ffecom_widest_expr_type_ (ffebld list);
269static bool ffecom_overlap_ (tree dest_decl, tree dest_offset,
270 tree dest_size, tree source_tree,
271 ffebld source, bool scalar_arg);
272static bool ffecom_args_overlapping_ (tree dest_tree, ffebld dest,
273 tree args, tree callee_commons,
274 bool scalar_args);
26f096f9 275static tree ffecom_build_f2c_string_ (int i, const char *s);
5ff904cd
JL
276static tree ffecom_call_ (tree fn, ffeinfoKindtype kt,
277 bool is_f2c_complex, tree type,
278 tree args, tree dest_tree,
279 ffebld dest, bool *dest_used,
c7e4ee3a 280 tree callee_commons, bool scalar_args, tree hook);
5ff904cd
JL
281static tree ffecom_call_binop_ (tree fn, ffeinfoKindtype kt,
282 bool is_f2c_complex, tree type,
283 ffebld left, ffebld right,
284 tree dest_tree, ffebld dest,
285 bool *dest_used, tree callee_commons,
95eb4fd9 286 bool scalar_args, bool ref, tree hook);
86fc7a6c
CB
287static void ffecom_char_args_x_ (tree *xitem, tree *length,
288 ffebld expr, bool with_null);
5ff904cd
JL
289static tree ffecom_check_size_overflow_ (ffesymbol s, tree type, bool dummy);
290static tree ffecom_char_enhance_arg_ (tree *xtype, ffesymbol s);
291static ffecomConcatList_
292 ffecom_concat_list_gather_ (ffecomConcatList_ catlist,
293 ffebld expr,
294 ffetargetCharacterSize max);
295static void ffecom_concat_list_kill_ (ffecomConcatList_ catlist);
296static ffecomConcatList_ ffecom_concat_list_new_ (ffebld expr,
297 ffetargetCharacterSize max);
26f096f9
KG
298static void ffecom_debug_kludge_ (tree aggr, const char *aggr_type,
299 ffesymbol member, tree member_type,
300 ffetargetOffset offset);
5ff904cd 301static void ffecom_do_entry_ (ffesymbol fn, int entrynum);
092a4ef8
RH
302static tree ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest,
303 bool *dest_used, bool assignp, bool widenp);
5ff904cd
JL
304static tree ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree,
305 ffebld dest, bool *dest_used);
c7e4ee3a 306static tree ffecom_expr_power_integer_ (ffebld expr);
5ff904cd 307static void ffecom_expr_transform_ (ffebld expr);
26f096f9 308static void ffecom_f2c_make_type_ (tree *type, int tcode, const char *name);
5ff904cd
JL
309static void ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size,
310 int code);
311static ffeglobal ffecom_finish_global_ (ffeglobal global);
312static ffesymbol ffecom_finish_symbol_transform_ (ffesymbol s);
26f096f9 313static tree ffecom_get_appended_identifier_ (char us, const char *text);
5ff904cd 314static tree ffecom_get_external_identifier_ (ffesymbol s);
26f096f9 315static tree ffecom_get_identifier_ (const char *text);
5ff904cd
JL
316static tree ffecom_gen_sfuncdef_ (ffesymbol s,
317 ffeinfoBasictype bt,
318 ffeinfoKindtype kt);
26f096f9 319static const char *ffecom_gfrt_args_ (ffecomGfrt ix);
5ff904cd
JL
320static tree ffecom_gfrt_tree_ (ffecomGfrt ix);
321static tree ffecom_init_zero_ (tree decl);
322static tree ffecom_intrinsic_ichar_ (tree tree_type, ffebld arg,
323 tree *maybe_tree);
324static tree ffecom_intrinsic_len_ (ffebld expr);
325static void ffecom_let_char_ (tree dest_tree,
326 tree dest_length,
327 ffetargetCharacterSize dest_size,
328 ffebld source);
329static void ffecom_make_gfrt_ (ffecomGfrt ix);
330static void ffecom_member_phase1_ (ffestorag mst, ffestorag st);
5ff904cd 331static void ffecom_member_phase2_ (ffestorag mst, ffestorag st);
c7e4ee3a
CB
332static void ffecom_prepare_let_char_ (ffetargetCharacterSize dest_size,
333 ffebld source);
5ff904cd
JL
334static void ffecom_push_dummy_decls_ (ffebld dumlist,
335 bool stmtfunc);
336static void ffecom_start_progunit_ (void);
337static ffesymbol ffecom_sym_transform_ (ffesymbol s);
338static ffesymbol ffecom_sym_transform_assign_ (ffesymbol s);
339static void ffecom_transform_common_ (ffesymbol s);
340static void ffecom_transform_equiv_ (ffestorag st);
341static tree ffecom_transform_namelist_ (ffesymbol s);
342static void ffecom_tree_canonize_ptr_ (tree *decl, tree *offset,
343 tree t);
344static void ffecom_tree_canonize_ref_ (tree *decl, tree *offset,
345 tree *size, tree tree);
346static tree ffecom_tree_divide_ (tree tree_type, tree left, tree right,
347 tree dest_tree, ffebld dest,
c7e4ee3a 348 bool *dest_used, tree hook);
5ff904cd
JL
349static tree ffecom_type_localvar_ (ffesymbol s,
350 ffeinfoBasictype bt,
351 ffeinfoKindtype kt);
352static tree ffecom_type_namelist_ (void);
5ff904cd
JL
353static tree ffecom_type_vardesc_ (void);
354static tree ffecom_vardesc_ (ffebld expr);
355static tree ffecom_vardesc_array_ (ffesymbol s);
356static tree ffecom_vardesc_dims_ (ffesymbol s);
26f096f9
KG
357static tree ffecom_convert_narrow_ (tree type, tree expr);
358static tree ffecom_convert_widen_ (tree type, tree expr);
5ff904cd
JL
359
360/* These are static functions that parallel those found in the C front
361 end and thus have the same names. */
362
c7e4ee3a 363static tree bison_rule_compstmt_ (void);
5ff904cd 364static void bison_rule_pushlevel_ (void);
c7e4ee3a 365static void delete_block (tree block);
5ff904cd
JL
366static int duplicate_decls (tree newdecl, tree olddecl);
367static void finish_decl (tree decl, tree init, bool is_top_level);
368static void finish_function (int nested);
4b731ffa 369static const char *lang_printable_name (tree decl, int v);
5ff904cd
JL
370static tree lookup_name_current_level (tree name);
371static struct binding_level *make_binding_level (void);
372static void pop_f_function_context (void);
373static void push_f_function_context (void);
374static void push_parm_decl (tree parm);
375static tree pushdecl_top_level (tree decl);
c7e4ee3a 376static int kept_level_p (void);
5ff904cd
JL
377static tree storedecls (tree decls);
378static void store_parm_decls (int is_main_program);
379static tree start_decl (tree decl, bool is_top_level);
380static void start_function (tree name, tree type, int nested, int public);
b0791fa9 381static void ffecom_file_ (const char *name);
5ff904cd
JL
382static void ffecom_initialize_char_syntax_ (void);
383static void ffecom_close_include_ (FILE *f);
384static int ffecom_decode_include_option_ (char *spec);
385static FILE *ffecom_open_include_ (char *name, ffewhereLine l,
386 ffewhereColumn c);
5ff904cd
JL
387
388/* Static objects accessed by functions in this module. */
389
390static ffesymbol ffecom_primary_entry_ = NULL;
391static ffesymbol ffecom_nested_entry_ = NULL;
392static ffeinfoKind ffecom_primary_entry_kind_;
393static bool ffecom_primary_entry_is_proc_;
5ff904cd
JL
394static tree ffecom_outer_function_decl_;
395static tree ffecom_previous_function_decl_;
396static tree ffecom_which_entrypoint_decl_;
5ff904cd
JL
397static tree ffecom_float_zero_ = NULL_TREE;
398static tree ffecom_float_half_ = NULL_TREE;
399static tree ffecom_double_zero_ = NULL_TREE;
400static tree ffecom_double_half_ = NULL_TREE;
401static tree ffecom_func_result_;/* For functions. */
402static tree ffecom_func_length_;/* For CHARACTER fns. */
403static ffebld ffecom_list_blockdata_;
404static ffebld ffecom_list_common_;
405static ffebld ffecom_master_arglist_;
406static ffeinfoBasictype ffecom_master_bt_;
407static ffeinfoKindtype ffecom_master_kt_;
408static ffetargetCharacterSize ffecom_master_size_;
409static int ffecom_num_fns_ = 0;
410static int ffecom_num_entrypoints_ = 0;
411static bool ffecom_is_altreturning_ = FALSE;
412static tree ffecom_multi_type_node_;
413static tree ffecom_multi_retval_;
414static tree
415 ffecom_multi_fields_[FFEINFO_basictype][FFEINFO_kindtype];
416static bool ffecom_member_namelisted_; /* _member_phase1_ namelisted? */
417static bool ffecom_doing_entry_ = FALSE;
418static bool ffecom_transform_only_dummies_ = FALSE;
ff852b44
CB
419static int ffecom_typesize_pointer_;
420static int ffecom_typesize_integer1_;
5ff904cd
JL
421
422/* Holds pointer-to-function expressions. */
423
424static tree ffecom_gfrt_[FFECOM_gfrt]
425=
426{
95eb4fd9 427#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) NULL_TREE,
5ff904cd
JL
428#include "com-rt.def"
429#undef DEFGFRT
430};
431
432/* Holds the external names of the functions. */
433
19dab795 434static const char *const ffecom_gfrt_name_[FFECOM_gfrt]
5ff904cd
JL
435=
436{
95eb4fd9 437#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) NAME,
5ff904cd
JL
438#include "com-rt.def"
439#undef DEFGFRT
440};
441
442/* Whether the function returns. */
443
444static bool ffecom_gfrt_volatile_[FFECOM_gfrt]
445=
446{
95eb4fd9 447#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) VOLATILE,
5ff904cd
JL
448#include "com-rt.def"
449#undef DEFGFRT
450};
451
452/* Whether the function returns type complex. */
453
454static bool ffecom_gfrt_complex_[FFECOM_gfrt]
455=
456{
95eb4fd9
TM
457#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) COMPLEX,
458#include "com-rt.def"
459#undef DEFGFRT
460};
461
462/* Whether the function is const
463 (i.e., has no side effects and only depends on its arguments). */
464
465static bool ffecom_gfrt_const_[FFECOM_gfrt]
466=
467{
468#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) CONST,
5ff904cd
JL
469#include "com-rt.def"
470#undef DEFGFRT
471};
472
473/* Type code for the function return value. */
474
475static ffecomRttype_ ffecom_gfrt_type_[FFECOM_gfrt]
476=
477{
95eb4fd9 478#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) TYPE,
5ff904cd
JL
479#include "com-rt.def"
480#undef DEFGFRT
481};
482
483/* String of codes for the function's arguments. */
484
19dab795 485static const char *const ffecom_gfrt_argstring_[FFECOM_gfrt]
5ff904cd
JL
486=
487{
95eb4fd9 488#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) ARGS,
5ff904cd
JL
489#include "com-rt.def"
490#undef DEFGFRT
491};
5ff904cd
JL
492
493/* Internal macros. */
494
5ff904cd
JL
495/* We let tm.h override the types used here, to handle trivial differences
496 such as the choice of unsigned int or long unsigned int for size_t.
497 When machines start needing nontrivial differences in the size type,
498 it would be best to do something here to figure out automatically
499 from other information what type to use. */
500
ff852b44
CB
501#ifndef SIZE_TYPE
502#define SIZE_TYPE "long unsigned int"
503#endif
5ff904cd 504
5ff904cd
JL
505#define ffecom_concat_list_count_(catlist) ((catlist).count)
506#define ffecom_concat_list_expr_(catlist,i) ((catlist).exprs[(i)])
507#define ffecom_concat_list_maxlen_(catlist) ((catlist).maxlen)
508#define ffecom_concat_list_minlen_(catlist) ((catlist).minlen)
509
86fc7a6c
CB
510#define ffecom_char_args_(i,l,e) ffecom_char_args_x_((i),(l),(e),FALSE)
511#define ffecom_char_args_with_null_(i,l,e) ffecom_char_args_x_((i),(l),(e),TRUE)
512
5ff904cd
JL
513/* For each binding contour we allocate a binding_level structure
514 * which records the names defined in that contour.
515 * Contours include:
516 * 0) the global one
517 * 1) one for each function definition,
518 * where internal declarations of the parameters appear.
519 *
520 * The current meaning of a name can be found by searching the levels from
521 * the current one out to the global one.
522 */
523
524/* Note that the information in the `names' component of the global contour
525 is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */
526
527struct binding_level
528 {
c7e4ee3a
CB
529 /* A chain of _DECL nodes for all variables, constants, functions,
530 and typedef types. These are in the reverse of the order supplied.
531 */
5ff904cd
JL
532 tree names;
533
c7e4ee3a
CB
534 /* For each level (except not the global one),
535 a chain of BLOCK nodes for all the levels
536 that were entered and exited one level down. */
5ff904cd
JL
537 tree blocks;
538
c7e4ee3a
CB
539 /* The BLOCK node for this level, if one has been preallocated.
540 If 0, the BLOCK is allocated (if needed) when the level is popped. */
5ff904cd
JL
541 tree this_block;
542
543 /* The binding level which this one is contained in (inherits from). */
544 struct binding_level *level_chain;
c7e4ee3a
CB
545
546 /* 0: no ffecom_prepare_* functions called at this level yet;
547 1: ffecom_prepare* functions called, except not ffecom_prepare_end;
548 2: ffecom_prepare_end called. */
549 int prep_state;
5ff904cd
JL
550 };
551
552#define NULL_BINDING_LEVEL (struct binding_level *) NULL
553
554/* The binding level currently in effect. */
555
556static struct binding_level *current_binding_level;
557
558/* A chain of binding_level structures awaiting reuse. */
559
560static struct binding_level *free_binding_level;
561
562/* The outermost binding level, for names of file scope.
563 This is created when the compiler is started and exists
564 through the entire run. */
565
566static struct binding_level *global_binding_level;
567
568/* Binding level structures are initialized by copying this one. */
569
570static struct binding_level clear_binding_level
571=
c7e4ee3a 572{NULL, NULL, NULL, NULL_BINDING_LEVEL, 0};
5ff904cd
JL
573
574/* Language-dependent contents of an identifier. */
575
576struct lang_identifier
577 {
578 struct tree_identifier ignore;
579 tree global_value, local_value, label_value;
580 bool invented;
581 };
582
583/* Macros for access to language-specific slots in an identifier. */
584/* Each of these slots contains a DECL node or null. */
585
586/* This represents the value which the identifier has in the
587 file-scope namespace. */
588#define IDENTIFIER_GLOBAL_VALUE(NODE) \
589 (((struct lang_identifier *)(NODE))->global_value)
590/* This represents the value which the identifier has in the current
591 scope. */
592#define IDENTIFIER_LOCAL_VALUE(NODE) \
593 (((struct lang_identifier *)(NODE))->local_value)
594/* This represents the value which the identifier has as a label in
595 the current label scope. */
596#define IDENTIFIER_LABEL_VALUE(NODE) \
597 (((struct lang_identifier *)(NODE))->label_value)
598/* This is nonzero if the identifier was "made up" by g77 code. */
599#define IDENTIFIER_INVENTED(NODE) \
600 (((struct lang_identifier *)(NODE))->invented)
601
602/* In identifiers, C uses the following fields in a special way:
603 TREE_PUBLIC to record that there was a previous local extern decl.
604 TREE_USED to record that such a decl was used.
605 TREE_ADDRESSABLE to record that the address of such a decl was used. */
606
607/* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function
608 that have names. Here so we can clear out their names' definitions
609 at the end of the function. */
610
611static tree named_labels;
612
613/* A list of LABEL_DECLs from outer contexts that are currently shadowed. */
614
615static tree shadowed_labels;
5ff904cd 616\f
6b55276e
CB
617/* Return the subscript expression, modified to do range-checking.
618
619 `array' is the array to be checked against.
620 `element' is the subscript expression to check.
621 `dim' is the dimension number (starting at 0).
622 `total_dims' is the total number of dimensions (0 for CHARACTER substring).
623*/
624
625static tree
626ffecom_subscript_check_ (tree array, tree element, int dim, int total_dims,
3b304f5b 627 const char *array_name)
6b55276e
CB
628{
629 tree low = TYPE_MIN_VALUE (TYPE_DOMAIN (array));
630 tree high = TYPE_MAX_VALUE (TYPE_DOMAIN (array));
631 tree cond;
632 tree die;
633 tree args;
634
635 if (element == error_mark_node)
636 return element;
637
ff852b44
CB
638 if (TREE_TYPE (low) != TREE_TYPE (element))
639 {
640 if (TYPE_PRECISION (TREE_TYPE (low))
641 > TYPE_PRECISION (TREE_TYPE (element)))
642 element = convert (TREE_TYPE (low), element);
643 else
644 {
645 low = convert (TREE_TYPE (element), low);
646 if (high)
647 high = convert (TREE_TYPE (element), high);
648 }
649 }
650
6b55276e 651 element = ffecom_save_tree (element);
2bc21ba5 652 if (total_dims == 0)
6b55276e 653 {
2bc21ba5
GH
654 /* Special handling for substring range checks. Fortran allows the
655 end subscript < begin subscript, which means that expressions like
656 string(1:0) are valid (and yield a null string). In view of this,
657 enforce two simpler conditions:
658 1) element<=high for end-substring;
659 2) element>=low for start-substring.
660 Run-time character movement will enforce remaining conditions.
661
662 More complicated checks would be better, but present structure only
663 provides one index element at a time, so it is not possible to
664 enforce a check of both i and j in string(i:j). If it were, the
665 complete set of rules would read,
666 if ( ((j<i) && ((low<=i<=high) || (low<=j<=high))) ||
667 ((low<=i<=high) && (low<=j<=high)) )
668 ok ;
669 else
670 range error ;
671 */
672 if (dim)
673 cond = ffecom_2 (LE_EXPR, integer_type_node, element, high);
674 else
675 cond = ffecom_2 (LE_EXPR, integer_type_node, low, element);
676 }
677 else
678 {
679 /* Array reference substring range checking. */
516b69ff 680
2bc21ba5
GH
681 cond = ffecom_2 (LE_EXPR, integer_type_node,
682 low,
683 element);
684 if (high)
685 {
686 cond = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
687 cond,
688 ffecom_2 (LE_EXPR, integer_type_node,
689 element,
690 high));
691 }
6b55276e
CB
692 }
693
694 {
695 int len;
696 char *proc;
697 char *var;
698 tree arg3;
699 tree arg2;
700 tree arg1;
701 tree arg4;
702
703 switch (total_dims)
704 {
705 case 0:
d4c3ec27
KG
706 var = concat (array_name, "[", (dim ? "end" : "start"),
707 "-substring]", NULL);
6b55276e 708 len = strlen (var) + 1;
3b304f5b
ZW
709 arg1 = build_string (len, var);
710 free (var);
6b55276e
CB
711 break;
712
713 case 1:
714 len = strlen (array_name) + 1;
3b304f5b 715 arg1 = build_string (len, array_name);
6b55276e
CB
716 break;
717
718 default:
719 var = xmalloc (strlen (array_name) + 40);
3b304f5b 720 sprintf (var, "%s[subscript-%d-of-%d]",
6b55276e
CB
721 array_name,
722 dim + 1, total_dims);
723 len = strlen (var) + 1;
3b304f5b
ZW
724 arg1 = build_string (len, var);
725 free (var);
6b55276e
CB
726 break;
727 }
728
6b55276e
CB
729 TREE_TYPE (arg1)
730 = build_type_variant (build_array_type (char_type_node,
731 build_range_type
732 (integer_type_node,
733 integer_one_node,
734 build_int_2 (len, 0))),
735 1, 0);
736 TREE_CONSTANT (arg1) = 1;
737 TREE_STATIC (arg1) = 1;
738 arg1 = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg1)),
739 arg1);
740
741 /* s_rnge adds one to the element to print it, so bias against
742 that -- want to print a faithful *subscript* value. */
743 arg2 = convert (ffecom_f2c_ftnint_type_node,
744 ffecom_2 (MINUS_EXPR,
745 TREE_TYPE (element),
746 element,
747 convert (TREE_TYPE (element),
748 integer_one_node)));
749
d4c3ec27
KG
750 proc = concat (input_filename, "/",
751 IDENTIFIER_POINTER (DECL_NAME (current_function_decl)),
752 NULL);
753 len = strlen (proc) + 1;
6b55276e
CB
754 arg3 = build_string (len, proc);
755
756 free (proc);
757
758 TREE_TYPE (arg3)
759 = build_type_variant (build_array_type (char_type_node,
760 build_range_type
761 (integer_type_node,
762 integer_one_node,
763 build_int_2 (len, 0))),
764 1, 0);
765 TREE_CONSTANT (arg3) = 1;
766 TREE_STATIC (arg3) = 1;
767 arg3 = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg3)),
768 arg3);
769
770 arg4 = convert (ffecom_f2c_ftnint_type_node,
771 build_int_2 (lineno, 0));
772
773 arg1 = build_tree_list (NULL_TREE, arg1);
774 arg2 = build_tree_list (NULL_TREE, arg2);
775 arg3 = build_tree_list (NULL_TREE, arg3);
776 arg4 = build_tree_list (NULL_TREE, arg4);
777 TREE_CHAIN (arg3) = arg4;
778 TREE_CHAIN (arg2) = arg3;
779 TREE_CHAIN (arg1) = arg2;
780
781 args = arg1;
782 }
783 die = ffecom_call_gfrt (FFECOM_gfrtRANGE,
784 args, NULL_TREE);
785 TREE_SIDE_EFFECTS (die) = 1;
786
787 element = ffecom_3 (COND_EXPR,
788 TREE_TYPE (element),
789 cond,
790 element,
791 die);
792
793 return element;
794}
795
796/* Return the computed element of an array reference.
797
ff852b44
CB
798 `item' is NULL_TREE, or the transformed pointer to the array.
799 `expr' is the original opARRAYREF expression, which is transformed
800 if `item' is NULL_TREE.
801 `want_ptr' is non-zero if a pointer to the element, instead of
6b55276e
CB
802 the element itself, is to be returned. */
803
804static tree
805ffecom_arrayref_ (tree item, ffebld expr, int want_ptr)
806{
807 ffebld dims[FFECOM_dimensionsMAX];
808 int i;
809 int total_dims;
ff852b44
CB
810 int flatten = ffe_is_flatten_arrays ();
811 int need_ptr;
6b55276e
CB
812 tree array;
813 tree element;
ff852b44
CB
814 tree tree_type;
815 tree tree_type_x;
3b304f5b 816 const char *array_name;
ff852b44
CB
817 ffetype type;
818 ffebld list;
6b55276e
CB
819
820 if (ffebld_op (ffebld_left (expr)) == FFEBLD_opSYMTER)
821 array_name = ffesymbol_text (ffebld_symter (ffebld_left (expr)));
822 else
823 array_name = "[expr?]";
824
825 /* Build up ARRAY_REFs in reverse order (since we're column major
826 here in Fortran land). */
827
ff852b44
CB
828 for (i = 0, list = ffebld_right (expr);
829 list != NULL;
830 ++i, list = ffebld_trail (list))
831 {
832 dims[i] = ffebld_head (list);
833 type = ffeinfo_type (ffebld_basictype (dims[i]),
834 ffebld_kindtype (dims[i]));
835 if (! flatten
836 && ffecom_typesize_pointer_ > ffecom_typesize_integer1_
837 && ffetype_size (type) > ffecom_typesize_integer1_)
838 /* E.g. ARRAY(INDEX), given INTEGER*8 INDEX, on a system with 64-bit
839 pointers and 32-bit integers. Do the full 64-bit pointer
840 arithmetic, for codes using arrays for nonstandard heap-like
841 work. */
842 flatten = 1;
843 }
6b55276e
CB
844
845 total_dims = i;
846
ff852b44
CB
847 need_ptr = want_ptr || flatten;
848
849 if (! item)
850 {
851 if (need_ptr)
852 item = ffecom_ptr_to_expr (ffebld_left (expr));
853 else
854 item = ffecom_expr (ffebld_left (expr));
855
856 if (item == error_mark_node)
857 return item;
858
859 if (ffeinfo_where (ffebld_info (expr)) == FFEINFO_whereFLEETING
860 && ! mark_addressable (item))
861 return error_mark_node;
862 }
863
864 if (item == error_mark_node)
865 return item;
866
6b55276e
CB
867 if (need_ptr)
868 {
ff852b44
CB
869 tree min;
870
6b55276e
CB
871 for (--i, array = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item)));
872 i >= 0;
873 --i, array = TYPE_MAIN_VARIANT (TREE_TYPE (array)))
874 {
ff852b44
CB
875 min = TYPE_MIN_VALUE (TYPE_DOMAIN (array));
876 element = ffecom_expr_ (dims[i], NULL, NULL, NULL, FALSE, TRUE);
02f06e64 877 if (flag_bounds_check)
6b55276e
CB
878 element = ffecom_subscript_check_ (array, element, i, total_dims,
879 array_name);
ff852b44
CB
880 if (element == error_mark_node)
881 return element;
882
883 /* Widen integral arithmetic as desired while preserving
884 signedness. */
885 tree_type = TREE_TYPE (element);
886 tree_type_x = tree_type;
887 if (tree_type
888 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
889 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
890 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
891
892 if (TREE_TYPE (min) != tree_type_x)
893 min = convert (tree_type_x, min);
894 if (TREE_TYPE (element) != tree_type_x)
895 element = convert (tree_type_x, element);
896
6b55276e
CB
897 item = ffecom_2 (PLUS_EXPR,
898 build_pointer_type (TREE_TYPE (array)),
899 item,
900 size_binop (MULT_EXPR,
901 size_in_bytes (TREE_TYPE (array)),
fed3cef0
RK
902 convert (sizetype,
903 fold (build (MINUS_EXPR,
904 tree_type_x,
905 element, min)))));
6b55276e
CB
906 }
907 if (! want_ptr)
908 {
909 item = ffecom_1 (INDIRECT_REF,
910 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item))),
911 item);
912 }
913 }
914 else
915 {
916 for (--i;
917 i >= 0;
918 --i)
919 {
920 array = TYPE_MAIN_VARIANT (TREE_TYPE (item));
921
922 element = ffecom_expr_ (dims[i], NULL, NULL, NULL, FALSE, TRUE);
02f06e64 923 if (flag_bounds_check)
6b55276e
CB
924 element = ffecom_subscript_check_ (array, element, i, total_dims,
925 array_name);
ff852b44
CB
926 if (element == error_mark_node)
927 return element;
928
929 /* Widen integral arithmetic as desired while preserving
930 signedness. */
931 tree_type = TREE_TYPE (element);
932 tree_type_x = tree_type;
933 if (tree_type
934 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
935 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
936 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
937
938 element = convert (tree_type_x, element);
939
6b55276e
CB
940 item = ffecom_2 (ARRAY_REF,
941 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item))),
942 item,
943 element);
944 }
945 }
946
947 return item;
948}
949
5ff904cd
JL
950/* This is like gcc's stabilize_reference -- in fact, most of the code
951 comes from that -- but it handles the situation where the reference
952 is going to have its subparts picked at, and it shouldn't change
953 (or trigger extra invocations of functions in the subtrees) due to
954 this. save_expr is a bit overzealous, because we don't need the
955 entire thing calculated and saved like a temp. So, for DECLs, no
956 change is needed, because these are stable aggregates, and ARRAY_REF
957 and such might well be stable too, but for things like calculations,
958 we do need to calculate a snapshot of a value before picking at it. */
959
5ff904cd
JL
960static tree
961ffecom_stabilize_aggregate_ (tree ref)
962{
963 tree result;
964 enum tree_code code = TREE_CODE (ref);
965
966 switch (code)
967 {
968 case VAR_DECL:
969 case PARM_DECL:
970 case RESULT_DECL:
971 /* No action is needed in this case. */
972 return ref;
973
974 case NOP_EXPR:
975 case CONVERT_EXPR:
976 case FLOAT_EXPR:
977 case FIX_TRUNC_EXPR:
978 case FIX_FLOOR_EXPR:
979 case FIX_ROUND_EXPR:
980 case FIX_CEIL_EXPR:
981 result = build_nt (code, stabilize_reference (TREE_OPERAND (ref, 0)));
982 break;
983
984 case INDIRECT_REF:
985 result = build_nt (INDIRECT_REF,
986 stabilize_reference_1 (TREE_OPERAND (ref, 0)));
987 break;
988
989 case COMPONENT_REF:
990 result = build_nt (COMPONENT_REF,
991 stabilize_reference (TREE_OPERAND (ref, 0)),
992 TREE_OPERAND (ref, 1));
993 break;
994
995 case BIT_FIELD_REF:
996 result = build_nt (BIT_FIELD_REF,
997 stabilize_reference (TREE_OPERAND (ref, 0)),
998 stabilize_reference_1 (TREE_OPERAND (ref, 1)),
999 stabilize_reference_1 (TREE_OPERAND (ref, 2)));
1000 break;
1001
1002 case ARRAY_REF:
1003 result = build_nt (ARRAY_REF,
1004 stabilize_reference (TREE_OPERAND (ref, 0)),
1005 stabilize_reference_1 (TREE_OPERAND (ref, 1)));
1006 break;
1007
1008 case COMPOUND_EXPR:
1009 result = build_nt (COMPOUND_EXPR,
1010 stabilize_reference_1 (TREE_OPERAND (ref, 0)),
1011 stabilize_reference (TREE_OPERAND (ref, 1)));
1012 break;
1013
1014 case RTL_EXPR:
a8d0a42e 1015 abort ();
5ff904cd
JL
1016
1017
1018 default:
1019 return save_expr (ref);
1020
1021 case ERROR_MARK:
1022 return error_mark_node;
1023 }
1024
1025 TREE_TYPE (result) = TREE_TYPE (ref);
1026 TREE_READONLY (result) = TREE_READONLY (ref);
1027 TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (ref);
1028 TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (ref);
5ff904cd
JL
1029
1030 return result;
1031}
5ff904cd
JL
1032
1033/* A rip-off of gcc's convert.c convert_to_complex function,
1034 reworked to handle complex implemented as C structures
1035 (RECORD_TYPE with two fields, real and imaginary `r' and `i'). */
1036
5ff904cd
JL
1037static tree
1038ffecom_convert_to_complex_ (tree type, tree expr)
1039{
1040 register enum tree_code form = TREE_CODE (TREE_TYPE (expr));
1041 tree subtype;
1042
1043 assert (TREE_CODE (type) == RECORD_TYPE);
1044
1045 subtype = TREE_TYPE (TYPE_FIELDS (type));
516b69ff 1046
5ff904cd
JL
1047 if (form == REAL_TYPE || form == INTEGER_TYPE || form == ENUMERAL_TYPE)
1048 {
1049 expr = convert (subtype, expr);
1050 return ffecom_2 (COMPLEX_EXPR, type, expr,
1051 convert (subtype, integer_zero_node));
1052 }
1053
1054 if (form == RECORD_TYPE)
1055 {
1056 tree elt_type = TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr)));
1057 if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype))
1058 return expr;
1059 else
1060 {
1061 expr = save_expr (expr);
1062 return ffecom_2 (COMPLEX_EXPR,
1063 type,
1064 convert (subtype,
1065 ffecom_1 (REALPART_EXPR,
1066 TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))),
1067 expr)),
1068 convert (subtype,
1069 ffecom_1 (IMAGPART_EXPR,
1070 TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))),
1071 expr)));
1072 }
1073 }
1074
1075 if (form == POINTER_TYPE || form == REFERENCE_TYPE)
1076 error ("pointer value used where a complex was expected");
1077 else
1078 error ("aggregate value used where a complex was expected");
516b69ff 1079
5ff904cd
JL
1080 return ffecom_2 (COMPLEX_EXPR, type,
1081 convert (subtype, integer_zero_node),
1082 convert (subtype, integer_zero_node));
1083}
5ff904cd
JL
1084
1085/* Like gcc's convert(), but crashes if widening might happen. */
1086
5ff904cd
JL
1087static tree
1088ffecom_convert_narrow_ (type, expr)
1089 tree type, expr;
1090{
1091 register tree e = expr;
1092 register enum tree_code code = TREE_CODE (type);
1093
1094 if (type == TREE_TYPE (e)
1095 || TREE_CODE (e) == ERROR_MARK)
1096 return e;
1097 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
1098 return fold (build1 (NOP_EXPR, type, e));
1099 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
1100 || code == ERROR_MARK)
1101 return error_mark_node;
1102 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
1103 {
1104 assert ("void value not ignored as it ought to be" == NULL);
1105 return error_mark_node;
1106 }
1107 assert (code != VOID_TYPE);
1108 if ((code != RECORD_TYPE)
1109 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
1110 assert ("converting COMPLEX to REAL" == NULL);
1111 assert (code != ENUMERAL_TYPE);
1112 if (code == INTEGER_TYPE)
1113 {
a74de6ea
CB
1114 assert ((TREE_CODE (TREE_TYPE (e)) == INTEGER_TYPE
1115 && TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (e)))
1116 || (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE
1117 && (TYPE_PRECISION (type)
1118 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e))))));
5ff904cd
JL
1119 return fold (convert_to_integer (type, e));
1120 }
1121 if (code == POINTER_TYPE)
1122 {
1123 assert (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE);
1124 return fold (convert_to_pointer (type, e));
1125 }
1126 if (code == REAL_TYPE)
1127 {
1128 assert (TREE_CODE (TREE_TYPE (e)) == REAL_TYPE);
1129 assert (TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (e)));
1130 return fold (convert_to_real (type, e));
1131 }
1132 if (code == COMPLEX_TYPE)
1133 {
1134 assert (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE);
1135 assert (TYPE_PRECISION (TREE_TYPE (type)) <= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e))));
1136 return fold (convert_to_complex (type, e));
1137 }
1138 if (code == RECORD_TYPE)
1139 {
1140 assert (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE);
270fc4e8
CB
1141 /* Check that at least the first field name agrees. */
1142 assert (DECL_NAME (TYPE_FIELDS (type))
1143 == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e))));
5ff904cd
JL
1144 assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1145 <= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))));
270fc4e8
CB
1146 if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1147 == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))))
1148 return e;
5ff904cd
JL
1149 return fold (ffecom_convert_to_complex_ (type, e));
1150 }
1151
1152 assert ("conversion to non-scalar type requested" == NULL);
1153 return error_mark_node;
1154}
5ff904cd
JL
1155
1156/* Like gcc's convert(), but crashes if narrowing might happen. */
1157
5ff904cd
JL
1158static tree
1159ffecom_convert_widen_ (type, expr)
1160 tree type, expr;
1161{
1162 register tree e = expr;
1163 register enum tree_code code = TREE_CODE (type);
1164
1165 if (type == TREE_TYPE (e)
1166 || TREE_CODE (e) == ERROR_MARK)
1167 return e;
1168 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
1169 return fold (build1 (NOP_EXPR, type, e));
1170 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
1171 || code == ERROR_MARK)
1172 return error_mark_node;
1173 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
1174 {
1175 assert ("void value not ignored as it ought to be" == NULL);
1176 return error_mark_node;
1177 }
1178 assert (code != VOID_TYPE);
1179 if ((code != RECORD_TYPE)
1180 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
1181 assert ("narrowing COMPLEX to REAL" == NULL);
1182 assert (code != ENUMERAL_TYPE);
1183 if (code == INTEGER_TYPE)
1184 {
a74de6ea
CB
1185 assert ((TREE_CODE (TREE_TYPE (e)) == INTEGER_TYPE
1186 && TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (e)))
1187 || (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE
1188 && (TYPE_PRECISION (type)
1189 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e))))));
5ff904cd
JL
1190 return fold (convert_to_integer (type, e));
1191 }
1192 if (code == POINTER_TYPE)
1193 {
1194 assert (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE);
1195 return fold (convert_to_pointer (type, e));
1196 }
1197 if (code == REAL_TYPE)
1198 {
1199 assert (TREE_CODE (TREE_TYPE (e)) == REAL_TYPE);
1200 assert (TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (e)));
1201 return fold (convert_to_real (type, e));
1202 }
1203 if (code == COMPLEX_TYPE)
1204 {
1205 assert (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE);
1206 assert (TYPE_PRECISION (TREE_TYPE (type)) >= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e))));
1207 return fold (convert_to_complex (type, e));
1208 }
1209 if (code == RECORD_TYPE)
1210 {
1211 assert (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE);
270fc4e8
CB
1212 /* Check that at least the first field name agrees. */
1213 assert (DECL_NAME (TYPE_FIELDS (type))
1214 == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e))));
5ff904cd
JL
1215 assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1216 >= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))));
270fc4e8
CB
1217 if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1218 == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))))
1219 return e;
5ff904cd
JL
1220 return fold (ffecom_convert_to_complex_ (type, e));
1221 }
1222
1223 assert ("conversion to non-scalar type requested" == NULL);
1224 return error_mark_node;
1225}
5ff904cd
JL
1226
1227/* Handles making a COMPLEX type, either the standard
1228 (but buggy?) gbe way, or the safer (but less elegant?)
1229 f2c way. */
1230
5ff904cd
JL
1231static tree
1232ffecom_make_complex_type_ (tree subtype)
1233{
1234 tree type;
1235 tree realfield;
1236 tree imagfield;
1237
1238 if (ffe_is_emulate_complex ())
1239 {
1240 type = make_node (RECORD_TYPE);
1241 realfield = ffecom_decl_field (type, NULL_TREE, "r", subtype);
1242 imagfield = ffecom_decl_field (type, realfield, "i", subtype);
1243 TYPE_FIELDS (type) = realfield;
1244 layout_type (type);
1245 }
1246 else
1247 {
1248 type = make_node (COMPLEX_TYPE);
1249 TREE_TYPE (type) = subtype;
1250 layout_type (type);
1251 }
1252
1253 return type;
1254}
5ff904cd
JL
1255
1256/* Chooses either the gbe or the f2c way to build a
1257 complex constant. */
1258
5ff904cd
JL
1259static tree
1260ffecom_build_complex_constant_ (tree type, tree realpart, tree imagpart)
1261{
1262 tree bothparts;
1263
1264 if (ffe_is_emulate_complex ())
1265 {
1266 bothparts = build_tree_list (TYPE_FIELDS (type), realpart);
1267 TREE_CHAIN (bothparts) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), imagpart);
1268 bothparts = build (CONSTRUCTOR, type, NULL_TREE, bothparts);
1269 }
1270 else
1271 {
1272 bothparts = build_complex (type, realpart, imagpart);
1273 }
1274
1275 return bothparts;
1276}
5ff904cd 1277
5ff904cd 1278static tree
26f096f9 1279ffecom_arglist_expr_ (const char *c, ffebld expr)
5ff904cd
JL
1280{
1281 tree list;
1282 tree *plist = &list;
1283 tree trail = NULL_TREE; /* Append char length args here. */
1284 tree *ptrail = &trail;
1285 tree length;
1286 ffebld exprh;
1287 tree item;
1288 bool ptr = FALSE;
1289 tree wanted = NULL_TREE;
e2fa159e
JL
1290 static char zed[] = "0";
1291
1292 if (c == NULL)
1293 c = &zed[0];
5ff904cd
JL
1294
1295 while (expr != NULL)
1296 {
1297 if (*c != '\0')
1298 {
1299 ptr = FALSE;
1300 if (*c == '&')
1301 {
1302 ptr = TRUE;
1303 ++c;
1304 }
1305 switch (*(c++))
1306 {
1307 case '\0':
1308 ptr = TRUE;
1309 wanted = NULL_TREE;
1310 break;
1311
1312 case 'a':
1313 assert (ptr);
1314 wanted = NULL_TREE;
1315 break;
1316
1317 case 'c':
1318 wanted = ffecom_f2c_complex_type_node;
1319 break;
1320
1321 case 'd':
1322 wanted = ffecom_f2c_doublereal_type_node;
1323 break;
1324
1325 case 'e':
1326 wanted = ffecom_f2c_doublecomplex_type_node;
1327 break;
1328
1329 case 'f':
1330 wanted = ffecom_f2c_real_type_node;
1331 break;
1332
1333 case 'i':
1334 wanted = ffecom_f2c_integer_type_node;
1335 break;
1336
1337 case 'j':
1338 wanted = ffecom_f2c_longint_type_node;
1339 break;
1340
1341 default:
1342 assert ("bad argstring code" == NULL);
1343 wanted = NULL_TREE;
1344 break;
1345 }
1346 }
1347
1348 exprh = ffebld_head (expr);
1349 if (exprh == NULL)
1350 wanted = NULL_TREE;
1351
1352 if ((wanted == NULL_TREE)
1353 || (ptr
1354 && (TYPE_MODE
1355 (ffecom_tree_type[ffeinfo_basictype (ffebld_info (exprh))]
1356 [ffeinfo_kindtype (ffebld_info (exprh))])
1357 == TYPE_MODE (wanted))))
1358 *plist
1359 = build_tree_list (NULL_TREE,
1360 ffecom_arg_ptr_to_expr (exprh,
1361 &length));
1362 else
1363 {
1364 item = ffecom_arg_expr (exprh, &length);
1365 item = ffecom_convert_widen_ (wanted, item);
1366 if (ptr)
1367 {
1368 item = ffecom_1 (ADDR_EXPR,
1369 build_pointer_type (TREE_TYPE (item)),
1370 item);
1371 }
1372 *plist
1373 = build_tree_list (NULL_TREE,
1374 item);
1375 }
1376
1377 plist = &TREE_CHAIN (*plist);
1378 expr = ffebld_trail (expr);
1379 if (length != NULL_TREE)
1380 {
1381 *ptrail = build_tree_list (NULL_TREE, length);
1382 ptrail = &TREE_CHAIN (*ptrail);
1383 }
1384 }
1385
e2fa159e
JL
1386 /* We've run out of args in the call; if the implementation expects
1387 more, supply null pointers for them, which the implementation can
1388 check to see if an arg was omitted. */
1389
1390 while (*c != '\0' && *c != '0')
1391 {
1392 if (*c == '&')
1393 ++c;
1394 else
1395 assert ("missing arg to run-time routine!" == NULL);
1396
1397 switch (*(c++))
1398 {
1399 case '\0':
1400 case 'a':
1401 case 'c':
1402 case 'd':
1403 case 'e':
1404 case 'f':
1405 case 'i':
1406 case 'j':
1407 break;
1408
1409 default:
1410 assert ("bad arg string code" == NULL);
1411 break;
1412 }
1413 *plist
1414 = build_tree_list (NULL_TREE,
1415 null_pointer_node);
1416 plist = &TREE_CHAIN (*plist);
1417 }
1418
5ff904cd
JL
1419 *plist = trail;
1420
1421 return list;
1422}
5ff904cd 1423
5ff904cd
JL
1424static tree
1425ffecom_widest_expr_type_ (ffebld list)
1426{
1427 ffebld item;
1428 ffebld widest = NULL;
1429 ffetype type;
1430 ffetype widest_type = NULL;
1431 tree t;
1432
1433 for (; list != NULL; list = ffebld_trail (list))
1434 {
1435 item = ffebld_head (list);
1436 if (item == NULL)
1437 continue;
1438 if ((widest != NULL)
1439 && (ffeinfo_basictype (ffebld_info (item))
1440 != ffeinfo_basictype (ffebld_info (widest))))
1441 continue;
1442 type = ffeinfo_type (ffeinfo_basictype (ffebld_info (item)),
1443 ffeinfo_kindtype (ffebld_info (item)));
1444 if ((widest == FFEINFO_kindtypeNONE)
1445 || (ffetype_size (type)
1446 > ffetype_size (widest_type)))
1447 {
1448 widest = item;
1449 widest_type = type;
1450 }
1451 }
1452
1453 assert (widest != NULL);
1454 t = ffecom_tree_type[ffeinfo_basictype (ffebld_info (widest))]
1455 [ffeinfo_kindtype (ffebld_info (widest))];
1456 assert (t != NULL_TREE);
1457 return t;
1458}
5ff904cd 1459
d6cd84e0
CB
1460/* Check whether a partial overlap between two expressions is possible.
1461
1462 Can *starting* to write a portion of expr1 change the value
1463 computed (perhaps already, *partially*) by expr2?
1464
1465 Currently, this is a concern only for a COMPLEX expr1. But if it
1466 isn't in COMMON or local EQUIVALENCE, since we don't support
1467 aliasing of arguments, it isn't a concern. */
1468
1469static bool
b0791fa9 1470ffecom_possible_partial_overlap_ (ffebld expr1, ffebld expr2 ATTRIBUTE_UNUSED)
d6cd84e0
CB
1471{
1472 ffesymbol sym;
1473 ffestorag st;
1474
1475 switch (ffebld_op (expr1))
1476 {
1477 case FFEBLD_opSYMTER:
1478 sym = ffebld_symter (expr1);
1479 break;
1480
1481 case FFEBLD_opARRAYREF:
1482 if (ffebld_op (ffebld_left (expr1)) != FFEBLD_opSYMTER)
1483 return FALSE;
1484 sym = ffebld_symter (ffebld_left (expr1));
1485 break;
1486
1487 default:
1488 return FALSE;
1489 }
1490
1491 if (ffesymbol_where (sym) != FFEINFO_whereCOMMON
1492 && (ffesymbol_where (sym) != FFEINFO_whereLOCAL
1493 || ! (st = ffesymbol_storage (sym))
1494 || ! ffestorag_parent (st)))
1495 return FALSE;
1496
1497 /* It's in COMMON or local EQUIVALENCE. */
1498
1499 return TRUE;
1500}
1501
5ff904cd
JL
1502/* Check whether dest and source might overlap. ffebld versions of these
1503 might or might not be passed, will be NULL if not.
1504
1505 The test is really whether source_tree is modifiable and, if modified,
1506 might overlap destination such that the value(s) in the destination might
1507 change before it is finally modified. dest_* are the canonized
1508 destination itself. */
1509
5ff904cd
JL
1510static bool
1511ffecom_overlap_ (tree dest_decl, tree dest_offset, tree dest_size,
1512 tree source_tree, ffebld source UNUSED,
1513 bool scalar_arg)
1514{
1515 tree source_decl;
1516 tree source_offset;
1517 tree source_size;
1518 tree t;
1519
1520 if (source_tree == NULL_TREE)
1521 return FALSE;
1522
1523 switch (TREE_CODE (source_tree))
1524 {
1525 case ERROR_MARK:
1526 case IDENTIFIER_NODE:
1527 case INTEGER_CST:
1528 case REAL_CST:
1529 case COMPLEX_CST:
1530 case STRING_CST:
1531 case CONST_DECL:
1532 case VAR_DECL:
1533 case RESULT_DECL:
1534 case FIELD_DECL:
1535 case MINUS_EXPR:
1536 case MULT_EXPR:
1537 case TRUNC_DIV_EXPR:
1538 case CEIL_DIV_EXPR:
1539 case FLOOR_DIV_EXPR:
1540 case ROUND_DIV_EXPR:
1541 case TRUNC_MOD_EXPR:
1542 case CEIL_MOD_EXPR:
1543 case FLOOR_MOD_EXPR:
1544 case ROUND_MOD_EXPR:
1545 case RDIV_EXPR:
1546 case EXACT_DIV_EXPR:
1547 case FIX_TRUNC_EXPR:
1548 case FIX_CEIL_EXPR:
1549 case FIX_FLOOR_EXPR:
1550 case FIX_ROUND_EXPR:
1551 case FLOAT_EXPR:
5ff904cd
JL
1552 case NEGATE_EXPR:
1553 case MIN_EXPR:
1554 case MAX_EXPR:
1555 case ABS_EXPR:
1556 case FFS_EXPR:
1557 case LSHIFT_EXPR:
1558 case RSHIFT_EXPR:
1559 case LROTATE_EXPR:
1560 case RROTATE_EXPR:
1561 case BIT_IOR_EXPR:
1562 case BIT_XOR_EXPR:
1563 case BIT_AND_EXPR:
1564 case BIT_ANDTC_EXPR:
1565 case BIT_NOT_EXPR:
1566 case TRUTH_ANDIF_EXPR:
1567 case TRUTH_ORIF_EXPR:
1568 case TRUTH_AND_EXPR:
1569 case TRUTH_OR_EXPR:
1570 case TRUTH_XOR_EXPR:
1571 case TRUTH_NOT_EXPR:
1572 case LT_EXPR:
1573 case LE_EXPR:
1574 case GT_EXPR:
1575 case GE_EXPR:
1576 case EQ_EXPR:
1577 case NE_EXPR:
1578 case COMPLEX_EXPR:
1579 case CONJ_EXPR:
1580 case REALPART_EXPR:
1581 case IMAGPART_EXPR:
1582 case LABEL_EXPR:
1583 case COMPONENT_REF:
1584 return FALSE;
1585
1586 case COMPOUND_EXPR:
1587 return ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1588 TREE_OPERAND (source_tree, 1), NULL,
1589 scalar_arg);
1590
1591 case MODIFY_EXPR:
1592 return ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1593 TREE_OPERAND (source_tree, 0), NULL,
1594 scalar_arg);
1595
1596 case CONVERT_EXPR:
1597 case NOP_EXPR:
1598 case NON_LVALUE_EXPR:
1599 case PLUS_EXPR:
1600 if (TREE_CODE (TREE_TYPE (source_tree)) != POINTER_TYPE)
1601 return TRUE;
1602
1603 ffecom_tree_canonize_ptr_ (&source_decl, &source_offset,
1604 source_tree);
1605 source_size = TYPE_SIZE (TREE_TYPE (TREE_TYPE (source_tree)));
1606 break;
1607
1608 case COND_EXPR:
1609 return
1610 ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1611 TREE_OPERAND (source_tree, 1), NULL,
1612 scalar_arg)
1613 || ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1614 TREE_OPERAND (source_tree, 2), NULL,
1615 scalar_arg);
1616
1617
1618 case ADDR_EXPR:
1619 ffecom_tree_canonize_ref_ (&source_decl, &source_offset,
1620 &source_size,
1621 TREE_OPERAND (source_tree, 0));
1622 break;
1623
1624 case PARM_DECL:
1625 if (TREE_CODE (TREE_TYPE (source_tree)) != POINTER_TYPE)
1626 return TRUE;
1627
1628 source_decl = source_tree;
76fa6b3b 1629 source_offset = bitsize_zero_node;
5ff904cd
JL
1630 source_size = TYPE_SIZE (TREE_TYPE (TREE_TYPE (source_tree)));
1631 break;
1632
1633 case SAVE_EXPR:
1634 case REFERENCE_EXPR:
1635 case PREDECREMENT_EXPR:
1636 case PREINCREMENT_EXPR:
1637 case POSTDECREMENT_EXPR:
1638 case POSTINCREMENT_EXPR:
1639 case INDIRECT_REF:
1640 case ARRAY_REF:
1641 case CALL_EXPR:
1642 default:
1643 return TRUE;
1644 }
1645
1646 /* Come here when source_decl, source_offset, and source_size filled
1647 in appropriately. */
1648
1649 if (source_decl == NULL_TREE)
1650 return FALSE; /* No decl involved, so no overlap. */
1651
1652 if (source_decl != dest_decl)
1653 return FALSE; /* Different decl, no overlap. */
1654
1655 if (TREE_CODE (dest_size) == ERROR_MARK)
1656 return TRUE; /* Assignment into entire assumed-size
1657 array? Shouldn't happen.... */
1658
1659 t = ffecom_2 (LE_EXPR, integer_type_node,
1660 ffecom_2 (PLUS_EXPR, TREE_TYPE (dest_offset),
1661 dest_offset,
1662 convert (TREE_TYPE (dest_offset),
1663 dest_size)),
1664 convert (TREE_TYPE (dest_offset),
1665 source_offset));
1666
1667 if (integer_onep (t))
1668 return FALSE; /* Destination precedes source. */
1669
1670 if (!scalar_arg
1671 || (source_size == NULL_TREE)
1672 || (TREE_CODE (source_size) == ERROR_MARK)
1673 || integer_zerop (source_size))
1674 return TRUE; /* No way to tell if dest follows source. */
1675
1676 t = ffecom_2 (LE_EXPR, integer_type_node,
1677 ffecom_2 (PLUS_EXPR, TREE_TYPE (source_offset),
1678 source_offset,
1679 convert (TREE_TYPE (source_offset),
1680 source_size)),
1681 convert (TREE_TYPE (source_offset),
1682 dest_offset));
1683
1684 if (integer_onep (t))
1685 return FALSE; /* Destination follows source. */
1686
1687 return TRUE; /* Destination and source overlap. */
1688}
5ff904cd
JL
1689
1690/* Check whether dest might overlap any of a list of arguments or is
1691 in a COMMON area the callee might know about (and thus modify). */
1692
5ff904cd
JL
1693static bool
1694ffecom_args_overlapping_ (tree dest_tree, ffebld dest UNUSED,
1695 tree args, tree callee_commons,
1696 bool scalar_args)
1697{
1698 tree arg;
1699 tree dest_decl;
1700 tree dest_offset;
1701 tree dest_size;
1702
1703 ffecom_tree_canonize_ref_ (&dest_decl, &dest_offset, &dest_size,
1704 dest_tree);
1705
1706 if (dest_decl == NULL_TREE)
1707 return FALSE; /* Seems unlikely! */
1708
1709 /* If the decl cannot be determined reliably, or if its in COMMON
1710 and the callee isn't known to not futz with COMMON via other
1711 means, overlap might happen. */
1712
1713 if ((TREE_CODE (dest_decl) == ERROR_MARK)
1714 || ((callee_commons != NULL_TREE)
1715 && TREE_PUBLIC (dest_decl)))
1716 return TRUE;
1717
1718 for (; args != NULL_TREE; args = TREE_CHAIN (args))
1719 {
1720 if (((arg = TREE_VALUE (args)) != NULL_TREE)
1721 && ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1722 arg, NULL, scalar_args))
1723 return TRUE;
1724 }
1725
1726 return FALSE;
1727}
5ff904cd
JL
1728
1729/* Build a string for a variable name as used by NAMELIST. This means that
1730 if we're using the f2c library, we build an uppercase string, since
1731 f2c does this. */
1732
5ff904cd 1733static tree
26f096f9 1734ffecom_build_f2c_string_ (int i, const char *s)
5ff904cd
JL
1735{
1736 if (!ffe_is_f2c_library ())
1737 return build_string (i, s);
1738
1739 {
1740 char *tmp;
26f096f9 1741 const char *p;
5ff904cd
JL
1742 char *q;
1743 char space[34];
1744 tree t;
1745
1746 if (((size_t) i) > ARRAY_SIZE (space))
1747 tmp = malloc_new_ks (malloc_pool_image (), "f2c_string", i);
1748 else
1749 tmp = &space[0];
1750
1751 for (p = s, q = tmp; *p != '\0'; ++p, ++q)
f6bbde28 1752 *q = TOUPPER (*p);
5ff904cd
JL
1753 *q = '\0';
1754
1755 t = build_string (i, tmp);
1756
1757 if (((size_t) i) > ARRAY_SIZE (space))
1758 malloc_kill_ks (malloc_pool_image (), tmp, i);
1759
1760 return t;
1761 }
1762}
1763
5ff904cd
JL
1764/* Returns CALL_EXPR or equivalent with given type (pass NULL_TREE for
1765 type to just get whatever the function returns), handling the
1766 f2c value-returning convention, if required, by prepending
1767 to the arglist a pointer to a temporary to receive the return value. */
1768
5ff904cd
JL
1769static tree
1770ffecom_call_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex,
1771 tree type, tree args, tree dest_tree,
1772 ffebld dest, bool *dest_used, tree callee_commons,
c7e4ee3a 1773 bool scalar_args, tree hook)
5ff904cd
JL
1774{
1775 tree item;
1776 tree tempvar;
1777
1778 if (dest_used != NULL)
1779 *dest_used = FALSE;
1780
1781 if (is_f2c_complex)
1782 {
1783 if ((dest_used == NULL)
1784 || (dest == NULL)
1785 || (ffeinfo_basictype (ffebld_info (dest))
1786 != FFEINFO_basictypeCOMPLEX)
1787 || (ffeinfo_kindtype (ffebld_info (dest)) != kt)
1788 || ((type != NULL_TREE) && (TREE_TYPE (dest_tree) != type))
1789 || ffecom_args_overlapping_ (dest_tree, dest, args,
1790 callee_commons,
1791 scalar_args))
1792 {
c7e4ee3a
CB
1793#ifdef HOHO
1794 tempvar = ffecom_make_tempvar (ffecom_tree_type
5ff904cd
JL
1795 [FFEINFO_basictypeCOMPLEX][kt],
1796 FFETARGET_charactersizeNONE,
c7e4ee3a
CB
1797 -1);
1798#else
1799 tempvar = hook;
1800 assert (tempvar);
1801#endif
5ff904cd
JL
1802 }
1803 else
1804 {
1805 *dest_used = TRUE;
1806 tempvar = dest_tree;
1807 type = NULL_TREE;
1808 }
1809
1810 item
1811 = build_tree_list (NULL_TREE,
1812 ffecom_1 (ADDR_EXPR,
c7e4ee3a 1813 build_pointer_type (TREE_TYPE (tempvar)),
5ff904cd
JL
1814 tempvar));
1815 TREE_CHAIN (item) = args;
1816
1817 item = ffecom_3s (CALL_EXPR, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), fn,
1818 item, NULL_TREE);
1819
1820 if (tempvar != dest_tree)
1821 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), item, tempvar);
1822 }
1823 else
1824 item = ffecom_3s (CALL_EXPR, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), fn,
1825 args, NULL_TREE);
1826
1827 if ((type != NULL_TREE) && (TREE_TYPE (item) != type))
1828 item = ffecom_convert_narrow_ (type, item);
1829
1830 return item;
1831}
5ff904cd
JL
1832
1833/* Given two arguments, transform them and make a call to the given
1834 function via ffecom_call_. */
1835
5ff904cd
JL
1836static tree
1837ffecom_call_binop_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex,
1838 tree type, ffebld left, ffebld right,
1839 tree dest_tree, ffebld dest, bool *dest_used,
95eb4fd9 1840 tree callee_commons, bool scalar_args, bool ref, tree hook)
5ff904cd
JL
1841{
1842 tree left_tree;
1843 tree right_tree;
1844 tree left_length;
1845 tree right_length;
1846
95eb4fd9
TM
1847 if (ref)
1848 {
1849 /* Pass arguments by reference. */
1850 left_tree = ffecom_arg_ptr_to_expr (left, &left_length);
1851 right_tree = ffecom_arg_ptr_to_expr (right, &right_length);
1852 }
1853 else
1854 {
1855 /* Pass arguments by value. */
1856 left_tree = ffecom_arg_expr (left, &left_length);
1857 right_tree = ffecom_arg_expr (right, &right_length);
1858 }
1859
5ff904cd
JL
1860
1861 left_tree = build_tree_list (NULL_TREE, left_tree);
1862 right_tree = build_tree_list (NULL_TREE, right_tree);
1863 TREE_CHAIN (left_tree) = right_tree;
1864
1865 if (left_length != NULL_TREE)
1866 {
1867 left_length = build_tree_list (NULL_TREE, left_length);
1868 TREE_CHAIN (right_tree) = left_length;
1869 }
1870
1871 if (right_length != NULL_TREE)
1872 {
1873 right_length = build_tree_list (NULL_TREE, right_length);
1874 if (left_length != NULL_TREE)
1875 TREE_CHAIN (left_length) = right_length;
1876 else
1877 TREE_CHAIN (right_tree) = right_length;
1878 }
1879
1880 return ffecom_call_ (fn, kt, is_f2c_complex, type, left_tree,
1881 dest_tree, dest, dest_used, callee_commons,
c7e4ee3a 1882 scalar_args, hook);
5ff904cd 1883}
5ff904cd 1884
c7e4ee3a 1885/* Return ptr/length args for char subexpression
5ff904cd
JL
1886
1887 Handles CHARACTER-type CONTER, SYMTER, SUBSTR, ARRAYREF, and FUNCREF
1888 subexpressions by constructing the appropriate trees for the ptr-to-
1889 character-text and length-of-character-text arguments in a calling
86fc7a6c
CB
1890 sequence.
1891
1892 Note that if with_null is TRUE, and the expression is an opCONTER,
1893 a null byte is appended to the string. */
5ff904cd 1894
5ff904cd 1895static void
86fc7a6c 1896ffecom_char_args_x_ (tree *xitem, tree *length, ffebld expr, bool with_null)
5ff904cd
JL
1897{
1898 tree item;
1899 tree high;
1900 ffetargetCharacter1 val;
86fc7a6c 1901 ffetargetCharacterSize newlen;
5ff904cd
JL
1902
1903 switch (ffebld_op (expr))
1904 {
1905 case FFEBLD_opCONTER:
1906 val = ffebld_constant_character1 (ffebld_conter (expr));
86fc7a6c
CB
1907 newlen = ffetarget_length_character1 (val);
1908 if (with_null)
1909 {
c7e4ee3a 1910 /* Begin FFETARGET-NULL-KLUDGE. */
86fc7a6c 1911 if (newlen != 0)
c7e4ee3a 1912 ++newlen;
86fc7a6c
CB
1913 }
1914 *length = build_int_2 (newlen, 0);
5ff904cd 1915 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
86fc7a6c 1916 high = build_int_2 (newlen, 0);
5ff904cd 1917 TREE_TYPE (high) = ffecom_f2c_ftnlen_type_node;
c7e4ee3a 1918 item = build_string (newlen,
5ff904cd 1919 ffetarget_text_character1 (val));
c7e4ee3a 1920 /* End FFETARGET-NULL-KLUDGE. */
5ff904cd
JL
1921 TREE_TYPE (item)
1922 = build_type_variant
1923 (build_array_type
1924 (char_type_node,
1925 build_range_type
1926 (ffecom_f2c_ftnlen_type_node,
1927 ffecom_f2c_ftnlen_one_node,
1928 high)),
1929 1, 0);
1930 TREE_CONSTANT (item) = 1;
1931 TREE_STATIC (item) = 1;
1932 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
1933 item);
1934 break;
1935
1936 case FFEBLD_opSYMTER:
1937 {
1938 ffesymbol s = ffebld_symter (expr);
1939
1940 item = ffesymbol_hook (s).decl_tree;
1941 if (item == NULL_TREE)
1942 {
1943 s = ffecom_sym_transform_ (s);
1944 item = ffesymbol_hook (s).decl_tree;
1945 }
1946 if (ffesymbol_kind (s) == FFEINFO_kindENTITY)
1947 {
1948 if (ffesymbol_size (s) == FFETARGET_charactersizeNONE)
1949 *length = ffesymbol_hook (s).length_tree;
1950 else
1951 {
1952 *length = build_int_2 (ffesymbol_size (s), 0);
1953 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
1954 }
1955 }
1956 else if (item == error_mark_node)
1957 *length = error_mark_node;
c7e4ee3a
CB
1958 else
1959 /* FFEINFO_kindFUNCTION. */
5ff904cd
JL
1960 *length = NULL_TREE;
1961 if (!ffesymbol_hook (s).addr
1962 && (item != error_mark_node))
1963 item = ffecom_1 (ADDR_EXPR,
1964 build_pointer_type (TREE_TYPE (item)),
1965 item);
1966 }
1967 break;
1968
1969 case FFEBLD_opARRAYREF:
1970 {
5ff904cd 1971 ffecom_char_args_ (&item, length, ffebld_left (expr));
5ff904cd
JL
1972
1973 if (item == error_mark_node || *length == error_mark_node)
1974 {
1975 item = *length = error_mark_node;
1976 break;
1977 }
1978
6b55276e 1979 item = ffecom_arrayref_ (item, expr, 1);
5ff904cd
JL
1980 }
1981 break;
1982
1983 case FFEBLD_opSUBSTR:
1984 {
1985 ffebld start;
1986 ffebld end;
1987 ffebld thing = ffebld_right (expr);
1988 tree start_tree;
1989 tree end_tree;
3b304f5b 1990 const char *char_name;
6b55276e
CB
1991 ffebld left_symter;
1992 tree array;
5ff904cd
JL
1993
1994 assert (ffebld_op (thing) == FFEBLD_opITEM);
1995 start = ffebld_head (thing);
1996 thing = ffebld_trail (thing);
1997 assert (ffebld_trail (thing) == NULL);
1998 end = ffebld_head (thing);
1999
6b55276e
CB
2000 /* Determine name for pretty-printing range-check errors. */
2001 for (left_symter = ffebld_left (expr);
2002 left_symter && ffebld_op (left_symter) == FFEBLD_opARRAYREF;
2003 left_symter = ffebld_left (left_symter))
2004 ;
2005 if (ffebld_op (left_symter) == FFEBLD_opSYMTER)
2006 char_name = ffesymbol_text (ffebld_symter (left_symter));
2007 else
2008 char_name = "[expr?]";
2009
5ff904cd 2010 ffecom_char_args_ (&item, length, ffebld_left (expr));
5ff904cd
JL
2011
2012 if (item == error_mark_node || *length == error_mark_node)
2013 {
2014 item = *length = error_mark_node;
2015 break;
2016 }
2017
6b55276e
CB
2018 array = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item)));
2019
ff852b44
CB
2020 /* ~~~~Handle INTEGER*8 start/end, a la FFEBLD_opARRAYREF. */
2021
5ff904cd
JL
2022 if (start == NULL)
2023 {
2024 if (end == NULL)
2025 ;
2026 else
2027 {
6b55276e 2028 end_tree = ffecom_expr (end);
02f06e64 2029 if (flag_bounds_check)
6b55276e
CB
2030 end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0,
2031 char_name);
5ff904cd 2032 end_tree = convert (ffecom_f2c_ftnlen_type_node,
6b55276e 2033 end_tree);
5ff904cd
JL
2034
2035 if (end_tree == error_mark_node)
2036 {
2037 item = *length = error_mark_node;
2038 break;
2039 }
2040
2041 *length = end_tree;
2042 }
2043 }
2044 else
2045 {
6b55276e 2046 start_tree = ffecom_expr (start);
02f06e64 2047 if (flag_bounds_check)
6b55276e
CB
2048 start_tree = ffecom_subscript_check_ (array, start_tree, 0, 0,
2049 char_name);
5ff904cd 2050 start_tree = convert (ffecom_f2c_ftnlen_type_node,
6b55276e 2051 start_tree);
5ff904cd
JL
2052
2053 if (start_tree == error_mark_node)
2054 {
2055 item = *length = error_mark_node;
2056 break;
2057 }
2058
2059 start_tree = ffecom_save_tree (start_tree);
2060
2061 item = ffecom_2 (PLUS_EXPR, TREE_TYPE (item),
2062 item,
2063 ffecom_2 (MINUS_EXPR,
2064 TREE_TYPE (start_tree),
2065 start_tree,
2066 ffecom_f2c_ftnlen_one_node));
2067
2068 if (end == NULL)
2069 {
2070 *length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
2071 ffecom_f2c_ftnlen_one_node,
2072 ffecom_2 (MINUS_EXPR,
2073 ffecom_f2c_ftnlen_type_node,
2074 *length,
2075 start_tree));
2076 }
2077 else
2078 {
6b55276e 2079 end_tree = ffecom_expr (end);
02f06e64 2080 if (flag_bounds_check)
6b55276e
CB
2081 end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0,
2082 char_name);
5ff904cd 2083 end_tree = convert (ffecom_f2c_ftnlen_type_node,
6b55276e 2084 end_tree);
5ff904cd
JL
2085
2086 if (end_tree == error_mark_node)
2087 {
2088 item = *length = error_mark_node;
2089 break;
2090 }
2091
2092 *length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
2093 ffecom_f2c_ftnlen_one_node,
2094 ffecom_2 (MINUS_EXPR,
2095 ffecom_f2c_ftnlen_type_node,
2096 end_tree, start_tree));
2097 }
2098 }
2099 }
2100 break;
2101
2102 case FFEBLD_opFUNCREF:
2103 {
2104 ffesymbol s = ffebld_symter (ffebld_left (expr));
2105 tree tempvar;
2106 tree args;
2107 ffetargetCharacterSize size = ffeinfo_size (ffebld_info (expr));
2108 ffecomGfrt ix;
2109
2110 if (size == FFETARGET_charactersizeNONE)
c7e4ee3a
CB
2111 /* ~~Kludge alert! This should someday be fixed. */
2112 size = 24;
5ff904cd
JL
2113
2114 *length = build_int_2 (size, 0);
2115 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
2116
2117 if (ffeinfo_where (ffebld_info (ffebld_left (expr)))
2118 == FFEINFO_whereINTRINSIC)
2119 {
2120 if (size == 1)
c7e4ee3a
CB
2121 {
2122 /* Invocation of an intrinsic returning CHARACTER*1. */
5ff904cd
JL
2123 item = ffecom_expr_intrinsic_ (expr, NULL_TREE,
2124 NULL, NULL);
2125 break;
2126 }
2127 ix = ffeintrin_gfrt_direct (ffebld_symter_implementation (ffebld_left (expr)));
2128 assert (ix != FFECOM_gfrt);
2129 item = ffecom_gfrt_tree_ (ix);
2130 }
2131 else
2132 {
2133 ix = FFECOM_gfrt;
2134 item = ffesymbol_hook (s).decl_tree;
2135 if (item == NULL_TREE)
2136 {
2137 s = ffecom_sym_transform_ (s);
2138 item = ffesymbol_hook (s).decl_tree;
2139 }
2140 if (item == error_mark_node)
2141 {
2142 item = *length = error_mark_node;
2143 break;
2144 }
2145
2146 if (!ffesymbol_hook (s).addr)
2147 item = ffecom_1_fn (item);
2148 }
2149
c7e4ee3a 2150#ifdef HOHO
5ff904cd 2151 tempvar = ffecom_push_tempvar (char_type_node, size, -1, TRUE);
c7e4ee3a
CB
2152#else
2153 tempvar = ffebld_nonter_hook (expr);
2154 assert (tempvar);
2155#endif
5ff904cd
JL
2156 tempvar = ffecom_1 (ADDR_EXPR,
2157 build_pointer_type (TREE_TYPE (tempvar)),
2158 tempvar);
2159
5ff904cd
JL
2160 args = build_tree_list (NULL_TREE, tempvar);
2161
2162 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT) /* Sfunc args by value. */
2163 TREE_CHAIN (args) = ffecom_list_expr (ffebld_right (expr));
2164 else
2165 {
2166 TREE_CHAIN (args) = build_tree_list (NULL_TREE, *length);
2167 if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC)
2168 {
2169 TREE_CHAIN (TREE_CHAIN (args))
2170 = ffecom_arglist_expr_ (ffecom_gfrt_args_ (ix),
2171 ffebld_right (expr));
2172 }
2173 else
2174 {
2175 TREE_CHAIN (TREE_CHAIN (args))
2176 = ffecom_list_ptr_to_expr (ffebld_right (expr));
2177 }
2178 }
2179
2180 item = ffecom_3s (CALL_EXPR,
2181 TREE_TYPE (TREE_TYPE (TREE_TYPE (item))),
2182 item, args, NULL_TREE);
2183 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), item,
2184 tempvar);
5ff904cd
JL
2185 }
2186 break;
2187
2188 case FFEBLD_opCONVERT:
2189
5ff904cd 2190 ffecom_char_args_ (&item, length, ffebld_left (expr));
5ff904cd
JL
2191
2192 if (item == error_mark_node || *length == error_mark_node)
2193 {
2194 item = *length = error_mark_node;
2195 break;
2196 }
2197
2198 if ((ffebld_size_known (ffebld_left (expr))
2199 == FFETARGET_charactersizeNONE)
2200 || (ffebld_size_known (ffebld_left (expr)) < (ffebld_size (expr))))
2201 { /* Possible blank-padding needed, copy into
2202 temporary. */
2203 tree tempvar;
2204 tree args;
2205 tree newlen;
2206
c7e4ee3a
CB
2207#ifdef HOHO
2208 tempvar = ffecom_make_tempvar (char_type_node,
2209 ffebld_size (expr), -1);
2210#else
2211 tempvar = ffebld_nonter_hook (expr);
2212 assert (tempvar);
2213#endif
5ff904cd
JL
2214 tempvar = ffecom_1 (ADDR_EXPR,
2215 build_pointer_type (TREE_TYPE (tempvar)),
2216 tempvar);
2217
2218 newlen = build_int_2 (ffebld_size (expr), 0);
2219 TREE_TYPE (newlen) = ffecom_f2c_ftnlen_type_node;
2220
2221 args = build_tree_list (NULL_TREE, tempvar);
2222 TREE_CHAIN (args) = build_tree_list (NULL_TREE, item);
2223 TREE_CHAIN (TREE_CHAIN (args)) = build_tree_list (NULL_TREE, newlen);
2224 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (args)))
2225 = build_tree_list (NULL_TREE, *length);
2226
c7e4ee3a 2227 item = ffecom_call_gfrt (FFECOM_gfrtCOPY, args, NULL_TREE);
5ff904cd
JL
2228 TREE_SIDE_EFFECTS (item) = 1;
2229 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), fold (item),
2230 tempvar);
2231 *length = newlen;
2232 }
2233 else
2234 { /* Just truncate the length. */
2235 *length = build_int_2 (ffebld_size (expr), 0);
2236 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
2237 }
2238 break;
2239
2240 default:
2241 assert ("bad op for single char arg expr" == NULL);
2242 item = NULL_TREE;
2243 break;
2244 }
2245
2246 *xitem = item;
2247}
5ff904cd
JL
2248
2249/* Check the size of the type to be sure it doesn't overflow the
2250 "portable" capacities of the compiler back end. `dummy' types
2251 can generally overflow the normal sizes as long as the computations
2252 themselves don't overflow. A particular target of the back end
2253 must still enforce its size requirements, though, and the back
2254 end takes care of this in stor-layout.c. */
2255
5ff904cd
JL
2256static tree
2257ffecom_check_size_overflow_ (ffesymbol s, tree type, bool dummy)
2258{
2259 if (TREE_CODE (type) == ERROR_MARK)
2260 return type;
2261
2262 if (TYPE_SIZE (type) == NULL_TREE)
2263 return type;
2264
2265 if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
2266 return type;
2267
2268 if ((tree_int_cst_sgn (TYPE_SIZE (type)) < 0)
e1cb83c5 2269 || (!dummy && TREE_OVERFLOW (TYPE_SIZE (type))))
5ff904cd
JL
2270 {
2271 ffebad_start (FFEBAD_ARRAY_LARGE);
2272 ffebad_string (ffesymbol_text (s));
2273 ffebad_here (0, ffesymbol_where_line (s), ffesymbol_where_column (s));
2274 ffebad_finish ();
2275
2276 return error_mark_node;
2277 }
2278
2279 return type;
2280}
5ff904cd
JL
2281
2282/* Builds a length argument (PARM_DECL). Also wraps type in an array type
2283 where the dimension info is (1:size) where <size> is ffesymbol_size(s) if
2284 known, length_arg if not known (FFETARGET_charactersizeNONE). */
2285
5ff904cd
JL
2286static tree
2287ffecom_char_enhance_arg_ (tree *xtype, ffesymbol s)
2288{
2289 ffetargetCharacterSize sz = ffesymbol_size (s);
2290 tree highval;
2291 tree tlen;
2292 tree type = *xtype;
2293
2294 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT)
2295 tlen = NULL_TREE; /* A statement function, no length passed. */
2296 else
2297 {
2298 if (ffesymbol_where (s) == FFEINFO_whereDUMMY)
2299 tlen = ffecom_get_invented_identifier ("__g77_length_%s",
14657de8 2300 ffesymbol_text (s));
5ff904cd 2301 else
14657de8 2302 tlen = ffecom_get_invented_identifier ("__g77_%s", "length");
5ff904cd 2303 tlen = build_decl (PARM_DECL, tlen, ffecom_f2c_ftnlen_type_node);
5ff904cd 2304 DECL_ARTIFICIAL (tlen) = 1;
5ff904cd
JL
2305 }
2306
2307 if (sz == FFETARGET_charactersizeNONE)
2308 {
2309 assert (tlen != NULL_TREE);
2b0c2df0 2310 highval = variable_size (tlen);
5ff904cd
JL
2311 }
2312 else
2313 {
2314 highval = build_int_2 (sz, 0);
2315 TREE_TYPE (highval) = ffecom_f2c_ftnlen_type_node;
2316 }
2317
2318 type = build_array_type (type,
2319 build_range_type (ffecom_f2c_ftnlen_type_node,
2320 ffecom_f2c_ftnlen_one_node,
2321 highval));
2322
2323 *xtype = type;
2324 return tlen;
2325}
2326
5ff904cd
JL
2327/* ffecom_concat_list_gather_ -- Gather list of concatenated string exprs
2328
2329 ffecomConcatList_ catlist;
2330 ffebld expr; // expr of CHARACTER basictype.
2331 ffetargetCharacterSize max; // max chars to gather or _...NONE if no max
2332 catlist = ffecom_concat_list_gather_(catlist,expr,max);
2333
2334 Scans expr for character subexpressions, updates and returns catlist
2335 accordingly. */
2336
5ff904cd
JL
2337static ffecomConcatList_
2338ffecom_concat_list_gather_ (ffecomConcatList_ catlist, ffebld expr,
2339 ffetargetCharacterSize max)
2340{
2341 ffetargetCharacterSize sz;
2342
516b69ff 2343 recurse:
5ff904cd
JL
2344
2345 if (expr == NULL)
2346 return catlist;
2347
2348 if ((max != FFETARGET_charactersizeNONE) && (catlist.minlen >= max))
2349 return catlist; /* Don't append any more items. */
2350
2351 switch (ffebld_op (expr))
2352 {
2353 case FFEBLD_opCONTER:
2354 case FFEBLD_opSYMTER:
2355 case FFEBLD_opARRAYREF:
2356 case FFEBLD_opFUNCREF:
2357 case FFEBLD_opSUBSTR:
2358 case FFEBLD_opCONVERT: /* Callers should strip this off beforehand
2359 if they don't need to preserve it. */
2360 if (catlist.count == catlist.max)
2361 { /* Make a (larger) list. */
2362 ffebld *newx;
2363 int newmax;
2364
2365 newmax = (catlist.max == 0) ? 8 : catlist.max * 2;
2366 newx = malloc_new_ks (malloc_pool_image (), "catlist",
2367 newmax * sizeof (newx[0]));
2368 if (catlist.max != 0)
2369 {
2370 memcpy (newx, catlist.exprs, catlist.max * sizeof (newx[0]));
2371 malloc_kill_ks (malloc_pool_image (), catlist.exprs,
2372 catlist.max * sizeof (newx[0]));
2373 }
2374 catlist.max = newmax;
2375 catlist.exprs = newx;
2376 }
2377 if ((sz = ffebld_size_known (expr)) != FFETARGET_charactersizeNONE)
2378 catlist.minlen += sz;
2379 else
2380 ++catlist.minlen; /* Not true for F90; can be 0 length. */
2381 if ((sz = ffebld_size_max (expr)) == FFETARGET_charactersizeNONE)
2382 catlist.maxlen = sz;
2383 else
2384 catlist.maxlen += sz;
2385 if ((max != FFETARGET_charactersizeNONE) && (catlist.minlen > max))
2386 { /* This item overlaps (or is beyond) the end
2387 of the destination. */
2388 switch (ffebld_op (expr))
2389 {
2390 case FFEBLD_opCONTER:
2391 case FFEBLD_opSYMTER:
2392 case FFEBLD_opARRAYREF:
2393 case FFEBLD_opFUNCREF:
2394 case FFEBLD_opSUBSTR:
c7e4ee3a
CB
2395 /* ~~Do useful truncations here. */
2396 break;
5ff904cd
JL
2397
2398 default:
2399 assert ("op changed or inconsistent switches!" == NULL);
2400 break;
2401 }
2402 }
2403 catlist.exprs[catlist.count++] = expr;
2404 return catlist;
2405
2406 case FFEBLD_opPAREN:
2407 expr = ffebld_left (expr);
2408 goto recurse; /* :::::::::::::::::::: */
2409
2410 case FFEBLD_opCONCATENATE:
2411 catlist = ffecom_concat_list_gather_ (catlist, ffebld_left (expr), max);
2412 expr = ffebld_right (expr);
2413 goto recurse; /* :::::::::::::::::::: */
2414
2415#if 0 /* Breaks passing small actual arg to larger
2416 dummy arg of sfunc */
2417 case FFEBLD_opCONVERT:
2418 expr = ffebld_left (expr);
2419 {
2420 ffetargetCharacterSize cmax;
2421
2422 cmax = catlist.len + ffebld_size_known (expr);
2423
2424 if ((max == FFETARGET_charactersizeNONE) || (max > cmax))
2425 max = cmax;
2426 }
2427 goto recurse; /* :::::::::::::::::::: */
2428#endif
2429
2430 case FFEBLD_opANY:
2431 return catlist;
2432
2433 default:
2434 assert ("bad op in _gather_" == NULL);
2435 return catlist;
2436 }
2437}
2438
5ff904cd
JL
2439/* ffecom_concat_list_kill_ -- Kill list of concatenated string exprs
2440
2441 ffecomConcatList_ catlist;
2442 ffecom_concat_list_kill_(catlist);
2443
2444 Anything allocated within the list info is deallocated. */
2445
5ff904cd
JL
2446static void
2447ffecom_concat_list_kill_ (ffecomConcatList_ catlist)
2448{
2449 if (catlist.max != 0)
2450 malloc_kill_ks (malloc_pool_image (), catlist.exprs,
2451 catlist.max * sizeof (catlist.exprs[0]));
2452}
2453
c7e4ee3a 2454/* Make list of concatenated string exprs.
5ff904cd
JL
2455
2456 Returns a flattened list of concatenated subexpressions given a
2457 tree of such expressions. */
2458
5ff904cd
JL
2459static ffecomConcatList_
2460ffecom_concat_list_new_ (ffebld expr, ffetargetCharacterSize max)
2461{
2462 ffecomConcatList_ catlist;
2463
2464 catlist.maxlen = catlist.minlen = catlist.max = catlist.count = 0;
2465 return ffecom_concat_list_gather_ (catlist, expr, max);
2466}
2467
5ff904cd
JL
2468/* Provide some kind of useful info on member of aggregate area,
2469 since current g77/gcc technology does not provide debug info
2470 on these members. */
2471
5ff904cd 2472static void
26f096f9 2473ffecom_debug_kludge_ (tree aggr, const char *aggr_type, ffesymbol member,
5ff904cd
JL
2474 tree member_type UNUSED, ffetargetOffset offset)
2475{
2476 tree value;
2477 tree decl;
2478 int len;
2479 char *buff;
2480 char space[120];
2481#if 0
2482 tree type_id;
2483
2484 for (type_id = member_type;
2485 TREE_CODE (type_id) != IDENTIFIER_NODE;
2486 )
2487 {
2488 switch (TREE_CODE (type_id))
2489 {
2490 case INTEGER_TYPE:
2491 case REAL_TYPE:
2492 type_id = TYPE_NAME (type_id);
2493 break;
2494
2495 case ARRAY_TYPE:
2496 case COMPLEX_TYPE:
2497 type_id = TREE_TYPE (type_id);
2498 break;
2499
2500 default:
2501 assert ("no IDENTIFIER_NODE for type!" == NULL);
2502 type_id = error_mark_node;
2503 break;
2504 }
2505 }
2506#endif
2507
2508 if (ffecom_transform_only_dummies_
2509 || !ffe_is_debug_kludge ())
2510 return; /* Can't do this yet, maybe later. */
2511
2512 len = 60
2513 + strlen (aggr_type)
2514 + IDENTIFIER_LENGTH (DECL_NAME (aggr));
2515#if 0
2516 + IDENTIFIER_LENGTH (type_id);
2517#endif
2518
2519 if (((size_t) len) >= ARRAY_SIZE (space))
2520 buff = malloc_new_ks (malloc_pool_image (), "debug_kludge", len + 1);
2521 else
2522 buff = &space[0];
2523
2524 sprintf (&buff[0], "At (%s) `%s' plus %ld bytes",
2525 aggr_type,
2526 IDENTIFIER_POINTER (DECL_NAME (aggr)),
2527 (long int) offset);
2528
2529 value = build_string (len, buff);
2530 TREE_TYPE (value)
2531 = build_type_variant (build_array_type (char_type_node,
2532 build_range_type
2533 (integer_type_node,
2534 integer_one_node,
2535 build_int_2 (strlen (buff), 0))),
2536 1, 0);
2537 decl = build_decl (VAR_DECL,
2538 ffecom_get_identifier_ (ffesymbol_text (member)),
2539 TREE_TYPE (value));
2540 TREE_CONSTANT (decl) = 1;
2541 TREE_STATIC (decl) = 1;
2542 DECL_INITIAL (decl) = error_mark_node;
2543 DECL_IN_SYSTEM_HEADER (decl) = 1; /* Don't let -Wunused complain. */
2544 decl = start_decl (decl, FALSE);
2545 finish_decl (decl, value, FALSE);
2546
2547 if (buff != &space[0])
2548 malloc_kill_ks (malloc_pool_image (), buff, len + 1);
2549}
5ff904cd
JL
2550
2551/* ffecom_do_entry_ -- Do compilation of a particular entrypoint
2552
2553 ffesymbol fn; // the SUBROUTINE, FUNCTION, or ENTRY symbol itself
2554 int i; // entry# for this entrypoint (used by master fn)
2555 ffecom_do_entrypoint_(s,i);
2556
2557 Makes a public entry point that calls our private master fn (already
2558 compiled). */
2559
5ff904cd
JL
2560static void
2561ffecom_do_entry_ (ffesymbol fn, int entrynum)
2562{
2563 ffebld item;
2564 tree type; /* Type of function. */
2565 tree multi_retval; /* Var holding return value (union). */
2566 tree result; /* Var holding result. */
2567 ffeinfoBasictype bt;
2568 ffeinfoKindtype kt;
2569 ffeglobal g;
2570 ffeglobalType gt;
2571 bool charfunc; /* All entry points return same type
2572 CHARACTER. */
2573 bool cmplxfunc; /* Use f2c way of returning COMPLEX. */
2574 bool multi; /* Master fn has multiple return types. */
2575 bool altreturning = FALSE; /* This entry point has alternate returns. */
44d2eabc 2576 int old_lineno = lineno;
3b304f5b 2577 const char *old_input_filename = input_filename;
44d2eabc
JL
2578
2579 input_filename = ffesymbol_where_filename (fn);
2580 lineno = ffesymbol_where_filelinenum (fn);
5ff904cd 2581
5ff904cd
JL
2582 ffecom_doing_entry_ = TRUE; /* Don't bother with array dimensions. */
2583
2584 switch (ffecom_primary_entry_kind_)
2585 {
2586 case FFEINFO_kindFUNCTION:
2587
2588 /* Determine actual return type for function. */
2589
2590 gt = FFEGLOBAL_typeFUNC;
2591 bt = ffesymbol_basictype (fn);
2592 kt = ffesymbol_kindtype (fn);
2593 if (bt == FFEINFO_basictypeNONE)
2594 {
2595 ffeimplic_establish_symbol (fn);
2596 if (ffesymbol_funcresult (fn) != NULL)
2597 ffeimplic_establish_symbol (ffesymbol_funcresult (fn));
2598 bt = ffesymbol_basictype (fn);
2599 kt = ffesymbol_kindtype (fn);
2600 }
2601
2602 if (bt == FFEINFO_basictypeCHARACTER)
2603 charfunc = TRUE, cmplxfunc = FALSE;
2604 else if ((bt == FFEINFO_basictypeCOMPLEX)
2605 && ffesymbol_is_f2c (fn))
2606 charfunc = FALSE, cmplxfunc = TRUE;
2607 else
2608 charfunc = cmplxfunc = FALSE;
2609
2610 if (charfunc)
2611 type = ffecom_tree_fun_type_void;
2612 else if (ffesymbol_is_f2c (fn))
2613 type = ffecom_tree_fun_type[bt][kt];
2614 else
2615 type = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
2616
2617 if ((type == NULL_TREE)
2618 || (TREE_TYPE (type) == NULL_TREE))
2619 type = ffecom_tree_fun_type_void; /* _sym_exec_transition. */
2620
2621 multi = (ffecom_master_bt_ == FFEINFO_basictypeNONE);
2622 break;
2623
2624 case FFEINFO_kindSUBROUTINE:
2625 gt = FFEGLOBAL_typeSUBR;
2626 bt = FFEINFO_basictypeNONE;
2627 kt = FFEINFO_kindtypeNONE;
2628 if (ffecom_is_altreturning_)
2629 { /* Am _I_ altreturning? */
2630 for (item = ffesymbol_dummyargs (fn);
2631 item != NULL;
2632 item = ffebld_trail (item))
2633 {
2634 if (ffebld_op (ffebld_head (item)) == FFEBLD_opSTAR)
2635 {
2636 altreturning = TRUE;
2637 break;
2638 }
2639 }
2640 if (altreturning)
2641 type = ffecom_tree_subr_type;
2642 else
2643 type = ffecom_tree_fun_type_void;
2644 }
2645 else
2646 type = ffecom_tree_fun_type_void;
2647 charfunc = FALSE;
2648 cmplxfunc = FALSE;
2649 multi = FALSE;
2650 break;
2651
2652 default:
2653 assert ("say what??" == NULL);
2654 /* Fall through. */
2655 case FFEINFO_kindANY:
2656 gt = FFEGLOBAL_typeANY;
2657 bt = FFEINFO_basictypeNONE;
2658 kt = FFEINFO_kindtypeNONE;
2659 type = error_mark_node;
2660 charfunc = FALSE;
2661 cmplxfunc = FALSE;
2662 multi = FALSE;
2663 break;
2664 }
2665
2666 /* build_decl uses the current lineno and input_filename to set the decl
2667 source info. So, I've putzed with ffestd and ffeste code to update that
2668 source info to point to the appropriate statement just before calling
2669 ffecom_do_entrypoint (which calls this fn). */
2670
2671 start_function (ffecom_get_external_identifier_ (fn),
2672 type,
2673 0, /* nested/inline */
2674 1); /* TREE_PUBLIC */
2675
2676 if (((g = ffesymbol_global (fn)) != NULL)
2677 && ((ffeglobal_type (g) == gt)
2678 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
2679 {
2680 ffeglobal_set_hook (g, current_function_decl);
2681 }
2682
2683 /* Reset args in master arg list so they get retransitioned. */
2684
2685 for (item = ffecom_master_arglist_;
2686 item != NULL;
2687 item = ffebld_trail (item))
2688 {
2689 ffebld arg;
2690 ffesymbol s;
2691
2692 arg = ffebld_head (item);
2693 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2694 continue; /* Alternate return or some such thing. */
2695 s = ffebld_symter (arg);
2696 ffesymbol_hook (s).decl_tree = NULL_TREE;
2697 ffesymbol_hook (s).length_tree = NULL_TREE;
2698 }
2699
2700 /* Build dummy arg list for this entry point. */
2701
5ff904cd
JL
2702 if (charfunc || cmplxfunc)
2703 { /* Prepend arg for where result goes. */
2704 tree type;
2705 tree length;
2706
2707 if (charfunc)
2708 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
2709 else
2710 type = ffecom_tree_type[FFEINFO_basictypeCOMPLEX][kt];
2711
14657de8 2712 result = ffecom_get_invented_identifier ("__g77_%s", "result");
5ff904cd
JL
2713
2714 /* Make length arg _and_ enhance type info for CHAR arg itself. */
2715
2716 if (charfunc)
2717 length = ffecom_char_enhance_arg_ (&type, fn);
2718 else
2719 length = NULL_TREE; /* Not ref'd if !charfunc. */
2720
2721 type = build_pointer_type (type);
2722 result = build_decl (PARM_DECL, result, type);
2723
2724 push_parm_decl (result);
2725 ffecom_func_result_ = result;
2726
2727 if (charfunc)
2728 {
2729 push_parm_decl (length);
2730 ffecom_func_length_ = length;
2731 }
2732 }
2733 else
2734 result = DECL_RESULT (current_function_decl);
2735
2736 ffecom_push_dummy_decls_ (ffesymbol_dummyargs (fn), FALSE);
2737
5ff904cd
JL
2738 store_parm_decls (0);
2739
c7e4ee3a
CB
2740 ffecom_start_compstmt ();
2741 /* Disallow temp vars at this level. */
2742 current_binding_level->prep_state = 2;
5ff904cd
JL
2743
2744 /* Make local var to hold return type for multi-type master fn. */
2745
2746 if (multi)
2747 {
5ff904cd 2748 multi_retval = ffecom_get_invented_identifier ("__g77_%s",
14657de8 2749 "multi_retval");
5ff904cd
JL
2750 multi_retval = build_decl (VAR_DECL, multi_retval,
2751 ffecom_multi_type_node_);
2752 multi_retval = start_decl (multi_retval, FALSE);
2753 finish_decl (multi_retval, NULL_TREE, FALSE);
5ff904cd
JL
2754 }
2755 else
2756 multi_retval = NULL_TREE; /* Not actually ref'd if !multi. */
2757
2758 /* Here we emit the actual code for the entry point. */
2759
2760 {
2761 ffebld list;
2762 ffebld arg;
2763 ffesymbol s;
2764 tree arglist = NULL_TREE;
2765 tree *plist = &arglist;
2766 tree prepend;
2767 tree call;
2768 tree actarg;
2769 tree master_fn;
2770
2771 /* Prepare actual arg list based on master arg list. */
2772
2773 for (list = ffecom_master_arglist_;
2774 list != NULL;
2775 list = ffebld_trail (list))
2776 {
2777 arg = ffebld_head (list);
2778 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2779 continue;
2780 s = ffebld_symter (arg);
702edf1d
CB
2781 if (ffesymbol_hook (s).decl_tree == NULL_TREE
2782 || ffesymbol_hook (s).decl_tree == error_mark_node)
5ff904cd
JL
2783 actarg = null_pointer_node; /* We don't have this arg. */
2784 else
2785 actarg = ffesymbol_hook (s).decl_tree;
2786 *plist = build_tree_list (NULL_TREE, actarg);
2787 plist = &TREE_CHAIN (*plist);
2788 }
2789
2790 /* This code appends the length arguments for character
2791 variables/arrays. */
2792
2793 for (list = ffecom_master_arglist_;
2794 list != NULL;
2795 list = ffebld_trail (list))
2796 {
2797 arg = ffebld_head (list);
2798 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2799 continue;
2800 s = ffebld_symter (arg);
2801 if (ffesymbol_basictype (s) != FFEINFO_basictypeCHARACTER)
2802 continue; /* Only looking for CHARACTER arguments. */
2803 if (ffesymbol_kind (s) != FFEINFO_kindENTITY)
2804 continue; /* Only looking for variables and arrays. */
702edf1d
CB
2805 if (ffesymbol_hook (s).length_tree == NULL_TREE
2806 || ffesymbol_hook (s).length_tree == error_mark_node)
5ff904cd
JL
2807 actarg = ffecom_f2c_ftnlen_zero_node; /* We don't have this arg. */
2808 else
2809 actarg = ffesymbol_hook (s).length_tree;
2810 *plist = build_tree_list (NULL_TREE, actarg);
2811 plist = &TREE_CHAIN (*plist);
2812 }
2813
2814 /* Prepend character-value return info to actual arg list. */
2815
2816 if (charfunc)
2817 {
2818 prepend = build_tree_list (NULL_TREE, ffecom_func_result_);
2819 TREE_CHAIN (prepend)
2820 = build_tree_list (NULL_TREE, ffecom_func_length_);
2821 TREE_CHAIN (TREE_CHAIN (prepend)) = arglist;
2822 arglist = prepend;
2823 }
2824
2825 /* Prepend multi-type return value to actual arg list. */
2826
2827 if (multi)
2828 {
2829 prepend
2830 = build_tree_list (NULL_TREE,
2831 ffecom_1 (ADDR_EXPR,
2832 build_pointer_type (TREE_TYPE (multi_retval)),
2833 multi_retval));
2834 TREE_CHAIN (prepend) = arglist;
2835 arglist = prepend;
2836 }
2837
2838 /* Prepend my entry-point number to the actual arg list. */
2839
2840 prepend = build_tree_list (NULL_TREE, build_int_2 (entrynum, 0));
2841 TREE_CHAIN (prepend) = arglist;
2842 arglist = prepend;
2843
2844 /* Build the call to the master function. */
2845
2846 master_fn = ffecom_1_fn (ffecom_previous_function_decl_);
2847 call = ffecom_3s (CALL_EXPR,
2848 TREE_TYPE (TREE_TYPE (TREE_TYPE (master_fn))),
2849 master_fn, arglist, NULL_TREE);
2850
2851 /* Decide whether the master function is a function or subroutine, and
2852 handle the return value for my entry point. */
2853
2854 if (charfunc || ((ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE)
2855 && !altreturning))
2856 {
2857 expand_expr_stmt (call);
2858 expand_null_return ();
2859 }
2860 else if (multi && cmplxfunc)
2861 {
2862 expand_expr_stmt (call);
2863 result
2864 = ffecom_1 (INDIRECT_REF,
2865 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result))),
2866 result);
2867 result = ffecom_modify (NULL_TREE, result,
2868 ffecom_2 (COMPONENT_REF, TREE_TYPE (result),
2869 multi_retval,
2870 ffecom_multi_fields_[bt][kt]));
2871 expand_expr_stmt (result);
2872 expand_null_return ();
2873 }
2874 else if (multi)
2875 {
2876 expand_expr_stmt (call);
2877 result
2878 = ffecom_modify (NULL_TREE, result,
2879 convert (TREE_TYPE (result),
2880 ffecom_2 (COMPONENT_REF,
2881 ffecom_tree_type[bt][kt],
2882 multi_retval,
2883 ffecom_multi_fields_[bt][kt])));
2884 expand_return (result);
2885 }
2886 else if (cmplxfunc)
2887 {
2888 result
2889 = ffecom_1 (INDIRECT_REF,
2890 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result))),
2891 result);
2892 result = ffecom_modify (NULL_TREE, result, call);
2893 expand_expr_stmt (result);
2894 expand_null_return ();
2895 }
2896 else
2897 {
2898 result = ffecom_modify (NULL_TREE,
2899 result,
2900 convert (TREE_TYPE (result),
2901 call));
2902 expand_return (result);
2903 }
5ff904cd
JL
2904 }
2905
c7e4ee3a 2906 ffecom_end_compstmt ();
5ff904cd
JL
2907
2908 finish_function (0);
2909
44d2eabc
JL
2910 lineno = old_lineno;
2911 input_filename = old_input_filename;
2912
5ff904cd
JL
2913 ffecom_doing_entry_ = FALSE;
2914}
2915
5ff904cd
JL
2916/* Transform expr into gcc tree with possible destination
2917
2918 Recursive descent on expr while making corresponding tree nodes and
2919 attaching type info and such. If destination supplied and compatible
2920 with temporary that would be made in certain cases, temporary isn't
092a4ef8 2921 made, destination used instead, and dest_used flag set TRUE. */
5ff904cd 2922
5ff904cd 2923static tree
092a4ef8
RH
2924ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest,
2925 bool *dest_used, bool assignp, bool widenp)
5ff904cd
JL
2926{
2927 tree item;
2928 tree list;
2929 tree args;
2930 ffeinfoBasictype bt;
2931 ffeinfoKindtype kt;
2932 tree t;
5ff904cd 2933 tree dt; /* decl_tree for an ffesymbol. */
092a4ef8 2934 tree tree_type, tree_type_x;
af752698 2935 tree left, right;
5ff904cd
JL
2936 ffesymbol s;
2937 enum tree_code code;
2938
2939 assert (expr != NULL);
2940
2941 if (dest_used != NULL)
2942 *dest_used = FALSE;
2943
2944 bt = ffeinfo_basictype (ffebld_info (expr));
2945 kt = ffeinfo_kindtype (ffebld_info (expr));
af752698 2946 tree_type = ffecom_tree_type[bt][kt];
5ff904cd 2947
092a4ef8
RH
2948 /* Widen integral arithmetic as desired while preserving signedness. */
2949 tree_type_x = NULL_TREE;
2950 if (widenp && tree_type
2951 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
2952 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
2953 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
2954
5ff904cd
JL
2955 switch (ffebld_op (expr))
2956 {
2957 case FFEBLD_opACCTER:
5ff904cd
JL
2958 {
2959 ffebitCount i;
2960 ffebit bits = ffebld_accter_bits (expr);
2961 ffetargetOffset source_offset = 0;
a6fa6420 2962 ffetargetOffset dest_offset = ffebld_accter_pad (expr);
5ff904cd
JL
2963 tree purpose;
2964
a6fa6420
CB
2965 assert (dest_offset == 0
2966 || (bt == FFEINFO_basictypeCHARACTER
2967 && kt == FFEINFO_kindtypeCHARACTER1));
5ff904cd
JL
2968
2969 list = item = NULL;
2970 for (;;)
2971 {
2972 ffebldConstantUnion cu;
2973 ffebitCount length;
2974 bool value;
2975 ffebldConstantArray ca = ffebld_accter (expr);
2976
2977 ffebit_test (bits, source_offset, &value, &length);
2978 if (length == 0)
2979 break;
2980
2981 if (value)
2982 {
2983 for (i = 0; i < length; ++i)
2984 {
2985 cu = ffebld_constantarray_get (ca, bt, kt,
2986 source_offset + i);
2987
2988 t = ffecom_constantunion (&cu, bt, kt, tree_type);
2989
a6fa6420
CB
2990 if (i == 0
2991 && dest_offset != 0)
2992 purpose = build_int_2 (dest_offset, 0);
5ff904cd
JL
2993 else
2994 purpose = NULL_TREE;
2995
2996 if (list == NULL_TREE)
2997 list = item = build_tree_list (purpose, t);
2998 else
2999 {
3000 TREE_CHAIN (item) = build_tree_list (purpose, t);
3001 item = TREE_CHAIN (item);
3002 }
3003 }
3004 }
3005 source_offset += length;
a6fa6420 3006 dest_offset += length;
5ff904cd
JL
3007 }
3008 }
3009
a6fa6420
CB
3010 item = build_int_2 ((ffebld_accter_size (expr)
3011 + ffebld_accter_pad (expr)) - 1, 0);
5ff904cd
JL
3012 ffebit_kill (ffebld_accter_bits (expr));
3013 TREE_TYPE (item) = ffecom_integer_type_node;
3014 item
3015 = build_array_type
3016 (tree_type,
3017 build_range_type (ffecom_integer_type_node,
3018 ffecom_integer_zero_node,
3019 item));
3020 list = build (CONSTRUCTOR, item, NULL_TREE, list);
3021 TREE_CONSTANT (list) = 1;
3022 TREE_STATIC (list) = 1;
3023 return list;
3024
3025 case FFEBLD_opARRTER:
5ff904cd
JL
3026 {
3027 ffetargetOffset i;
3028
a6fa6420
CB
3029 list = NULL_TREE;
3030 if (ffebld_arrter_pad (expr) == 0)
3031 item = NULL_TREE;
3032 else
3033 {
3034 assert (bt == FFEINFO_basictypeCHARACTER
3035 && kt == FFEINFO_kindtypeCHARACTER1);
3036
3037 /* Becomes PURPOSE first time through loop. */
3038 item = build_int_2 (ffebld_arrter_pad (expr), 0);
3039 }
3040
5ff904cd
JL
3041 for (i = 0; i < ffebld_arrter_size (expr); ++i)
3042 {
3043 ffebldConstantUnion cu
3044 = ffebld_constantarray_get (ffebld_arrter (expr), bt, kt, i);
3045
3046 t = ffecom_constantunion (&cu, bt, kt, tree_type);
3047
3048 if (list == NULL_TREE)
a6fa6420
CB
3049 /* Assume item is PURPOSE first time through loop. */
3050 list = item = build_tree_list (item, t);
5ff904cd
JL
3051 else
3052 {
3053 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
3054 item = TREE_CHAIN (item);
3055 }
3056 }
3057 }
3058
a6fa6420
CB
3059 item = build_int_2 ((ffebld_arrter_size (expr)
3060 + ffebld_arrter_pad (expr)) - 1, 0);
5ff904cd
JL
3061 TREE_TYPE (item) = ffecom_integer_type_node;
3062 item
3063 = build_array_type
3064 (tree_type,
3065 build_range_type (ffecom_integer_type_node,
a6fa6420 3066 ffecom_integer_zero_node,
5ff904cd
JL
3067 item));
3068 list = build (CONSTRUCTOR, item, NULL_TREE, list);
3069 TREE_CONSTANT (list) = 1;
3070 TREE_STATIC (list) = 1;
3071 return list;
3072
3073 case FFEBLD_opCONTER:
c264f113 3074 assert (ffebld_conter_pad (expr) == 0);
5ff904cd
JL
3075 item
3076 = ffecom_constantunion (&ffebld_constant_union (ffebld_conter (expr)),
3077 bt, kt, tree_type);
3078 return item;
3079
3080 case FFEBLD_opSYMTER:
3081 if ((ffebld_symter_generic (expr) != FFEINTRIN_genNONE)
3082 || (ffebld_symter_specific (expr) != FFEINTRIN_specNONE))
3083 return ffecom_ptr_to_expr (expr); /* Same as %REF(intrinsic). */
3084 s = ffebld_symter (expr);
3085 t = ffesymbol_hook (s).decl_tree;
3086
3087 if (assignp)
3088 { /* ASSIGN'ed-label expr. */
3089 if (ffe_is_ugly_assign ())
3090 {
3091 /* User explicitly wants ASSIGN'ed variables to be at the same
3092 memory address as the variables when used in non-ASSIGN
3093 contexts. That can make old, arcane, non-standard code
3094 work, but don't try to do it when a pointer wouldn't fit
3095 in the normal variable (take other approach, and warn,
3096 instead). */
3097
3098 if (t == NULL_TREE)
3099 {
3100 s = ffecom_sym_transform_ (s);
3101 t = ffesymbol_hook (s).decl_tree;
3102 assert (t != NULL_TREE);
3103 }
3104
3105 if (t == error_mark_node)
3106 return t;
3107
3108 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (t)))
3109 >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
3110 {
3111 if (ffesymbol_hook (s).addr)
3112 t = ffecom_1 (INDIRECT_REF,
3113 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), t);
3114 return t;
3115 }
3116
3117 if (ffesymbol_hook (s).assign_tree == NULL_TREE)
3118 {
3119 ffebad_start_msg ("ASSIGN'ed label cannot fit into `%A' at %0 -- using wider sibling",
3120 FFEBAD_severityWARNING);
3121 ffebad_string (ffesymbol_text (s));
3122 ffebad_here (0, ffesymbol_where_line (s),
3123 ffesymbol_where_column (s));
3124 ffebad_finish ();
3125 }
3126 }
3127
3128 /* Don't use the normal variable's tree for ASSIGN, though mark
3129 it as in the system header (housekeeping). Use an explicit,
3130 specially created sibling that is known to be wide enough
3131 to hold pointers to labels. */
3132
3133 if (t != NULL_TREE
3134 && TREE_CODE (t) == VAR_DECL)
3135 DECL_IN_SYSTEM_HEADER (t) = 1; /* Don't let -Wunused complain. */
3136
3137 t = ffesymbol_hook (s).assign_tree;
3138 if (t == NULL_TREE)
3139 {
3140 s = ffecom_sym_transform_assign_ (s);
3141 t = ffesymbol_hook (s).assign_tree;
3142 assert (t != NULL_TREE);
3143 }
3144 }
3145 else
3146 {
3147 if (t == NULL_TREE)
3148 {
3149 s = ffecom_sym_transform_ (s);
3150 t = ffesymbol_hook (s).decl_tree;
3151 assert (t != NULL_TREE);
3152 }
3153 if (ffesymbol_hook (s).addr)
3154 t = ffecom_1 (INDIRECT_REF,
3155 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), t);
3156 }
3157 return t;
3158
3159 case FFEBLD_opARRAYREF:
ff852b44 3160 return ffecom_arrayref_ (NULL_TREE, expr, 0);
5ff904cd
JL
3161
3162 case FFEBLD_opUPLUS:
092a4ef8 3163 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
af752698 3164 return ffecom_1 (NOP_EXPR, tree_type, left);
5ff904cd 3165
c7e4ee3a
CB
3166 case FFEBLD_opPAREN:
3167 /* ~~~Make sure Fortran rules respected here */
092a4ef8 3168 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
af752698 3169 return ffecom_1 (NOP_EXPR, tree_type, left);
5ff904cd
JL
3170
3171 case FFEBLD_opUMINUS:
092a4ef8 3172 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
516b69ff 3173 if (tree_type_x)
af752698
RH
3174 {
3175 tree_type = tree_type_x;
3176 left = convert (tree_type, left);
3177 }
3178 return ffecom_1 (NEGATE_EXPR, tree_type, left);
5ff904cd
JL
3179
3180 case FFEBLD_opADD:
092a4ef8
RH
3181 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3182 right = ffecom_expr_ (ffebld_right (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 right = convert (tree_type, right);
3188 }
3189 return ffecom_2 (PLUS_EXPR, tree_type, left, right);
5ff904cd
JL
3190
3191 case FFEBLD_opSUBTRACT:
092a4ef8
RH
3192 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3193 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
516b69ff 3194 if (tree_type_x)
af752698
RH
3195 {
3196 tree_type = tree_type_x;
3197 left = convert (tree_type, left);
3198 right = convert (tree_type, right);
3199 }
3200 return ffecom_2 (MINUS_EXPR, tree_type, left, right);
5ff904cd
JL
3201
3202 case FFEBLD_opMULTIPLY:
092a4ef8
RH
3203 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3204 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
516b69ff 3205 if (tree_type_x)
af752698
RH
3206 {
3207 tree_type = tree_type_x;
3208 left = convert (tree_type, left);
3209 right = convert (tree_type, right);
3210 }
3211 return ffecom_2 (MULT_EXPR, tree_type, left, right);
5ff904cd
JL
3212
3213 case FFEBLD_opDIVIDE:
092a4ef8
RH
3214 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3215 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
516b69ff 3216 if (tree_type_x)
af752698
RH
3217 {
3218 tree_type = tree_type_x;
3219 left = convert (tree_type, left);
3220 right = convert (tree_type, right);
3221 }
3222 return ffecom_tree_divide_ (tree_type, left, right,
c7e4ee3a
CB
3223 dest_tree, dest, dest_used,
3224 ffebld_nonter_hook (expr));
5ff904cd
JL
3225
3226 case FFEBLD_opPOWER:
5ff904cd
JL
3227 {
3228 ffebld left = ffebld_left (expr);
3229 ffebld right = ffebld_right (expr);
3230 ffecomGfrt code;
3231 ffeinfoKindtype rtkt;
270fc4e8 3232 ffeinfoKindtype ltkt;
95eb4fd9 3233 bool ref = TRUE;
5ff904cd
JL
3234
3235 switch (ffeinfo_basictype (ffebld_info (right)))
3236 {
95eb4fd9 3237
5ff904cd
JL
3238 case FFEINFO_basictypeINTEGER:
3239 if (1 || optimize)
3240 {
c7e4ee3a 3241 item = ffecom_expr_power_integer_ (expr);
5ff904cd
JL
3242 if (item != NULL_TREE)
3243 return item;
3244 }
3245
3246 rtkt = FFEINFO_kindtypeINTEGER1;
3247 switch (ffeinfo_basictype (ffebld_info (left)))
3248 {
3249 case FFEINFO_basictypeINTEGER:
3250 if ((ffeinfo_kindtype (ffebld_info (left))
3251 == FFEINFO_kindtypeINTEGER4)
3252 || (ffeinfo_kindtype (ffebld_info (right))
3253 == FFEINFO_kindtypeINTEGER4))
3254 {
3255 code = FFECOM_gfrtPOW_QQ;
270fc4e8 3256 ltkt = FFEINFO_kindtypeINTEGER4;
5ff904cd
JL
3257 rtkt = FFEINFO_kindtypeINTEGER4;
3258 }
3259 else
6a047254
CB
3260 {
3261 code = FFECOM_gfrtPOW_II;
3262 ltkt = FFEINFO_kindtypeINTEGER1;
3263 }
5ff904cd
JL
3264 break;
3265
3266 case FFEINFO_basictypeREAL:
3267 if (ffeinfo_kindtype (ffebld_info (left))
3268 == FFEINFO_kindtypeREAL1)
6a047254
CB
3269 {
3270 code = FFECOM_gfrtPOW_RI;
3271 ltkt = FFEINFO_kindtypeREAL1;
3272 }
5ff904cd 3273 else
6a047254
CB
3274 {
3275 code = FFECOM_gfrtPOW_DI;
3276 ltkt = FFEINFO_kindtypeREAL2;
3277 }
5ff904cd
JL
3278 break;
3279
3280 case FFEINFO_basictypeCOMPLEX:
3281 if (ffeinfo_kindtype (ffebld_info (left))
3282 == FFEINFO_kindtypeREAL1)
6a047254
CB
3283 {
3284 code = FFECOM_gfrtPOW_CI; /* Overlapping result okay. */
3285 ltkt = FFEINFO_kindtypeREAL1;
3286 }
5ff904cd 3287 else
6a047254
CB
3288 {
3289 code = FFECOM_gfrtPOW_ZI; /* Overlapping result okay. */
3290 ltkt = FFEINFO_kindtypeREAL2;
3291 }
5ff904cd
JL
3292 break;
3293
3294 default:
3295 assert ("bad pow_*i" == NULL);
3296 code = FFECOM_gfrtPOW_CI; /* Overlapping result okay. */
6a047254 3297 ltkt = FFEINFO_kindtypeREAL1;
5ff904cd
JL
3298 break;
3299 }
270fc4e8 3300 if (ffeinfo_kindtype (ffebld_info (left)) != ltkt)
5ff904cd 3301 left = ffeexpr_convert (left, NULL, NULL,
6a047254 3302 ffeinfo_basictype (ffebld_info (left)),
270fc4e8 3303 ltkt, 0,
5ff904cd
JL
3304 FFETARGET_charactersizeNONE,
3305 FFEEXPR_contextLET);
3306 if (ffeinfo_kindtype (ffebld_info (right)) != rtkt)
3307 right = ffeexpr_convert (right, NULL, NULL,
3308 FFEINFO_basictypeINTEGER,
3309 rtkt, 0,
3310 FFETARGET_charactersizeNONE,
3311 FFEEXPR_contextLET);
3312 break;
3313
3314 case FFEINFO_basictypeREAL:
3315 if (ffeinfo_kindtype (ffebld_info (left)) == FFEINFO_kindtypeREAL1)
3316 left = ffeexpr_convert (left, NULL, NULL, FFEINFO_basictypeREAL,
3317 FFEINFO_kindtypeREALDOUBLE, 0,
3318 FFETARGET_charactersizeNONE,
3319 FFEEXPR_contextLET);
3320 if (ffeinfo_kindtype (ffebld_info (right))
3321 == FFEINFO_kindtypeREAL1)
3322 right = ffeexpr_convert (right, NULL, NULL,
3323 FFEINFO_basictypeREAL,
3324 FFEINFO_kindtypeREALDOUBLE, 0,
3325 FFETARGET_charactersizeNONE,
3326 FFEEXPR_contextLET);
95eb4fd9
TM
3327 /* We used to call FFECOM_gfrtPOW_DD here,
3328 which passes arguments by reference. */
3329 code = FFECOM_gfrtL_POW;
3330 /* Pass arguments by value. */
3331 ref = FALSE;
5ff904cd
JL
3332 break;
3333
3334 case FFEINFO_basictypeCOMPLEX:
3335 if (ffeinfo_kindtype (ffebld_info (left)) == FFEINFO_kindtypeREAL1)
3336 left = ffeexpr_convert (left, NULL, NULL,
3337 FFEINFO_basictypeCOMPLEX,
3338 FFEINFO_kindtypeREALDOUBLE, 0,
3339 FFETARGET_charactersizeNONE,
3340 FFEEXPR_contextLET);
3341 if (ffeinfo_kindtype (ffebld_info (right))
3342 == FFEINFO_kindtypeREAL1)
3343 right = ffeexpr_convert (right, NULL, NULL,
3344 FFEINFO_basictypeCOMPLEX,
3345 FFEINFO_kindtypeREALDOUBLE, 0,
3346 FFETARGET_charactersizeNONE,
3347 FFEEXPR_contextLET);
3348 code = FFECOM_gfrtPOW_ZZ; /* Overlapping result okay. */
95eb4fd9 3349 ref = TRUE; /* Pass arguments by reference. */
5ff904cd
JL
3350 break;
3351
3352 default:
3353 assert ("bad pow_x*" == NULL);
3354 code = FFECOM_gfrtPOW_II;
3355 break;
3356 }
3357 return ffecom_call_binop_ (ffecom_gfrt_tree_ (code),
3358 ffecom_gfrt_kindtype (code),
3359 (ffe_is_f2c_library ()
3360 && ffecom_gfrt_complex_[code]),
3361 tree_type, left, right,
3362 dest_tree, dest, dest_used,
95eb4fd9 3363 NULL_TREE, FALSE, ref,
c7e4ee3a 3364 ffebld_nonter_hook (expr));
5ff904cd
JL
3365 }
3366
3367 case FFEBLD_opNOT:
5ff904cd
JL
3368 switch (bt)
3369 {
3370 case FFEINFO_basictypeLOGICAL:
83ffecd2 3371 item = ffecom_truth_value_invert (ffecom_expr (ffebld_left (expr)));
5ff904cd
JL
3372 return convert (tree_type, item);
3373
3374 case FFEINFO_basictypeINTEGER:
3375 return ffecom_1 (BIT_NOT_EXPR, tree_type,
3376 ffecom_expr (ffebld_left (expr)));
3377
3378 default:
3379 assert ("NOT bad basictype" == NULL);
3380 /* Fall through. */
3381 case FFEINFO_basictypeANY:
3382 return error_mark_node;
3383 }
3384 break;
3385
3386 case FFEBLD_opFUNCREF:
3387 assert (ffeinfo_basictype (ffebld_info (expr))
3388 != FFEINFO_basictypeCHARACTER);
3389 /* Fall through. */
3390 case FFEBLD_opSUBRREF:
5ff904cd
JL
3391 if (ffeinfo_where (ffebld_info (ffebld_left (expr)))
3392 == FFEINFO_whereINTRINSIC)
3393 { /* Invocation of an intrinsic. */
3394 item = ffecom_expr_intrinsic_ (expr, dest_tree, dest,
3395 dest_used);
3396 return item;
3397 }
3398 s = ffebld_symter (ffebld_left (expr));
3399 dt = ffesymbol_hook (s).decl_tree;
3400 if (dt == NULL_TREE)
3401 {
3402 s = ffecom_sym_transform_ (s);
3403 dt = ffesymbol_hook (s).decl_tree;
3404 }
3405 if (dt == error_mark_node)
3406 return dt;
3407
3408 if (ffesymbol_hook (s).addr)
3409 item = dt;
3410 else
3411 item = ffecom_1_fn (dt);
3412
5ff904cd
JL
3413 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT)
3414 args = ffecom_list_expr (ffebld_right (expr));
3415 else
3416 args = ffecom_list_ptr_to_expr (ffebld_right (expr));
5ff904cd 3417
702edf1d
CB
3418 if (args == error_mark_node)
3419 return error_mark_node;
3420
5ff904cd
JL
3421 item = ffecom_call_ (item, kt,
3422 ffesymbol_is_f2c (s)
3423 && (bt == FFEINFO_basictypeCOMPLEX)
3424 && (ffesymbol_where (s)
3425 != FFEINFO_whereCONSTANT),
3426 tree_type,
3427 args,
3428 dest_tree, dest, dest_used,
c7e4ee3a
CB
3429 error_mark_node, FALSE,
3430 ffebld_nonter_hook (expr));
5ff904cd
JL
3431 TREE_SIDE_EFFECTS (item) = 1;
3432 return item;
3433
3434 case FFEBLD_opAND:
5ff904cd
JL
3435 switch (bt)
3436 {
3437 case FFEINFO_basictypeLOGICAL:
3438 item
3439 = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
3440 ffecom_truth_value (ffecom_expr (ffebld_left (expr))),
3441 ffecom_truth_value (ffecom_expr (ffebld_right (expr))));
3442 return convert (tree_type, item);
3443
3444 case FFEINFO_basictypeINTEGER:
3445 return ffecom_2 (BIT_AND_EXPR, tree_type,
3446 ffecom_expr (ffebld_left (expr)),
3447 ffecom_expr (ffebld_right (expr)));
3448
3449 default:
3450 assert ("AND bad basictype" == NULL);
3451 /* Fall through. */
3452 case FFEINFO_basictypeANY:
3453 return error_mark_node;
3454 }
3455 break;
3456
3457 case FFEBLD_opOR:
5ff904cd
JL
3458 switch (bt)
3459 {
3460 case FFEINFO_basictypeLOGICAL:
3461 item
3462 = ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
3463 ffecom_truth_value (ffecom_expr (ffebld_left (expr))),
3464 ffecom_truth_value (ffecom_expr (ffebld_right (expr))));
3465 return convert (tree_type, item);
3466
3467 case FFEINFO_basictypeINTEGER:
3468 return ffecom_2 (BIT_IOR_EXPR, tree_type,
3469 ffecom_expr (ffebld_left (expr)),
3470 ffecom_expr (ffebld_right (expr)));
3471
3472 default:
3473 assert ("OR bad basictype" == NULL);
3474 /* Fall through. */
3475 case FFEINFO_basictypeANY:
3476 return error_mark_node;
3477 }
3478 break;
3479
3480 case FFEBLD_opXOR:
3481 case FFEBLD_opNEQV:
5ff904cd
JL
3482 switch (bt)
3483 {
3484 case FFEINFO_basictypeLOGICAL:
3485 item
3486 = ffecom_2 (NE_EXPR, integer_type_node,
3487 ffecom_expr (ffebld_left (expr)),
3488 ffecom_expr (ffebld_right (expr)));
3489 return convert (tree_type, ffecom_truth_value (item));
3490
3491 case FFEINFO_basictypeINTEGER:
3492 return ffecom_2 (BIT_XOR_EXPR, tree_type,
3493 ffecom_expr (ffebld_left (expr)),
3494 ffecom_expr (ffebld_right (expr)));
3495
3496 default:
3497 assert ("XOR/NEQV bad basictype" == NULL);
3498 /* Fall through. */
3499 case FFEINFO_basictypeANY:
3500 return error_mark_node;
3501 }
3502 break;
3503
3504 case FFEBLD_opEQV:
5ff904cd
JL
3505 switch (bt)
3506 {
3507 case FFEINFO_basictypeLOGICAL:
3508 item
3509 = ffecom_2 (EQ_EXPR, integer_type_node,
3510 ffecom_expr (ffebld_left (expr)),
3511 ffecom_expr (ffebld_right (expr)));
3512 return convert (tree_type, ffecom_truth_value (item));
3513
3514 case FFEINFO_basictypeINTEGER:
3515 return
3516 ffecom_1 (BIT_NOT_EXPR, tree_type,
3517 ffecom_2 (BIT_XOR_EXPR, tree_type,
3518 ffecom_expr (ffebld_left (expr)),
3519 ffecom_expr (ffebld_right (expr))));
3520
3521 default:
3522 assert ("EQV bad basictype" == NULL);
3523 /* Fall through. */
3524 case FFEINFO_basictypeANY:
3525 return error_mark_node;
3526 }
3527 break;
3528
3529 case FFEBLD_opCONVERT:
3530 if (ffebld_op (ffebld_left (expr)) == FFEBLD_opANY)
3531 return error_mark_node;
3532
5ff904cd
JL
3533 switch (bt)
3534 {
3535 case FFEINFO_basictypeLOGICAL:
3536 case FFEINFO_basictypeINTEGER:
3537 case FFEINFO_basictypeREAL:
3538 return convert (tree_type, ffecom_expr (ffebld_left (expr)));
3539
3540 case FFEINFO_basictypeCOMPLEX:
3541 switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr))))
3542 {
3543 case FFEINFO_basictypeINTEGER:
3544 case FFEINFO_basictypeLOGICAL:
3545 case FFEINFO_basictypeREAL:
3546 item = ffecom_expr (ffebld_left (expr));
3547 if (item == error_mark_node)
3548 return error_mark_node;
3549 /* convert() takes care of converting to the subtype first,
3550 at least in gcc-2.7.2. */
3551 item = convert (tree_type, item);
3552 return item;
3553
3554 case FFEINFO_basictypeCOMPLEX:
3555 return convert (tree_type, ffecom_expr (ffebld_left (expr)));
3556
3557 default:
3558 assert ("CONVERT COMPLEX bad basictype" == NULL);
3559 /* Fall through. */
3560 case FFEINFO_basictypeANY:
3561 return error_mark_node;
3562 }
3563 break;
3564
3565 default:
3566 assert ("CONVERT bad basictype" == NULL);
3567 /* Fall through. */
3568 case FFEINFO_basictypeANY:
3569 return error_mark_node;
3570 }
3571 break;
3572
3573 case FFEBLD_opLT:
3574 code = LT_EXPR;
3575 goto relational; /* :::::::::::::::::::: */
3576
3577 case FFEBLD_opLE:
3578 code = LE_EXPR;
3579 goto relational; /* :::::::::::::::::::: */
3580
3581 case FFEBLD_opEQ:
3582 code = EQ_EXPR;
3583 goto relational; /* :::::::::::::::::::: */
3584
3585 case FFEBLD_opNE:
3586 code = NE_EXPR;
3587 goto relational; /* :::::::::::::::::::: */
3588
3589 case FFEBLD_opGT:
3590 code = GT_EXPR;
3591 goto relational; /* :::::::::::::::::::: */
3592
3593 case FFEBLD_opGE:
3594 code = GE_EXPR;
3595
3596 relational: /* :::::::::::::::::::: */
5ff904cd
JL
3597 switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr))))
3598 {
3599 case FFEINFO_basictypeLOGICAL:
3600 case FFEINFO_basictypeINTEGER:
3601 case FFEINFO_basictypeREAL:
3602 item = ffecom_2 (code, integer_type_node,
3603 ffecom_expr (ffebld_left (expr)),
3604 ffecom_expr (ffebld_right (expr)));
3605 return convert (tree_type, item);
3606
3607 case FFEINFO_basictypeCOMPLEX:
3608 assert (code == EQ_EXPR || code == NE_EXPR);
3609 {
3610 tree real_type;
3611 tree arg1 = ffecom_expr (ffebld_left (expr));
3612 tree arg2 = ffecom_expr (ffebld_right (expr));
3613
3614 if (arg1 == error_mark_node || arg2 == error_mark_node)
3615 return error_mark_node;
3616
3617 arg1 = ffecom_save_tree (arg1);
3618 arg2 = ffecom_save_tree (arg2);
3619
3620 if (TREE_CODE (TREE_TYPE (arg1)) == COMPLEX_TYPE)
3621 {
3622 real_type = TREE_TYPE (TREE_TYPE (arg1));
3623 assert (real_type == TREE_TYPE (TREE_TYPE (arg2)));
3624 }
3625 else
3626 {
3627 real_type = TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg1)));
3628 assert (real_type == TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg2))));
3629 }
3630
3631 item
3632 = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
3633 ffecom_2 (EQ_EXPR, integer_type_node,
3634 ffecom_1 (REALPART_EXPR, real_type, arg1),
3635 ffecom_1 (REALPART_EXPR, real_type, arg2)),
3636 ffecom_2 (EQ_EXPR, integer_type_node,
3637 ffecom_1 (IMAGPART_EXPR, real_type, arg1),
3638 ffecom_1 (IMAGPART_EXPR, real_type,
3639 arg2)));
3640 if (code == EQ_EXPR)
3641 item = ffecom_truth_value (item);
3642 else
3643 item = ffecom_truth_value_invert (item);
3644 return convert (tree_type, item);
3645 }
3646
3647 case FFEINFO_basictypeCHARACTER:
5ff904cd
JL
3648 {
3649 ffebld left = ffebld_left (expr);
3650 ffebld right = ffebld_right (expr);
3651 tree left_tree;
3652 tree right_tree;
3653 tree left_length;
3654 tree right_length;
3655
3656 /* f2c run-time functions do the implicit blank-padding for us,
3657 so we don't usually have to implement blank-padding ourselves.
3658 (The exception is when we pass an argument to a separately
3659 compiled statement function -- if we know the arg is not the
3660 same length as the dummy, we must truncate or extend it. If
3661 we "inline" statement functions, that necessity goes away as
3662 well.)
3663
3664 Strip off the CONVERT operators that blank-pad. (Truncation by
3665 CONVERT shouldn't happen here, but it can happen in
3666 assignments.) */
3667
3668 while (ffebld_op (left) == FFEBLD_opCONVERT)
3669 left = ffebld_left (left);
3670 while (ffebld_op (right) == FFEBLD_opCONVERT)
3671 right = ffebld_left (right);
3672
3673 left_tree = ffecom_arg_ptr_to_expr (left, &left_length);
3674 right_tree = ffecom_arg_ptr_to_expr (right, &right_length);
3675
3676 if (left_tree == error_mark_node || left_length == error_mark_node
3677 || right_tree == error_mark_node
3678 || right_length == error_mark_node)
c7e4ee3a 3679 return error_mark_node;
5ff904cd
JL
3680
3681 if ((ffebld_size_known (left) == 1)
3682 && (ffebld_size_known (right) == 1))
3683 {
3684 left_tree
3685 = ffecom_1 (INDIRECT_REF,
3686 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree))),
3687 left_tree);
3688 right_tree
3689 = ffecom_1 (INDIRECT_REF,
3690 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree))),
3691 right_tree);
3692
3693 item
3694 = ffecom_2 (code, integer_type_node,
3695 ffecom_2 (ARRAY_REF,
3696 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree))),
3697 left_tree,
3698 integer_one_node),
3699 ffecom_2 (ARRAY_REF,
3700 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree))),
3701 right_tree,
3702 integer_one_node));
3703 }
3704 else
3705 {
3706 item = build_tree_list (NULL_TREE, left_tree);
3707 TREE_CHAIN (item) = build_tree_list (NULL_TREE, right_tree);
3708 TREE_CHAIN (TREE_CHAIN (item)) = build_tree_list (NULL_TREE,
3709 left_length);
3710 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item)))
3711 = build_tree_list (NULL_TREE, right_length);
c7e4ee3a 3712 item = ffecom_call_gfrt (FFECOM_gfrtCMP, item, NULL_TREE);
5ff904cd
JL
3713 item = ffecom_2 (code, integer_type_node,
3714 item,
3715 convert (TREE_TYPE (item),
3716 integer_zero_node));
3717 }
3718 item = convert (tree_type, item);
3719 }
3720
5ff904cd
JL
3721 return item;
3722
3723 default:
3724 assert ("relational bad basictype" == NULL);
3725 /* Fall through. */
3726 case FFEINFO_basictypeANY:
3727 return error_mark_node;
3728 }
3729 break;
3730
3731 case FFEBLD_opPERCENT_LOC:
5ff904cd
JL
3732 item = ffecom_arg_ptr_to_expr (ffebld_left (expr), &list);
3733 return convert (tree_type, item);
3734
3735 case FFEBLD_opITEM:
3736 case FFEBLD_opSTAR:
3737 case FFEBLD_opBOUNDS:
3738 case FFEBLD_opREPEAT:
3739 case FFEBLD_opLABTER:
3740 case FFEBLD_opLABTOK:
3741 case FFEBLD_opIMPDO:
3742 case FFEBLD_opCONCATENATE:
3743 case FFEBLD_opSUBSTR:
3744 default:
3745 assert ("bad op" == NULL);
3746 /* Fall through. */
3747 case FFEBLD_opANY:
3748 return error_mark_node;
3749 }
3750
3751#if 1
3752 assert ("didn't think anything got here anymore!!" == NULL);
3753#else
3754 switch (ffebld_arity (expr))
3755 {
3756 case 2:
3757 TREE_OPERAND (item, 0) = ffecom_expr (ffebld_left (expr));
3758 TREE_OPERAND (item, 1) = ffecom_expr (ffebld_right (expr));
3759 if (TREE_OPERAND (item, 0) == error_mark_node
3760 || TREE_OPERAND (item, 1) == error_mark_node)
3761 return error_mark_node;
3762 break;
3763
3764 case 1:
3765 TREE_OPERAND (item, 0) = ffecom_expr (ffebld_left (expr));
3766 if (TREE_OPERAND (item, 0) == error_mark_node)
3767 return error_mark_node;
3768 break;
3769
3770 default:
3771 break;
3772 }
3773
3774 return fold (item);
3775#endif
3776}
3777
5ff904cd
JL
3778/* Returns the tree that does the intrinsic invocation.
3779
3780 Note: this function applies only to intrinsics returning
3781 CHARACTER*1 or non-CHARACTER results, and to intrinsic
3782 subroutines. */
3783
5ff904cd
JL
3784static tree
3785ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree,
3786 ffebld dest, bool *dest_used)
3787{
3788 tree expr_tree;
3789 tree saved_expr1; /* For those who need it. */
3790 tree saved_expr2; /* For those who need it. */
3791 ffeinfoBasictype bt;
3792 ffeinfoKindtype kt;
3793 tree tree_type;
3794 tree arg1_type;
3795 tree real_type; /* REAL type corresponding to COMPLEX. */
3796 tree tempvar;
3797 ffebld list = ffebld_right (expr); /* List of (some) args. */
3798 ffebld arg1; /* For handy reference. */
3799 ffebld arg2;
3800 ffebld arg3;
3801 ffeintrinImp codegen_imp;
3802 ffecomGfrt gfrt;
3803
3804 assert (ffebld_op (ffebld_left (expr)) == FFEBLD_opSYMTER);
3805
3806 if (dest_used != NULL)
3807 *dest_used = FALSE;
3808
3809 bt = ffeinfo_basictype (ffebld_info (expr));
3810 kt = ffeinfo_kindtype (ffebld_info (expr));
3811 tree_type = ffecom_tree_type[bt][kt];
3812
3813 if (list != NULL)
3814 {
3815 arg1 = ffebld_head (list);
3816 if (arg1 != NULL && ffebld_op (arg1) == FFEBLD_opANY)
3817 return error_mark_node;
3818 if ((list = ffebld_trail (list)) != NULL)
3819 {
3820 arg2 = ffebld_head (list);
3821 if (arg2 != NULL && ffebld_op (arg2) == FFEBLD_opANY)
3822 return error_mark_node;
3823 if ((list = ffebld_trail (list)) != NULL)
3824 {
3825 arg3 = ffebld_head (list);
3826 if (arg3 != NULL && ffebld_op (arg3) == FFEBLD_opANY)
3827 return error_mark_node;
3828 }
3829 else
3830 arg3 = NULL;
3831 }
3832 else
3833 arg2 = arg3 = NULL;
3834 }
3835 else
3836 arg1 = arg2 = arg3 = NULL;
3837
3838 /* <list> ends up at the opITEM of the 3rd arg, or NULL if there are < 3
3839 args. This is used by the MAX/MIN expansions. */
3840
3841 if (arg1 != NULL)
3842 arg1_type = ffecom_tree_type
3843 [ffeinfo_basictype (ffebld_info (arg1))]
3844 [ffeinfo_kindtype (ffebld_info (arg1))];
3845 else
3846 arg1_type = NULL_TREE; /* Really not needed, but might catch bugs
3847 here. */
3848
3849 /* There are several ways for each of the cases in the following switch
3850 statements to exit (from simplest to use to most complicated):
3851
3852 break; (when expr_tree == NULL)
3853
3854 A standard call is made to the specific intrinsic just as if it had been
3855 passed in as a dummy procedure and called as any old procedure. This
3856 method can produce slower code but in some cases it's the easiest way for
3857 now. However, if a (presumably faster) direct call is available,
3858 that is used, so this is the easiest way in many more cases now.
3859
3860 gfrt = FFECOM_gfrtWHATEVER;
3861 break;
3862
3863 gfrt contains the gfrt index of a library function to call, passing the
3864 argument(s) by value rather than by reference. Used when a more
3865 careful choice of library function is needed than that provided
3866 by the vanilla `break;'.
3867
3868 return expr_tree;
3869
3870 The expr_tree has been completely set up and is ready to be returned
3871 as is. No further actions are taken. Use this when the tree is not
3872 in the simple form for one of the arity_n labels. */
3873
3874 /* For info on how the switch statement cases were written, see the files
3875 enclosed in comments below the switch statement. */
3876
3877 codegen_imp = ffebld_symter_implementation (ffebld_left (expr));
3878 gfrt = ffeintrin_gfrt_direct (codegen_imp);
3879 if (gfrt == FFECOM_gfrt)
3880 gfrt = ffeintrin_gfrt_indirect (codegen_imp);
3881
3882 switch (codegen_imp)
3883 {
3884 case FFEINTRIN_impABS:
3885 case FFEINTRIN_impCABS:
3886 case FFEINTRIN_impCDABS:
3887 case FFEINTRIN_impDABS:
3888 case FFEINTRIN_impIABS:
3889 if (ffeinfo_basictype (ffebld_info (arg1))
3890 == FFEINFO_basictypeCOMPLEX)
3891 {
3892 if (kt == FFEINFO_kindtypeREAL1)
3893 gfrt = FFECOM_gfrtCABS;
3894 else if (kt == FFEINFO_kindtypeREAL2)
3895 gfrt = FFECOM_gfrtCDABS;
3896 break;
3897 }
3898 return ffecom_1 (ABS_EXPR, tree_type,
3899 convert (tree_type, ffecom_expr (arg1)));
3900
3901 case FFEINTRIN_impACOS:
3902 case FFEINTRIN_impDACOS:
3903 break;
3904
3905 case FFEINTRIN_impAIMAG:
3906 case FFEINTRIN_impDIMAG:
3907 case FFEINTRIN_impIMAGPART:
3908 if (TREE_CODE (arg1_type) == COMPLEX_TYPE)
3909 arg1_type = TREE_TYPE (arg1_type);
3910 else
3911 arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type));
3912
3913 return
3914 convert (tree_type,
3915 ffecom_1 (IMAGPART_EXPR, arg1_type,
3916 ffecom_expr (arg1)));
3917
3918 case FFEINTRIN_impAINT:
3919 case FFEINTRIN_impDINT:
c7e4ee3a
CB
3920#if 0
3921 /* ~~Someday implement FIX_TRUNC_EXPR yielding same type as arg. */
5ff904cd
JL
3922 return ffecom_1 (FIX_TRUNC_EXPR, tree_type, ffecom_expr (arg1));
3923#else /* in the meantime, must use floor to avoid range problems with ints */
3924 /* r__1 = r1 >= 0 ? floor(r1) : -floor(-r1); */
3925 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
3926 return
3927 convert (tree_type,
3928 ffecom_3 (COND_EXPR, double_type_node,
3929 ffecom_truth_value
3930 (ffecom_2 (GE_EXPR, integer_type_node,
3931 saved_expr1,
3932 convert (arg1_type,
3933 ffecom_float_zero_))),
3934 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
3935 build_tree_list (NULL_TREE,
3936 convert (double_type_node,
c7e4ee3a
CB
3937 saved_expr1)),
3938 NULL_TREE),
5ff904cd
JL
3939 ffecom_1 (NEGATE_EXPR, double_type_node,
3940 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
3941 build_tree_list (NULL_TREE,
3942 convert (double_type_node,
3943 ffecom_1 (NEGATE_EXPR,
3944 arg1_type,
c7e4ee3a
CB
3945 saved_expr1))),
3946 NULL_TREE)
5ff904cd
JL
3947 ))
3948 );
3949#endif
3950
3951 case FFEINTRIN_impANINT:
3952 case FFEINTRIN_impDNINT:
3953#if 0 /* This way of doing it won't handle real
3954 numbers of large magnitudes. */
3955 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
3956 expr_tree = convert (tree_type,
3957 convert (integer_type_node,
3958 ffecom_3 (COND_EXPR, tree_type,
3959 ffecom_truth_value
3960 (ffecom_2 (GE_EXPR,
3961 integer_type_node,
3962 saved_expr1,
3963 ffecom_float_zero_)),
3964 ffecom_2 (PLUS_EXPR,
3965 tree_type,
3966 saved_expr1,
3967 ffecom_float_half_),
3968 ffecom_2 (MINUS_EXPR,
3969 tree_type,
3970 saved_expr1,
3971 ffecom_float_half_))));
3972 return expr_tree;
3973#else /* So we instead call floor. */
3974 /* r__1 = r1 >= 0 ? floor(r1 + .5) : -floor(.5 - r1) */
3975 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
3976 return
3977 convert (tree_type,
3978 ffecom_3 (COND_EXPR, double_type_node,
3979 ffecom_truth_value
3980 (ffecom_2 (GE_EXPR, integer_type_node,
3981 saved_expr1,
3982 convert (arg1_type,
3983 ffecom_float_zero_))),
3984 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
3985 build_tree_list (NULL_TREE,
3986 convert (double_type_node,
3987 ffecom_2 (PLUS_EXPR,
3988 arg1_type,
3989 saved_expr1,
3990 convert (arg1_type,
c7e4ee3a
CB
3991 ffecom_float_half_)))),
3992 NULL_TREE),
5ff904cd
JL
3993 ffecom_1 (NEGATE_EXPR, double_type_node,
3994 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
3995 build_tree_list (NULL_TREE,
3996 convert (double_type_node,
3997 ffecom_2 (MINUS_EXPR,
3998 arg1_type,
3999 convert (arg1_type,
4000 ffecom_float_half_),
c7e4ee3a
CB
4001 saved_expr1))),
4002 NULL_TREE))
5ff904cd
JL
4003 )
4004 );
4005#endif
4006
4007 case FFEINTRIN_impASIN:
4008 case FFEINTRIN_impDASIN:
4009 case FFEINTRIN_impATAN:
4010 case FFEINTRIN_impDATAN:
4011 case FFEINTRIN_impATAN2:
4012 case FFEINTRIN_impDATAN2:
4013 break;
4014
4015 case FFEINTRIN_impCHAR:
4016 case FFEINTRIN_impACHAR:
c7e4ee3a
CB
4017#ifdef HOHO
4018 tempvar = ffecom_make_tempvar (char_type_node, 1, -1);
4019#else
4020 tempvar = ffebld_nonter_hook (expr);
4021 assert (tempvar);
4022#endif
5ff904cd
JL
4023 {
4024 tree tmv = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (tempvar)));
4025
4026 expr_tree = ffecom_modify (tmv,
4027 ffecom_2 (ARRAY_REF, tmv, tempvar,
4028 integer_one_node),
4029 convert (tmv, ffecom_expr (arg1)));
4030 }
4031 expr_tree = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar),
4032 expr_tree,
4033 tempvar);
4034 expr_tree = ffecom_1 (ADDR_EXPR,
4035 build_pointer_type (TREE_TYPE (expr_tree)),
4036 expr_tree);
4037 return expr_tree;
4038
4039 case FFEINTRIN_impCMPLX:
4040 case FFEINTRIN_impDCMPLX:
4041 if (arg2 == NULL)
4042 return
4043 convert (tree_type, ffecom_expr (arg1));
4044
4045 real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
4046 return
4047 ffecom_2 (COMPLEX_EXPR, tree_type,
4048 convert (real_type, ffecom_expr (arg1)),
4049 convert (real_type,
4050 ffecom_expr (arg2)));
4051
4052 case FFEINTRIN_impCOMPLEX:
4053 return
4054 ffecom_2 (COMPLEX_EXPR, tree_type,
4055 ffecom_expr (arg1),
4056 ffecom_expr (arg2));
4057
4058 case FFEINTRIN_impCONJG:
4059 case FFEINTRIN_impDCONJG:
4060 {
4061 tree arg1_tree;
4062
4063 real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
4064 arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4065 return
4066 ffecom_2 (COMPLEX_EXPR, tree_type,
4067 ffecom_1 (REALPART_EXPR, real_type, arg1_tree),
4068 ffecom_1 (NEGATE_EXPR, real_type,
4069 ffecom_1 (IMAGPART_EXPR, real_type, arg1_tree)));
4070 }
4071
4072 case FFEINTRIN_impCOS:
4073 case FFEINTRIN_impCCOS:
4074 case FFEINTRIN_impCDCOS:
4075 case FFEINTRIN_impDCOS:
4076 if (bt == FFEINFO_basictypeCOMPLEX)
4077 {
4078 if (kt == FFEINFO_kindtypeREAL1)
4079 gfrt = FFECOM_gfrtCCOS; /* Overlapping result okay. */
4080 else if (kt == FFEINFO_kindtypeREAL2)
4081 gfrt = FFECOM_gfrtCDCOS; /* Overlapping result okay. */
4082 }
4083 break;
4084
4085 case FFEINTRIN_impCOSH:
4086 case FFEINTRIN_impDCOSH:
4087 break;
4088
4089 case FFEINTRIN_impDBLE:
4090 case FFEINTRIN_impDFLOAT:
4091 case FFEINTRIN_impDREAL:
4092 case FFEINTRIN_impFLOAT:
4093 case FFEINTRIN_impIDINT:
4094 case FFEINTRIN_impIFIX:
4095 case FFEINTRIN_impINT2:
4096 case FFEINTRIN_impINT8:
4097 case FFEINTRIN_impINT:
4098 case FFEINTRIN_impLONG:
4099 case FFEINTRIN_impREAL:
4100 case FFEINTRIN_impSHORT:
4101 case FFEINTRIN_impSNGL:
4102 return convert (tree_type, ffecom_expr (arg1));
4103
4104 case FFEINTRIN_impDIM:
4105 case FFEINTRIN_impDDIM:
4106 case FFEINTRIN_impIDIM:
4107 saved_expr1 = ffecom_save_tree (convert (tree_type,
4108 ffecom_expr (arg1)));
4109 saved_expr2 = ffecom_save_tree (convert (tree_type,
4110 ffecom_expr (arg2)));
4111 return
4112 ffecom_3 (COND_EXPR, tree_type,
4113 ffecom_truth_value
4114 (ffecom_2 (GT_EXPR, integer_type_node,
4115 saved_expr1,
4116 saved_expr2)),
4117 ffecom_2 (MINUS_EXPR, tree_type,
4118 saved_expr1,
4119 saved_expr2),
4120 convert (tree_type, ffecom_float_zero_));
4121
4122 case FFEINTRIN_impDPROD:
4123 return
4124 ffecom_2 (MULT_EXPR, tree_type,
4125 convert (tree_type, ffecom_expr (arg1)),
4126 convert (tree_type, ffecom_expr (arg2)));
4127
4128 case FFEINTRIN_impEXP:
4129 case FFEINTRIN_impCDEXP:
4130 case FFEINTRIN_impCEXP:
4131 case FFEINTRIN_impDEXP:
4132 if (bt == FFEINFO_basictypeCOMPLEX)
4133 {
4134 if (kt == FFEINFO_kindtypeREAL1)
4135 gfrt = FFECOM_gfrtCEXP; /* Overlapping result okay. */
4136 else if (kt == FFEINFO_kindtypeREAL2)
4137 gfrt = FFECOM_gfrtCDEXP; /* Overlapping result okay. */
4138 }
4139 break;
4140
4141 case FFEINTRIN_impICHAR:
4142 case FFEINTRIN_impIACHAR:
4143#if 0 /* The simple approach. */
4144 ffecom_char_args_ (&expr_tree, &saved_expr1 /* Ignored */ , arg1);
4145 expr_tree
4146 = ffecom_1 (INDIRECT_REF,
4147 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
4148 expr_tree);
4149 expr_tree
4150 = ffecom_2 (ARRAY_REF,
4151 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
4152 expr_tree,
4153 integer_one_node);
4154 return convert (tree_type, expr_tree);
4155#else /* The more interesting (and more optimal) approach. */
4156 expr_tree = ffecom_intrinsic_ichar_ (tree_type, arg1, &saved_expr1);
4157 expr_tree = ffecom_3 (COND_EXPR, tree_type,
4158 saved_expr1,
4159 expr_tree,
4160 convert (tree_type, integer_zero_node));
4161 return expr_tree;
4162#endif
4163
4164 case FFEINTRIN_impINDEX:
4165 break;
4166
4167 case FFEINTRIN_impLEN:
4168#if 0
4169 break; /* The simple approach. */
4170#else
4171 return ffecom_intrinsic_len_ (arg1); /* The more optimal approach. */
4172#endif
4173
4174 case FFEINTRIN_impLGE:
4175 case FFEINTRIN_impLGT:
4176 case FFEINTRIN_impLLE:
4177 case FFEINTRIN_impLLT:
4178 break;
4179
4180 case FFEINTRIN_impLOG:
4181 case FFEINTRIN_impALOG:
4182 case FFEINTRIN_impCDLOG:
4183 case FFEINTRIN_impCLOG:
4184 case FFEINTRIN_impDLOG:
4185 if (bt == FFEINFO_basictypeCOMPLEX)
4186 {
4187 if (kt == FFEINFO_kindtypeREAL1)
4188 gfrt = FFECOM_gfrtCLOG; /* Overlapping result okay. */
4189 else if (kt == FFEINFO_kindtypeREAL2)
4190 gfrt = FFECOM_gfrtCDLOG; /* Overlapping result okay. */
4191 }
4192 break;
4193
4194 case FFEINTRIN_impLOG10:
4195 case FFEINTRIN_impALOG10:
4196 case FFEINTRIN_impDLOG10:
4197 if (gfrt != FFECOM_gfrt)
4198 break; /* Already picked one, stick with it. */
4199
4200 if (kt == FFEINFO_kindtypeREAL1)
95eb4fd9
TM
4201 /* We used to call FFECOM_gfrtALOG10 here. */
4202 gfrt = FFECOM_gfrtL_LOG10;
5ff904cd 4203 else if (kt == FFEINFO_kindtypeREAL2)
95eb4fd9
TM
4204 /* We used to call FFECOM_gfrtDLOG10 here. */
4205 gfrt = FFECOM_gfrtL_LOG10;
5ff904cd
JL
4206 break;
4207
4208 case FFEINTRIN_impMAX:
4209 case FFEINTRIN_impAMAX0:
4210 case FFEINTRIN_impAMAX1:
4211 case FFEINTRIN_impDMAX1:
4212 case FFEINTRIN_impMAX0:
4213 case FFEINTRIN_impMAX1:
4214 if (bt != ffeinfo_basictype (ffebld_info (arg1)))
4215 arg1_type = ffecom_widest_expr_type_ (ffebld_right (expr));
4216 else
4217 arg1_type = tree_type;
4218 expr_tree = ffecom_2 (MAX_EXPR, arg1_type,
4219 convert (arg1_type, ffecom_expr (arg1)),
4220 convert (arg1_type, ffecom_expr (arg2)));
4221 for (; list != NULL; list = ffebld_trail (list))
4222 {
4223 if ((ffebld_head (list) == NULL)
4224 || (ffebld_op (ffebld_head (list)) == FFEBLD_opANY))
4225 continue;
4226 expr_tree = ffecom_2 (MAX_EXPR, arg1_type,
4227 expr_tree,
4228 convert (arg1_type,
4229 ffecom_expr (ffebld_head (list))));
4230 }
4231 return convert (tree_type, expr_tree);
4232
4233 case FFEINTRIN_impMIN:
4234 case FFEINTRIN_impAMIN0:
4235 case FFEINTRIN_impAMIN1:
4236 case FFEINTRIN_impDMIN1:
4237 case FFEINTRIN_impMIN0:
4238 case FFEINTRIN_impMIN1:
4239 if (bt != ffeinfo_basictype (ffebld_info (arg1)))
4240 arg1_type = ffecom_widest_expr_type_ (ffebld_right (expr));
4241 else
4242 arg1_type = tree_type;
4243 expr_tree = ffecom_2 (MIN_EXPR, arg1_type,
4244 convert (arg1_type, ffecom_expr (arg1)),
4245 convert (arg1_type, ffecom_expr (arg2)));
4246 for (; list != NULL; list = ffebld_trail (list))
4247 {
4248 if ((ffebld_head (list) == NULL)
4249 || (ffebld_op (ffebld_head (list)) == FFEBLD_opANY))
4250 continue;
4251 expr_tree = ffecom_2 (MIN_EXPR, arg1_type,
4252 expr_tree,
4253 convert (arg1_type,
4254 ffecom_expr (ffebld_head (list))));
4255 }
4256 return convert (tree_type, expr_tree);
4257
4258 case FFEINTRIN_impMOD:
4259 case FFEINTRIN_impAMOD:
4260 case FFEINTRIN_impDMOD:
4261 if (bt != FFEINFO_basictypeREAL)
4262 return ffecom_2 (TRUNC_MOD_EXPR, tree_type,
4263 convert (tree_type, ffecom_expr (arg1)),
4264 convert (tree_type, ffecom_expr (arg2)));
4265
4266 if (kt == FFEINFO_kindtypeREAL1)
95eb4fd9
TM
4267 /* We used to call FFECOM_gfrtAMOD here. */
4268 gfrt = FFECOM_gfrtL_FMOD;
5ff904cd 4269 else if (kt == FFEINFO_kindtypeREAL2)
95eb4fd9
TM
4270 /* We used to call FFECOM_gfrtDMOD here. */
4271 gfrt = FFECOM_gfrtL_FMOD;
5ff904cd
JL
4272 break;
4273
4274 case FFEINTRIN_impNINT:
4275 case FFEINTRIN_impIDNINT:
c7e4ee3a
CB
4276#if 0
4277 /* ~~Ideally FIX_ROUND_EXPR would be implemented, but it ain't yet. */
5ff904cd
JL
4278 return ffecom_1 (FIX_ROUND_EXPR, tree_type, ffecom_expr (arg1));
4279#else
4280 /* i__1 = r1 >= 0 ? floor(r1 + .5) : -floor(.5 - r1); */
4281 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
4282 return
4283 convert (ffecom_integer_type_node,
4284 ffecom_3 (COND_EXPR, arg1_type,
4285 ffecom_truth_value
4286 (ffecom_2 (GE_EXPR, integer_type_node,
4287 saved_expr1,
4288 convert (arg1_type,
4289 ffecom_float_zero_))),
4290 ffecom_2 (PLUS_EXPR, arg1_type,
4291 saved_expr1,
4292 convert (arg1_type,
4293 ffecom_float_half_)),
4294 ffecom_2 (MINUS_EXPR, arg1_type,
4295 saved_expr1,
4296 convert (arg1_type,
4297 ffecom_float_half_))));
4298#endif
4299
4300 case FFEINTRIN_impSIGN:
4301 case FFEINTRIN_impDSIGN:
4302 case FFEINTRIN_impISIGN:
4303 {
4304 tree arg2_tree = ffecom_expr (arg2);
4305
4306 saved_expr1
4307 = ffecom_save_tree
4308 (ffecom_1 (ABS_EXPR, tree_type,
4309 convert (tree_type,
4310 ffecom_expr (arg1))));
4311 expr_tree
4312 = ffecom_3 (COND_EXPR, tree_type,
4313 ffecom_truth_value
4314 (ffecom_2 (GE_EXPR, integer_type_node,
4315 arg2_tree,
4316 convert (TREE_TYPE (arg2_tree),
4317 integer_zero_node))),
4318 saved_expr1,
4319 ffecom_1 (NEGATE_EXPR, tree_type, saved_expr1));
4320 /* Make sure SAVE_EXPRs get referenced early enough. */
4321 expr_tree
4322 = ffecom_2 (COMPOUND_EXPR, tree_type,
4323 convert (void_type_node, saved_expr1),
4324 expr_tree);
4325 }
4326 return expr_tree;
4327
4328 case FFEINTRIN_impSIN:
4329 case FFEINTRIN_impCDSIN:
4330 case FFEINTRIN_impCSIN:
4331 case FFEINTRIN_impDSIN:
4332 if (bt == FFEINFO_basictypeCOMPLEX)
4333 {
4334 if (kt == FFEINFO_kindtypeREAL1)
4335 gfrt = FFECOM_gfrtCSIN; /* Overlapping result okay. */
4336 else if (kt == FFEINFO_kindtypeREAL2)
4337 gfrt = FFECOM_gfrtCDSIN; /* Overlapping result okay. */
4338 }
4339 break;
4340
4341 case FFEINTRIN_impSINH:
4342 case FFEINTRIN_impDSINH:
4343 break;
4344
4345 case FFEINTRIN_impSQRT:
4346 case FFEINTRIN_impCDSQRT:
4347 case FFEINTRIN_impCSQRT:
4348 case FFEINTRIN_impDSQRT:
4349 if (bt == FFEINFO_basictypeCOMPLEX)
4350 {
4351 if (kt == FFEINFO_kindtypeREAL1)
4352 gfrt = FFECOM_gfrtCSQRT; /* Overlapping result okay. */
4353 else if (kt == FFEINFO_kindtypeREAL2)
4354 gfrt = FFECOM_gfrtCDSQRT; /* Overlapping result okay. */
4355 }
4356 break;
4357
4358 case FFEINTRIN_impTAN:
4359 case FFEINTRIN_impDTAN:
4360 case FFEINTRIN_impTANH:
4361 case FFEINTRIN_impDTANH:
4362 break;
4363
4364 case FFEINTRIN_impREALPART:
4365 if (TREE_CODE (arg1_type) == COMPLEX_TYPE)
4366 arg1_type = TREE_TYPE (arg1_type);
4367 else
4368 arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type));
4369
4370 return
4371 convert (tree_type,
4372 ffecom_1 (REALPART_EXPR, arg1_type,
4373 ffecom_expr (arg1)));
4374
4375 case FFEINTRIN_impIAND:
4376 case FFEINTRIN_impAND:
4377 return ffecom_2 (BIT_AND_EXPR, tree_type,
4378 convert (tree_type,
4379 ffecom_expr (arg1)),
4380 convert (tree_type,
4381 ffecom_expr (arg2)));
4382
4383 case FFEINTRIN_impIOR:
4384 case FFEINTRIN_impOR:
4385 return ffecom_2 (BIT_IOR_EXPR, tree_type,
4386 convert (tree_type,
4387 ffecom_expr (arg1)),
4388 convert (tree_type,
4389 ffecom_expr (arg2)));
4390
4391 case FFEINTRIN_impIEOR:
4392 case FFEINTRIN_impXOR:
4393 return ffecom_2 (BIT_XOR_EXPR, tree_type,
4394 convert (tree_type,
4395 ffecom_expr (arg1)),
4396 convert (tree_type,
4397 ffecom_expr (arg2)));
4398
4399 case FFEINTRIN_impLSHIFT:
4400 return ffecom_2 (LSHIFT_EXPR, tree_type,
4401 ffecom_expr (arg1),
4402 convert (integer_type_node,
4403 ffecom_expr (arg2)));
4404
4405 case FFEINTRIN_impRSHIFT:
4406 return ffecom_2 (RSHIFT_EXPR, tree_type,
4407 ffecom_expr (arg1),
4408 convert (integer_type_node,
4409 ffecom_expr (arg2)));
4410
4411 case FFEINTRIN_impNOT:
4412 return ffecom_1 (BIT_NOT_EXPR, tree_type, ffecom_expr (arg1));
4413
4414 case FFEINTRIN_impBIT_SIZE:
4415 return convert (tree_type, TYPE_SIZE (arg1_type));
4416
4417 case FFEINTRIN_impBTEST:
4418 {
d6edb99e
ZW
4419 ffetargetLogical1 target_true;
4420 ffetargetLogical1 target_false;
5ff904cd
JL
4421 tree true_tree;
4422 tree false_tree;
4423
d6edb99e
ZW
4424 ffetarget_logical1 (&target_true, TRUE);
4425 ffetarget_logical1 (&target_false, FALSE);
4426 if (target_true == 1)
5ff904cd
JL
4427 true_tree = convert (tree_type, integer_one_node);
4428 else
d6edb99e
ZW
4429 true_tree = convert (tree_type, build_int_2 (target_true, 0));
4430 if (target_false == 0)
5ff904cd
JL
4431 false_tree = convert (tree_type, integer_zero_node);
4432 else
d6edb99e 4433 false_tree = convert (tree_type, build_int_2 (target_false, 0));
5ff904cd
JL
4434
4435 return
4436 ffecom_3 (COND_EXPR, tree_type,
4437 ffecom_truth_value
4438 (ffecom_2 (EQ_EXPR, integer_type_node,
4439 ffecom_2 (BIT_AND_EXPR, arg1_type,
4440 ffecom_expr (arg1),
4441 ffecom_2 (LSHIFT_EXPR, arg1_type,
4442 convert (arg1_type,
4443 integer_one_node),
4444 convert (integer_type_node,
4445 ffecom_expr (arg2)))),
4446 convert (arg1_type,
4447 integer_zero_node))),
4448 false_tree,
4449 true_tree);
4450 }
4451
4452 case FFEINTRIN_impIBCLR:
4453 return
4454 ffecom_2 (BIT_AND_EXPR, tree_type,
4455 ffecom_expr (arg1),
4456 ffecom_1 (BIT_NOT_EXPR, tree_type,
4457 ffecom_2 (LSHIFT_EXPR, tree_type,
4458 convert (tree_type,
4459 integer_one_node),
4460 convert (integer_type_node,
4461 ffecom_expr (arg2)))));
4462
4463 case FFEINTRIN_impIBITS:
4464 {
4465 tree arg3_tree = ffecom_save_tree (convert (integer_type_node,
4466 ffecom_expr (arg3)));
4467 tree uns_type
4468 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4469
4470 expr_tree
4471 = ffecom_2 (BIT_AND_EXPR, tree_type,
4472 ffecom_2 (RSHIFT_EXPR, tree_type,
4473 ffecom_expr (arg1),
4474 convert (integer_type_node,
4475 ffecom_expr (arg2))),
4476 convert (tree_type,
4477 ffecom_2 (RSHIFT_EXPR, uns_type,
4478 ffecom_1 (BIT_NOT_EXPR,
4479 uns_type,
4480 convert (uns_type,
4481 integer_zero_node)),
4482 ffecom_2 (MINUS_EXPR,
4483 integer_type_node,
4484 TYPE_SIZE (uns_type),
4485 arg3_tree))));
eec9ac3d 4486 /* Fix up, because the RSHIFT_EXPR above can't shift over TYPE_SIZE. */
5ff904cd
JL
4487 expr_tree
4488 = ffecom_3 (COND_EXPR, tree_type,
4489 ffecom_truth_value
4490 (ffecom_2 (NE_EXPR, integer_type_node,
4491 arg3_tree,
4492 integer_zero_node)),
4493 expr_tree,
4494 convert (tree_type, integer_zero_node));
5ff904cd
JL
4495 }
4496 return expr_tree;
4497
4498 case FFEINTRIN_impIBSET:
4499 return
4500 ffecom_2 (BIT_IOR_EXPR, tree_type,
4501 ffecom_expr (arg1),
4502 ffecom_2 (LSHIFT_EXPR, tree_type,
4503 convert (tree_type, integer_one_node),
4504 convert (integer_type_node,
4505 ffecom_expr (arg2))));
4506
4507 case FFEINTRIN_impISHFT:
4508 {
4509 tree arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4510 tree arg2_tree = ffecom_save_tree (convert (integer_type_node,
4511 ffecom_expr (arg2)));
4512 tree uns_type
4513 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4514
4515 expr_tree
4516 = ffecom_3 (COND_EXPR, tree_type,
4517 ffecom_truth_value
4518 (ffecom_2 (GE_EXPR, integer_type_node,
4519 arg2_tree,
4520 integer_zero_node)),
4521 ffecom_2 (LSHIFT_EXPR, tree_type,
4522 arg1_tree,
4523 arg2_tree),
4524 convert (tree_type,
4525 ffecom_2 (RSHIFT_EXPR, uns_type,
4526 convert (uns_type, arg1_tree),
4527 ffecom_1 (NEGATE_EXPR,
4528 integer_type_node,
4529 arg2_tree))));
eec9ac3d 4530 /* Fix up, because {L|R}SHIFT_EXPR don't go over TYPE_SIZE bounds. */
5ff904cd
JL
4531 expr_tree
4532 = ffecom_3 (COND_EXPR, tree_type,
4533 ffecom_truth_value
eec9ac3d 4534 (ffecom_2 (NE_EXPR, integer_type_node,
7d46d516
TM
4535 ffecom_1 (ABS_EXPR,
4536 integer_type_node,
4537 arg2_tree),
5ff904cd
JL
4538 TYPE_SIZE (uns_type))),
4539 expr_tree,
4540 convert (tree_type, integer_zero_node));
5ff904cd
JL
4541 /* Make sure SAVE_EXPRs get referenced early enough. */
4542 expr_tree
4543 = ffecom_2 (COMPOUND_EXPR, tree_type,
4544 convert (void_type_node, arg1_tree),
4545 ffecom_2 (COMPOUND_EXPR, tree_type,
4546 convert (void_type_node, arg2_tree),
4547 expr_tree));
4548 }
4549 return expr_tree;
4550
4551 case FFEINTRIN_impISHFTC:
4552 {
4553 tree arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4554 tree arg2_tree = ffecom_save_tree (convert (integer_type_node,
4555 ffecom_expr (arg2)));
4556 tree arg3_tree = (arg3 == NULL) ? TYPE_SIZE (tree_type)
4557 : ffecom_save_tree (convert (integer_type_node, ffecom_expr (arg3)));
4558 tree shift_neg;
4559 tree shift_pos;
4560 tree mask_arg1;
4561 tree masked_arg1;
4562 tree uns_type
4563 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4564
4565 mask_arg1
4566 = ffecom_2 (LSHIFT_EXPR, tree_type,
4567 ffecom_1 (BIT_NOT_EXPR, tree_type,
4568 convert (tree_type, integer_zero_node)),
4569 arg3_tree);
eec9ac3d 4570 /* Fix up, because LSHIFT_EXPR above can't shift over TYPE_SIZE. */
5ff904cd
JL
4571 mask_arg1
4572 = ffecom_3 (COND_EXPR, tree_type,
4573 ffecom_truth_value
4574 (ffecom_2 (NE_EXPR, integer_type_node,
4575 arg3_tree,
4576 TYPE_SIZE (uns_type))),
4577 mask_arg1,
4578 convert (tree_type, integer_zero_node));
5ff904cd
JL
4579 mask_arg1 = ffecom_save_tree (mask_arg1);
4580 masked_arg1
4581 = ffecom_2 (BIT_AND_EXPR, tree_type,
4582 arg1_tree,
4583 ffecom_1 (BIT_NOT_EXPR, tree_type,
4584 mask_arg1));
4585 masked_arg1 = ffecom_save_tree (masked_arg1);
4586 shift_neg
4587 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4588 convert (tree_type,
4589 ffecom_2 (RSHIFT_EXPR, uns_type,
4590 convert (uns_type, masked_arg1),
4591 ffecom_1 (NEGATE_EXPR,
4592 integer_type_node,
4593 arg2_tree))),
4594 ffecom_2 (LSHIFT_EXPR, tree_type,
4595 arg1_tree,
4596 ffecom_2 (PLUS_EXPR, integer_type_node,
4597 arg2_tree,
4598 arg3_tree)));
4599 shift_pos
4600 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4601 ffecom_2 (LSHIFT_EXPR, tree_type,
4602 arg1_tree,
4603 arg2_tree),
4604 convert (tree_type,
4605 ffecom_2 (RSHIFT_EXPR, uns_type,
4606 convert (uns_type, masked_arg1),
4607 ffecom_2 (MINUS_EXPR,
4608 integer_type_node,
4609 arg3_tree,
4610 arg2_tree))));
4611 expr_tree
4612 = ffecom_3 (COND_EXPR, tree_type,
4613 ffecom_truth_value
4614 (ffecom_2 (LT_EXPR, integer_type_node,
4615 arg2_tree,
4616 integer_zero_node)),
4617 shift_neg,
4618 shift_pos);
4619 expr_tree
4620 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4621 ffecom_2 (BIT_AND_EXPR, tree_type,
4622 mask_arg1,
4623 arg1_tree),
4624 ffecom_2 (BIT_AND_EXPR, tree_type,
4625 ffecom_1 (BIT_NOT_EXPR, tree_type,
4626 mask_arg1),
4627 expr_tree));
4628 expr_tree
4629 = ffecom_3 (COND_EXPR, tree_type,
4630 ffecom_truth_value
4631 (ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
4632 ffecom_2 (EQ_EXPR, integer_type_node,
4633 ffecom_1 (ABS_EXPR,
4634 integer_type_node,
4635 arg2_tree),
4636 arg3_tree),
4637 ffecom_2 (EQ_EXPR, integer_type_node,
4638 arg2_tree,
4639 integer_zero_node))),
4640 arg1_tree,
4641 expr_tree);
4642 /* Make sure SAVE_EXPRs get referenced early enough. */
4643 expr_tree
4644 = ffecom_2 (COMPOUND_EXPR, tree_type,
4645 convert (void_type_node, arg1_tree),
4646 ffecom_2 (COMPOUND_EXPR, tree_type,
4647 convert (void_type_node, arg2_tree),
4648 ffecom_2 (COMPOUND_EXPR, tree_type,
4649 convert (void_type_node,
4650 mask_arg1),
4651 ffecom_2 (COMPOUND_EXPR, tree_type,
4652 convert (void_type_node,
4653 masked_arg1),
4654 expr_tree))));
4655 expr_tree
4656 = ffecom_2 (COMPOUND_EXPR, tree_type,
4657 convert (void_type_node,
4658 arg3_tree),
4659 expr_tree);
4660 }
4661 return expr_tree;
4662
4663 case FFEINTRIN_impLOC:
4664 {
4665 tree arg1_tree = ffecom_expr (arg1);
4666
4667 expr_tree
4668 = convert (tree_type,
4669 ffecom_1 (ADDR_EXPR,
4670 build_pointer_type (TREE_TYPE (arg1_tree)),
4671 arg1_tree));
4672 }
4673 return expr_tree;
4674
4675 case FFEINTRIN_impMVBITS:
4676 {
4677 tree arg1_tree;
4678 tree arg2_tree;
4679 tree arg3_tree;
4680 ffebld arg4 = ffebld_head (ffebld_trail (list));
4681 tree arg4_tree;
4682 tree arg4_type;
4683 ffebld arg5 = ffebld_head (ffebld_trail (ffebld_trail (list)));
4684 tree arg5_tree;
4685 tree prep_arg1;
4686 tree prep_arg4;
4687 tree arg5_plus_arg3;
4688
5ff904cd
JL
4689 arg2_tree = convert (integer_type_node,
4690 ffecom_expr (arg2));
4691 arg3_tree = ffecom_save_tree (convert (integer_type_node,
4692 ffecom_expr (arg3)));
c7e4ee3a 4693 arg4_tree = ffecom_expr_rw (NULL_TREE, arg4);
5ff904cd
JL
4694 arg4_type = TREE_TYPE (arg4_tree);
4695
4696 arg1_tree = ffecom_save_tree (convert (arg4_type,
4697 ffecom_expr (arg1)));
4698
4699 arg5_tree = ffecom_save_tree (convert (integer_type_node,
4700 ffecom_expr (arg5)));
4701
5ff904cd
JL
4702 prep_arg1
4703 = ffecom_2 (LSHIFT_EXPR, arg4_type,
4704 ffecom_2 (BIT_AND_EXPR, arg4_type,
4705 ffecom_2 (RSHIFT_EXPR, arg4_type,
4706 arg1_tree,
4707 arg2_tree),
4708 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4709 ffecom_2 (LSHIFT_EXPR, arg4_type,
4710 ffecom_1 (BIT_NOT_EXPR,
4711 arg4_type,
4712 convert
4713 (arg4_type,
4714 integer_zero_node)),
4715 arg3_tree))),
4716 arg5_tree);
4717 arg5_plus_arg3
4718 = ffecom_save_tree (ffecom_2 (PLUS_EXPR, arg4_type,
4719 arg5_tree,
4720 arg3_tree));
4721 prep_arg4
4722 = ffecom_2 (LSHIFT_EXPR, arg4_type,
4723 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4724 convert (arg4_type,
4725 integer_zero_node)),
4726 arg5_plus_arg3);
eec9ac3d 4727 /* Fix up, because LSHIFT_EXPR above can't shift over TYPE_SIZE. */
5ff904cd
JL
4728 prep_arg4
4729 = ffecom_3 (COND_EXPR, arg4_type,
4730 ffecom_truth_value
4731 (ffecom_2 (NE_EXPR, integer_type_node,
4732 arg5_plus_arg3,
4733 convert (TREE_TYPE (arg5_plus_arg3),
4734 TYPE_SIZE (arg4_type)))),
4735 prep_arg4,
4736 convert (arg4_type, integer_zero_node));
5ff904cd
JL
4737 prep_arg4
4738 = ffecom_2 (BIT_AND_EXPR, arg4_type,
4739 arg4_tree,
4740 ffecom_2 (BIT_IOR_EXPR, arg4_type,
4741 prep_arg4,
4742 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4743 ffecom_2 (LSHIFT_EXPR, arg4_type,
4744 ffecom_1 (BIT_NOT_EXPR,
4745 arg4_type,
4746 convert
4747 (arg4_type,
4748 integer_zero_node)),
4749 arg5_tree))));
4750 prep_arg1
4751 = ffecom_2 (BIT_IOR_EXPR, arg4_type,
4752 prep_arg1,
4753 prep_arg4);
eec9ac3d
TM
4754 /* Fix up (twice), because LSHIFT_EXPR above
4755 can't shift over TYPE_SIZE. */
5ff904cd
JL
4756 prep_arg1
4757 = ffecom_3 (COND_EXPR, arg4_type,
4758 ffecom_truth_value
4759 (ffecom_2 (NE_EXPR, integer_type_node,
4760 arg3_tree,
4761 convert (TREE_TYPE (arg3_tree),
4762 integer_zero_node))),
4763 prep_arg1,
4764 arg4_tree);
4765 prep_arg1
4766 = ffecom_3 (COND_EXPR, arg4_type,
4767 ffecom_truth_value
4768 (ffecom_2 (NE_EXPR, integer_type_node,
4769 arg3_tree,
4770 convert (TREE_TYPE (arg3_tree),
4771 TYPE_SIZE (arg4_type)))),
4772 prep_arg1,
4773 arg1_tree);
5ff904cd
JL
4774 expr_tree
4775 = ffecom_2s (MODIFY_EXPR, void_type_node,
4776 arg4_tree,
4777 prep_arg1);
4778 /* Make sure SAVE_EXPRs get referenced early enough. */
4779 expr_tree
4780 = ffecom_2 (COMPOUND_EXPR, void_type_node,
4781 arg1_tree,
4782 ffecom_2 (COMPOUND_EXPR, void_type_node,
4783 arg3_tree,
4784 ffecom_2 (COMPOUND_EXPR, void_type_node,
4785 arg5_tree,
4786 ffecom_2 (COMPOUND_EXPR, void_type_node,
4787 arg5_plus_arg3,
4788 expr_tree))));
4789 expr_tree
4790 = ffecom_2 (COMPOUND_EXPR, void_type_node,
4791 arg4_tree,
4792 expr_tree);
4793
4794 }
4795 return expr_tree;
4796
4797 case FFEINTRIN_impDERF:
4798 case FFEINTRIN_impERF:
4799 case FFEINTRIN_impDERFC:
4800 case FFEINTRIN_impERFC:
4801 break;
4802
4803 case FFEINTRIN_impIARGC:
4804 /* extern int xargc; i__1 = xargc - 1; */
4805 expr_tree = ffecom_2 (MINUS_EXPR, TREE_TYPE (ffecom_tree_xargc_),
4806 ffecom_tree_xargc_,
4807 convert (TREE_TYPE (ffecom_tree_xargc_),
4808 integer_one_node));
4809 return expr_tree;
4810
4811 case FFEINTRIN_impSIGNAL_func:
4812 case FFEINTRIN_impSIGNAL_subr:
4813 {
4814 tree arg1_tree;
4815 tree arg2_tree;
4816 tree arg3_tree;
4817
5ff904cd
JL
4818 arg1_tree = convert (ffecom_f2c_integer_type_node,
4819 ffecom_expr (arg1));
4820 arg1_tree = ffecom_1 (ADDR_EXPR,
4821 build_pointer_type (TREE_TYPE (arg1_tree)),
4822 arg1_tree);
4823
4824 /* Pass procedure as a pointer to it, anything else by value. */
4825 if (ffeinfo_kind (ffebld_info (arg2)) == FFEINFO_kindENTITY)
4826 arg2_tree = convert (integer_type_node, ffecom_expr (arg2));
4827 else
4828 arg2_tree = ffecom_ptr_to_expr (arg2);
4829 arg2_tree = convert (TREE_TYPE (null_pointer_node),
4830 arg2_tree);
4831
4832 if (arg3 != NULL)
c7e4ee3a 4833 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
4834 else
4835 arg3_tree = NULL_TREE;
4836
5ff904cd
JL
4837 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4838 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
4839 TREE_CHAIN (arg1_tree) = arg2_tree;
4840
4841 expr_tree
4842 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4843 ffecom_gfrt_kindtype (gfrt),
4844 FALSE,
4845 ((codegen_imp == FFEINTRIN_impSIGNAL_subr) ?
4846 NULL_TREE :
4847 tree_type),
4848 arg1_tree,
c7e4ee3a
CB
4849 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4850 ffebld_nonter_hook (expr));
5ff904cd
JL
4851
4852 if (arg3_tree != NULL_TREE)
4853 expr_tree
4854 = ffecom_modify (NULL_TREE, arg3_tree,
4855 convert (TREE_TYPE (arg3_tree),
4856 expr_tree));
4857 }
4858 return expr_tree;
4859
4860 case FFEINTRIN_impALARM:
4861 {
4862 tree arg1_tree;
4863 tree arg2_tree;
4864 tree arg3_tree;
4865
5ff904cd
JL
4866 arg1_tree = convert (ffecom_f2c_integer_type_node,
4867 ffecom_expr (arg1));
4868 arg1_tree = ffecom_1 (ADDR_EXPR,
4869 build_pointer_type (TREE_TYPE (arg1_tree)),
4870 arg1_tree);
4871
4872 /* Pass procedure as a pointer to it, anything else by value. */
4873 if (ffeinfo_kind (ffebld_info (arg2)) == FFEINFO_kindENTITY)
4874 arg2_tree = convert (integer_type_node, ffecom_expr (arg2));
4875 else
4876 arg2_tree = ffecom_ptr_to_expr (arg2);
4877 arg2_tree = convert (TREE_TYPE (null_pointer_node),
4878 arg2_tree);
4879
4880 if (arg3 != NULL)
c7e4ee3a 4881 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
4882 else
4883 arg3_tree = NULL_TREE;
4884
5ff904cd
JL
4885 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4886 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
4887 TREE_CHAIN (arg1_tree) = arg2_tree;
4888
4889 expr_tree
4890 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4891 ffecom_gfrt_kindtype (gfrt),
4892 FALSE,
4893 NULL_TREE,
4894 arg1_tree,
c7e4ee3a
CB
4895 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4896 ffebld_nonter_hook (expr));
5ff904cd
JL
4897
4898 if (arg3_tree != NULL_TREE)
4899 expr_tree
4900 = ffecom_modify (NULL_TREE, arg3_tree,
4901 convert (TREE_TYPE (arg3_tree),
4902 expr_tree));
4903 }
4904 return expr_tree;
4905
4906 case FFEINTRIN_impCHDIR_subr:
4907 case FFEINTRIN_impFDATE_subr:
4908 case FFEINTRIN_impFGET_subr:
4909 case FFEINTRIN_impFPUT_subr:
4910 case FFEINTRIN_impGETCWD_subr:
4911 case FFEINTRIN_impHOSTNM_subr:
4912 case FFEINTRIN_impSYSTEM_subr:
4913 case FFEINTRIN_impUNLINK_subr:
4914 {
4915 tree arg1_len = integer_zero_node;
4916 tree arg1_tree;
4917 tree arg2_tree;
4918
5ff904cd
JL
4919 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
4920
4921 if (arg2 != NULL)
c7e4ee3a 4922 arg2_tree = ffecom_expr_w (NULL_TREE, arg2);
5ff904cd
JL
4923 else
4924 arg2_tree = NULL_TREE;
4925
5ff904cd
JL
4926 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4927 arg1_len = build_tree_list (NULL_TREE, arg1_len);
4928 TREE_CHAIN (arg1_tree) = arg1_len;
4929
4930 expr_tree
4931 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4932 ffecom_gfrt_kindtype (gfrt),
4933 FALSE,
4934 NULL_TREE,
4935 arg1_tree,
c7e4ee3a
CB
4936 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4937 ffebld_nonter_hook (expr));
5ff904cd
JL
4938
4939 if (arg2_tree != NULL_TREE)
4940 expr_tree
4941 = ffecom_modify (NULL_TREE, arg2_tree,
4942 convert (TREE_TYPE (arg2_tree),
4943 expr_tree));
4944 }
4945 return expr_tree;
4946
4947 case FFEINTRIN_impEXIT:
4948 if (arg1 != NULL)
4949 break;
4950
4951 expr_tree = build_tree_list (NULL_TREE,
4952 ffecom_1 (ADDR_EXPR,
4953 build_pointer_type
4954 (ffecom_integer_type_node),
4955 integer_zero_node));
4956
4957 return
4958 ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4959 ffecom_gfrt_kindtype (gfrt),
4960 FALSE,
4961 void_type_node,
4962 expr_tree,
c7e4ee3a
CB
4963 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4964 ffebld_nonter_hook (expr));
5ff904cd
JL
4965
4966 case FFEINTRIN_impFLUSH:
4967 if (arg1 == NULL)
4968 gfrt = FFECOM_gfrtFLUSH;
4969 else
4970 gfrt = FFECOM_gfrtFLUSH1;
4971 break;
4972
4973 case FFEINTRIN_impCHMOD_subr:
4974 case FFEINTRIN_impLINK_subr:
4975 case FFEINTRIN_impRENAME_subr:
4976 case FFEINTRIN_impSYMLNK_subr:
4977 {
4978 tree arg1_len = integer_zero_node;
4979 tree arg1_tree;
4980 tree arg2_len = integer_zero_node;
4981 tree arg2_tree;
4982 tree arg3_tree;
4983
5ff904cd
JL
4984 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
4985 arg2_tree = ffecom_arg_ptr_to_expr (arg2, &arg2_len);
4986 if (arg3 != NULL)
c7e4ee3a 4987 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
4988 else
4989 arg3_tree = NULL_TREE;
4990
5ff904cd
JL
4991 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4992 arg1_len = build_tree_list (NULL_TREE, arg1_len);
4993 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
4994 arg2_len = build_tree_list (NULL_TREE, arg2_len);
4995 TREE_CHAIN (arg1_tree) = arg2_tree;
4996 TREE_CHAIN (arg2_tree) = arg1_len;
4997 TREE_CHAIN (arg1_len) = arg2_len;
4998 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4999 ffecom_gfrt_kindtype (gfrt),
5000 FALSE,
5001 NULL_TREE,
5002 arg1_tree,
c7e4ee3a
CB
5003 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5004 ffebld_nonter_hook (expr));
5ff904cd
JL
5005 if (arg3_tree != NULL_TREE)
5006 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5007 convert (TREE_TYPE (arg3_tree),
5008 expr_tree));
5009 }
5010 return expr_tree;
5011
5012 case FFEINTRIN_impLSTAT_subr:
5013 case FFEINTRIN_impSTAT_subr:
5014 {
5015 tree arg1_len = integer_zero_node;
5016 tree arg1_tree;
5017 tree arg2_tree;
5018 tree arg3_tree;
5019
5ff904cd
JL
5020 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
5021
5022 arg2_tree = ffecom_ptr_to_expr (arg2);
5023
5024 if (arg3 != NULL)
c7e4ee3a 5025 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
5026 else
5027 arg3_tree = NULL_TREE;
5028
5ff904cd
JL
5029 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5030 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5031 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5032 TREE_CHAIN (arg1_tree) = arg2_tree;
5033 TREE_CHAIN (arg2_tree) = arg1_len;
5034 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5035 ffecom_gfrt_kindtype (gfrt),
5036 FALSE,
5037 NULL_TREE,
5038 arg1_tree,
c7e4ee3a
CB
5039 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5040 ffebld_nonter_hook (expr));
5ff904cd
JL
5041 if (arg3_tree != NULL_TREE)
5042 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5043 convert (TREE_TYPE (arg3_tree),
5044 expr_tree));
5045 }
5046 return expr_tree;
5047
5048 case FFEINTRIN_impFGETC_subr:
5049 case FFEINTRIN_impFPUTC_subr:
5050 {
5051 tree arg1_tree;
5052 tree arg2_tree;
5053 tree arg2_len = integer_zero_node;
5054 tree arg3_tree;
5055
5ff904cd
JL
5056 arg1_tree = convert (ffecom_f2c_integer_type_node,
5057 ffecom_expr (arg1));
5058 arg1_tree = ffecom_1 (ADDR_EXPR,
5059 build_pointer_type (TREE_TYPE (arg1_tree)),
5060 arg1_tree);
5061
5062 arg2_tree = ffecom_arg_ptr_to_expr (arg2, &arg2_len);
62b3b9db
TM
5063 if (arg3 != NULL)
5064 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5065 else
5066 arg3_tree = NULL_TREE;
5ff904cd
JL
5067
5068 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5069 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5070 arg2_len = build_tree_list (NULL_TREE, arg2_len);
5071 TREE_CHAIN (arg1_tree) = arg2_tree;
5072 TREE_CHAIN (arg2_tree) = arg2_len;
5073
5074 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5075 ffecom_gfrt_kindtype (gfrt),
5076 FALSE,
5077 NULL_TREE,
5078 arg1_tree,
c7e4ee3a
CB
5079 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5080 ffebld_nonter_hook (expr));
62b3b9db
TM
5081 if (arg3_tree != NULL_TREE)
5082 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5083 convert (TREE_TYPE (arg3_tree),
5084 expr_tree));
5ff904cd
JL
5085 }
5086 return expr_tree;
5087
5088 case FFEINTRIN_impFSTAT_subr:
5089 {
5090 tree arg1_tree;
5091 tree arg2_tree;
5092 tree arg3_tree;
5093
5ff904cd
JL
5094 arg1_tree = convert (ffecom_f2c_integer_type_node,
5095 ffecom_expr (arg1));
5096 arg1_tree = ffecom_1 (ADDR_EXPR,
5097 build_pointer_type (TREE_TYPE (arg1_tree)),
5098 arg1_tree);
5099
5100 arg2_tree = convert (ffecom_f2c_ptr_to_integer_type_node,
5101 ffecom_ptr_to_expr (arg2));
5102
5103 if (arg3 == NULL)
5104 arg3_tree = NULL_TREE;
5105 else
c7e4ee3a 5106 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
5107
5108 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5109 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5110 TREE_CHAIN (arg1_tree) = arg2_tree;
5111 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5112 ffecom_gfrt_kindtype (gfrt),
5113 FALSE,
5114 NULL_TREE,
5115 arg1_tree,
c7e4ee3a
CB
5116 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5117 ffebld_nonter_hook (expr));
5ff904cd
JL
5118 if (arg3_tree != NULL_TREE) {
5119 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5120 convert (TREE_TYPE (arg3_tree),
5121 expr_tree));
5122 }
5123 }
5124 return expr_tree;
5125
5126 case FFEINTRIN_impKILL_subr:
5127 {
5128 tree arg1_tree;
5129 tree arg2_tree;
5130 tree arg3_tree;
5131
5ff904cd
JL
5132 arg1_tree = convert (ffecom_f2c_integer_type_node,
5133 ffecom_expr (arg1));
5134 arg1_tree = ffecom_1 (ADDR_EXPR,
5135 build_pointer_type (TREE_TYPE (arg1_tree)),
5136 arg1_tree);
5137
5138 arg2_tree = convert (ffecom_f2c_integer_type_node,
5139 ffecom_expr (arg2));
5140 arg2_tree = ffecom_1 (ADDR_EXPR,
5141 build_pointer_type (TREE_TYPE (arg2_tree)),
5142 arg2_tree);
5143
5144 if (arg3 == NULL)
5145 arg3_tree = NULL_TREE;
5146 else
c7e4ee3a 5147 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
5148
5149 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5150 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5151 TREE_CHAIN (arg1_tree) = arg2_tree;
5152 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5153 ffecom_gfrt_kindtype (gfrt),
5154 FALSE,
5155 NULL_TREE,
5156 arg1_tree,
c7e4ee3a
CB
5157 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5158 ffebld_nonter_hook (expr));
5ff904cd
JL
5159 if (arg3_tree != NULL_TREE) {
5160 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5161 convert (TREE_TYPE (arg3_tree),
5162 expr_tree));
5163 }
5164 }
5165 return expr_tree;
5166
5167 case FFEINTRIN_impCTIME_subr:
5168 case FFEINTRIN_impTTYNAM_subr:
5169 {
5170 tree arg1_len = integer_zero_node;
5171 tree arg1_tree;
5172 tree arg2_tree;
5173
2b0bdd9a 5174 arg1_tree = ffecom_arg_ptr_to_expr (arg2, &arg1_len);
5ff904cd 5175
c56f65d6 5176 arg2_tree = convert (((codegen_imp == FFEINTRIN_impCTIME_subr) ?
5ff904cd
JL
5177 ffecom_f2c_longint_type_node :
5178 ffecom_f2c_integer_type_node),
2b0bdd9a 5179 ffecom_expr (arg1));
5ff904cd
JL
5180 arg2_tree = ffecom_1 (ADDR_EXPR,
5181 build_pointer_type (TREE_TYPE (arg2_tree)),
5182 arg2_tree);
5183
5ff904cd
JL
5184 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5185 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5186 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5187 TREE_CHAIN (arg1_len) = arg2_tree;
5188 TREE_CHAIN (arg1_tree) = arg1_len;
5189
5190 expr_tree
5191 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5192 ffecom_gfrt_kindtype (gfrt),
5193 FALSE,
5194 NULL_TREE,
5195 arg1_tree,
c7e4ee3a
CB
5196 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5197 ffebld_nonter_hook (expr));
2b0bdd9a 5198 TREE_SIDE_EFFECTS (expr_tree) = 1;
5ff904cd
JL
5199 }
5200 return expr_tree;
5201
5202 case FFEINTRIN_impIRAND:
5203 case FFEINTRIN_impRAND:
5204 /* Arg defaults to 0 (normal random case) */
5205 {
5206 tree arg1_tree;
5207
5208 if (arg1 == NULL)
5209 arg1_tree = ffecom_integer_zero_node;
5210 else
5211 arg1_tree = ffecom_expr (arg1);
5212 arg1_tree = convert (ffecom_f2c_integer_type_node,
5213 arg1_tree);
5214 arg1_tree = ffecom_1 (ADDR_EXPR,
5215 build_pointer_type (TREE_TYPE (arg1_tree)),
5216 arg1_tree);
5217 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5218
5219 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5220 ffecom_gfrt_kindtype (gfrt),
5221 FALSE,
5222 ((codegen_imp == FFEINTRIN_impIRAND) ?
5223 ffecom_f2c_integer_type_node :
de7f278a 5224 ffecom_f2c_real_type_node),
5ff904cd
JL
5225 arg1_tree,
5226 dest_tree, dest, dest_used,
c7e4ee3a
CB
5227 NULL_TREE, TRUE,
5228 ffebld_nonter_hook (expr));
5ff904cd
JL
5229 }
5230 return expr_tree;
5231
5232 case FFEINTRIN_impFTELL_subr:
5233 case FFEINTRIN_impUMASK_subr:
5234 {
5235 tree arg1_tree;
5236 tree arg2_tree;
5237
5ff904cd
JL
5238 arg1_tree = convert (ffecom_f2c_integer_type_node,
5239 ffecom_expr (arg1));
5240 arg1_tree = ffecom_1 (ADDR_EXPR,
5241 build_pointer_type (TREE_TYPE (arg1_tree)),
5242 arg1_tree);
5243
5244 if (arg2 == NULL)
5245 arg2_tree = NULL_TREE;
5246 else
c7e4ee3a 5247 arg2_tree = ffecom_expr_w (NULL_TREE, arg2);
5ff904cd
JL
5248
5249 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5250 ffecom_gfrt_kindtype (gfrt),
5251 FALSE,
5252 NULL_TREE,
5253 build_tree_list (NULL_TREE, arg1_tree),
5254 NULL_TREE, NULL, NULL, NULL_TREE,
c7e4ee3a
CB
5255 TRUE,
5256 ffebld_nonter_hook (expr));
5ff904cd
JL
5257 if (arg2_tree != NULL_TREE) {
5258 expr_tree = ffecom_modify (NULL_TREE, arg2_tree,
5259 convert (TREE_TYPE (arg2_tree),
5260 expr_tree));
5261 }
5262 }
5263 return expr_tree;
5264
5265 case FFEINTRIN_impCPU_TIME:
5266 case FFEINTRIN_impSECOND_subr:
5267 {
5268 tree arg1_tree;
5269
c7e4ee3a 5270 arg1_tree = ffecom_expr_w (NULL_TREE, arg1);
5ff904cd
JL
5271
5272 expr_tree
5273 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5274 ffecom_gfrt_kindtype (gfrt),
5275 FALSE,
5276 NULL_TREE,
5277 NULL_TREE,
c7e4ee3a
CB
5278 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5279 ffebld_nonter_hook (expr));
5ff904cd
JL
5280
5281 expr_tree
5282 = ffecom_modify (NULL_TREE, arg1_tree,
5283 convert (TREE_TYPE (arg1_tree),
5284 expr_tree));
5285 }
5286 return expr_tree;
5287
5288 case FFEINTRIN_impDTIME_subr:
5289 case FFEINTRIN_impETIME_subr:
5290 {
5291 tree arg1_tree;
2b0bdd9a 5292 tree result_tree;
5ff904cd 5293
2b0bdd9a 5294 result_tree = ffecom_expr_w (NULL_TREE, arg2);
5ff904cd 5295
2b0bdd9a 5296 arg1_tree = ffecom_ptr_to_expr (arg1);
5ff904cd 5297
5ff904cd
JL
5298 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5299 ffecom_gfrt_kindtype (gfrt),
5300 FALSE,
5301 NULL_TREE,
2b0bdd9a 5302 build_tree_list (NULL_TREE, arg1_tree),
5ff904cd 5303 NULL_TREE, NULL, NULL, NULL_TREE,
c7e4ee3a
CB
5304 TRUE,
5305 ffebld_nonter_hook (expr));
2b0bdd9a
CB
5306 expr_tree = ffecom_modify (NULL_TREE, result_tree,
5307 convert (TREE_TYPE (result_tree),
5ff904cd
JL
5308 expr_tree));
5309 }
5310 return expr_tree;
5311
c7e4ee3a 5312 /* Straightforward calls of libf2c routines: */
5ff904cd
JL
5313 case FFEINTRIN_impABORT:
5314 case FFEINTRIN_impACCESS:
5315 case FFEINTRIN_impBESJ0:
5316 case FFEINTRIN_impBESJ1:
5317 case FFEINTRIN_impBESJN:
5318 case FFEINTRIN_impBESY0:
5319 case FFEINTRIN_impBESY1:
5320 case FFEINTRIN_impBESYN:
5321 case FFEINTRIN_impCHDIR_func:
5322 case FFEINTRIN_impCHMOD_func:
5323 case FFEINTRIN_impDATE:
9e8e701d 5324 case FFEINTRIN_impDATE_AND_TIME:
5ff904cd
JL
5325 case FFEINTRIN_impDBESJ0:
5326 case FFEINTRIN_impDBESJ1:
5327 case FFEINTRIN_impDBESJN:
5328 case FFEINTRIN_impDBESY0:
5329 case FFEINTRIN_impDBESY1:
5330 case FFEINTRIN_impDBESYN:
5331 case FFEINTRIN_impDTIME_func:
5332 case FFEINTRIN_impETIME_func:
5333 case FFEINTRIN_impFGETC_func:
5334 case FFEINTRIN_impFGET_func:
5335 case FFEINTRIN_impFNUM:
5336 case FFEINTRIN_impFPUTC_func:
5337 case FFEINTRIN_impFPUT_func:
5338 case FFEINTRIN_impFSEEK:
5339 case FFEINTRIN_impFSTAT_func:
5340 case FFEINTRIN_impFTELL_func:
5341 case FFEINTRIN_impGERROR:
5342 case FFEINTRIN_impGETARG:
5343 case FFEINTRIN_impGETCWD_func:
5344 case FFEINTRIN_impGETENV:
5345 case FFEINTRIN_impGETGID:
5346 case FFEINTRIN_impGETLOG:
5347 case FFEINTRIN_impGETPID:
5348 case FFEINTRIN_impGETUID:
5349 case FFEINTRIN_impGMTIME:
5350 case FFEINTRIN_impHOSTNM_func:
5351 case FFEINTRIN_impIDATE_unix:
5352 case FFEINTRIN_impIDATE_vxt:
5353 case FFEINTRIN_impIERRNO:
5354 case FFEINTRIN_impISATTY:
5355 case FFEINTRIN_impITIME:
5356 case FFEINTRIN_impKILL_func:
5357 case FFEINTRIN_impLINK_func:
5358 case FFEINTRIN_impLNBLNK:
5359 case FFEINTRIN_impLSTAT_func:
5360 case FFEINTRIN_impLTIME:
5361 case FFEINTRIN_impMCLOCK8:
5362 case FFEINTRIN_impMCLOCK:
5363 case FFEINTRIN_impPERROR:
5364 case FFEINTRIN_impRENAME_func:
5365 case FFEINTRIN_impSECNDS:
5366 case FFEINTRIN_impSECOND_func:
5367 case FFEINTRIN_impSLEEP:
5368 case FFEINTRIN_impSRAND:
5369 case FFEINTRIN_impSTAT_func:
5370 case FFEINTRIN_impSYMLNK_func:
5371 case FFEINTRIN_impSYSTEM_CLOCK:
5372 case FFEINTRIN_impSYSTEM_func:
5373 case FFEINTRIN_impTIME8:
5374 case FFEINTRIN_impTIME_unix:
5375 case FFEINTRIN_impTIME_vxt:
5376 case FFEINTRIN_impUMASK_func:
5377 case FFEINTRIN_impUNLINK_func:
5378 break;
5379
5380 case FFEINTRIN_impCTIME_func: /* CHARACTER functions not handled here. */
5381 case FFEINTRIN_impFDATE_func: /* CHARACTER functions not handled here. */
5382 case FFEINTRIN_impTTYNAM_func: /* CHARACTER functions not handled here. */
5383 case FFEINTRIN_impNONE:
5384 case FFEINTRIN_imp: /* Hush up gcc warning. */
5385 fprintf (stderr, "No %s implementation.\n",
5386 ffeintrin_name_implementation (ffebld_symter_implementation (ffebld_left (expr))));
5387 assert ("unimplemented intrinsic" == NULL);
5388 return error_mark_node;
5389 }
5390
5391 assert (gfrt != FFECOM_gfrt); /* Must have an implementation! */
5392
5ff904cd
JL
5393 expr_tree = ffecom_arglist_expr_ (ffecom_gfrt_args_ (gfrt),
5394 ffebld_right (expr));
5ff904cd
JL
5395
5396 return ffecom_call_ (ffecom_gfrt_tree_ (gfrt), ffecom_gfrt_kindtype (gfrt),
5397 (ffe_is_f2c_library () && ffecom_gfrt_complex_[gfrt]),
5398 tree_type,
5399 expr_tree, dest_tree, dest, dest_used,
c7e4ee3a
CB
5400 NULL_TREE, TRUE,
5401 ffebld_nonter_hook (expr));
5ff904cd 5402
c7e4ee3a
CB
5403 /* See bottom of this file for f2c transforms used to determine
5404 many of the above implementations. The info seems to confuse
5405 Emacs's C mode indentation, which is why it's been moved to
5406 the bottom of this source file. */
5407}
5ff904cd 5408
c7e4ee3a
CB
5409/* For power (exponentiation) where right-hand operand is type INTEGER,
5410 generate in-line code to do it the fast way (which, if the operand
5411 is a constant, might just mean a series of multiplies). */
5ff904cd 5412
c7e4ee3a
CB
5413static tree
5414ffecom_expr_power_integer_ (ffebld expr)
5415{
5416 tree l = ffecom_expr (ffebld_left (expr));
5417 tree r = ffecom_expr (ffebld_right (expr));
5418 tree ltype = TREE_TYPE (l);
5419 tree rtype = TREE_TYPE (r);
5420 tree result = NULL_TREE;
5ff904cd 5421
c7e4ee3a
CB
5422 if (l == error_mark_node
5423 || r == error_mark_node)
5424 return error_mark_node;
5ff904cd 5425
c7e4ee3a
CB
5426 if (TREE_CODE (r) == INTEGER_CST)
5427 {
5428 int sgn = tree_int_cst_sgn (r);
5ff904cd 5429
c7e4ee3a
CB
5430 if (sgn == 0)
5431 return convert (ltype, integer_one_node);
5ff904cd 5432
c7e4ee3a
CB
5433 if ((TREE_CODE (ltype) == INTEGER_TYPE)
5434 && (sgn < 0))
5435 {
5436 /* Reciprocal of integer is either 0, -1, or 1, so after
5437 calculating that (which we leave to the back end to do
5438 or not do optimally), don't bother with any multiplying. */
5ff904cd 5439
c7e4ee3a
CB
5440 result = ffecom_tree_divide_ (ltype,
5441 convert (ltype, integer_one_node),
5442 l,
5443 NULL_TREE, NULL, NULL, NULL_TREE);
5444 r = ffecom_1 (NEGATE_EXPR,
5445 rtype,
5446 r);
5447 if ((TREE_INT_CST_LOW (r) & 1) == 0)
5448 result = ffecom_1 (ABS_EXPR, rtype,
5449 result);
5450 }
5ff904cd 5451
c7e4ee3a
CB
5452 /* Generate appropriate series of multiplies, preceded
5453 by divide if the exponent is negative. */
5ff904cd 5454
c7e4ee3a 5455 l = save_expr (l);
5ff904cd 5456
c7e4ee3a
CB
5457 if (sgn < 0)
5458 {
5459 l = ffecom_tree_divide_ (ltype,
5460 convert (ltype, integer_one_node),
5461 l,
5462 NULL_TREE, NULL, NULL,
5463 ffebld_nonter_hook (expr));
5464 r = ffecom_1 (NEGATE_EXPR, rtype, r);
5465 assert (TREE_CODE (r) == INTEGER_CST);
5ff904cd 5466
c7e4ee3a
CB
5467 if (tree_int_cst_sgn (r) < 0)
5468 { /* The "most negative" number. */
5469 r = ffecom_1 (NEGATE_EXPR, rtype,
5470 ffecom_2 (RSHIFT_EXPR, rtype,
5471 r,
5472 integer_one_node));
5473 l = save_expr (l);
5474 l = ffecom_2 (MULT_EXPR, ltype,
5475 l,
5476 l);
5477 }
5478 }
5ff904cd 5479
c7e4ee3a
CB
5480 for (;;)
5481 {
5482 if (TREE_INT_CST_LOW (r) & 1)
5483 {
5484 if (result == NULL_TREE)
5485 result = l;
5486 else
5487 result = ffecom_2 (MULT_EXPR, ltype,
5488 result,
5489 l);
5490 }
5ff904cd 5491
c7e4ee3a
CB
5492 r = ffecom_2 (RSHIFT_EXPR, rtype,
5493 r,
5494 integer_one_node);
5495 if (integer_zerop (r))
5496 break;
5497 assert (TREE_CODE (r) == INTEGER_CST);
5ff904cd 5498
c7e4ee3a
CB
5499 l = save_expr (l);
5500 l = ffecom_2 (MULT_EXPR, ltype,
5501 l,
5502 l);
5503 }
5504 return result;
5505 }
5ff904cd 5506
c7e4ee3a
CB
5507 /* Though rhs isn't a constant, in-line code cannot be expanded
5508 while transforming dummies
5509 because the back end cannot be easily convinced to generate
5510 stores (MODIFY_EXPR), handle temporaries, and so on before
5511 all the appropriate rtx's have been generated for things like
5512 dummy args referenced in rhs -- which doesn't happen until
5513 store_parm_decls() is called (expand_function_start, I believe,
5514 does the actual rtx-stuffing of PARM_DECLs).
5ff904cd 5515
c7e4ee3a
CB
5516 So, in this case, let the caller generate the call to the
5517 run-time-library function to evaluate the power for us. */
5ff904cd 5518
c7e4ee3a
CB
5519 if (ffecom_transform_only_dummies_)
5520 return NULL_TREE;
5ff904cd 5521
c7e4ee3a
CB
5522 /* Right-hand operand not a constant, expand in-line code to figure
5523 out how to do the multiplies, &c.
5ff904cd 5524
c7e4ee3a
CB
5525 The returned expression is expressed this way in GNU C, where l and
5526 r are the "inputs":
5ff904cd 5527
c7e4ee3a
CB
5528 ({ typeof (r) rtmp = r;
5529 typeof (l) ltmp = l;
5530 typeof (l) result;
5ff904cd 5531
c7e4ee3a
CB
5532 if (rtmp == 0)
5533 result = 1;
5534 else
5535 {
5536 if ((basetypeof (l) == basetypeof (int))
5537 && (rtmp < 0))
5538 {
5539 result = ((typeof (l)) 1) / ltmp;
5540 if ((ltmp < 0) && (((-rtmp) & 1) == 0))
5541 result = -result;
5542 }
5543 else
5544 {
5545 result = 1;
5546 if ((basetypeof (l) != basetypeof (int))
5547 && (rtmp < 0))
5548 {
5549 ltmp = ((typeof (l)) 1) / ltmp;
5550 rtmp = -rtmp;
5551 if (rtmp < 0)
5552 {
5553 rtmp = -(rtmp >> 1);
5554 ltmp *= ltmp;
5555 }
5556 }
5557 for (;;)
5558 {
5559 if (rtmp & 1)
5560 result *= ltmp;
5561 if ((rtmp >>= 1) == 0)
5562 break;
5563 ltmp *= ltmp;
5564 }
5565 }
5566 }
5567 result;
5568 })
5ff904cd 5569
c7e4ee3a
CB
5570 Note that some of the above is compile-time collapsable, such as
5571 the first part of the if statements that checks the base type of
5572 l against int. The if statements are phrased that way to suggest
5573 an easy way to generate the if/else constructs here, knowing that
5574 the back end should (and probably does) eliminate the resulting
5575 dead code (either the int case or the non-int case), something
5576 it couldn't do without the redundant phrasing, requiring explicit
5577 dead-code elimination here, which would be kind of difficult to
5578 read. */
5ff904cd 5579
c7e4ee3a
CB
5580 {
5581 tree rtmp;
5582 tree ltmp;
5583 tree divide;
5584 tree basetypeof_l_is_int;
5585 tree se;
5586 tree t;
5ff904cd 5587
c7e4ee3a
CB
5588 basetypeof_l_is_int
5589 = build_int_2 ((TREE_CODE (ltype) == INTEGER_TYPE), 0);
5ff904cd 5590
c7e4ee3a 5591 se = expand_start_stmt_expr ();
5ff904cd 5592
c7e4ee3a
CB
5593 ffecom_start_compstmt ();
5594
5595#ifndef HAHA
5596 rtmp = ffecom_make_tempvar ("power_r", rtype,
5597 FFETARGET_charactersizeNONE, -1);
5598 ltmp = ffecom_make_tempvar ("power_l", ltype,
5599 FFETARGET_charactersizeNONE, -1);
5600 result = ffecom_make_tempvar ("power_res", ltype,
5601 FFETARGET_charactersizeNONE, -1);
5602 if (TREE_CODE (ltype) == COMPLEX_TYPE
5603 || TREE_CODE (ltype) == RECORD_TYPE)
5604 divide = ffecom_make_tempvar ("power_div", ltype,
5605 FFETARGET_charactersizeNONE, -1);
5606 else
5607 divide = NULL_TREE;
5608#else /* HAHA */
5609 {
5610 tree hook;
5611
5612 hook = ffebld_nonter_hook (expr);
5613 assert (hook);
5614 assert (TREE_CODE (hook) == TREE_VEC);
5615 assert (TREE_VEC_LENGTH (hook) == 4);
5616 rtmp = TREE_VEC_ELT (hook, 0);
5617 ltmp = TREE_VEC_ELT (hook, 1);
5618 result = TREE_VEC_ELT (hook, 2);
5619 divide = TREE_VEC_ELT (hook, 3);
5620 if (TREE_CODE (ltype) == COMPLEX_TYPE
5621 || TREE_CODE (ltype) == RECORD_TYPE)
5622 assert (divide);
5623 else
5624 assert (! divide);
5625 }
5626#endif /* HAHA */
5ff904cd 5627
c7e4ee3a
CB
5628 expand_expr_stmt (ffecom_modify (void_type_node,
5629 rtmp,
5630 r));
5631 expand_expr_stmt (ffecom_modify (void_type_node,
5632 ltmp,
5633 l));
5634 expand_start_cond (ffecom_truth_value
5635 (ffecom_2 (EQ_EXPR, integer_type_node,
5636 rtmp,
5637 convert (rtype, integer_zero_node))),
5638 0);
5639 expand_expr_stmt (ffecom_modify (void_type_node,
5640 result,
5641 convert (ltype, integer_one_node)));
5642 expand_start_else ();
5643 if (! integer_zerop (basetypeof_l_is_int))
5644 {
5645 expand_start_cond (ffecom_2 (LT_EXPR, integer_type_node,
5646 rtmp,
5647 convert (rtype,
5648 integer_zero_node)),
5649 0);
5650 expand_expr_stmt (ffecom_modify (void_type_node,
5651 result,
5652 ffecom_tree_divide_
5653 (ltype,
5654 convert (ltype, integer_one_node),
5655 ltmp,
5656 NULL_TREE, NULL, NULL,
5657 divide)));
5658 expand_start_cond (ffecom_truth_value
5659 (ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
5660 ffecom_2 (LT_EXPR, integer_type_node,
5661 ltmp,
5662 convert (ltype,
5663 integer_zero_node)),
5664 ffecom_2 (EQ_EXPR, integer_type_node,
5665 ffecom_2 (BIT_AND_EXPR,
5666 rtype,
5667 ffecom_1 (NEGATE_EXPR,
5668 rtype,
5669 rtmp),
5670 convert (rtype,
5671 integer_one_node)),
5672 convert (rtype,
5673 integer_zero_node)))),
5674 0);
5675 expand_expr_stmt (ffecom_modify (void_type_node,
5676 result,
5677 ffecom_1 (NEGATE_EXPR,
5678 ltype,
5679 result)));
5680 expand_end_cond ();
5681 expand_start_else ();
5682 }
5683 expand_expr_stmt (ffecom_modify (void_type_node,
5684 result,
5685 convert (ltype, integer_one_node)));
5686 expand_start_cond (ffecom_truth_value
5687 (ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
5688 ffecom_truth_value_invert
5689 (basetypeof_l_is_int),
5690 ffecom_2 (LT_EXPR, integer_type_node,
5691 rtmp,
5692 convert (rtype,
5693 integer_zero_node)))),
5694 0);
5695 expand_expr_stmt (ffecom_modify (void_type_node,
5696 ltmp,
5697 ffecom_tree_divide_
5698 (ltype,
5699 convert (ltype, integer_one_node),
5700 ltmp,
5701 NULL_TREE, NULL, NULL,
5702 divide)));
5703 expand_expr_stmt (ffecom_modify (void_type_node,
5704 rtmp,
5705 ffecom_1 (NEGATE_EXPR, rtype,
5706 rtmp)));
5707 expand_start_cond (ffecom_truth_value
5708 (ffecom_2 (LT_EXPR, integer_type_node,
5709 rtmp,
5710 convert (rtype, integer_zero_node))),
5711 0);
5712 expand_expr_stmt (ffecom_modify (void_type_node,
5713 rtmp,
5714 ffecom_1 (NEGATE_EXPR, rtype,
5715 ffecom_2 (RSHIFT_EXPR,
5716 rtype,
5717 rtmp,
5718 integer_one_node))));
5719 expand_expr_stmt (ffecom_modify (void_type_node,
5720 ltmp,
5721 ffecom_2 (MULT_EXPR, ltype,
5722 ltmp,
5723 ltmp)));
5724 expand_end_cond ();
5725 expand_end_cond ();
5726 expand_start_loop (1);
5727 expand_start_cond (ffecom_truth_value
5728 (ffecom_2 (BIT_AND_EXPR, rtype,
5729 rtmp,
5730 convert (rtype, integer_one_node))),
5731 0);
5732 expand_expr_stmt (ffecom_modify (void_type_node,
5733 result,
5734 ffecom_2 (MULT_EXPR, ltype,
5735 result,
5736 ltmp)));
5737 expand_end_cond ();
5738 expand_exit_loop_if_false (NULL,
5739 ffecom_truth_value
5740 (ffecom_modify (rtype,
5741 rtmp,
5742 ffecom_2 (RSHIFT_EXPR,
5743 rtype,
5744 rtmp,
5745 integer_one_node))));
5746 expand_expr_stmt (ffecom_modify (void_type_node,
5747 ltmp,
5748 ffecom_2 (MULT_EXPR, ltype,
5749 ltmp,
5750 ltmp)));
5751 expand_end_loop ();
5752 expand_end_cond ();
5753 if (!integer_zerop (basetypeof_l_is_int))
5754 expand_end_cond ();
5755 expand_expr_stmt (result);
5ff904cd 5756
c7e4ee3a 5757 t = ffecom_end_compstmt ();
5ff904cd 5758
c7e4ee3a 5759 result = expand_end_stmt_expr (se);
5ff904cd 5760
c7e4ee3a 5761 /* This code comes from c-parse.in, after its expand_end_stmt_expr. */
5ff904cd 5762
c7e4ee3a
CB
5763 if (TREE_CODE (t) == BLOCK)
5764 {
5765 /* Make a BIND_EXPR for the BLOCK already made. */
5766 result = build (BIND_EXPR, TREE_TYPE (result),
5767 NULL_TREE, result, t);
5768 /* Remove the block from the tree at this point.
5769 It gets put back at the proper place
5770 when the BIND_EXPR is expanded. */
5771 delete_block (t);
5772 }
5773 else
5774 result = t;
5775 }
5ff904cd 5776
c7e4ee3a
CB
5777 return result;
5778}
5ff904cd 5779
c7e4ee3a 5780/* ffecom_expr_transform_ -- Transform symbols in expr
5ff904cd 5781
c7e4ee3a
CB
5782 ffebld expr; // FFE expression.
5783 ffecom_expr_transform_ (expr);
5ff904cd 5784
c7e4ee3a 5785 Recursive descent on expr while transforming any untransformed SYMTERs. */
5ff904cd 5786
c7e4ee3a
CB
5787static void
5788ffecom_expr_transform_ (ffebld expr)
5789{
5790 tree t;
5791 ffesymbol s;
5ff904cd 5792
516b69ff 5793 tail_recurse:
5ff904cd 5794
c7e4ee3a
CB
5795 if (expr == NULL)
5796 return;
5ff904cd 5797
c7e4ee3a
CB
5798 switch (ffebld_op (expr))
5799 {
5800 case FFEBLD_opSYMTER:
5801 s = ffebld_symter (expr);
5802 t = ffesymbol_hook (s).decl_tree;
5803 if ((t == NULL_TREE)
5804 && ((ffesymbol_kind (s) != FFEINFO_kindNONE)
5805 || ((ffesymbol_where (s) != FFEINFO_whereNONE)
5806 && (ffesymbol_where (s) != FFEINFO_whereINTRINSIC))))
5807 {
5808 s = ffecom_sym_transform_ (s);
5809 t = ffesymbol_hook (s).decl_tree; /* Sfunc expr non-dummy,
5810 DIMENSION expr? */
5811 }
5812 break; /* Ok if (t == NULL) here. */
5ff904cd 5813
c7e4ee3a
CB
5814 case FFEBLD_opITEM:
5815 ffecom_expr_transform_ (ffebld_head (expr));
5816 expr = ffebld_trail (expr);
5817 goto tail_recurse; /* :::::::::::::::::::: */
5ff904cd 5818
c7e4ee3a
CB
5819 default:
5820 break;
5821 }
5ff904cd 5822
c7e4ee3a
CB
5823 switch (ffebld_arity (expr))
5824 {
5825 case 2:
5826 ffecom_expr_transform_ (ffebld_left (expr));
5827 expr = ffebld_right (expr);
5828 goto tail_recurse; /* :::::::::::::::::::: */
5ff904cd 5829
c7e4ee3a
CB
5830 case 1:
5831 expr = ffebld_left (expr);
5832 goto tail_recurse; /* :::::::::::::::::::: */
5ff904cd 5833
c7e4ee3a
CB
5834 default:
5835 break;
5836 }
5ff904cd 5837
c7e4ee3a
CB
5838 return;
5839}
5ff904cd 5840
c7e4ee3a 5841/* Make a type based on info in live f2c.h file. */
5ff904cd 5842
c7e4ee3a
CB
5843static void
5844ffecom_f2c_make_type_ (tree *type, int tcode, const char *name)
5845{
5846 switch (tcode)
5847 {
5848 case FFECOM_f2ccodeCHAR:
5849 *type = make_signed_type (CHAR_TYPE_SIZE);
5850 break;
5ff904cd 5851
c7e4ee3a
CB
5852 case FFECOM_f2ccodeSHORT:
5853 *type = make_signed_type (SHORT_TYPE_SIZE);
5854 break;
5ff904cd 5855
c7e4ee3a
CB
5856 case FFECOM_f2ccodeINT:
5857 *type = make_signed_type (INT_TYPE_SIZE);
5858 break;
5ff904cd 5859
c7e4ee3a
CB
5860 case FFECOM_f2ccodeLONG:
5861 *type = make_signed_type (LONG_TYPE_SIZE);
5862 break;
5ff904cd 5863
c7e4ee3a
CB
5864 case FFECOM_f2ccodeLONGLONG:
5865 *type = make_signed_type (LONG_LONG_TYPE_SIZE);
5866 break;
5ff904cd 5867
c7e4ee3a
CB
5868 case FFECOM_f2ccodeCHARPTR:
5869 *type = build_pointer_type (DEFAULT_SIGNED_CHAR
5870 ? signed_char_type_node
5871 : unsigned_char_type_node);
5872 break;
5ff904cd 5873
c7e4ee3a
CB
5874 case FFECOM_f2ccodeFLOAT:
5875 *type = make_node (REAL_TYPE);
5876 TYPE_PRECISION (*type) = FLOAT_TYPE_SIZE;
5877 layout_type (*type);
5878 break;
5879
5880 case FFECOM_f2ccodeDOUBLE:
5881 *type = make_node (REAL_TYPE);
5882 TYPE_PRECISION (*type) = DOUBLE_TYPE_SIZE;
5883 layout_type (*type);
5884 break;
5885
5886 case FFECOM_f2ccodeLONGDOUBLE:
5887 *type = make_node (REAL_TYPE);
5888 TYPE_PRECISION (*type) = LONG_DOUBLE_TYPE_SIZE;
5889 layout_type (*type);
5890 break;
5ff904cd 5891
c7e4ee3a
CB
5892 case FFECOM_f2ccodeTWOREALS:
5893 *type = ffecom_make_complex_type_ (ffecom_f2c_real_type_node);
5894 break;
5ff904cd 5895
c7e4ee3a
CB
5896 case FFECOM_f2ccodeTWODOUBLEREALS:
5897 *type = ffecom_make_complex_type_ (ffecom_f2c_doublereal_type_node);
5898 break;
5ff904cd 5899
c7e4ee3a
CB
5900 default:
5901 assert ("unexpected FFECOM_f2ccodeXYZZY!" == NULL);
5902 *type = error_mark_node;
5903 return;
5904 }
5ff904cd 5905
c7e4ee3a 5906 pushdecl (build_decl (TYPE_DECL,
14657de8 5907 ffecom_get_invented_identifier ("__g77_f2c_%s", name),
c7e4ee3a
CB
5908 *type));
5909}
5ff904cd 5910
c7e4ee3a
CB
5911/* Set the f2c list-directed-I/O code for whatever (integral) type has the
5912 given size. */
5ff904cd 5913
c7e4ee3a
CB
5914static void
5915ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size,
5916 int code)
5917{
5918 int j;
5919 tree t;
5ff904cd 5920
c7e4ee3a 5921 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
05bccae2
RK
5922 if ((t = ffecom_tree_type[bt][j]) != NULL_TREE
5923 && compare_tree_int (TYPE_SIZE (t), size) == 0)
c7e4ee3a
CB
5924 {
5925 assert (code != -1);
5926 ffecom_f2c_typecode_[bt][j] = code;
5927 code = -1;
5928 }
5929}
5ff904cd 5930
c7e4ee3a 5931/* Finish up globals after doing all program units in file
5ff904cd 5932
c7e4ee3a 5933 Need to handle only uninitialized COMMON areas. */
5ff904cd 5934
c7e4ee3a
CB
5935static ffeglobal
5936ffecom_finish_global_ (ffeglobal global)
5937{
5938 tree cbtype;
5939 tree cbt;
5940 tree size;
5ff904cd 5941
c7e4ee3a
CB
5942 if (ffeglobal_type (global) != FFEGLOBAL_typeCOMMON)
5943 return global;
5ff904cd 5944
c7e4ee3a
CB
5945 if (ffeglobal_common_init (global))
5946 return global;
5ff904cd 5947
c7e4ee3a
CB
5948 cbt = ffeglobal_hook (global);
5949 if ((cbt == NULL_TREE)
5950 || !ffeglobal_common_have_size (global))
5951 return global; /* No need to make common, never ref'd. */
5ff904cd 5952
c7e4ee3a 5953 DECL_EXTERNAL (cbt) = 0;
5ff904cd 5954
c7e4ee3a 5955 /* Give the array a size now. */
5ff904cd 5956
c7e4ee3a
CB
5957 size = build_int_2 ((ffeglobal_common_size (global)
5958 + ffeglobal_common_pad (global)) - 1,
5959 0);
5ff904cd 5960
c7e4ee3a
CB
5961 cbtype = TREE_TYPE (cbt);
5962 TYPE_DOMAIN (cbtype) = build_range_type (integer_type_node,
5963 integer_zero_node,
5964 size);
5965 if (!TREE_TYPE (size))
5966 TREE_TYPE (size) = TYPE_DOMAIN (cbtype);
5967 layout_type (cbtype);
5ff904cd 5968
c7e4ee3a
CB
5969 cbt = start_decl (cbt, FALSE);
5970 assert (cbt == ffeglobal_hook (global));
5ff904cd 5971
c7e4ee3a 5972 finish_decl (cbt, NULL_TREE, FALSE);
5ff904cd 5973
c7e4ee3a
CB
5974 return global;
5975}
5ff904cd 5976
c7e4ee3a 5977/* Finish up any untransformed symbols. */
5ff904cd 5978
c7e4ee3a
CB
5979static ffesymbol
5980ffecom_finish_symbol_transform_ (ffesymbol s)
5ff904cd 5981{
c7e4ee3a
CB
5982 if ((s == NULL) || (TREE_CODE (current_function_decl) == ERROR_MARK))
5983 return s;
5ff904cd 5984
c7e4ee3a
CB
5985 /* It's easy to know to transform an untransformed symbol, to make sure
5986 we put out debugging info for it. But COMMON variables, unlike
5987 EQUIVALENCE ones, aren't given declarations in addition to the
5988 tree expressions that specify offsets, because COMMON variables
5989 can be referenced in the outer scope where only dummy arguments
5990 (PARM_DECLs) should really be seen. To be safe, just don't do any
5991 VAR_DECLs for COMMON variables when we transform them for real
5992 use, and therefore we do all the VAR_DECL creating here. */
5ff904cd 5993
c7e4ee3a
CB
5994 if (ffesymbol_hook (s).decl_tree == NULL_TREE)
5995 {
5996 if (ffesymbol_kind (s) != FFEINFO_kindNONE
5997 || (ffesymbol_where (s) != FFEINFO_whereNONE
5998 && ffesymbol_where (s) != FFEINFO_whereINTRINSIC
5999 && ffesymbol_where (s) != FFEINFO_whereDUMMY))
6000 /* Not transformed, and not CHARACTER*(*), and not a dummy
6001 argument, which can happen only if the entry point names
6002 it "rides in on" are all invalidated for other reasons. */
6003 s = ffecom_sym_transform_ (s);
6004 }
5ff904cd 6005
c7e4ee3a
CB
6006 if ((ffesymbol_where (s) == FFEINFO_whereCOMMON)
6007 && (ffesymbol_hook (s).decl_tree != error_mark_node))
6008 {
c7e4ee3a
CB
6009 /* This isn't working, at least for dbxout. The .s file looks
6010 okay to me (burley), but in gdb 4.9 at least, the variables
6011 appear to reside somewhere outside of the common area, so
6012 it doesn't make sense to mislead anyone by generating the info
6013 on those variables until this is fixed. NOTE: Same problem
6014 with EQUIVALENCE, sadly...see similar #if later. */
6015 ffecom_member_phase2_ (ffesymbol_storage (ffesymbol_common (s)),
6016 ffesymbol_storage (s));
5ff904cd
JL
6017 }
6018
c7e4ee3a
CB
6019 return s;
6020}
5ff904cd 6021
c7e4ee3a
CB
6022/* Append underscore(s) to name before calling get_identifier. "us"
6023 is nonzero if the name already contains an underscore and thus
6024 needs two underscores appended. */
5ff904cd 6025
c7e4ee3a
CB
6026static tree
6027ffecom_get_appended_identifier_ (char us, const char *name)
6028{
6029 int i;
6030 char *newname;
6031 tree id;
5ff904cd 6032
c7e4ee3a
CB
6033 newname = xmalloc ((i = strlen (name)) + 1
6034 + ffe_is_underscoring ()
6035 + us);
6036 memcpy (newname, name, i);
6037 newname[i] = '_';
6038 newname[i + us] = '_';
6039 newname[i + 1 + us] = '\0';
6040 id = get_identifier (newname);
5ff904cd 6041
c7e4ee3a 6042 free (newname);
5ff904cd 6043
c7e4ee3a
CB
6044 return id;
6045}
5ff904cd 6046
c7e4ee3a
CB
6047/* Decide whether to append underscore to name before calling
6048 get_identifier. */
5ff904cd 6049
c7e4ee3a
CB
6050static tree
6051ffecom_get_external_identifier_ (ffesymbol s)
6052{
6053 char us;
6054 const char *name = ffesymbol_text (s);
5ff904cd 6055
c7e4ee3a 6056 /* If name is a built-in name, just return it as is. */
5ff904cd 6057
c7e4ee3a
CB
6058 if (!ffe_is_underscoring ()
6059 || (strcmp (name, FFETARGET_nameBLANK_COMMON) == 0)
6060#if FFETARGET_isENFORCED_MAIN_NAME
6061 || (strcmp (name, FFETARGET_nameENFORCED_NAME) == 0)
6062#else
6063 || (strcmp (name, FFETARGET_nameUNNAMED_MAIN) == 0)
6064#endif
6065 || (strcmp (name, FFETARGET_nameUNNAMED_BLOCK_DATA) == 0))
6066 return get_identifier (name);
5ff904cd 6067
c7e4ee3a
CB
6068 us = ffe_is_second_underscore ()
6069 ? (strchr (name, '_') != NULL)
6070 : 0;
5ff904cd 6071
c7e4ee3a
CB
6072 return ffecom_get_appended_identifier_ (us, name);
6073}
5ff904cd 6074
c7e4ee3a
CB
6075/* Decide whether to append underscore to internal name before calling
6076 get_identifier.
6077
6078 This is for non-external, top-function-context names only. Transform
6079 identifier so it doesn't conflict with the transformed result
6080 of using a _different_ external name. E.g. if "CALL FOO" is
6081 transformed into "FOO_();", then the variable in "FOO_ = 3"
6082 must be transformed into something that does not conflict, since
6083 these two things should be independent.
5ff904cd 6084
c7e4ee3a
CB
6085 The transformation is as follows. If the name does not contain
6086 an underscore, there is no possible conflict, so just return.
6087 If the name does contain an underscore, then transform it just
6088 like we transform an external identifier. */
5ff904cd 6089
c7e4ee3a
CB
6090static tree
6091ffecom_get_identifier_ (const char *name)
6092{
6093 /* If name does not contain an underscore, just return it as is. */
6094
6095 if (!ffe_is_underscoring ()
6096 || (strchr (name, '_') == NULL))
6097 return get_identifier (name);
6098
6099 return ffecom_get_appended_identifier_ (ffe_is_second_underscore (),
6100 name);
5ff904cd
JL
6101}
6102
c7e4ee3a 6103/* ffecom_gen_sfuncdef_ -- Generate definition of statement function
5ff904cd 6104
c7e4ee3a
CB
6105 tree t;
6106 ffesymbol s; // kindFUNCTION, whereIMMEDIATE.
6107 t = ffecom_gen_sfuncdef_(s,ffesymbol_basictype(s),
6108 ffesymbol_kindtype(s));
5ff904cd 6109
c7e4ee3a
CB
6110 Call after setting up containing function and getting trees for all
6111 other symbols. */
5ff904cd 6112
c7e4ee3a
CB
6113static tree
6114ffecom_gen_sfuncdef_ (ffesymbol s, ffeinfoBasictype bt, ffeinfoKindtype kt)
5ff904cd 6115{
c7e4ee3a
CB
6116 ffebld expr = ffesymbol_sfexpr (s);
6117 tree type;
6118 tree func;
6119 tree result;
6120 bool charfunc = (bt == FFEINFO_basictypeCHARACTER);
6121 static bool recurse = FALSE;
c7e4ee3a 6122 int old_lineno = lineno;
3b304f5b 6123 const char *old_input_filename = input_filename;
5ff904cd 6124
c7e4ee3a 6125 ffecom_nested_entry_ = s;
5ff904cd 6126
c7e4ee3a
CB
6127 /* For now, we don't have a handy pointer to where the sfunc is actually
6128 defined, though that should be easy to add to an ffesymbol. (The
6129 token/where info available might well point to the place where the type
6130 of the sfunc is declared, especially if that precedes the place where
6131 the sfunc itself is defined, which is typically the case.) We should
6132 put out a null pointer rather than point somewhere wrong, but I want to
6133 see how it works at this point. */
5ff904cd 6134
c7e4ee3a
CB
6135 input_filename = ffesymbol_where_filename (s);
6136 lineno = ffesymbol_where_filelinenum (s);
5ff904cd 6137
c7e4ee3a
CB
6138 /* Pretransform the expression so any newly discovered things belong to the
6139 outer program unit, not to the statement function. */
5ff904cd 6140
c7e4ee3a 6141 ffecom_expr_transform_ (expr);
5ff904cd 6142
c7e4ee3a
CB
6143 /* Make sure no recursive invocation of this fn (a specific case of failing
6144 to pretransform an sfunc's expression, i.e. where its expression
6145 references another untransformed sfunc) happens. */
6146
6147 assert (!recurse);
6148 recurse = TRUE;
6149
c7e4ee3a
CB
6150 push_f_function_context ();
6151
6152 if (charfunc)
6153 type = void_type_node;
6154 else
5ff904cd 6155 {
c7e4ee3a
CB
6156 type = ffecom_tree_type[bt][kt];
6157 if (type == NULL_TREE)
6158 type = integer_type_node; /* _sym_exec_transition reports
6159 error. */
6160 }
5ff904cd 6161
c7e4ee3a
CB
6162 start_function (ffecom_get_identifier_ (ffesymbol_text (s)),
6163 build_function_type (type, NULL_TREE),
6164 1, /* nested/inline */
6165 0); /* TREE_PUBLIC */
5ff904cd 6166
c7e4ee3a
CB
6167 /* We don't worry about COMPLEX return values here, because this is
6168 entirely internal to our code, and gcc has the ability to return COMPLEX
6169 directly as a value. */
6170
c7e4ee3a
CB
6171 if (charfunc)
6172 { /* Prepend arg for where result goes. */
6173 tree type;
6174
6175 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
6176
14657de8 6177 result = ffecom_get_invented_identifier ("__g77_%s", "result");
c7e4ee3a
CB
6178
6179 ffecom_char_enhance_arg_ (&type, s); /* Ignore returned length. */
6180
6181 type = build_pointer_type (type);
6182 result = build_decl (PARM_DECL, result, type);
6183
6184 push_parm_decl (result);
5ff904cd 6185 }
c7e4ee3a
CB
6186 else
6187 result = NULL_TREE; /* Not ref'd if !charfunc. */
5ff904cd 6188
c7e4ee3a 6189 ffecom_push_dummy_decls_ (ffesymbol_dummyargs (s), TRUE);
5ff904cd 6190
c7e4ee3a
CB
6191 store_parm_decls (0);
6192
6193 ffecom_start_compstmt ();
6194
6195 if (expr != NULL)
5ff904cd 6196 {
c7e4ee3a
CB
6197 if (charfunc)
6198 {
6199 ffetargetCharacterSize sz = ffesymbol_size (s);
6200 tree result_length;
5ff904cd 6201
c7e4ee3a
CB
6202 result_length = build_int_2 (sz, 0);
6203 TREE_TYPE (result_length) = ffecom_f2c_ftnlen_type_node;
5ff904cd 6204
c7e4ee3a 6205 ffecom_prepare_let_char_ (sz, expr);
5ff904cd 6206
c7e4ee3a 6207 ffecom_prepare_end ();
5ff904cd 6208
c7e4ee3a
CB
6209 ffecom_let_char_ (result, result_length, sz, expr);
6210 expand_null_return ();
6211 }
6212 else
6213 {
6214 ffecom_prepare_expr (expr);
5ff904cd 6215
c7e4ee3a 6216 ffecom_prepare_end ();
5ff904cd 6217
c7e4ee3a
CB
6218 expand_return (ffecom_modify (NULL_TREE,
6219 DECL_RESULT (current_function_decl),
6220 ffecom_expr (expr)));
6221 }
c7e4ee3a 6222 }
5ff904cd 6223
c7e4ee3a 6224 ffecom_end_compstmt ();
5ff904cd 6225
c7e4ee3a
CB
6226 func = current_function_decl;
6227 finish_function (1);
5ff904cd 6228
c7e4ee3a 6229 pop_f_function_context ();
5ff904cd 6230
c7e4ee3a
CB
6231 recurse = FALSE;
6232
6233 lineno = old_lineno;
6234 input_filename = old_input_filename;
6235
6236 ffecom_nested_entry_ = NULL;
6237
6238 return func;
5ff904cd
JL
6239}
6240
c7e4ee3a
CB
6241static const char *
6242ffecom_gfrt_args_ (ffecomGfrt ix)
5ff904cd 6243{
c7e4ee3a
CB
6244 return ffecom_gfrt_argstring_[ix];
6245}
5ff904cd 6246
c7e4ee3a
CB
6247static tree
6248ffecom_gfrt_tree_ (ffecomGfrt ix)
6249{
6250 if (ffecom_gfrt_[ix] == NULL_TREE)
6251 ffecom_make_gfrt_ (ix);
6252
6253 return ffecom_1 (ADDR_EXPR,
6254 build_pointer_type (TREE_TYPE (ffecom_gfrt_[ix])),
6255 ffecom_gfrt_[ix]);
5ff904cd
JL
6256}
6257
c7e4ee3a 6258/* Return initialize-to-zero expression for this VAR_DECL. */
5ff904cd 6259
7189a4b0
GK
6260/* A somewhat evil way to prevent the garbage collector
6261 from collecting 'tree' structures. */
6262#define NUM_TRACKED_CHUNK 63
516b69ff 6263static struct tree_ggc_tracker
7189a4b0
GK
6264{
6265 struct tree_ggc_tracker *next;
6266 tree trees[NUM_TRACKED_CHUNK];
6267} *tracker_head = NULL;
6268
516b69ff 6269static void
54551044 6270mark_tracker_head (void *arg)
7189a4b0
GK
6271{
6272 struct tree_ggc_tracker *head;
6273 int i;
516b69ff 6274
7189a4b0
GK
6275 for (head = * (struct tree_ggc_tracker **) arg;
6276 head != NULL;
6277 head = head->next)
6278 {
6279 ggc_mark (head);
6280 for (i = 0; i < NUM_TRACKED_CHUNK; i++)
6281 ggc_mark_tree (head->trees[i]);
6282 }
6283}
6284
6285void
6286ffecom_save_tree_forever (tree t)
6287{
6288 int i;
6289 if (tracker_head != NULL)
6290 for (i = 0; i < NUM_TRACKED_CHUNK; i++)
6291 if (tracker_head->trees[i] == NULL)
6292 {
6293 tracker_head->trees[i] = t;
6294 return;
6295 }
6296
6297 {
6298 /* Need to allocate a new block. */
6299 struct tree_ggc_tracker *old_head = tracker_head;
516b69ff 6300
7189a4b0
GK
6301 tracker_head = ggc_alloc (sizeof (*tracker_head));
6302 tracker_head->next = old_head;
6303 tracker_head->trees[0] = t;
6304 for (i = 1; i < NUM_TRACKED_CHUNK; i++)
6305 tracker_head->trees[i] = NULL;
6306 }
6307}
6308
c7e4ee3a
CB
6309static tree
6310ffecom_init_zero_ (tree decl)
5ff904cd 6311{
c7e4ee3a
CB
6312 tree init;
6313 int incremental = TREE_STATIC (decl);
6314 tree type = TREE_TYPE (decl);
5ff904cd 6315
c7e4ee3a
CB
6316 if (incremental)
6317 {
6c418184 6318 make_decl_rtl (decl, NULL);
c7e4ee3a 6319 assemble_variable (decl, TREE_PUBLIC (decl) ? 1 : 0, 0, 1);
c7e4ee3a 6320 }
5ff904cd 6321
c7e4ee3a
CB
6322 if ((TREE_CODE (type) != ARRAY_TYPE)
6323 && (TREE_CODE (type) != RECORD_TYPE)
6324 && (TREE_CODE (type) != UNION_TYPE)
6325 && !incremental)
6326 init = convert (type, integer_zero_node);
6327 else if (!incremental)
6328 {
c7e4ee3a
CB
6329 init = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
6330 TREE_CONSTANT (init) = 1;
6331 TREE_STATIC (init) = 1;
c7e4ee3a
CB
6332 }
6333 else
6334 {
c7e4ee3a
CB
6335 assemble_zeros (int_size_in_bytes (type));
6336 init = error_mark_node;
c7e4ee3a 6337 }
5ff904cd 6338
c7e4ee3a 6339 return init;
5ff904cd
JL
6340}
6341
c7e4ee3a
CB
6342static tree
6343ffecom_intrinsic_ichar_ (tree tree_type, ffebld arg,
6344 tree *maybe_tree)
5ff904cd 6345{
c7e4ee3a
CB
6346 tree expr_tree;
6347 tree length_tree;
5ff904cd 6348
c7e4ee3a 6349 switch (ffebld_op (arg))
6829256f 6350 {
c7e4ee3a
CB
6351 case FFEBLD_opCONTER: /* For F90, check 0-length. */
6352 if (ffetarget_length_character1
6353 (ffebld_constant_character1
6354 (ffebld_conter (arg))) == 0)
6355 {
6356 *maybe_tree = integer_zero_node;
6357 return convert (tree_type, integer_zero_node);
6358 }
5ff904cd 6359
c7e4ee3a
CB
6360 *maybe_tree = integer_one_node;
6361 expr_tree = build_int_2 (*ffetarget_text_character1
6362 (ffebld_constant_character1
6363 (ffebld_conter (arg))),
6364 0);
6365 TREE_TYPE (expr_tree) = tree_type;
6366 return expr_tree;
5ff904cd 6367
c7e4ee3a
CB
6368 case FFEBLD_opSYMTER:
6369 case FFEBLD_opARRAYREF:
6370 case FFEBLD_opFUNCREF:
6371 case FFEBLD_opSUBSTR:
6372 ffecom_char_args_ (&expr_tree, &length_tree, arg);
5ff904cd 6373
c7e4ee3a
CB
6374 if ((expr_tree == error_mark_node)
6375 || (length_tree == error_mark_node))
6376 {
6377 *maybe_tree = error_mark_node;
6378 return error_mark_node;
6379 }
5ff904cd 6380
c7e4ee3a
CB
6381 if (integer_zerop (length_tree))
6382 {
6383 *maybe_tree = integer_zero_node;
6384 return convert (tree_type, integer_zero_node);
6385 }
6386
6387 expr_tree
6388 = ffecom_1 (INDIRECT_REF,
6389 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
6390 expr_tree);
6391 expr_tree
6392 = ffecom_2 (ARRAY_REF,
6393 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
6394 expr_tree,
6395 integer_one_node);
6396 expr_tree = convert (tree_type, expr_tree);
6397
6398 if (TREE_CODE (length_tree) == INTEGER_CST)
6399 *maybe_tree = integer_one_node;
6400 else /* Must check length at run time. */
6401 *maybe_tree
6402 = ffecom_truth_value
6403 (ffecom_2 (GT_EXPR, integer_type_node,
6404 length_tree,
6405 ffecom_f2c_ftnlen_zero_node));
6406 return expr_tree;
6407
6408 case FFEBLD_opPAREN:
6409 case FFEBLD_opCONVERT:
6410 if (ffeinfo_size (ffebld_info (arg)) == 0)
6411 {
6412 *maybe_tree = integer_zero_node;
6413 return convert (tree_type, integer_zero_node);
6414 }
6415 return ffecom_intrinsic_ichar_ (tree_type, ffebld_left (arg),
6416 maybe_tree);
6417
6418 case FFEBLD_opCONCATENATE:
6419 {
6420 tree maybe_left;
6421 tree maybe_right;
6422 tree expr_left;
6423 tree expr_right;
6424
6425 expr_left = ffecom_intrinsic_ichar_ (tree_type, ffebld_left (arg),
6426 &maybe_left);
6427 expr_right = ffecom_intrinsic_ichar_ (tree_type, ffebld_right (arg),
6428 &maybe_right);
6429 *maybe_tree = ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
6430 maybe_left,
6431 maybe_right);
6432 expr_tree = ffecom_3 (COND_EXPR, tree_type,
6433 maybe_left,
6434 expr_left,
6435 expr_right);
6436 return expr_tree;
6437 }
6438
6439 default:
6440 assert ("bad op in ICHAR" == NULL);
6441 return error_mark_node;
6442 }
5ff904cd
JL
6443}
6444
c7e4ee3a
CB
6445/* ffecom_intrinsic_len_ -- Return length info for char arg (LEN())
6446
6447 tree length_arg;
6448 ffebld expr;
6449 length_arg = ffecom_intrinsic_len_ (expr);
6450
6451 Handles CHARACTER-type CONTER, SYMTER, SUBSTR, ARRAYREF, and FUNCREF
6452 subexpressions by constructing the appropriate tree for the
6453 length-of-character-text argument in a calling sequence. */
5ff904cd 6454
5ff904cd 6455static tree
c7e4ee3a 6456ffecom_intrinsic_len_ (ffebld expr)
5ff904cd 6457{
c7e4ee3a
CB
6458 ffetargetCharacter1 val;
6459 tree length;
6460
6461 switch (ffebld_op (expr))
6462 {
6463 case FFEBLD_opCONTER:
6464 val = ffebld_constant_character1 (ffebld_conter (expr));
6465 length = build_int_2 (ffetarget_length_character1 (val), 0);
6466 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6467 break;
6468
6469 case FFEBLD_opSYMTER:
6470 {
6471 ffesymbol s = ffebld_symter (expr);
6472 tree item;
6473
6474 item = ffesymbol_hook (s).decl_tree;
6475 if (item == NULL_TREE)
6476 {
6477 s = ffecom_sym_transform_ (s);
6478 item = ffesymbol_hook (s).decl_tree;
6479 }
6480 if (ffesymbol_kind (s) == FFEINFO_kindENTITY)
6481 {
6482 if (ffesymbol_size (s) == FFETARGET_charactersizeNONE)
6483 length = ffesymbol_hook (s).length_tree;
6484 else
6485 {
6486 length = build_int_2 (ffesymbol_size (s), 0);
6487 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6488 }
6489 }
6490 else if (item == error_mark_node)
6491 length = error_mark_node;
6492 else /* FFEINFO_kindFUNCTION: */
6493 length = NULL_TREE;
6494 }
6495 break;
5ff904cd 6496
c7e4ee3a
CB
6497 case FFEBLD_opARRAYREF:
6498 length = ffecom_intrinsic_len_ (ffebld_left (expr));
6499 break;
5ff904cd 6500
c7e4ee3a
CB
6501 case FFEBLD_opSUBSTR:
6502 {
6503 ffebld start;
6504 ffebld end;
6505 ffebld thing = ffebld_right (expr);
6506 tree start_tree;
6507 tree end_tree;
5ff904cd 6508
c7e4ee3a
CB
6509 assert (ffebld_op (thing) == FFEBLD_opITEM);
6510 start = ffebld_head (thing);
6511 thing = ffebld_trail (thing);
6512 assert (ffebld_trail (thing) == NULL);
6513 end = ffebld_head (thing);
5ff904cd 6514
c7e4ee3a 6515 length = ffecom_intrinsic_len_ (ffebld_left (expr));
5ff904cd 6516
c7e4ee3a
CB
6517 if (length == error_mark_node)
6518 break;
5ff904cd 6519
c7e4ee3a
CB
6520 if (start == NULL)
6521 {
6522 if (end == NULL)
6523 ;
6524 else
6525 {
6526 length = convert (ffecom_f2c_ftnlen_type_node,
6527 ffecom_expr (end));
6528 }
6529 }
6530 else
6531 {
6532 start_tree = convert (ffecom_f2c_ftnlen_type_node,
6533 ffecom_expr (start));
5ff904cd 6534
c7e4ee3a
CB
6535 if (start_tree == error_mark_node)
6536 {
6537 length = error_mark_node;
6538 break;
6539 }
5ff904cd 6540
c7e4ee3a
CB
6541 if (end == NULL)
6542 {
6543 length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6544 ffecom_f2c_ftnlen_one_node,
6545 ffecom_2 (MINUS_EXPR,
6546 ffecom_f2c_ftnlen_type_node,
6547 length,
6548 start_tree));
6549 }
6550 else
6551 {
6552 end_tree = convert (ffecom_f2c_ftnlen_type_node,
6553 ffecom_expr (end));
5ff904cd 6554
c7e4ee3a
CB
6555 if (end_tree == error_mark_node)
6556 {
6557 length = error_mark_node;
6558 break;
6559 }
5ff904cd 6560
c7e4ee3a
CB
6561 length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6562 ffecom_f2c_ftnlen_one_node,
6563 ffecom_2 (MINUS_EXPR,
6564 ffecom_f2c_ftnlen_type_node,
6565 end_tree, start_tree));
6566 }
6567 }
6568 }
6569 break;
5ff904cd 6570
c7e4ee3a
CB
6571 case FFEBLD_opCONCATENATE:
6572 length
6573 = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6574 ffecom_intrinsic_len_ (ffebld_left (expr)),
6575 ffecom_intrinsic_len_ (ffebld_right (expr)));
6576 break;
5ff904cd 6577
c7e4ee3a
CB
6578 case FFEBLD_opFUNCREF:
6579 case FFEBLD_opCONVERT:
6580 length = build_int_2 (ffebld_size (expr), 0);
6581 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6582 break;
5ff904cd 6583
c7e4ee3a
CB
6584 default:
6585 assert ("bad op for single char arg expr" == NULL);
6586 length = ffecom_f2c_ftnlen_zero_node;
6587 break;
6588 }
5ff904cd 6589
c7e4ee3a 6590 assert (length != NULL_TREE);
5ff904cd 6591
c7e4ee3a 6592 return length;
5ff904cd
JL
6593}
6594
c7e4ee3a 6595/* Handle CHARACTER assignments.
5ff904cd 6596
c7e4ee3a
CB
6597 Generates code to do the assignment. Used by ordinary assignment
6598 statement handler ffecom_let_stmt and by statement-function
6599 handler to generate code for a statement function. */
5ff904cd 6600
c7e4ee3a
CB
6601static void
6602ffecom_let_char_ (tree dest_tree, tree dest_length,
6603 ffetargetCharacterSize dest_size, ffebld source)
5ff904cd 6604{
c7e4ee3a
CB
6605 ffecomConcatList_ catlist;
6606 tree source_length;
6607 tree source_tree;
6608 tree expr_tree;
5ff904cd 6609
c7e4ee3a
CB
6610 if ((dest_tree == error_mark_node)
6611 || (dest_length == error_mark_node))
6612 return;
5ff904cd 6613
c7e4ee3a
CB
6614 assert (dest_tree != NULL_TREE);
6615 assert (dest_length != NULL_TREE);
5ff904cd 6616
c7e4ee3a
CB
6617 /* Source might be an opCONVERT, which just means it is a different size
6618 than the destination. Since the underlying implementation here handles
6619 that (directly or via the s_copy or s_cat run-time-library functions),
6620 we don't need the "convenience" of an opCONVERT that tells us to
6621 truncate or blank-pad, particularly since the resulting implementation
6622 would probably be slower than otherwise. */
5ff904cd 6623
c7e4ee3a
CB
6624 while (ffebld_op (source) == FFEBLD_opCONVERT)
6625 source = ffebld_left (source);
5ff904cd 6626
c7e4ee3a
CB
6627 catlist = ffecom_concat_list_new_ (source, dest_size);
6628 switch (ffecom_concat_list_count_ (catlist))
6629 {
6630 case 0: /* Shouldn't happen, but in case it does... */
6631 ffecom_concat_list_kill_ (catlist);
6632 source_tree = null_pointer_node;
6633 source_length = ffecom_f2c_ftnlen_zero_node;
6634 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6635 TREE_CHAIN (expr_tree) = build_tree_list (NULL_TREE, source_tree);
6636 TREE_CHAIN (TREE_CHAIN (expr_tree))
6637 = build_tree_list (NULL_TREE, dest_length);
6638 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6639 = build_tree_list (NULL_TREE, source_length);
5ff904cd 6640
c7e4ee3a
CB
6641 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCOPY, expr_tree, NULL_TREE);
6642 TREE_SIDE_EFFECTS (expr_tree) = 1;
5ff904cd 6643
c7e4ee3a 6644 expand_expr_stmt (expr_tree);
5ff904cd 6645
c7e4ee3a 6646 return;
5ff904cd 6647
c7e4ee3a
CB
6648 case 1: /* The (fairly) easy case. */
6649 ffecom_char_args_ (&source_tree, &source_length,
6650 ffecom_concat_list_expr_ (catlist, 0));
6651 ffecom_concat_list_kill_ (catlist);
6652 assert (source_tree != NULL_TREE);
6653 assert (source_length != NULL_TREE);
6654
6655 if ((source_tree == error_mark_node)
6656 || (source_length == error_mark_node))
6657 return;
6658
6659 if (dest_size == 1)
6660 {
6661 dest_tree
6662 = ffecom_1 (INDIRECT_REF,
6663 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6664 (dest_tree))),
6665 dest_tree);
6666 dest_tree
6667 = ffecom_2 (ARRAY_REF,
6668 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6669 (dest_tree))),
6670 dest_tree,
6671 integer_one_node);
6672 source_tree
6673 = ffecom_1 (INDIRECT_REF,
6674 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6675 (source_tree))),
6676 source_tree);
6677 source_tree
6678 = ffecom_2 (ARRAY_REF,
6679 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6680 (source_tree))),
6681 source_tree,
6682 integer_one_node);
5ff904cd 6683
c7e4ee3a 6684 expr_tree = ffecom_modify (void_type_node, dest_tree, source_tree);
5ff904cd 6685
c7e4ee3a 6686 expand_expr_stmt (expr_tree);
5ff904cd 6687
c7e4ee3a
CB
6688 return;
6689 }
5ff904cd 6690
c7e4ee3a
CB
6691 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6692 TREE_CHAIN (expr_tree) = build_tree_list (NULL_TREE, source_tree);
6693 TREE_CHAIN (TREE_CHAIN (expr_tree))
6694 = build_tree_list (NULL_TREE, dest_length);
6695 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6696 = build_tree_list (NULL_TREE, source_length);
5ff904cd 6697
c7e4ee3a
CB
6698 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCOPY, expr_tree, NULL_TREE);
6699 TREE_SIDE_EFFECTS (expr_tree) = 1;
5ff904cd 6700
c7e4ee3a 6701 expand_expr_stmt (expr_tree);
5ff904cd 6702
c7e4ee3a 6703 return;
5ff904cd 6704
c7e4ee3a
CB
6705 default: /* Must actually concatenate things. */
6706 break;
6707 }
5ff904cd 6708
c7e4ee3a 6709 /* Heavy-duty concatenation. */
5ff904cd 6710
c7e4ee3a
CB
6711 {
6712 int count = ffecom_concat_list_count_ (catlist);
6713 int i;
6714 tree lengths;
6715 tree items;
6716 tree length_array;
6717 tree item_array;
6718 tree citem;
6719 tree clength;
5ff904cd 6720
c7e4ee3a
CB
6721#ifdef HOHO
6722 length_array
6723 = lengths
6724 = ffecom_push_tempvar (ffecom_f2c_ftnlen_type_node,
6725 FFETARGET_charactersizeNONE, count, TRUE);
6726 item_array = items = ffecom_push_tempvar (ffecom_f2c_address_type_node,
6727 FFETARGET_charactersizeNONE,
6728 count, TRUE);
6729#else
6730 {
6731 tree hook;
6732
6733 hook = ffebld_nonter_hook (source);
6734 assert (hook);
6735 assert (TREE_CODE (hook) == TREE_VEC);
6736 assert (TREE_VEC_LENGTH (hook) == 2);
6737 length_array = lengths = TREE_VEC_ELT (hook, 0);
6738 item_array = items = TREE_VEC_ELT (hook, 1);
5ff904cd 6739 }
c7e4ee3a 6740#endif
5ff904cd 6741
c7e4ee3a
CB
6742 for (i = 0; i < count; ++i)
6743 {
6744 ffecom_char_args_ (&citem, &clength,
6745 ffecom_concat_list_expr_ (catlist, i));
6746 if ((citem == error_mark_node)
6747 || (clength == error_mark_node))
6748 {
6749 ffecom_concat_list_kill_ (catlist);
6750 return;
6751 }
5ff904cd 6752
c7e4ee3a
CB
6753 items
6754 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (items),
6755 ffecom_modify (void_type_node,
6756 ffecom_2 (ARRAY_REF,
6757 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array))),
6758 item_array,
6759 build_int_2 (i, 0)),
6760 citem),
6761 items);
6762 lengths
6763 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (lengths),
6764 ffecom_modify (void_type_node,
6765 ffecom_2 (ARRAY_REF,
6766 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array))),
6767 length_array,
6768 build_int_2 (i, 0)),
6769 clength),
6770 lengths);
6771 }
5ff904cd 6772
c7e4ee3a
CB
6773 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6774 TREE_CHAIN (expr_tree)
6775 = build_tree_list (NULL_TREE,
6776 ffecom_1 (ADDR_EXPR,
6777 build_pointer_type (TREE_TYPE (items)),
6778 items));
6779 TREE_CHAIN (TREE_CHAIN (expr_tree))
6780 = build_tree_list (NULL_TREE,
6781 ffecom_1 (ADDR_EXPR,
6782 build_pointer_type (TREE_TYPE (lengths)),
6783 lengths));
6784 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6785 = build_tree_list
6786 (NULL_TREE,
6787 ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
6788 convert (ffecom_f2c_ftnlen_type_node,
6789 build_int_2 (count, 0))));
6790 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree))))
6791 = build_tree_list (NULL_TREE, dest_length);
5ff904cd 6792
c7e4ee3a
CB
6793 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCAT, expr_tree, NULL_TREE);
6794 TREE_SIDE_EFFECTS (expr_tree) = 1;
5ff904cd 6795
c7e4ee3a
CB
6796 expand_expr_stmt (expr_tree);
6797 }
5ff904cd 6798
c7e4ee3a
CB
6799 ffecom_concat_list_kill_ (catlist);
6800}
5ff904cd 6801
c7e4ee3a 6802/* ffecom_make_gfrt_ -- Make initial info for run-time routine
5ff904cd 6803
c7e4ee3a
CB
6804 ffecomGfrt ix;
6805 ffecom_make_gfrt_(ix);
5ff904cd 6806
c7e4ee3a
CB
6807 Assumes gfrt_[ix] is NULL_TREE, and replaces it with the FUNCTION_DECL
6808 for the indicated run-time routine (ix). */
5ff904cd 6809
c7e4ee3a
CB
6810static void
6811ffecom_make_gfrt_ (ffecomGfrt ix)
6812{
6813 tree t;
6814 tree ttype;
5ff904cd 6815
c7e4ee3a
CB
6816 switch (ffecom_gfrt_type_[ix])
6817 {
6818 case FFECOM_rttypeVOID_:
6819 ttype = void_type_node;
6820 break;
5ff904cd 6821
c7e4ee3a
CB
6822 case FFECOM_rttypeVOIDSTAR_:
6823 ttype = TREE_TYPE (null_pointer_node); /* `void *'. */
6824 break;
5ff904cd 6825
c7e4ee3a
CB
6826 case FFECOM_rttypeFTNINT_:
6827 ttype = ffecom_f2c_ftnint_type_node;
6828 break;
5ff904cd 6829
c7e4ee3a
CB
6830 case FFECOM_rttypeINTEGER_:
6831 ttype = ffecom_f2c_integer_type_node;
6832 break;
5ff904cd 6833
c7e4ee3a
CB
6834 case FFECOM_rttypeLONGINT_:
6835 ttype = ffecom_f2c_longint_type_node;
6836 break;
5ff904cd 6837
c7e4ee3a
CB
6838 case FFECOM_rttypeLOGICAL_:
6839 ttype = ffecom_f2c_logical_type_node;
6840 break;
5ff904cd 6841
c7e4ee3a
CB
6842 case FFECOM_rttypeREAL_F2C_:
6843 ttype = double_type_node;
6844 break;
5ff904cd 6845
c7e4ee3a
CB
6846 case FFECOM_rttypeREAL_GNU_:
6847 ttype = float_type_node;
6848 break;
5ff904cd 6849
c7e4ee3a
CB
6850 case FFECOM_rttypeCOMPLEX_F2C_:
6851 ttype = void_type_node;
6852 break;
5ff904cd 6853
c7e4ee3a
CB
6854 case FFECOM_rttypeCOMPLEX_GNU_:
6855 ttype = ffecom_f2c_complex_type_node;
6856 break;
5ff904cd 6857
c7e4ee3a
CB
6858 case FFECOM_rttypeDOUBLE_:
6859 ttype = double_type_node;
6860 break;
5ff904cd 6861
c7e4ee3a
CB
6862 case FFECOM_rttypeDOUBLEREAL_:
6863 ttype = ffecom_f2c_doublereal_type_node;
6864 break;
5ff904cd 6865
c7e4ee3a
CB
6866 case FFECOM_rttypeDBLCMPLX_F2C_:
6867 ttype = void_type_node;
6868 break;
5ff904cd 6869
c7e4ee3a
CB
6870 case FFECOM_rttypeDBLCMPLX_GNU_:
6871 ttype = ffecom_f2c_doublecomplex_type_node;
6872 break;
5ff904cd 6873
c7e4ee3a
CB
6874 case FFECOM_rttypeCHARACTER_:
6875 ttype = void_type_node;
6876 break;
6877
6878 default:
6879 ttype = NULL;
6880 assert ("bad rttype" == NULL);
6881 break;
5ff904cd 6882 }
5ff904cd 6883
c7e4ee3a
CB
6884 ttype = build_function_type (ttype, NULL_TREE);
6885 t = build_decl (FUNCTION_DECL,
6886 get_identifier (ffecom_gfrt_name_[ix]),
6887 ttype);
6888 DECL_EXTERNAL (t) = 1;
95eb4fd9 6889 TREE_READONLY (t) = ffecom_gfrt_const_[ix] ? 1 : 0;
c7e4ee3a
CB
6890 TREE_PUBLIC (t) = 1;
6891 TREE_THIS_VOLATILE (t) = ffecom_gfrt_volatile_[ix] ? 1 : 0;
5ff904cd 6892
95eb4fd9
TM
6893 /* Sanity check: A function that's const cannot be volatile. */
6894
6895 assert (ffecom_gfrt_const_[ix] ? !ffecom_gfrt_volatile_[ix] : 1);
6896
6897 /* Sanity check: A function that's const cannot return complex. */
6898
6899 assert (ffecom_gfrt_const_[ix] ? !ffecom_gfrt_complex_[ix] : 1);
6900
c7e4ee3a 6901 t = start_decl (t, TRUE);
5ff904cd 6902
c7e4ee3a 6903 finish_decl (t, NULL_TREE, TRUE);
5ff904cd 6904
c7e4ee3a 6905 ffecom_gfrt_[ix] = t;
5ff904cd
JL
6906}
6907
c7e4ee3a
CB
6908/* Phase 1 pass over each member of a COMMON/EQUIVALENCE group. */
6909
c7e4ee3a
CB
6910static void
6911ffecom_member_phase1_ (ffestorag mst UNUSED, ffestorag st)
5ff904cd 6912{
c7e4ee3a 6913 ffesymbol s = ffestorag_symbol (st);
5ff904cd 6914
c7e4ee3a
CB
6915 if (ffesymbol_namelisted (s))
6916 ffecom_member_namelisted_ = TRUE;
6917}
5ff904cd 6918
c7e4ee3a
CB
6919/* Phase 2 pass over each member of a COMMON/EQUIVALENCE group. Declare
6920 the member so debugger will see it. Otherwise nobody should be
6921 referencing the member. */
5ff904cd 6922
c7e4ee3a
CB
6923static void
6924ffecom_member_phase2_ (ffestorag mst, ffestorag st)
6925{
6926 ffesymbol s;
6927 tree t;
6928 tree mt;
6929 tree type;
5ff904cd 6930
c7e4ee3a
CB
6931 if ((mst == NULL)
6932 || ((mt = ffestorag_hook (mst)) == NULL)
6933 || (mt == error_mark_node))
6934 return;
5ff904cd 6935
c7e4ee3a
CB
6936 if ((st == NULL)
6937 || ((s = ffestorag_symbol (st)) == NULL))
6938 return;
5ff904cd 6939
c7e4ee3a
CB
6940 type = ffecom_type_localvar_ (s,
6941 ffesymbol_basictype (s),
6942 ffesymbol_kindtype (s));
6943 if (type == error_mark_node)
6944 return;
5ff904cd 6945
c7e4ee3a
CB
6946 t = build_decl (VAR_DECL,
6947 ffecom_get_identifier_ (ffesymbol_text (s)),
6948 type);
5ff904cd 6949
c7e4ee3a
CB
6950 TREE_STATIC (t) = TREE_STATIC (mt);
6951 DECL_INITIAL (t) = NULL_TREE;
6952 TREE_ASM_WRITTEN (t) = 1;
045edebe 6953 TREE_USED (t) = 1;
5ff904cd 6954
19e7881c
MM
6955 SET_DECL_RTL (t,
6956 gen_rtx (MEM, TYPE_MODE (type),
6957 plus_constant (XEXP (DECL_RTL (mt), 0),
6958 ffestorag_modulo (mst)
6959 + ffestorag_offset (st)
6960 - ffestorag_offset (mst))));
5ff904cd 6961
c7e4ee3a 6962 t = start_decl (t, FALSE);
5ff904cd 6963
c7e4ee3a 6964 finish_decl (t, NULL_TREE, FALSE);
5ff904cd
JL
6965}
6966
c7e4ee3a
CB
6967/* Prepare source expression for assignment into a destination perhaps known
6968 to be of a specific size. */
5ff904cd 6969
c7e4ee3a
CB
6970static void
6971ffecom_prepare_let_char_ (ffetargetCharacterSize dest_size, ffebld source)
5ff904cd 6972{
c7e4ee3a
CB
6973 ffecomConcatList_ catlist;
6974 int count;
6975 int i;
6976 tree ltmp;
6977 tree itmp;
6978 tree tempvar = NULL_TREE;
5ff904cd 6979
c7e4ee3a
CB
6980 while (ffebld_op (source) == FFEBLD_opCONVERT)
6981 source = ffebld_left (source);
5ff904cd 6982
c7e4ee3a
CB
6983 catlist = ffecom_concat_list_new_ (source, dest_size);
6984 count = ffecom_concat_list_count_ (catlist);
5ff904cd 6985
c7e4ee3a
CB
6986 if (count >= 2)
6987 {
6988 ltmp
6989 = ffecom_make_tempvar ("let_char_len", ffecom_f2c_ftnlen_type_node,
6990 FFETARGET_charactersizeNONE, count);
6991 itmp
6992 = ffecom_make_tempvar ("let_char_item", ffecom_f2c_address_type_node,
6993 FFETARGET_charactersizeNONE, count);
6994
6995 tempvar = make_tree_vec (2);
6996 TREE_VEC_ELT (tempvar, 0) = ltmp;
6997 TREE_VEC_ELT (tempvar, 1) = itmp;
6998 }
5ff904cd 6999
c7e4ee3a
CB
7000 for (i = 0; i < count; ++i)
7001 ffecom_prepare_arg_ptr_to_expr (ffecom_concat_list_expr_ (catlist, i));
5ff904cd 7002
c7e4ee3a 7003 ffecom_concat_list_kill_ (catlist);
5ff904cd 7004
c7e4ee3a
CB
7005 if (tempvar)
7006 {
7007 ffebld_nonter_set_hook (source, tempvar);
7008 current_binding_level->prep_state = 1;
7009 }
7010}
5ff904cd 7011
c7e4ee3a 7012/* ffecom_push_dummy_decls_ -- Transform dummy args, push parm decls in order
5ff904cd 7013
c7e4ee3a
CB
7014 Ignores STAR (alternate-return) dummies. All other get exec-transitioned
7015 (which generates their trees) and then their trees get push_parm_decl'd.
5ff904cd 7016
c7e4ee3a
CB
7017 The second arg is TRUE if the dummies are for a statement function, in
7018 which case lengths are not pushed for character arguments (since they are
7019 always known by both the caller and the callee, though the code allows
7020 for someday permitting CHAR*(*) stmtfunc dummies). */
5ff904cd 7021
c7e4ee3a
CB
7022static void
7023ffecom_push_dummy_decls_ (ffebld dummy_list, bool stmtfunc)
7024{
7025 ffebld dummy;
7026 ffebld dumlist;
7027 ffesymbol s;
7028 tree parm;
5ff904cd 7029
c7e4ee3a 7030 ffecom_transform_only_dummies_ = TRUE;
5ff904cd 7031
c7e4ee3a 7032 /* First push the parms corresponding to actual dummy "contents". */
5ff904cd 7033
c7e4ee3a
CB
7034 for (dumlist = dummy_list; dumlist != NULL; dumlist = ffebld_trail (dumlist))
7035 {
7036 dummy = ffebld_head (dumlist);
7037 switch (ffebld_op (dummy))
7038 {
7039 case FFEBLD_opSTAR:
7040 case FFEBLD_opANY:
7041 continue; /* Forget alternate returns. */
5ff904cd 7042
c7e4ee3a
CB
7043 default:
7044 break;
7045 }
7046 assert (ffebld_op (dummy) == FFEBLD_opSYMTER);
7047 s = ffebld_symter (dummy);
7048 parm = ffesymbol_hook (s).decl_tree;
7049 if (parm == NULL_TREE)
7050 {
7051 s = ffecom_sym_transform_ (s);
7052 parm = ffesymbol_hook (s).decl_tree;
7053 assert (parm != NULL_TREE);
7054 }
7055 if (parm != error_mark_node)
7056 push_parm_decl (parm);
5ff904cd
JL
7057 }
7058
c7e4ee3a 7059 /* Then, for CHARACTER dummies, push the parms giving their lengths. */
5ff904cd 7060
c7e4ee3a
CB
7061 for (dumlist = dummy_list; dumlist != NULL; dumlist = ffebld_trail (dumlist))
7062 {
7063 dummy = ffebld_head (dumlist);
7064 switch (ffebld_op (dummy))
7065 {
7066 case FFEBLD_opSTAR:
7067 case FFEBLD_opANY:
7068 continue; /* Forget alternate returns, they mean
7069 NOTHING! */
7070
7071 default:
7072 break;
7073 }
7074 s = ffebld_symter (dummy);
7075 if (ffesymbol_basictype (s) != FFEINFO_basictypeCHARACTER)
7076 continue; /* Only looking for CHARACTER arguments. */
7077 if (stmtfunc && (ffesymbol_size (s) != FFETARGET_charactersizeNONE))
7078 continue; /* Stmtfunc arg with known size needs no
7079 length param. */
7080 if (ffesymbol_kind (s) != FFEINFO_kindENTITY)
7081 continue; /* Only looking for variables and arrays. */
7082 parm = ffesymbol_hook (s).length_tree;
7083 assert (parm != NULL_TREE);
7084 if (parm != error_mark_node)
7085 push_parm_decl (parm);
7086 }
7087
7088 ffecom_transform_only_dummies_ = FALSE;
5ff904cd
JL
7089}
7090
c7e4ee3a 7091/* ffecom_start_progunit_ -- Beginning of program unit
5ff904cd 7092
c7e4ee3a
CB
7093 Does GNU back end stuff necessary to teach it about the start of its
7094 equivalent of a Fortran program unit. */
5ff904cd 7095
5ff904cd 7096static void
c7e4ee3a 7097ffecom_start_progunit_ ()
5ff904cd 7098{
c7e4ee3a
CB
7099 ffesymbol fn = ffecom_primary_entry_;
7100 ffebld arglist;
7101 tree id; /* Identifier (name) of function. */
7102 tree type; /* Type of function. */
7103 tree result; /* Result of function. */
7104 ffeinfoBasictype bt;
7105 ffeinfoKindtype kt;
7106 ffeglobal g;
7107 ffeglobalType gt;
7108 ffeglobalType egt = FFEGLOBAL_type;
7109 bool charfunc;
7110 bool cmplxfunc;
7111 bool altentries = (ffecom_num_entrypoints_ != 0);
7112 bool multi
7113 = altentries
7114 && (ffecom_primary_entry_kind_ == FFEINFO_kindFUNCTION)
7115 && (ffecom_master_bt_ == FFEINFO_basictypeNONE);
7116 bool main_program = FALSE;
7117 int old_lineno = lineno;
3b304f5b 7118 const char *old_input_filename = input_filename;
5ff904cd 7119
c7e4ee3a
CB
7120 assert (fn != NULL);
7121 assert (ffesymbol_hook (fn).decl_tree == NULL_TREE);
5ff904cd 7122
c7e4ee3a
CB
7123 input_filename = ffesymbol_where_filename (fn);
7124 lineno = ffesymbol_where_filelinenum (fn);
5ff904cd 7125
c7e4ee3a
CB
7126 switch (ffecom_primary_entry_kind_)
7127 {
7128 case FFEINFO_kindPROGRAM:
7129 main_program = TRUE;
7130 gt = FFEGLOBAL_typeMAIN;
7131 bt = FFEINFO_basictypeNONE;
7132 kt = FFEINFO_kindtypeNONE;
7133 type = ffecom_tree_fun_type_void;
7134 charfunc = FALSE;
7135 cmplxfunc = FALSE;
7136 break;
7137
7138 case FFEINFO_kindBLOCKDATA:
7139 gt = FFEGLOBAL_typeBDATA;
7140 bt = FFEINFO_basictypeNONE;
7141 kt = FFEINFO_kindtypeNONE;
7142 type = ffecom_tree_fun_type_void;
7143 charfunc = FALSE;
7144 cmplxfunc = FALSE;
7145 break;
7146
7147 case FFEINFO_kindFUNCTION:
7148 gt = FFEGLOBAL_typeFUNC;
7149 egt = FFEGLOBAL_typeEXT;
7150 bt = ffesymbol_basictype (fn);
7151 kt = ffesymbol_kindtype (fn);
7152 if (bt == FFEINFO_basictypeNONE)
7153 {
7154 ffeimplic_establish_symbol (fn);
7155 if (ffesymbol_funcresult (fn) != NULL)
7156 ffeimplic_establish_symbol (ffesymbol_funcresult (fn));
7157 bt = ffesymbol_basictype (fn);
7158 kt = ffesymbol_kindtype (fn);
7159 }
7160
7161 if (multi)
7162 charfunc = cmplxfunc = FALSE;
7163 else if (bt == FFEINFO_basictypeCHARACTER)
7164 charfunc = TRUE, cmplxfunc = FALSE;
7165 else if ((bt == FFEINFO_basictypeCOMPLEX)
7166 && ffesymbol_is_f2c (fn)
7167 && !altentries)
7168 charfunc = FALSE, cmplxfunc = TRUE;
7169 else
7170 charfunc = cmplxfunc = FALSE;
7171
7172 if (multi || charfunc)
7173 type = ffecom_tree_fun_type_void;
7174 else if (ffesymbol_is_f2c (fn) && !altentries)
7175 type = ffecom_tree_fun_type[bt][kt];
7176 else
7177 type = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
7178
7179 if ((type == NULL_TREE)
7180 || (TREE_TYPE (type) == NULL_TREE))
7181 type = ffecom_tree_fun_type_void; /* _sym_exec_transition. */
7182 break;
7183
7184 case FFEINFO_kindSUBROUTINE:
7185 gt = FFEGLOBAL_typeSUBR;
7186 egt = FFEGLOBAL_typeEXT;
7187 bt = FFEINFO_basictypeNONE;
7188 kt = FFEINFO_kindtypeNONE;
7189 if (ffecom_is_altreturning_)
7190 type = ffecom_tree_subr_type;
7191 else
7192 type = ffecom_tree_fun_type_void;
7193 charfunc = FALSE;
7194 cmplxfunc = FALSE;
7195 break;
5ff904cd 7196
c7e4ee3a
CB
7197 default:
7198 assert ("say what??" == NULL);
7199 /* Fall through. */
7200 case FFEINFO_kindANY:
7201 gt = FFEGLOBAL_typeANY;
7202 bt = FFEINFO_basictypeNONE;
7203 kt = FFEINFO_kindtypeNONE;
7204 type = error_mark_node;
7205 charfunc = FALSE;
7206 cmplxfunc = FALSE;
7207 break;
7208 }
5ff904cd 7209
c7e4ee3a 7210 if (altentries)
5ff904cd 7211 {
c7e4ee3a 7212 id = ffecom_get_invented_identifier ("__g77_masterfun_%s",
14657de8 7213 ffesymbol_text (fn));
c7e4ee3a
CB
7214 }
7215#if FFETARGET_isENFORCED_MAIN
7216 else if (main_program)
7217 id = get_identifier (FFETARGET_nameENFORCED_MAIN_NAME);
7218#endif
7219 else
7220 id = ffecom_get_external_identifier_ (fn);
5ff904cd 7221
c7e4ee3a
CB
7222 start_function (id,
7223 type,
7224 0, /* nested/inline */
7225 !altentries); /* TREE_PUBLIC */
5ff904cd 7226
c7e4ee3a 7227 TREE_USED (current_function_decl) = 1; /* Avoid spurious warning if altentries. */
5ff904cd 7228
c7e4ee3a
CB
7229 if (!altentries
7230 && ((g = ffesymbol_global (fn)) != NULL)
7231 && ((ffeglobal_type (g) == gt)
7232 || (ffeglobal_type (g) == egt)))
7233 {
7234 ffeglobal_set_hook (g, current_function_decl);
7235 }
5ff904cd 7236
c7e4ee3a
CB
7237 /* Arg handling needs exec-transitioned ffesymbols to work with. But
7238 exec-transitioning needs current_function_decl to be filled in. So we
7239 do these things in two phases. */
5ff904cd 7240
c7e4ee3a
CB
7241 if (altentries)
7242 { /* 1st arg identifies which entrypoint. */
7243 ffecom_which_entrypoint_decl_
7244 = build_decl (PARM_DECL,
7245 ffecom_get_invented_identifier ("__g77_%s",
14657de8 7246 "which_entrypoint"),
c7e4ee3a
CB
7247 integer_type_node);
7248 push_parm_decl (ffecom_which_entrypoint_decl_);
7249 }
5ff904cd 7250
c7e4ee3a
CB
7251 if (charfunc
7252 || cmplxfunc
7253 || multi)
7254 { /* Arg for result (return value). */
7255 tree type;
7256 tree length;
5ff904cd 7257
c7e4ee3a
CB
7258 if (charfunc)
7259 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
7260 else if (cmplxfunc)
7261 type = ffecom_tree_type[FFEINFO_basictypeCOMPLEX][kt];
7262 else
7263 type = ffecom_multi_type_node_;
5ff904cd 7264
14657de8 7265 result = ffecom_get_invented_identifier ("__g77_%s", "result");
5ff904cd 7266
c7e4ee3a 7267 /* Make length arg _and_ enhance type info for CHAR arg itself. */
5ff904cd 7268
c7e4ee3a
CB
7269 if (charfunc)
7270 length = ffecom_char_enhance_arg_ (&type, fn);
7271 else
7272 length = NULL_TREE; /* Not ref'd if !charfunc. */
5ff904cd 7273
c7e4ee3a
CB
7274 type = build_pointer_type (type);
7275 result = build_decl (PARM_DECL, result, type);
5ff904cd 7276
c7e4ee3a
CB
7277 push_parm_decl (result);
7278 if (multi)
7279 ffecom_multi_retval_ = result;
7280 else
7281 ffecom_func_result_ = result;
5ff904cd 7282
c7e4ee3a
CB
7283 if (charfunc)
7284 {
7285 push_parm_decl (length);
7286 ffecom_func_length_ = length;
7287 }
5ff904cd
JL
7288 }
7289
c7e4ee3a
CB
7290 if (ffecom_primary_entry_is_proc_)
7291 {
7292 if (altentries)
7293 arglist = ffecom_master_arglist_;
7294 else
7295 arglist = ffesymbol_dummyargs (fn);
7296 ffecom_push_dummy_decls_ (arglist, FALSE);
7297 }
5ff904cd 7298
c7e4ee3a
CB
7299 if (TREE_CODE (current_function_decl) != ERROR_MARK)
7300 store_parm_decls (main_program ? 1 : 0);
5ff904cd 7301
c7e4ee3a
CB
7302 ffecom_start_compstmt ();
7303 /* Disallow temp vars at this level. */
7304 current_binding_level->prep_state = 2;
5ff904cd 7305
c7e4ee3a
CB
7306 lineno = old_lineno;
7307 input_filename = old_input_filename;
5ff904cd 7308
c7e4ee3a
CB
7309 /* This handles any symbols still untransformed, in case -g specified.
7310 This used to be done in ffecom_finish_progunit, but it turns out to
7311 be necessary to do it here so that statement functions are
7312 expanded before code. But don't bother for BLOCK DATA. */
5ff904cd 7313
c7e4ee3a
CB
7314 if (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA)
7315 ffesymbol_drive (ffecom_finish_symbol_transform_);
5ff904cd
JL
7316}
7317
c7e4ee3a 7318/* ffecom_sym_transform_ -- Transform FFE sym into backend sym
5ff904cd 7319
c7e4ee3a
CB
7320 ffesymbol s;
7321 ffecom_sym_transform_(s);
7322
7323 The ffesymbol_hook info for s is updated with appropriate backend info
7324 on the symbol. */
7325
c7e4ee3a
CB
7326static ffesymbol
7327ffecom_sym_transform_ (ffesymbol s)
7328{
7329 tree t; /* Transformed thingy. */
7330 tree tlen; /* Length if CHAR*(*). */
7331 bool addr; /* Is t the address of the thingy? */
7332 ffeinfoBasictype bt;
7333 ffeinfoKindtype kt;
7334 ffeglobal g;
c7e4ee3a 7335 int old_lineno = lineno;
3b304f5b 7336 const char *old_input_filename = input_filename;
5ff904cd 7337
c7e4ee3a
CB
7338 /* Must ensure special ASSIGN variables are declared at top of outermost
7339 block, else they'll end up in the innermost block when their first
7340 ASSIGN is seen, which leaves them out of scope when they're the
7341 subject of a GOTO or I/O statement.
5ff904cd 7342
c7e4ee3a
CB
7343 We make this variable even if -fugly-assign. Just let it go unused,
7344 in case it turns out there are cases where we really want to use this
7345 variable anyway (e.g. ASSIGN to INTEGER*2 variable). */
5ff904cd 7346
c7e4ee3a
CB
7347 if (! ffecom_transform_only_dummies_
7348 && ffesymbol_assigned (s)
7349 && ! ffesymbol_hook (s).assign_tree)
7350 s = ffecom_sym_transform_assign_ (s);
5ff904cd 7351
c7e4ee3a 7352 if (ffesymbol_sfdummyparent (s) == NULL)
5ff904cd 7353 {
c7e4ee3a
CB
7354 input_filename = ffesymbol_where_filename (s);
7355 lineno = ffesymbol_where_filelinenum (s);
7356 }
7357 else
7358 {
7359 ffesymbol sf = ffesymbol_sfdummyparent (s);
5ff904cd 7360
c7e4ee3a
CB
7361 input_filename = ffesymbol_where_filename (sf);
7362 lineno = ffesymbol_where_filelinenum (sf);
7363 }
6d433196 7364
c7e4ee3a
CB
7365 bt = ffeinfo_basictype (ffebld_info (s));
7366 kt = ffeinfo_kindtype (ffebld_info (s));
5ff904cd 7367
c7e4ee3a
CB
7368 t = NULL_TREE;
7369 tlen = NULL_TREE;
7370 addr = FALSE;
5ff904cd 7371
c7e4ee3a
CB
7372 switch (ffesymbol_kind (s))
7373 {
7374 case FFEINFO_kindNONE:
7375 switch (ffesymbol_where (s))
7376 {
7377 case FFEINFO_whereDUMMY: /* Subroutine or function. */
7378 assert (ffecom_transform_only_dummies_);
5ff904cd 7379
c7e4ee3a
CB
7380 /* Before 0.4, this could be ENTITY/DUMMY, but see
7381 ffestu_sym_end_transition -- no longer true (in particular, if
7382 it could be an ENTITY, it _will_ be made one, so that
7383 possibility won't come through here). So we never make length
7384 arg for CHARACTER type. */
5ff904cd 7385
c7e4ee3a
CB
7386 t = build_decl (PARM_DECL,
7387 ffecom_get_identifier_ (ffesymbol_text (s)),
7388 ffecom_tree_ptr_to_subr_type);
c7e4ee3a 7389 DECL_ARTIFICIAL (t) = 1;
c7e4ee3a
CB
7390 addr = TRUE;
7391 break;
5ff904cd 7392
c7e4ee3a
CB
7393 case FFEINFO_whereGLOBAL: /* Subroutine or function. */
7394 assert (!ffecom_transform_only_dummies_);
5ff904cd 7395
c7e4ee3a
CB
7396 if (((g = ffesymbol_global (s)) != NULL)
7397 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
7398 || (ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
7399 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
7400 && (ffeglobal_hook (g) != NULL_TREE)
7401 && ffe_is_globals ())
7402 {
7403 t = ffeglobal_hook (g);
7404 break;
7405 }
5ff904cd 7406
c7e4ee3a
CB
7407 t = build_decl (FUNCTION_DECL,
7408 ffecom_get_external_identifier_ (s),
7409 ffecom_tree_subr_type); /* Assume subr. */
7410 DECL_EXTERNAL (t) = 1;
7411 TREE_PUBLIC (t) = 1;
5ff904cd 7412
c7e4ee3a
CB
7413 t = start_decl (t, FALSE);
7414 finish_decl (t, NULL_TREE, FALSE);
795232f7 7415
c7e4ee3a
CB
7416 if ((g != NULL)
7417 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
7418 || (ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
7419 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
7420 ffeglobal_set_hook (g, t);
5ff904cd 7421
7189a4b0 7422 ffecom_save_tree_forever (t);
5ff904cd 7423
c7e4ee3a 7424 break;
5ff904cd 7425
c7e4ee3a
CB
7426 default:
7427 assert ("NONE where unexpected" == NULL);
7428 /* Fall through. */
7429 case FFEINFO_whereANY:
7430 break;
7431 }
5ff904cd 7432 break;
5ff904cd 7433
c7e4ee3a
CB
7434 case FFEINFO_kindENTITY:
7435 switch (ffeinfo_where (ffesymbol_info (s)))
7436 {
5ff904cd 7437
c7e4ee3a
CB
7438 case FFEINFO_whereCONSTANT:
7439 /* ~~Debugging info needed? */
7440 assert (!ffecom_transform_only_dummies_);
7441 t = error_mark_node; /* Shouldn't ever see this in expr. */
7442 break;
5ff904cd 7443
c7e4ee3a
CB
7444 case FFEINFO_whereLOCAL:
7445 assert (!ffecom_transform_only_dummies_);
5ff904cd 7446
c7e4ee3a
CB
7447 {
7448 ffestorag st = ffesymbol_storage (s);
7449 tree type;
5ff904cd 7450
c7e4ee3a
CB
7451 if ((st != NULL)
7452 && (ffestorag_size (st) == 0))
7453 {
7454 t = error_mark_node;
7455 break;
7456 }
5ff904cd 7457
c7e4ee3a 7458 type = ffecom_type_localvar_ (s, bt, kt);
5ff904cd 7459
c7e4ee3a
CB
7460 if (type == error_mark_node)
7461 {
7462 t = error_mark_node;
7463 break;
7464 }
5ff904cd 7465
c7e4ee3a
CB
7466 if ((st != NULL)
7467 && (ffestorag_parent (st) != NULL))
7468 { /* Child of EQUIVALENCE parent. */
7469 ffestorag est;
7470 tree et;
c7e4ee3a 7471 ffetargetOffset offset;
5ff904cd 7472
c7e4ee3a
CB
7473 est = ffestorag_parent (st);
7474 ffecom_transform_equiv_ (est);
5ff904cd 7475
c7e4ee3a
CB
7476 et = ffestorag_hook (est);
7477 assert (et != NULL_TREE);
5ff904cd 7478
c7e4ee3a
CB
7479 if (! TREE_STATIC (et))
7480 put_var_into_stack (et);
5ff904cd 7481
c7e4ee3a
CB
7482 offset = ffestorag_modulo (est)
7483 + ffestorag_offset (ffesymbol_storage (s))
7484 - ffestorag_offset (est);
5ff904cd 7485
c7e4ee3a 7486 ffecom_debug_kludge_ (et, "EQUIVALENCE", s, type, offset);
5ff904cd 7487
c7e4ee3a 7488 /* (t_type *) (((char *) &et) + offset) */
5ff904cd 7489
c7e4ee3a
CB
7490 t = convert (string_type_node, /* (char *) */
7491 ffecom_1 (ADDR_EXPR,
7492 build_pointer_type (TREE_TYPE (et)),
7493 et));
7494 t = ffecom_2 (PLUS_EXPR, TREE_TYPE (t),
7495 t,
7496 build_int_2 (offset, 0));
7497 t = convert (build_pointer_type (type),
7498 t);
d50108c7 7499 TREE_CONSTANT (t) = staticp (et);
5ff904cd 7500
c7e4ee3a 7501 addr = TRUE;
c7e4ee3a
CB
7502 }
7503 else
7504 {
7505 tree initexpr;
7506 bool init = ffesymbol_is_init (s);
5ff904cd 7507
c7e4ee3a
CB
7508 t = build_decl (VAR_DECL,
7509 ffecom_get_identifier_ (ffesymbol_text (s)),
7510 type);
5ff904cd 7511
c7e4ee3a
CB
7512 if (init
7513 || ffesymbol_namelisted (s)
7514#ifdef FFECOM_sizeMAXSTACKITEM
7515 || ((st != NULL)
7516 && (ffestorag_size (st) > FFECOM_sizeMAXSTACKITEM))
7517#endif
7518 || ((ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
7519 && (ffecom_primary_entry_kind_
7520 != FFEINFO_kindBLOCKDATA)
7521 && (ffesymbol_is_save (s) || ffe_is_saveall ())))
7522 TREE_STATIC (t) = !ffesymbol_attr (s, FFESYMBOL_attrADJUSTABLE);
7523 else
7524 TREE_STATIC (t) = 0; /* No need to make static. */
5ff904cd 7525
c7e4ee3a
CB
7526 if (init || ffe_is_init_local_zero ())
7527 DECL_INITIAL (t) = error_mark_node;
5ff904cd 7528
c7e4ee3a
CB
7529 /* Keep -Wunused from complaining about var if it
7530 is used as sfunc arg or DATA implied-DO. */
7531 if (ffesymbol_attrs (s) & FFESYMBOL_attrsSFARG)
7532 DECL_IN_SYSTEM_HEADER (t) = 1;
5ff904cd 7533
c7e4ee3a 7534 t = start_decl (t, FALSE);
5ff904cd 7535
c7e4ee3a
CB
7536 if (init)
7537 {
7538 if (ffesymbol_init (s) != NULL)
7539 initexpr = ffecom_expr (ffesymbol_init (s));
7540 else
7541 initexpr = ffecom_init_zero_ (t);
7542 }
7543 else if (ffe_is_init_local_zero ())
7544 initexpr = ffecom_init_zero_ (t);
7545 else
7546 initexpr = NULL_TREE; /* Not ref'd if !init. */
5ff904cd 7547
c7e4ee3a 7548 finish_decl (t, initexpr, FALSE);
5ff904cd 7549
06ceef4e 7550 if (st != NULL && DECL_SIZE (t) != error_mark_node)
c7e4ee3a 7551 {
06ceef4e 7552 assert (TREE_CODE (DECL_SIZE_UNIT (t)) == INTEGER_CST);
05bccae2
RK
7553 assert (0 == compare_tree_int (DECL_SIZE_UNIT (t),
7554 ffestorag_size (st)));
c7e4ee3a 7555 }
c7e4ee3a
CB
7556 }
7557 }
5ff904cd 7558 break;
5ff904cd 7559
c7e4ee3a
CB
7560 case FFEINFO_whereRESULT:
7561 assert (!ffecom_transform_only_dummies_);
5ff904cd 7562
c7e4ee3a
CB
7563 if (bt == FFEINFO_basictypeCHARACTER)
7564 { /* Result is already in list of dummies, use
7565 it (& length). */
7566 t = ffecom_func_result_;
7567 tlen = ffecom_func_length_;
7568 addr = TRUE;
7569 break;
7570 }
7571 if ((ffecom_num_entrypoints_ == 0)
7572 && (bt == FFEINFO_basictypeCOMPLEX)
7573 && (ffesymbol_is_f2c (ffecom_primary_entry_)))
7574 { /* Result is already in list of dummies, use
7575 it. */
7576 t = ffecom_func_result_;
7577 addr = TRUE;
7578 break;
7579 }
7580 if (ffecom_func_result_ != NULL_TREE)
7581 {
7582 t = ffecom_func_result_;
7583 break;
7584 }
7585 if ((ffecom_num_entrypoints_ != 0)
7586 && (ffecom_master_bt_ == FFEINFO_basictypeNONE))
7587 {
c7e4ee3a
CB
7588 assert (ffecom_multi_retval_ != NULL_TREE);
7589 t = ffecom_1 (INDIRECT_REF, ffecom_multi_type_node_,
7590 ffecom_multi_retval_);
7591 t = ffecom_2 (COMPONENT_REF, ffecom_tree_type[bt][kt],
7592 t, ffecom_multi_fields_[bt][kt]);
5ff904cd 7593
c7e4ee3a
CB
7594 break;
7595 }
5ff904cd 7596
c7e4ee3a
CB
7597 t = build_decl (VAR_DECL,
7598 ffecom_get_identifier_ (ffesymbol_text (s)),
7599 ffecom_tree_type[bt][kt]);
7600 TREE_STATIC (t) = 0; /* Put result on stack. */
7601 t = start_decl (t, FALSE);
7602 finish_decl (t, NULL_TREE, FALSE);
5ff904cd 7603
c7e4ee3a 7604 ffecom_func_result_ = t;
5ff904cd 7605
c7e4ee3a 7606 break;
5ff904cd 7607
c7e4ee3a
CB
7608 case FFEINFO_whereDUMMY:
7609 {
7610 tree type;
7611 ffebld dl;
7612 ffebld dim;
7613 tree low;
7614 tree high;
7615 tree old_sizes;
7616 bool adjustable = FALSE; /* Conditionally adjustable? */
5ff904cd 7617
c7e4ee3a
CB
7618 type = ffecom_tree_type[bt][kt];
7619 if (ffesymbol_sfdummyparent (s) != NULL)
7620 {
7621 if (current_function_decl == ffecom_outer_function_decl_)
7622 { /* Exec transition before sfunc
7623 context; get it later. */
7624 break;
7625 }
7626 t = ffecom_get_identifier_ (ffesymbol_text
7627 (ffesymbol_sfdummyparent (s)));
7628 }
7629 else
7630 t = ffecom_get_identifier_ (ffesymbol_text (s));
5ff904cd 7631
c7e4ee3a 7632 assert (ffecom_transform_only_dummies_);
5ff904cd 7633
c7e4ee3a
CB
7634 old_sizes = get_pending_sizes ();
7635 put_pending_sizes (old_sizes);
5ff904cd 7636
c7e4ee3a
CB
7637 if (bt == FFEINFO_basictypeCHARACTER)
7638 tlen = ffecom_char_enhance_arg_ (&type, s);
7639 type = ffecom_check_size_overflow_ (s, type, TRUE);
5ff904cd 7640
c7e4ee3a
CB
7641 for (dl = ffesymbol_dims (s); dl != NULL; dl = ffebld_trail (dl))
7642 {
7643 if (type == error_mark_node)
7644 break;
5ff904cd 7645
c7e4ee3a
CB
7646 dim = ffebld_head (dl);
7647 assert (ffebld_op (dim) == FFEBLD_opBOUNDS);
7648 if ((ffebld_left (dim) == NULL) || ffecom_doing_entry_)
7649 low = ffecom_integer_one_node;
7650 else
7651 low = ffecom_expr (ffebld_left (dim));
7652 assert (ffebld_right (dim) != NULL);
7653 if ((ffebld_op (ffebld_right (dim)) == FFEBLD_opSTAR)
7654 || ffecom_doing_entry_)
7655 {
7656 /* Used to just do high=low. But for ffecom_tree_
7657 canonize_ref_, it probably is important to correctly
7658 assess the size. E.g. given COMPLEX C(*),CFUNC and
7659 C(2)=CFUNC(C), overlap can happen, while it can't
7660 for, say, C(1)=CFUNC(C(2)). */
7661 /* Even more recently used to set to INT_MAX, but that
7662 broke when some overflow checking went into the back
7663 end. Now we just leave the upper bound unspecified. */
7664 high = NULL;
7665 }
7666 else
7667 high = ffecom_expr (ffebld_right (dim));
5ff904cd 7668
c7e4ee3a
CB
7669 /* Determine whether array is conditionally adjustable,
7670 to decide whether back-end magic is needed.
5ff904cd 7671
c7e4ee3a
CB
7672 Normally the front end uses the back-end function
7673 variable_size to wrap SAVE_EXPR's around expressions
7674 affecting the size/shape of an array so that the
7675 size/shape info doesn't change during execution
7676 of the compiled code even though variables and
7677 functions referenced in those expressions might.
5ff904cd 7678
c7e4ee3a
CB
7679 variable_size also makes sure those saved expressions
7680 get evaluated immediately upon entry to the
7681 compiled procedure -- the front end normally doesn't
7682 have to worry about that.
3cf0cea4 7683
c7e4ee3a
CB
7684 However, there is a problem with this that affects
7685 g77's implementation of entry points, and that is
7686 that it is _not_ true that each invocation of the
7687 compiled procedure is permitted to evaluate
7688 array size/shape info -- because it is possible
7689 that, for some invocations, that info is invalid (in
7690 which case it is "promised" -- i.e. a violation of
7691 the Fortran standard -- that the compiled code
7692 won't reference the array or its size/shape
7693 during that particular invocation).
5ff904cd 7694
c7e4ee3a 7695 To phrase this in C terms, consider this gcc function:
5ff904cd 7696
c7e4ee3a
CB
7697 void foo (int *n, float (*a)[*n])
7698 {
7699 // a is "pointer to array ...", fyi.
7700 }
5ff904cd 7701
c7e4ee3a
CB
7702 Suppose that, for some invocations, it is permitted
7703 for a caller of foo to do this:
5ff904cd 7704
c7e4ee3a 7705 foo (NULL, NULL);
5ff904cd 7706
c7e4ee3a
CB
7707 Now the _written_ code for foo can take such a call
7708 into account by either testing explicitly for whether
7709 (a == NULL) || (n == NULL) -- presumably it is
7710 not permitted to reference *a in various fashions
7711 if (n == NULL) I suppose -- or it can avoid it by
7712 looking at other info (other arguments, static/global
7713 data, etc.).
5ff904cd 7714
c7e4ee3a
CB
7715 However, this won't work in gcc 2.5.8 because it'll
7716 automatically emit the code to save the "*n"
7717 expression, which'll yield a NULL dereference for
7718 the "foo (NULL, NULL)" call, something the code
7719 for foo cannot prevent.
5ff904cd 7720
c7e4ee3a
CB
7721 g77 definitely needs to avoid executing such
7722 code anytime the pointer to the adjustable array
7723 is NULL, because even if its bounds expressions
7724 don't have any references to possible "absent"
7725 variables like "*n" -- say all variable references
7726 are to COMMON variables, i.e. global (though in C,
7727 local static could actually make sense) -- the
7728 expressions could yield other run-time problems
7729 for allowably "dead" values in those variables.
5ff904cd 7730
c7e4ee3a
CB
7731 For example, let's consider a more complicated
7732 version of foo:
5ff904cd 7733
c7e4ee3a
CB
7734 extern int i;
7735 extern int j;
5ff904cd 7736
c7e4ee3a
CB
7737 void foo (float (*a)[i/j])
7738 {
7739 ...
7740 }
5ff904cd 7741
c7e4ee3a
CB
7742 The above is (essentially) quite valid for Fortran
7743 but, again, for a call like "foo (NULL);", it is
7744 permitted for i and j to be undefined when the
7745 call is made. If j happened to be zero, for
7746 example, emitting the code to evaluate "i/j"
7747 could result in a run-time error.
5ff904cd 7748
c7e4ee3a
CB
7749 Offhand, though I don't have my F77 or F90
7750 standards handy, it might even be valid for a
7751 bounds expression to contain a function reference,
7752 in which case I doubt it is permitted for an
7753 implementation to invoke that function in the
7754 Fortran case involved here (invocation of an
7755 alternate ENTRY point that doesn't have the adjustable
7756 array as one of its arguments).
5ff904cd 7757
c7e4ee3a
CB
7758 So, the code that the compiler would normally emit
7759 to preevaluate the size/shape info for an
7760 adjustable array _must not_ be executed at run time
7761 in certain cases. Specifically, for Fortran,
7762 the case is when the pointer to the adjustable
7763 array == NULL. (For gnu-ish C, it might be nice
7764 for the source code itself to specify an expression
7765 that, if TRUE, inhibits execution of the code. Or
7766 reverse the sense for elegance.)
5ff904cd 7767
c7e4ee3a
CB
7768 (Note that g77 could use a different test than NULL,
7769 actually, since it happens to always pass an
7770 integer to the called function that specifies which
7771 entry point is being invoked. Hmm, this might
7772 solve the next problem.)
7773
7774 One way a user could, I suppose, write "foo" so
7775 it works is to insert COND_EXPR's for the
7776 size/shape info so the dangerous stuff isn't
7777 actually done, as in:
7778
7779 void foo (int *n, float (*a)[(a == NULL) ? 0 : *n])
7780 {
7781 ...
7782 }
5ff904cd 7783
c7e4ee3a
CB
7784 The next problem is that the front end needs to
7785 be able to tell the back end about the array's
7786 decl _before_ it tells it about the conditional
7787 expression to inhibit evaluation of size/shape info,
7788 as shown above.
5ff904cd 7789
c7e4ee3a
CB
7790 To solve this, the front end needs to be able
7791 to give the back end the expression to inhibit
7792 generation of the preevaluation code _after_
7793 it makes the decl for the adjustable array.
5ff904cd 7794
c7e4ee3a
CB
7795 Until then, the above example using the COND_EXPR
7796 doesn't pass muster with gcc because the "(a == NULL)"
7797 part has a reference to "a", which is still
7798 undefined at that point.
5ff904cd 7799
c7e4ee3a
CB
7800 g77 will therefore use a different mechanism in the
7801 meantime. */
5ff904cd 7802
c7e4ee3a
CB
7803 if (!adjustable
7804 && ((TREE_CODE (low) != INTEGER_CST)
7805 || (high && TREE_CODE (high) != INTEGER_CST)))
7806 adjustable = TRUE;
5ff904cd 7807
c7e4ee3a
CB
7808#if 0 /* Old approach -- see below. */
7809 if (TREE_CODE (low) != INTEGER_CST)
7810 low = ffecom_3 (COND_EXPR, integer_type_node,
7811 ffecom_adjarray_passed_ (s),
7812 low,
7813 ffecom_integer_zero_node);
5ff904cd 7814
c7e4ee3a
CB
7815 if (high && TREE_CODE (high) != INTEGER_CST)
7816 high = ffecom_3 (COND_EXPR, integer_type_node,
7817 ffecom_adjarray_passed_ (s),
7818 high,
7819 ffecom_integer_zero_node);
7820#endif
5ff904cd 7821
c7e4ee3a
CB
7822 /* ~~~gcc/stor-layout.c (layout_type) should do this,
7823 probably. Fixes 950302-1.f. */
5ff904cd 7824
c7e4ee3a
CB
7825 if (TREE_CODE (low) != INTEGER_CST)
7826 low = variable_size (low);
5ff904cd 7827
c7e4ee3a
CB
7828 /* ~~~Similarly, this fixes dumb0.f. The C front end
7829 does this, which is why dumb0.c would work. */
5ff904cd 7830
c7e4ee3a
CB
7831 if (high && TREE_CODE (high) != INTEGER_CST)
7832 high = variable_size (high);
5ff904cd 7833
c7e4ee3a
CB
7834 type
7835 = build_array_type
7836 (type,
7837 build_range_type (ffecom_integer_type_node,
7838 low, high));
7839 type = ffecom_check_size_overflow_ (s, type, TRUE);
7840 }
5ff904cd 7841
c7e4ee3a
CB
7842 if (type == error_mark_node)
7843 {
7844 t = error_mark_node;
7845 break;
7846 }
5ff904cd 7847
c7e4ee3a
CB
7848 if ((ffesymbol_sfdummyparent (s) == NULL)
7849 || (ffesymbol_basictype (s) == FFEINFO_basictypeCHARACTER))
7850 {
7851 type = build_pointer_type (type);
7852 addr = TRUE;
7853 }
5ff904cd 7854
c7e4ee3a 7855 t = build_decl (PARM_DECL, t, type);
c7e4ee3a 7856 DECL_ARTIFICIAL (t) = 1;
5ff904cd 7857
c7e4ee3a
CB
7858 /* If this arg is present in every entry point's list of
7859 dummy args, then we're done. */
5ff904cd 7860
c7e4ee3a
CB
7861 if (ffesymbol_numentries (s)
7862 == (ffecom_num_entrypoints_ + 1))
5ff904cd 7863 break;
5ff904cd 7864
c7e4ee3a 7865#if 1
5ff904cd 7866
c7e4ee3a
CB
7867 /* If variable_size in stor-layout has been called during
7868 the above, then get_pending_sizes should have the
7869 yet-to-be-evaluated saved expressions pending.
7870 Make the whole lot of them get emitted, conditionally
7871 on whether the array decl ("t" above) is not NULL. */
5ff904cd 7872
c7e4ee3a
CB
7873 {
7874 tree sizes = get_pending_sizes ();
7875 tree tem;
5ff904cd 7876
c7e4ee3a
CB
7877 for (tem = sizes;
7878 tem != old_sizes;
7879 tem = TREE_CHAIN (tem))
7880 {
7881 tree temv = TREE_VALUE (tem);
5ff904cd 7882
c7e4ee3a
CB
7883 if (sizes == tem)
7884 sizes = temv;
7885 else
7886 sizes
7887 = ffecom_2 (COMPOUND_EXPR,
7888 TREE_TYPE (sizes),
7889 temv,
7890 sizes);
7891 }
5ff904cd 7892
c7e4ee3a
CB
7893 if (sizes != tem)
7894 {
7895 sizes
7896 = ffecom_3 (COND_EXPR,
7897 TREE_TYPE (sizes),
7898 ffecom_2 (NE_EXPR,
7899 integer_type_node,
7900 t,
7901 null_pointer_node),
7902 sizes,
7903 convert (TREE_TYPE (sizes),
7904 integer_zero_node));
7905 sizes = ffecom_save_tree (sizes);
5ff904cd 7906
c7e4ee3a
CB
7907 sizes
7908 = tree_cons (NULL_TREE, sizes, tem);
7909 }
5ff904cd 7910
c7e4ee3a
CB
7911 if (sizes)
7912 put_pending_sizes (sizes);
7913 }
5ff904cd 7914
c7e4ee3a
CB
7915#else
7916#if 0
7917 if (adjustable
7918 && (ffesymbol_numentries (s)
7919 != ffecom_num_entrypoints_ + 1))
7920 DECL_SOMETHING (t)
7921 = ffecom_2 (NE_EXPR, integer_type_node,
7922 t,
7923 null_pointer_node);
7924#else
7925#if 0
7926 if (adjustable
7927 && (ffesymbol_numentries (s)
7928 != ffecom_num_entrypoints_ + 1))
7929 {
7930 ffebad_start (FFEBAD_MISSING_ADJARRAY_UNSUPPORTED);
7931 ffebad_here (0, ffesymbol_where_line (s),
7932 ffesymbol_where_column (s));
7933 ffebad_string (ffesymbol_text (s));
7934 ffebad_finish ();
7935 }
7936#endif
7937#endif
7938#endif
7939 }
5ff904cd
JL
7940 break;
7941
c7e4ee3a 7942 case FFEINFO_whereCOMMON:
5ff904cd 7943 {
c7e4ee3a
CB
7944 ffesymbol cs;
7945 ffeglobal cg;
7946 tree ct;
5ff904cd
JL
7947 ffestorag st = ffesymbol_storage (s);
7948 tree type;
7949
c7e4ee3a
CB
7950 cs = ffesymbol_common (s); /* The COMMON area itself. */
7951 if (st != NULL) /* Else not laid out. */
5ff904cd 7952 {
c7e4ee3a
CB
7953 ffecom_transform_common_ (cs);
7954 st = ffesymbol_storage (s);
5ff904cd
JL
7955 }
7956
c7e4ee3a 7957 type = ffecom_type_localvar_ (s, bt, kt);
5ff904cd 7958
c7e4ee3a
CB
7959 cg = ffesymbol_global (cs); /* The global COMMON info. */
7960 if ((cg == NULL)
7961 || (ffeglobal_type (cg) != FFEGLOBAL_typeCOMMON))
7962 ct = NULL_TREE;
7963 else
7964 ct = ffeglobal_hook (cg); /* The common area's tree. */
5ff904cd 7965
c7e4ee3a
CB
7966 if ((ct == NULL_TREE)
7967 || (st == NULL)
7968 || (type == error_mark_node))
7969 t = error_mark_node;
7970 else
7971 {
7972 ffetargetOffset offset;
7973 ffestorag cst;
5ff904cd 7974
c7e4ee3a
CB
7975 cst = ffestorag_parent (st);
7976 assert (cst == ffesymbol_storage (cs));
5ff904cd 7977
c7e4ee3a
CB
7978 offset = ffestorag_modulo (cst)
7979 + ffestorag_offset (st)
7980 - ffestorag_offset (cst);
5ff904cd 7981
c7e4ee3a 7982 ffecom_debug_kludge_ (ct, "COMMON", s, type, offset);
5ff904cd 7983
c7e4ee3a 7984 /* (t_type *) (((char *) &ct) + offset) */
5ff904cd
JL
7985
7986 t = convert (string_type_node, /* (char *) */
7987 ffecom_1 (ADDR_EXPR,
c7e4ee3a
CB
7988 build_pointer_type (TREE_TYPE (ct)),
7989 ct));
5ff904cd
JL
7990 t = ffecom_2 (PLUS_EXPR, TREE_TYPE (t),
7991 t,
7992 build_int_2 (offset, 0));
7993 t = convert (build_pointer_type (type),
7994 t);
d50108c7 7995 TREE_CONSTANT (t) = 1;
5ff904cd
JL
7996
7997 addr = TRUE;
5ff904cd 7998 }
c7e4ee3a
CB
7999 }
8000 break;
5ff904cd 8001
c7e4ee3a
CB
8002 case FFEINFO_whereIMMEDIATE:
8003 case FFEINFO_whereGLOBAL:
8004 case FFEINFO_whereFLEETING:
8005 case FFEINFO_whereFLEETING_CADDR:
8006 case FFEINFO_whereFLEETING_IADDR:
8007 case FFEINFO_whereINTRINSIC:
8008 case FFEINFO_whereCONSTANT_SUBOBJECT:
8009 default:
8010 assert ("ENTITY where unheard of" == NULL);
8011 /* Fall through. */
8012 case FFEINFO_whereANY:
8013 t = error_mark_node;
8014 break;
8015 }
8016 break;
5ff904cd 8017
c7e4ee3a
CB
8018 case FFEINFO_kindFUNCTION:
8019 switch (ffeinfo_where (ffesymbol_info (s)))
8020 {
8021 case FFEINFO_whereLOCAL: /* Me. */
8022 assert (!ffecom_transform_only_dummies_);
8023 t = current_function_decl;
5ff904cd
JL
8024 break;
8025
c7e4ee3a 8026 case FFEINFO_whereGLOBAL:
5ff904cd
JL
8027 assert (!ffecom_transform_only_dummies_);
8028
c7e4ee3a
CB
8029 if (((g = ffesymbol_global (s)) != NULL)
8030 && ((ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
8031 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
8032 && (ffeglobal_hook (g) != NULL_TREE)
8033 && ffe_is_globals ())
5ff904cd 8034 {
c7e4ee3a 8035 t = ffeglobal_hook (g);
5ff904cd
JL
8036 break;
8037 }
5ff904cd 8038
c7e4ee3a
CB
8039 if (ffesymbol_is_f2c (s)
8040 && (ffesymbol_where (s) != FFEINFO_whereCONSTANT))
8041 t = ffecom_tree_fun_type[bt][kt];
8042 else
8043 t = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
5ff904cd 8044
c7e4ee3a
CB
8045 t = build_decl (FUNCTION_DECL,
8046 ffecom_get_external_identifier_ (s),
8047 t);
8048 DECL_EXTERNAL (t) = 1;
8049 TREE_PUBLIC (t) = 1;
5ff904cd 8050
5ff904cd
JL
8051 t = start_decl (t, FALSE);
8052 finish_decl (t, NULL_TREE, FALSE);
8053
c7e4ee3a
CB
8054 if ((g != NULL)
8055 && ((ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
8056 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
8057 ffeglobal_set_hook (g, t);
8058
7189a4b0 8059 ffecom_save_tree_forever (t);
5ff904cd 8060
5ff904cd
JL
8061 break;
8062
8063 case FFEINFO_whereDUMMY:
c7e4ee3a 8064 assert (ffecom_transform_only_dummies_);
5ff904cd 8065
c7e4ee3a
CB
8066 if (ffesymbol_is_f2c (s)
8067 && (ffesymbol_where (s) != FFEINFO_whereCONSTANT))
8068 t = ffecom_tree_ptr_to_fun_type[bt][kt];
8069 else
8070 t = build_pointer_type
8071 (build_function_type (ffecom_tree_type[bt][kt], NULL_TREE));
8072
8073 t = build_decl (PARM_DECL,
8074 ffecom_get_identifier_ (ffesymbol_text (s)),
8075 t);
c7e4ee3a 8076 DECL_ARTIFICIAL (t) = 1;
c7e4ee3a
CB
8077 addr = TRUE;
8078 break;
8079
8080 case FFEINFO_whereCONSTANT: /* Statement function. */
8081 assert (!ffecom_transform_only_dummies_);
8082 t = ffecom_gen_sfuncdef_ (s, bt, kt);
8083 break;
8084
8085 case FFEINFO_whereINTRINSIC:
8086 assert (!ffecom_transform_only_dummies_);
8087 break; /* Let actual references generate their
8088 decls. */
8089
8090 default:
8091 assert ("FUNCTION where unheard of" == NULL);
8092 /* Fall through. */
8093 case FFEINFO_whereANY:
8094 t = error_mark_node;
8095 break;
8096 }
8097 break;
8098
8099 case FFEINFO_kindSUBROUTINE:
8100 switch (ffeinfo_where (ffesymbol_info (s)))
8101 {
8102 case FFEINFO_whereLOCAL: /* Me. */
8103 assert (!ffecom_transform_only_dummies_);
8104 t = current_function_decl;
8105 break;
5ff904cd 8106
c7e4ee3a
CB
8107 case FFEINFO_whereGLOBAL:
8108 assert (!ffecom_transform_only_dummies_);
5ff904cd 8109
c7e4ee3a
CB
8110 if (((g = ffesymbol_global (s)) != NULL)
8111 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
8112 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
8113 && (ffeglobal_hook (g) != NULL_TREE)
8114 && ffe_is_globals ())
8115 {
8116 t = ffeglobal_hook (g);
8117 break;
8118 }
5ff904cd 8119
c7e4ee3a
CB
8120 t = build_decl (FUNCTION_DECL,
8121 ffecom_get_external_identifier_ (s),
8122 ffecom_tree_subr_type);
8123 DECL_EXTERNAL (t) = 1;
8124 TREE_PUBLIC (t) = 1;
5ff904cd 8125
c7e4ee3a
CB
8126 t = start_decl (t, FALSE);
8127 finish_decl (t, NULL_TREE, FALSE);
5ff904cd 8128
c7e4ee3a
CB
8129 if ((g != NULL)
8130 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
8131 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
8132 ffeglobal_set_hook (g, t);
5ff904cd 8133
7189a4b0 8134 ffecom_save_tree_forever (t);
5ff904cd 8135
c7e4ee3a 8136 break;
5ff904cd 8137
c7e4ee3a
CB
8138 case FFEINFO_whereDUMMY:
8139 assert (ffecom_transform_only_dummies_);
5ff904cd 8140
c7e4ee3a
CB
8141 t = build_decl (PARM_DECL,
8142 ffecom_get_identifier_ (ffesymbol_text (s)),
8143 ffecom_tree_ptr_to_subr_type);
c7e4ee3a 8144 DECL_ARTIFICIAL (t) = 1;
c7e4ee3a
CB
8145 addr = TRUE;
8146 break;
5ff904cd 8147
c7e4ee3a
CB
8148 case FFEINFO_whereINTRINSIC:
8149 assert (!ffecom_transform_only_dummies_);
8150 break; /* Let actual references generate their
8151 decls. */
5ff904cd 8152
c7e4ee3a
CB
8153 default:
8154 assert ("SUBROUTINE where unheard of" == NULL);
8155 /* Fall through. */
8156 case FFEINFO_whereANY:
8157 t = error_mark_node;
8158 break;
8159 }
8160 break;
5ff904cd 8161
c7e4ee3a
CB
8162 case FFEINFO_kindPROGRAM:
8163 switch (ffeinfo_where (ffesymbol_info (s)))
8164 {
8165 case FFEINFO_whereLOCAL: /* Me. */
8166 assert (!ffecom_transform_only_dummies_);
8167 t = current_function_decl;
8168 break;
5ff904cd 8169
c7e4ee3a
CB
8170 case FFEINFO_whereCOMMON:
8171 case FFEINFO_whereDUMMY:
8172 case FFEINFO_whereGLOBAL:
8173 case FFEINFO_whereRESULT:
8174 case FFEINFO_whereFLEETING:
8175 case FFEINFO_whereFLEETING_CADDR:
8176 case FFEINFO_whereFLEETING_IADDR:
8177 case FFEINFO_whereIMMEDIATE:
8178 case FFEINFO_whereINTRINSIC:
8179 case FFEINFO_whereCONSTANT:
8180 case FFEINFO_whereCONSTANT_SUBOBJECT:
8181 default:
8182 assert ("PROGRAM where unheard of" == NULL);
8183 /* Fall through. */
8184 case FFEINFO_whereANY:
8185 t = error_mark_node;
8186 break;
8187 }
8188 break;
5ff904cd 8189
c7e4ee3a
CB
8190 case FFEINFO_kindBLOCKDATA:
8191 switch (ffeinfo_where (ffesymbol_info (s)))
8192 {
8193 case FFEINFO_whereLOCAL: /* Me. */
8194 assert (!ffecom_transform_only_dummies_);
8195 t = current_function_decl;
8196 break;
5ff904cd 8197
c7e4ee3a
CB
8198 case FFEINFO_whereGLOBAL:
8199 assert (!ffecom_transform_only_dummies_);
5ff904cd 8200
c7e4ee3a
CB
8201 t = build_decl (FUNCTION_DECL,
8202 ffecom_get_external_identifier_ (s),
8203 ffecom_tree_blockdata_type);
8204 DECL_EXTERNAL (t) = 1;
8205 TREE_PUBLIC (t) = 1;
5ff904cd 8206
c7e4ee3a
CB
8207 t = start_decl (t, FALSE);
8208 finish_decl (t, NULL_TREE, FALSE);
5ff904cd 8209
7189a4b0 8210 ffecom_save_tree_forever (t);
5ff904cd 8211
c7e4ee3a 8212 break;
5ff904cd 8213
c7e4ee3a
CB
8214 case FFEINFO_whereCOMMON:
8215 case FFEINFO_whereDUMMY:
8216 case FFEINFO_whereRESULT:
8217 case FFEINFO_whereFLEETING:
8218 case FFEINFO_whereFLEETING_CADDR:
8219 case FFEINFO_whereFLEETING_IADDR:
8220 case FFEINFO_whereIMMEDIATE:
8221 case FFEINFO_whereINTRINSIC:
8222 case FFEINFO_whereCONSTANT:
8223 case FFEINFO_whereCONSTANT_SUBOBJECT:
8224 default:
8225 assert ("BLOCKDATA where unheard of" == NULL);
8226 /* Fall through. */
8227 case FFEINFO_whereANY:
8228 t = error_mark_node;
8229 break;
8230 }
8231 break;
5ff904cd 8232
c7e4ee3a
CB
8233 case FFEINFO_kindCOMMON:
8234 switch (ffeinfo_where (ffesymbol_info (s)))
8235 {
8236 case FFEINFO_whereLOCAL:
8237 assert (!ffecom_transform_only_dummies_);
8238 ffecom_transform_common_ (s);
8239 break;
8240
8241 case FFEINFO_whereNONE:
8242 case FFEINFO_whereCOMMON:
8243 case FFEINFO_whereDUMMY:
8244 case FFEINFO_whereGLOBAL:
8245 case FFEINFO_whereRESULT:
8246 case FFEINFO_whereFLEETING:
8247 case FFEINFO_whereFLEETING_CADDR:
8248 case FFEINFO_whereFLEETING_IADDR:
8249 case FFEINFO_whereIMMEDIATE:
8250 case FFEINFO_whereINTRINSIC:
8251 case FFEINFO_whereCONSTANT:
8252 case FFEINFO_whereCONSTANT_SUBOBJECT:
8253 default:
8254 assert ("COMMON where unheard of" == NULL);
8255 /* Fall through. */
8256 case FFEINFO_whereANY:
8257 t = error_mark_node;
8258 break;
8259 }
8260 break;
5ff904cd 8261
c7e4ee3a
CB
8262 case FFEINFO_kindCONSTRUCT:
8263 switch (ffeinfo_where (ffesymbol_info (s)))
8264 {
8265 case FFEINFO_whereLOCAL:
8266 assert (!ffecom_transform_only_dummies_);
8267 break;
5ff904cd 8268
c7e4ee3a
CB
8269 case FFEINFO_whereNONE:
8270 case FFEINFO_whereCOMMON:
8271 case FFEINFO_whereDUMMY:
8272 case FFEINFO_whereGLOBAL:
8273 case FFEINFO_whereRESULT:
8274 case FFEINFO_whereFLEETING:
8275 case FFEINFO_whereFLEETING_CADDR:
8276 case FFEINFO_whereFLEETING_IADDR:
8277 case FFEINFO_whereIMMEDIATE:
8278 case FFEINFO_whereINTRINSIC:
8279 case FFEINFO_whereCONSTANT:
8280 case FFEINFO_whereCONSTANT_SUBOBJECT:
8281 default:
8282 assert ("CONSTRUCT where unheard of" == NULL);
8283 /* Fall through. */
8284 case FFEINFO_whereANY:
8285 t = error_mark_node;
8286 break;
8287 }
8288 break;
5ff904cd 8289
c7e4ee3a
CB
8290 case FFEINFO_kindNAMELIST:
8291 switch (ffeinfo_where (ffesymbol_info (s)))
8292 {
8293 case FFEINFO_whereLOCAL:
8294 assert (!ffecom_transform_only_dummies_);
8295 t = ffecom_transform_namelist_ (s);
8296 break;
5ff904cd 8297
c7e4ee3a
CB
8298 case FFEINFO_whereNONE:
8299 case FFEINFO_whereCOMMON:
8300 case FFEINFO_whereDUMMY:
8301 case FFEINFO_whereGLOBAL:
8302 case FFEINFO_whereRESULT:
8303 case FFEINFO_whereFLEETING:
8304 case FFEINFO_whereFLEETING_CADDR:
8305 case FFEINFO_whereFLEETING_IADDR:
8306 case FFEINFO_whereIMMEDIATE:
8307 case FFEINFO_whereINTRINSIC:
8308 case FFEINFO_whereCONSTANT:
8309 case FFEINFO_whereCONSTANT_SUBOBJECT:
8310 default:
8311 assert ("NAMELIST where unheard of" == NULL);
8312 /* Fall through. */
8313 case FFEINFO_whereANY:
8314 t = error_mark_node;
8315 break;
8316 }
8317 break;
5ff904cd 8318
c7e4ee3a
CB
8319 default:
8320 assert ("kind unheard of" == NULL);
8321 /* Fall through. */
8322 case FFEINFO_kindANY:
8323 t = error_mark_node;
8324 break;
8325 }
5ff904cd 8326
c7e4ee3a
CB
8327 ffesymbol_hook (s).decl_tree = t;
8328 ffesymbol_hook (s).length_tree = tlen;
8329 ffesymbol_hook (s).addr = addr;
5ff904cd 8330
c7e4ee3a
CB
8331 lineno = old_lineno;
8332 input_filename = old_input_filename;
5ff904cd 8333
c7e4ee3a
CB
8334 return s;
8335}
5ff904cd 8336
c7e4ee3a 8337/* Transform into ASSIGNable symbol.
5ff904cd 8338
c7e4ee3a
CB
8339 Symbol has already been transformed, but for whatever reason, the
8340 resulting decl_tree has been deemed not usable for an ASSIGN target.
8341 (E.g. it isn't wide enough to hold a pointer.) So, here we invent
8342 another local symbol of type void * and stuff that in the assign_tree
8343 argument. The F77/F90 standards allow this implementation. */
5ff904cd 8344
c7e4ee3a
CB
8345static ffesymbol
8346ffecom_sym_transform_assign_ (ffesymbol s)
8347{
8348 tree t; /* Transformed thingy. */
c7e4ee3a 8349 int old_lineno = lineno;
3b304f5b 8350 const char *old_input_filename = input_filename;
5ff904cd 8351
c7e4ee3a
CB
8352 if (ffesymbol_sfdummyparent (s) == NULL)
8353 {
8354 input_filename = ffesymbol_where_filename (s);
8355 lineno = ffesymbol_where_filelinenum (s);
8356 }
8357 else
8358 {
8359 ffesymbol sf = ffesymbol_sfdummyparent (s);
5ff904cd 8360
c7e4ee3a
CB
8361 input_filename = ffesymbol_where_filename (sf);
8362 lineno = ffesymbol_where_filelinenum (sf);
8363 }
5ff904cd 8364
c7e4ee3a 8365 assert (!ffecom_transform_only_dummies_);
5ff904cd 8366
c7e4ee3a
CB
8367 t = build_decl (VAR_DECL,
8368 ffecom_get_invented_identifier ("__g77_ASSIGN_%s",
14657de8 8369 ffesymbol_text (s)),
c7e4ee3a 8370 TREE_TYPE (null_pointer_node));
5ff904cd 8371
c7e4ee3a
CB
8372 switch (ffesymbol_where (s))
8373 {
8374 case FFEINFO_whereLOCAL:
8375 /* Unlike for regular vars, SAVE status is easy to determine for
8376 ASSIGNed vars, since there's no initialization, there's no
8377 effective storage association (so "SAVE J" does not apply to
8378 K even given "EQUIVALENCE (J,K)"), there's no size issue
8379 to worry about, etc. */
8380 if ((ffesymbol_is_save (s) || ffe_is_saveall ())
8381 && (ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
8382 && (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA))
8383 TREE_STATIC (t) = 1; /* SAVEd in proc, make static. */
8384 else
8385 TREE_STATIC (t) = 0; /* No need to make static. */
8386 break;
5ff904cd 8387
c7e4ee3a
CB
8388 case FFEINFO_whereCOMMON:
8389 TREE_STATIC (t) = 1; /* Assume COMMONs always SAVEd. */
8390 break;
5ff904cd 8391
c7e4ee3a
CB
8392 case FFEINFO_whereDUMMY:
8393 /* Note that twinning a DUMMY means the caller won't see
8394 the ASSIGNed value. But both F77 and F90 allow implementations
8395 to do this, i.e. disallow Fortran code that would try and
8396 take advantage of actually putting a label into a variable
8397 via a dummy argument (or any other storage association, for
8398 that matter). */
8399 TREE_STATIC (t) = 0;
8400 break;
5ff904cd 8401
c7e4ee3a
CB
8402 default:
8403 TREE_STATIC (t) = 0;
8404 break;
8405 }
5ff904cd 8406
c7e4ee3a
CB
8407 t = start_decl (t, FALSE);
8408 finish_decl (t, NULL_TREE, FALSE);
5ff904cd 8409
c7e4ee3a 8410 ffesymbol_hook (s).assign_tree = t;
5ff904cd 8411
c7e4ee3a
CB
8412 lineno = old_lineno;
8413 input_filename = old_input_filename;
5ff904cd 8414
c7e4ee3a
CB
8415 return s;
8416}
5ff904cd 8417
c7e4ee3a 8418/* Implement COMMON area in back end.
5ff904cd 8419
c7e4ee3a
CB
8420 Because COMMON-based variables can be referenced in the dimension
8421 expressions of dummy (adjustable) arrays, and because dummies
8422 (in the gcc back end) need to be put in the outer binding level
8423 of a function (which has two binding levels, the outer holding
8424 the dummies and the inner holding the other vars), special care
8425 must be taken to handle COMMON areas.
5ff904cd 8426
c7e4ee3a
CB
8427 The current strategy is basically to always tell the back end about
8428 the COMMON area as a top-level external reference to just a block
8429 of storage of the master type of that area (e.g. integer, real,
8430 character, whatever -- not a structure). As a distinct action,
8431 if initial values are provided, tell the back end about the area
8432 as a top-level non-external (initialized) area and remember not to
8433 allow further initialization or expansion of the area. Meanwhile,
8434 if no initialization happens at all, tell the back end about
8435 the largest size we've seen declared so the space does get reserved.
8436 (This function doesn't handle all that stuff, but it does some
8437 of the important things.)
5ff904cd 8438
c7e4ee3a
CB
8439 Meanwhile, for COMMON variables themselves, just keep creating
8440 references like *((float *) (&common_area + offset)) each time
8441 we reference the variable. In other words, don't make a VAR_DECL
8442 or any kind of component reference (like we used to do before 0.4),
8443 though we might do that as well just for debugging purposes (and
8444 stuff the rtl with the appropriate offset expression). */
5ff904cd 8445
c7e4ee3a
CB
8446static void
8447ffecom_transform_common_ (ffesymbol s)
8448{
8449 ffestorag st = ffesymbol_storage (s);
8450 ffeglobal g = ffesymbol_global (s);
8451 tree cbt;
8452 tree cbtype;
8453 tree init;
8454 tree high;
8455 bool is_init = ffestorag_is_init (st);
5ff904cd 8456
c7e4ee3a 8457 assert (st != NULL);
5ff904cd 8458
c7e4ee3a
CB
8459 if ((g == NULL)
8460 || (ffeglobal_type (g) != FFEGLOBAL_typeCOMMON))
8461 return;
5ff904cd 8462
c7e4ee3a 8463 /* First update the size of the area in global terms. */
5ff904cd 8464
c7e4ee3a 8465 ffeglobal_size_common (s, ffestorag_size (st));
5ff904cd 8466
c7e4ee3a
CB
8467 if (!ffeglobal_common_init (g))
8468 is_init = FALSE; /* No explicit init, don't let erroneous joins init. */
5ff904cd 8469
c7e4ee3a 8470 cbt = ffeglobal_hook (g);
5ff904cd 8471
c7e4ee3a
CB
8472 /* If we already have declared this common block for a previous program
8473 unit, and either we already initialized it or we don't have new
8474 initialization for it, just return what we have without changing it. */
5ff904cd 8475
c7e4ee3a
CB
8476 if ((cbt != NULL_TREE)
8477 && (!is_init
8478 || !DECL_EXTERNAL (cbt)))
b7a80862
AV
8479 {
8480 if (st->hook == NULL) ffestorag_set_hook (st, cbt);
8481 return;
8482 }
5ff904cd 8483
c7e4ee3a 8484 /* Process inits. */
5ff904cd 8485
c7e4ee3a
CB
8486 if (is_init)
8487 {
8488 if (ffestorag_init (st) != NULL)
5ff904cd 8489 {
c7e4ee3a 8490 ffebld sexp;
5ff904cd 8491
c7e4ee3a
CB
8492 /* Set the padding for the expression, so ffecom_expr
8493 knows to insert that many zeros. */
8494 switch (ffebld_op (sexp = ffestorag_init (st)))
5ff904cd 8495 {
c7e4ee3a
CB
8496 case FFEBLD_opCONTER:
8497 ffebld_conter_set_pad (sexp, ffestorag_modulo (st));
5ff904cd 8498 break;
5ff904cd 8499
c7e4ee3a
CB
8500 case FFEBLD_opARRTER:
8501 ffebld_arrter_set_pad (sexp, ffestorag_modulo (st));
8502 break;
5ff904cd 8503
c7e4ee3a
CB
8504 case FFEBLD_opACCTER:
8505 ffebld_accter_set_pad (sexp, ffestorag_modulo (st));
8506 break;
5ff904cd 8507
c7e4ee3a
CB
8508 default:
8509 assert ("bad op for cmn init (pad)" == NULL);
8510 break;
8511 }
5ff904cd 8512
c7e4ee3a
CB
8513 init = ffecom_expr (sexp);
8514 if (init == error_mark_node)
8515 { /* Hopefully the back end complained! */
8516 init = NULL_TREE;
8517 if (cbt != NULL_TREE)
8518 return;
8519 }
8520 }
8521 else
8522 init = error_mark_node;
8523 }
8524 else
8525 init = NULL_TREE;
5ff904cd 8526
c7e4ee3a 8527 /* cbtype must be permanently allocated! */
5ff904cd 8528
c7e4ee3a
CB
8529 /* Allocate the MAX of the areas so far, seen filewide. */
8530 high = build_int_2 ((ffeglobal_common_size (g)
8531 + ffeglobal_common_pad (g)) - 1, 0);
8532 TREE_TYPE (high) = ffecom_integer_type_node;
5ff904cd 8533
c7e4ee3a
CB
8534 if (init)
8535 cbtype = build_array_type (char_type_node,
8536 build_range_type (integer_type_node,
8537 integer_zero_node,
8538 high));
8539 else
8540 cbtype = build_array_type (char_type_node, NULL_TREE);
5ff904cd 8541
c7e4ee3a
CB
8542 if (cbt == NULL_TREE)
8543 {
8544 cbt
8545 = build_decl (VAR_DECL,
8546 ffecom_get_external_identifier_ (s),
8547 cbtype);
8548 TREE_STATIC (cbt) = 1;
8549 TREE_PUBLIC (cbt) = 1;
8550 }
8551 else
8552 {
8553 assert (is_init);
8554 TREE_TYPE (cbt) = cbtype;
8555 }
8556 DECL_EXTERNAL (cbt) = init ? 0 : 1;
8557 DECL_INITIAL (cbt) = init ? error_mark_node : NULL_TREE;
5ff904cd 8558
c7e4ee3a
CB
8559 cbt = start_decl (cbt, TRUE);
8560 if (ffeglobal_hook (g) != NULL)
8561 assert (cbt == ffeglobal_hook (g));
5ff904cd 8562
c7e4ee3a 8563 assert (!init || !DECL_EXTERNAL (cbt));
5ff904cd 8564
c7e4ee3a
CB
8565 /* Make sure that any type can live in COMMON and be referenced
8566 without getting a bus error. We could pick the most restrictive
8567 alignment of all entities actually placed in the COMMON, but
8568 this seems easy enough. */
5ff904cd 8569
c7e4ee3a 8570 DECL_ALIGN (cbt) = BIGGEST_ALIGNMENT;
11cf4d18 8571 DECL_USER_ALIGN (cbt) = 0;
5ff904cd 8572
c7e4ee3a
CB
8573 if (is_init && (ffestorag_init (st) == NULL))
8574 init = ffecom_init_zero_ (cbt);
5ff904cd 8575
c7e4ee3a 8576 finish_decl (cbt, init, TRUE);
5ff904cd 8577
c7e4ee3a
CB
8578 if (is_init)
8579 ffestorag_set_init (st, ffebld_new_any ());
5ff904cd 8580
c7e4ee3a
CB
8581 if (init)
8582 {
06ceef4e
RK
8583 assert (DECL_SIZE_UNIT (cbt) != NULL_TREE);
8584 assert (TREE_CODE (DECL_SIZE_UNIT (cbt)) == INTEGER_CST);
05bccae2
RK
8585 assert (0 == compare_tree_int (DECL_SIZE_UNIT (cbt),
8586 (ffeglobal_common_size (g)
8587 + ffeglobal_common_pad (g))));
c7e4ee3a 8588 }
5ff904cd 8589
c7e4ee3a 8590 ffeglobal_set_hook (g, cbt);
5ff904cd 8591
c7e4ee3a 8592 ffestorag_set_hook (st, cbt);
5ff904cd 8593
7189a4b0 8594 ffecom_save_tree_forever (cbt);
c7e4ee3a 8595}
5ff904cd 8596
c7e4ee3a 8597/* Make master area for local EQUIVALENCE. */
5ff904cd 8598
c7e4ee3a
CB
8599static void
8600ffecom_transform_equiv_ (ffestorag eqst)
8601{
8602 tree eqt;
8603 tree eqtype;
8604 tree init;
8605 tree high;
8606 bool is_init = ffestorag_is_init (eqst);
5ff904cd 8607
c7e4ee3a 8608 assert (eqst != NULL);
5ff904cd 8609
c7e4ee3a 8610 eqt = ffestorag_hook (eqst);
5ff904cd 8611
c7e4ee3a
CB
8612 if (eqt != NULL_TREE)
8613 return;
5ff904cd 8614
c7e4ee3a
CB
8615 /* Process inits. */
8616
8617 if (is_init)
8618 {
8619 if (ffestorag_init (eqst) != NULL)
5ff904cd 8620 {
c7e4ee3a 8621 ffebld sexp;
5ff904cd 8622
c7e4ee3a
CB
8623 /* Set the padding for the expression, so ffecom_expr
8624 knows to insert that many zeros. */
8625 switch (ffebld_op (sexp = ffestorag_init (eqst)))
8626 {
8627 case FFEBLD_opCONTER:
8628 ffebld_conter_set_pad (sexp, ffestorag_modulo (eqst));
8629 break;
5ff904cd 8630
c7e4ee3a
CB
8631 case FFEBLD_opARRTER:
8632 ffebld_arrter_set_pad (sexp, ffestorag_modulo (eqst));
8633 break;
5ff904cd 8634
c7e4ee3a
CB
8635 case FFEBLD_opACCTER:
8636 ffebld_accter_set_pad (sexp, ffestorag_modulo (eqst));
8637 break;
5ff904cd 8638
c7e4ee3a
CB
8639 default:
8640 assert ("bad op for eqv init (pad)" == NULL);
8641 break;
8642 }
5ff904cd 8643
c7e4ee3a
CB
8644 init = ffecom_expr (sexp);
8645 if (init == error_mark_node)
8646 init = NULL_TREE; /* Hopefully the back end complained! */
8647 }
8648 else
8649 init = error_mark_node;
8650 }
8651 else if (ffe_is_init_local_zero ())
8652 init = error_mark_node;
8653 else
8654 init = NULL_TREE;
5ff904cd 8655
c7e4ee3a
CB
8656 ffecom_member_namelisted_ = FALSE;
8657 ffestorag_drive (ffestorag_list_equivs (eqst),
8658 &ffecom_member_phase1_,
8659 eqst);
5ff904cd 8660
c7e4ee3a
CB
8661 high = build_int_2 ((ffestorag_size (eqst)
8662 + ffestorag_modulo (eqst)) - 1, 0);
8663 TREE_TYPE (high) = ffecom_integer_type_node;
5ff904cd 8664
c7e4ee3a
CB
8665 eqtype = build_array_type (char_type_node,
8666 build_range_type (ffecom_integer_type_node,
8667 ffecom_integer_zero_node,
8668 high));
8669
8670 eqt = build_decl (VAR_DECL,
8671 ffecom_get_invented_identifier ("__g77_equiv_%s",
8672 ffesymbol_text
14657de8 8673 (ffestorag_symbol (eqst))),
c7e4ee3a
CB
8674 eqtype);
8675 DECL_EXTERNAL (eqt) = 0;
8676 if (is_init
8677 || ffecom_member_namelisted_
8678#ifdef FFECOM_sizeMAXSTACKITEM
8679 || (ffestorag_size (eqst) > FFECOM_sizeMAXSTACKITEM)
8680#endif
8681 || ((ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
8682 && (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA)
8683 && (ffestorag_is_save (eqst) || ffe_is_saveall ())))
8684 TREE_STATIC (eqt) = 1;
8685 else
8686 TREE_STATIC (eqt) = 0;
8687 TREE_PUBLIC (eqt) = 0;
a8e2bb76 8688 TREE_ADDRESSABLE (eqt) = 1; /* Ensure non-register allocation */
c7e4ee3a
CB
8689 DECL_CONTEXT (eqt) = current_function_decl;
8690 if (init)
8691 DECL_INITIAL (eqt) = error_mark_node;
8692 else
8693 DECL_INITIAL (eqt) = NULL_TREE;
5ff904cd 8694
c7e4ee3a 8695 eqt = start_decl (eqt, FALSE);
5ff904cd 8696
c7e4ee3a
CB
8697 /* Make sure that any type can live in EQUIVALENCE and be referenced
8698 without getting a bus error. We could pick the most restrictive
8699 alignment of all entities actually placed in the EQUIVALENCE, but
8700 this seems easy enough. */
5ff904cd 8701
c7e4ee3a 8702 DECL_ALIGN (eqt) = BIGGEST_ALIGNMENT;
11cf4d18 8703 DECL_USER_ALIGN (eqt) = 0;
5ff904cd 8704
c7e4ee3a
CB
8705 if ((!is_init && ffe_is_init_local_zero ())
8706 || (is_init && (ffestorag_init (eqst) == NULL)))
8707 init = ffecom_init_zero_ (eqt);
5ff904cd 8708
c7e4ee3a 8709 finish_decl (eqt, init, FALSE);
5ff904cd 8710
c7e4ee3a
CB
8711 if (is_init)
8712 ffestorag_set_init (eqst, ffebld_new_any ());
5ff904cd 8713
c7e4ee3a 8714 {
06ceef4e 8715 assert (TREE_CODE (DECL_SIZE_UNIT (eqt)) == INTEGER_CST);
05bccae2
RK
8716 assert (0 == compare_tree_int (DECL_SIZE_UNIT (eqt),
8717 (ffestorag_size (eqst)
8718 + ffestorag_modulo (eqst))));
c7e4ee3a 8719 }
5ff904cd 8720
c7e4ee3a 8721 ffestorag_set_hook (eqst, eqt);
5ff904cd 8722
c7e4ee3a
CB
8723 ffestorag_drive (ffestorag_list_equivs (eqst),
8724 &ffecom_member_phase2_,
8725 eqst);
5ff904cd
JL
8726}
8727
c7e4ee3a 8728/* Implement NAMELIST in back end. See f2c/format.c for more info. */
5ff904cd 8729
c7e4ee3a
CB
8730static tree
8731ffecom_transform_namelist_ (ffesymbol s)
5ff904cd 8732{
c7e4ee3a
CB
8733 tree nmlt;
8734 tree nmltype = ffecom_type_namelist_ ();
8735 tree nmlinits;
8736 tree nameinit;
8737 tree varsinit;
8738 tree nvarsinit;
8739 tree field;
8740 tree high;
c7e4ee3a
CB
8741 int i;
8742 static int mynumber = 0;
5ff904cd 8743
c7e4ee3a
CB
8744 nmlt = build_decl (VAR_DECL,
8745 ffecom_get_invented_identifier ("__g77_namelist_%d",
14657de8 8746 mynumber++),
c7e4ee3a
CB
8747 nmltype);
8748 TREE_STATIC (nmlt) = 1;
8749 DECL_INITIAL (nmlt) = error_mark_node;
5ff904cd 8750
c7e4ee3a 8751 nmlt = start_decl (nmlt, FALSE);
5ff904cd 8752
c7e4ee3a 8753 /* Process inits. */
5ff904cd 8754
c7e4ee3a 8755 i = strlen (ffesymbol_text (s));
5ff904cd 8756
c7e4ee3a
CB
8757 high = build_int_2 (i, 0);
8758 TREE_TYPE (high) = ffecom_f2c_ftnlen_type_node;
8759
8760 nameinit = ffecom_build_f2c_string_ (i + 1,
8761 ffesymbol_text (s));
8762 TREE_TYPE (nameinit)
8763 = build_type_variant
8764 (build_array_type
8765 (char_type_node,
8766 build_range_type (ffecom_f2c_ftnlen_type_node,
8767 ffecom_f2c_ftnlen_one_node,
8768 high)),
8769 1, 0);
8770 TREE_CONSTANT (nameinit) = 1;
8771 TREE_STATIC (nameinit) = 1;
8772 nameinit = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (nameinit)),
8773 nameinit);
8774
8775 varsinit = ffecom_vardesc_array_ (s);
8776 varsinit = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (varsinit)),
8777 varsinit);
8778 TREE_CONSTANT (varsinit) = 1;
8779 TREE_STATIC (varsinit) = 1;
8780
8781 {
8782 ffebld b;
8783
8784 for (i = 0, b = ffesymbol_namelist (s); b != NULL; b = ffebld_trail (b))
8785 ++i;
8786 }
8787 nvarsinit = build_int_2 (i, 0);
8788 TREE_TYPE (nvarsinit) = integer_type_node;
8789 TREE_CONSTANT (nvarsinit) = 1;
8790 TREE_STATIC (nvarsinit) = 1;
8791
8792 nmlinits = build_tree_list ((field = TYPE_FIELDS (nmltype)), nameinit);
8793 TREE_CHAIN (nmlinits) = build_tree_list ((field = TREE_CHAIN (field)),
8794 varsinit);
8795 TREE_CHAIN (TREE_CHAIN (nmlinits))
8796 = build_tree_list ((field = TREE_CHAIN (field)), nvarsinit);
8797
8798 nmlinits = build (CONSTRUCTOR, nmltype, NULL_TREE, nmlinits);
8799 TREE_CONSTANT (nmlinits) = 1;
8800 TREE_STATIC (nmlinits) = 1;
8801
8802 finish_decl (nmlt, nmlinits, FALSE);
8803
8804 nmlt = ffecom_1 (ADDR_EXPR, build_pointer_type (nmltype), nmlt);
8805
c7e4ee3a
CB
8806 return nmlt;
8807}
8808
c7e4ee3a
CB
8809/* A subroutine of ffecom_tree_canonize_ref_. The incoming tree is
8810 analyzed on the assumption it is calculating a pointer to be
8811 indirected through. It must return the proper decl and offset,
8812 taking into account different units of measurements for offsets. */
8813
c7e4ee3a
CB
8814static void
8815ffecom_tree_canonize_ptr_ (tree *decl, tree *offset,
8816 tree t)
8817{
8818 switch (TREE_CODE (t))
8819 {
8820 case NOP_EXPR:
8821 case CONVERT_EXPR:
8822 case NON_LVALUE_EXPR:
8823 ffecom_tree_canonize_ptr_ (decl, offset, TREE_OPERAND (t, 0));
5ff904cd
JL
8824 break;
8825
c7e4ee3a
CB
8826 case PLUS_EXPR:
8827 ffecom_tree_canonize_ptr_ (decl, offset, TREE_OPERAND (t, 0));
8828 if ((*decl == NULL_TREE)
8829 || (*decl == error_mark_node))
8830 break;
8831
8832 if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST)
8833 {
8834 /* An offset into COMMON. */
fed3cef0
RK
8835 *offset = fold (build (PLUS_EXPR, TREE_TYPE (*offset),
8836 *offset, TREE_OPERAND (t, 1)));
c7e4ee3a
CB
8837 /* Convert offset (presumably in bytes) into canonical units
8838 (presumably bits). */
76fa6b3b
ZW
8839 *offset = size_binop (MULT_EXPR,
8840 convert (bitsizetype, *offset),
8841 TYPE_SIZE (TREE_TYPE (TREE_TYPE (t))));
c7e4ee3a
CB
8842 break;
8843 }
8844 /* Not a COMMON reference, so an unrecognized pattern. */
8845 *decl = error_mark_node;
5ff904cd
JL
8846 break;
8847
c7e4ee3a
CB
8848 case PARM_DECL:
8849 *decl = t;
770ae6cc 8850 *offset = bitsize_zero_node;
5ff904cd
JL
8851 break;
8852
c7e4ee3a
CB
8853 case ADDR_EXPR:
8854 if (TREE_CODE (TREE_OPERAND (t, 0)) == VAR_DECL)
8855 {
8856 /* A reference to COMMON. */
8857 *decl = TREE_OPERAND (t, 0);
770ae6cc 8858 *offset = bitsize_zero_node;
c7e4ee3a
CB
8859 break;
8860 }
8861 /* Fall through. */
5ff904cd 8862 default:
c7e4ee3a
CB
8863 /* Not a COMMON reference, so an unrecognized pattern. */
8864 *decl = error_mark_node;
5ff904cd
JL
8865 break;
8866 }
c7e4ee3a 8867}
5ff904cd 8868
c7e4ee3a
CB
8869/* Given a tree that is possibly intended for use as an lvalue, return
8870 information representing a canonical view of that tree as a decl, an
8871 offset into that decl, and a size for the lvalue.
5ff904cd 8872
c7e4ee3a
CB
8873 If there's no applicable decl, NULL_TREE is returned for the decl,
8874 and the other fields are left undefined.
5ff904cd 8875
c7e4ee3a
CB
8876 If the tree doesn't fit the recognizable forms, an ERROR_MARK node
8877 is returned for the decl, and the other fields are left undefined.
5ff904cd 8878
c7e4ee3a
CB
8879 Otherwise, the decl returned currently is either a VAR_DECL or a
8880 PARM_DECL.
5ff904cd 8881
c7e4ee3a
CB
8882 The offset returned is always valid, but of course not necessarily
8883 a constant, and not necessarily converted into the appropriate
8884 type, leaving that up to the caller (so as to avoid that overhead
8885 if the decls being looked at are different anyway).
5ff904cd 8886
c7e4ee3a
CB
8887 If the size cannot be determined (e.g. an adjustable array),
8888 an ERROR_MARK node is returned for the size. Otherwise, the
8889 size returned is valid, not necessarily a constant, and not
8890 necessarily converted into the appropriate type as with the
8891 offset.
5ff904cd 8892
c7e4ee3a
CB
8893 Note that the offset and size expressions are expressed in the
8894 base storage units (usually bits) rather than in the units of
8895 the type of the decl, because two decls with different types
8896 might overlap but with apparently non-overlapping array offsets,
8897 whereas converting the array offsets to consistant offsets will
8898 reveal the overlap. */
5ff904cd 8899
5ff904cd 8900static void
c7e4ee3a
CB
8901ffecom_tree_canonize_ref_ (tree *decl, tree *offset,
8902 tree *size, tree t)
5ff904cd 8903{
c7e4ee3a
CB
8904 /* The default path is to report a nonexistant decl. */
8905 *decl = NULL_TREE;
5ff904cd 8906
c7e4ee3a 8907 if (t == NULL_TREE)
5ff904cd
JL
8908 return;
8909
c7e4ee3a
CB
8910 switch (TREE_CODE (t))
8911 {
8912 case ERROR_MARK:
8913 case IDENTIFIER_NODE:
8914 case INTEGER_CST:
8915 case REAL_CST:
8916 case COMPLEX_CST:
8917 case STRING_CST:
8918 case CONST_DECL:
8919 case PLUS_EXPR:
8920 case MINUS_EXPR:
8921 case MULT_EXPR:
8922 case TRUNC_DIV_EXPR:
8923 case CEIL_DIV_EXPR:
8924 case FLOOR_DIV_EXPR:
8925 case ROUND_DIV_EXPR:
8926 case TRUNC_MOD_EXPR:
8927 case CEIL_MOD_EXPR:
8928 case FLOOR_MOD_EXPR:
8929 case ROUND_MOD_EXPR:
8930 case RDIV_EXPR:
8931 case EXACT_DIV_EXPR:
8932 case FIX_TRUNC_EXPR:
8933 case FIX_CEIL_EXPR:
8934 case FIX_FLOOR_EXPR:
8935 case FIX_ROUND_EXPR:
8936 case FLOAT_EXPR:
c7e4ee3a
CB
8937 case NEGATE_EXPR:
8938 case MIN_EXPR:
8939 case MAX_EXPR:
8940 case ABS_EXPR:
8941 case FFS_EXPR:
8942 case LSHIFT_EXPR:
8943 case RSHIFT_EXPR:
8944 case LROTATE_EXPR:
8945 case RROTATE_EXPR:
8946 case BIT_IOR_EXPR:
8947 case BIT_XOR_EXPR:
8948 case BIT_AND_EXPR:
8949 case BIT_ANDTC_EXPR:
8950 case BIT_NOT_EXPR:
8951 case TRUTH_ANDIF_EXPR:
8952 case TRUTH_ORIF_EXPR:
8953 case TRUTH_AND_EXPR:
8954 case TRUTH_OR_EXPR:
8955 case TRUTH_XOR_EXPR:
8956 case TRUTH_NOT_EXPR:
8957 case LT_EXPR:
8958 case LE_EXPR:
8959 case GT_EXPR:
8960 case GE_EXPR:
8961 case EQ_EXPR:
8962 case NE_EXPR:
8963 case COMPLEX_EXPR:
8964 case CONJ_EXPR:
8965 case REALPART_EXPR:
8966 case IMAGPART_EXPR:
8967 case LABEL_EXPR:
8968 case COMPONENT_REF:
8969 case COMPOUND_EXPR:
8970 case ADDR_EXPR:
8971 return;
5ff904cd 8972
c7e4ee3a
CB
8973 case VAR_DECL:
8974 case PARM_DECL:
8975 *decl = t;
770ae6cc 8976 *offset = bitsize_zero_node;
c7e4ee3a
CB
8977 *size = TYPE_SIZE (TREE_TYPE (t));
8978 return;
5ff904cd 8979
c7e4ee3a
CB
8980 case ARRAY_REF:
8981 {
8982 tree array = TREE_OPERAND (t, 0);
8983 tree element = TREE_OPERAND (t, 1);
8984 tree init_offset;
8985
8986 if ((array == NULL_TREE)
8987 || (element == NULL_TREE))
8988 {
8989 *decl = error_mark_node;
8990 return;
8991 }
8992
8993 ffecom_tree_canonize_ref_ (decl, &init_offset, size,
8994 array);
8995 if ((*decl == NULL_TREE)
8996 || (*decl == error_mark_node))
8997 return;
8998
76fa6b3b
ZW
8999 /* Calculate ((element - base) * NBBY) + init_offset. */
9000 *offset = fold (build (MINUS_EXPR, TREE_TYPE (element),
9001 element,
9002 TYPE_MIN_VALUE (TYPE_DOMAIN
9003 (TREE_TYPE (array)))));
9004
9005 *offset = size_binop (MULT_EXPR,
9006 convert (bitsizetype, *offset),
9007 TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))));
9008
9009 *offset = size_binop (PLUS_EXPR, init_offset, *offset);
c7e4ee3a
CB
9010
9011 *size = TYPE_SIZE (TREE_TYPE (t));
9012 return;
9013 }
9014
9015 case INDIRECT_REF:
9016
9017 /* Most of this code is to handle references to COMMON. And so
9018 far that is useful only for calling library functions, since
9019 external (user) functions might reference common areas. But
9020 even calling an external function, it's worthwhile to decode
9021 COMMON references because if not storing into COMMON, we don't
9022 want COMMON-based arguments to gratuitously force use of a
9023 temporary. */
9024
9025 *size = TYPE_SIZE (TREE_TYPE (t));
5ff904cd 9026
c7e4ee3a
CB
9027 ffecom_tree_canonize_ptr_ (decl, offset,
9028 TREE_OPERAND (t, 0));
5ff904cd 9029
c7e4ee3a 9030 return;
5ff904cd 9031
c7e4ee3a
CB
9032 case CONVERT_EXPR:
9033 case NOP_EXPR:
9034 case MODIFY_EXPR:
9035 case NON_LVALUE_EXPR:
9036 case RESULT_DECL:
9037 case FIELD_DECL:
9038 case COND_EXPR: /* More cases than we can handle. */
9039 case SAVE_EXPR:
9040 case REFERENCE_EXPR:
9041 case PREDECREMENT_EXPR:
9042 case PREINCREMENT_EXPR:
9043 case POSTDECREMENT_EXPR:
9044 case POSTINCREMENT_EXPR:
9045 case CALL_EXPR:
9046 default:
9047 *decl = error_mark_node;
9048 return;
9049 }
9050}
5ff904cd 9051
c7e4ee3a 9052/* Do divide operation appropriate to type of operands. */
5ff904cd 9053
c7e4ee3a
CB
9054static tree
9055ffecom_tree_divide_ (tree tree_type, tree left, tree right,
9056 tree dest_tree, ffebld dest, bool *dest_used,
9057 tree hook)
9058{
9059 if ((left == error_mark_node)
9060 || (right == error_mark_node))
9061 return error_mark_node;
a6fa6420 9062
c7e4ee3a
CB
9063 switch (TREE_CODE (tree_type))
9064 {
9065 case INTEGER_TYPE:
9066 return ffecom_2 (TRUNC_DIV_EXPR, tree_type,
9067 left,
9068 right);
a6fa6420 9069
c7e4ee3a 9070 case COMPLEX_TYPE:
c64f913e
CB
9071 if (! optimize_size)
9072 return ffecom_2 (RDIV_EXPR, tree_type,
9073 left,
9074 right);
c7e4ee3a
CB
9075 {
9076 ffecomGfrt ix;
a6fa6420 9077
c7e4ee3a
CB
9078 if (TREE_TYPE (tree_type)
9079 == ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1])
9080 ix = FFECOM_gfrtDIV_CC; /* Overlapping result okay. */
9081 else
9082 ix = FFECOM_gfrtDIV_ZZ; /* Overlapping result okay. */
a6fa6420 9083
c7e4ee3a
CB
9084 left = ffecom_1 (ADDR_EXPR,
9085 build_pointer_type (TREE_TYPE (left)),
9086 left);
9087 left = build_tree_list (NULL_TREE, left);
9088 right = ffecom_1 (ADDR_EXPR,
9089 build_pointer_type (TREE_TYPE (right)),
9090 right);
9091 right = build_tree_list (NULL_TREE, right);
9092 TREE_CHAIN (left) = right;
a6fa6420 9093
c7e4ee3a
CB
9094 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
9095 ffecom_gfrt_kindtype (ix),
9096 ffe_is_f2c_library (),
9097 tree_type,
9098 left,
9099 dest_tree, dest, dest_used,
9100 NULL_TREE, TRUE, hook);
9101 }
9102 break;
5ff904cd 9103
c7e4ee3a
CB
9104 case RECORD_TYPE:
9105 {
9106 ffecomGfrt ix;
5ff904cd 9107
c7e4ee3a
CB
9108 if (TREE_TYPE (TYPE_FIELDS (tree_type))
9109 == ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1])
9110 ix = FFECOM_gfrtDIV_CC; /* Overlapping result okay. */
9111 else
9112 ix = FFECOM_gfrtDIV_ZZ; /* Overlapping result okay. */
5ff904cd 9113
c7e4ee3a
CB
9114 left = ffecom_1 (ADDR_EXPR,
9115 build_pointer_type (TREE_TYPE (left)),
9116 left);
9117 left = build_tree_list (NULL_TREE, left);
9118 right = ffecom_1 (ADDR_EXPR,
9119 build_pointer_type (TREE_TYPE (right)),
9120 right);
9121 right = build_tree_list (NULL_TREE, right);
9122 TREE_CHAIN (left) = right;
a6fa6420 9123
c7e4ee3a
CB
9124 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
9125 ffecom_gfrt_kindtype (ix),
9126 ffe_is_f2c_library (),
9127 tree_type,
9128 left,
9129 dest_tree, dest, dest_used,
9130 NULL_TREE, TRUE, hook);
9131 }
9132 break;
5ff904cd 9133
c7e4ee3a
CB
9134 default:
9135 return ffecom_2 (RDIV_EXPR, tree_type,
9136 left,
9137 right);
5ff904cd 9138 }
c7e4ee3a 9139}
5ff904cd 9140
c7e4ee3a 9141/* Build type info for non-dummy variable. */
5ff904cd 9142
c7e4ee3a
CB
9143static tree
9144ffecom_type_localvar_ (ffesymbol s, ffeinfoBasictype bt,
9145 ffeinfoKindtype kt)
9146{
9147 tree type;
9148 ffebld dl;
9149 ffebld dim;
9150 tree lowt;
9151 tree hight;
5ff904cd 9152
c7e4ee3a
CB
9153 type = ffecom_tree_type[bt][kt];
9154 if (bt == FFEINFO_basictypeCHARACTER)
9155 {
9156 hight = build_int_2 (ffesymbol_size (s), 0);
9157 TREE_TYPE (hight) = ffecom_f2c_ftnlen_type_node;
5ff904cd 9158
c7e4ee3a
CB
9159 type
9160 = build_array_type
9161 (type,
9162 build_range_type (ffecom_f2c_ftnlen_type_node,
9163 ffecom_f2c_ftnlen_one_node,
9164 hight));
9165 type = ffecom_check_size_overflow_ (s, type, FALSE);
9166 }
5ff904cd 9167
c7e4ee3a
CB
9168 for (dl = ffesymbol_dims (s); dl != NULL; dl = ffebld_trail (dl))
9169 {
9170 if (type == error_mark_node)
9171 break;
5ff904cd 9172
c7e4ee3a
CB
9173 dim = ffebld_head (dl);
9174 assert (ffebld_op (dim) == FFEBLD_opBOUNDS);
5ff904cd 9175
c7e4ee3a
CB
9176 if (ffebld_left (dim) == NULL)
9177 lowt = integer_one_node;
9178 else
9179 lowt = ffecom_expr (ffebld_left (dim));
5ff904cd 9180
c7e4ee3a
CB
9181 if (TREE_CODE (lowt) != INTEGER_CST)
9182 lowt = variable_size (lowt);
5ff904cd 9183
c7e4ee3a
CB
9184 assert (ffebld_right (dim) != NULL);
9185 hight = ffecom_expr (ffebld_right (dim));
5ff904cd 9186
c7e4ee3a
CB
9187 if (TREE_CODE (hight) != INTEGER_CST)
9188 hight = variable_size (hight);
5ff904cd 9189
c7e4ee3a
CB
9190 type = build_array_type (type,
9191 build_range_type (ffecom_integer_type_node,
9192 lowt, hight));
9193 type = ffecom_check_size_overflow_ (s, type, FALSE);
9194 }
5ff904cd 9195
c7e4ee3a 9196 return type;
5ff904cd
JL
9197}
9198
c7e4ee3a 9199/* Build Namelist type. */
5ff904cd 9200
c7e4ee3a
CB
9201static tree
9202ffecom_type_namelist_ ()
9203{
9204 static tree type = NULL_TREE;
5ff904cd 9205
c7e4ee3a
CB
9206 if (type == NULL_TREE)
9207 {
9208 static tree namefield, varsfield, nvarsfield;
9209 tree vardesctype;
5ff904cd 9210
c7e4ee3a 9211 vardesctype = ffecom_type_vardesc_ ();
5ff904cd 9212
c7e4ee3a 9213 type = make_node (RECORD_TYPE);
a6fa6420 9214
c7e4ee3a 9215 vardesctype = build_pointer_type (build_pointer_type (vardesctype));
a6fa6420 9216
c7e4ee3a
CB
9217 namefield = ffecom_decl_field (type, NULL_TREE, "name",
9218 string_type_node);
9219 varsfield = ffecom_decl_field (type, namefield, "vars", vardesctype);
9220 nvarsfield = ffecom_decl_field (type, varsfield, "nvars",
9221 integer_type_node);
a6fa6420 9222
c7e4ee3a
CB
9223 TYPE_FIELDS (type) = namefield;
9224 layout_type (type);
a6fa6420 9225
7189a4b0 9226 ggc_add_tree_root (&type, 1);
5ff904cd 9227 }
5ff904cd 9228
c7e4ee3a
CB
9229 return type;
9230}
5ff904cd 9231
c7e4ee3a 9232/* Build Vardesc type. */
5ff904cd 9233
c7e4ee3a
CB
9234static tree
9235ffecom_type_vardesc_ ()
9236{
9237 static tree type = NULL_TREE;
9238 static tree namefield, addrfield, dimsfield, typefield;
5ff904cd 9239
c7e4ee3a
CB
9240 if (type == NULL_TREE)
9241 {
c7e4ee3a 9242 type = make_node (RECORD_TYPE);
5ff904cd 9243
c7e4ee3a
CB
9244 namefield = ffecom_decl_field (type, NULL_TREE, "name",
9245 string_type_node);
9246 addrfield = ffecom_decl_field (type, namefield, "addr",
9247 string_type_node);
9248 dimsfield = ffecom_decl_field (type, addrfield, "dims",
9249 ffecom_f2c_ptr_to_ftnlen_type_node);
9250 typefield = ffecom_decl_field (type, dimsfield, "type",
9251 integer_type_node);
5ff904cd 9252
c7e4ee3a
CB
9253 TYPE_FIELDS (type) = namefield;
9254 layout_type (type);
9255
7189a4b0 9256 ggc_add_tree_root (&type, 1);
c7e4ee3a
CB
9257 }
9258
9259 return type;
5ff904cd
JL
9260}
9261
5ff904cd 9262static tree
c7e4ee3a 9263ffecom_vardesc_ (ffebld expr)
5ff904cd 9264{
c7e4ee3a 9265 ffesymbol s;
5ff904cd 9266
c7e4ee3a
CB
9267 assert (ffebld_op (expr) == FFEBLD_opSYMTER);
9268 s = ffebld_symter (expr);
5ff904cd 9269
c7e4ee3a
CB
9270 if (ffesymbol_hook (s).vardesc_tree == NULL_TREE)
9271 {
9272 int i;
9273 tree vardesctype = ffecom_type_vardesc_ ();
9274 tree var;
9275 tree nameinit;
9276 tree dimsinit;
9277 tree addrinit;
9278 tree typeinit;
9279 tree field;
9280 tree varinits;
c7e4ee3a 9281 static int mynumber = 0;
5ff904cd 9282
c7e4ee3a
CB
9283 var = build_decl (VAR_DECL,
9284 ffecom_get_invented_identifier ("__g77_vardesc_%d",
14657de8 9285 mynumber++),
c7e4ee3a
CB
9286 vardesctype);
9287 TREE_STATIC (var) = 1;
9288 DECL_INITIAL (var) = error_mark_node;
5ff904cd 9289
c7e4ee3a 9290 var = start_decl (var, FALSE);
5ff904cd 9291
c7e4ee3a 9292 /* Process inits. */
5ff904cd 9293
c7e4ee3a
CB
9294 nameinit = ffecom_build_f2c_string_ ((i = strlen (ffesymbol_text (s)))
9295 + 1,
9296 ffesymbol_text (s));
9297 TREE_TYPE (nameinit)
9298 = build_type_variant
9299 (build_array_type
9300 (char_type_node,
9301 build_range_type (integer_type_node,
9302 integer_one_node,
9303 build_int_2 (i, 0))),
9304 1, 0);
9305 TREE_CONSTANT (nameinit) = 1;
9306 TREE_STATIC (nameinit) = 1;
9307 nameinit = ffecom_1 (ADDR_EXPR,
9308 build_pointer_type (TREE_TYPE (nameinit)),
9309 nameinit);
5ff904cd 9310
c7e4ee3a 9311 addrinit = ffecom_arg_ptr_to_expr (expr, &typeinit);
5ff904cd 9312
c7e4ee3a 9313 dimsinit = ffecom_vardesc_dims_ (s);
5ff904cd 9314
c7e4ee3a
CB
9315 if (typeinit == NULL_TREE)
9316 {
9317 ffeinfoBasictype bt = ffesymbol_basictype (s);
9318 ffeinfoKindtype kt = ffesymbol_kindtype (s);
9319 int tc = ffecom_f2c_typecode (bt, kt);
5ff904cd 9320
c7e4ee3a
CB
9321 assert (tc != -1);
9322 typeinit = build_int_2 (tc, (tc < 0) ? -1 : 0);
9323 }
9324 else
9325 typeinit = ffecom_1 (NEGATE_EXPR, TREE_TYPE (typeinit), typeinit);
5ff904cd 9326
c7e4ee3a
CB
9327 varinits = build_tree_list ((field = TYPE_FIELDS (vardesctype)),
9328 nameinit);
9329 TREE_CHAIN (varinits) = build_tree_list ((field = TREE_CHAIN (field)),
9330 addrinit);
9331 TREE_CHAIN (TREE_CHAIN (varinits))
9332 = build_tree_list ((field = TREE_CHAIN (field)), dimsinit);
9333 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (varinits)))
9334 = build_tree_list ((field = TREE_CHAIN (field)), typeinit);
5ff904cd 9335
c7e4ee3a
CB
9336 varinits = build (CONSTRUCTOR, vardesctype, NULL_TREE, varinits);
9337 TREE_CONSTANT (varinits) = 1;
9338 TREE_STATIC (varinits) = 1;
5ff904cd 9339
c7e4ee3a 9340 finish_decl (var, varinits, FALSE);
5ff904cd 9341
c7e4ee3a 9342 var = ffecom_1 (ADDR_EXPR, build_pointer_type (vardesctype), var);
5ff904cd 9343
c7e4ee3a
CB
9344 ffesymbol_hook (s).vardesc_tree = var;
9345 }
5ff904cd 9346
c7e4ee3a
CB
9347 return ffesymbol_hook (s).vardesc_tree;
9348}
5ff904cd 9349
c7e4ee3a
CB
9350static tree
9351ffecom_vardesc_array_ (ffesymbol s)
5ff904cd 9352{
c7e4ee3a
CB
9353 ffebld b;
9354 tree list;
9355 tree item = NULL_TREE;
9356 tree var;
9357 int i;
c7e4ee3a 9358 static int mynumber = 0;
5ff904cd 9359
c7e4ee3a
CB
9360 for (i = 0, list = NULL_TREE, b = ffesymbol_namelist (s);
9361 b != NULL;
9362 b = ffebld_trail (b), ++i)
9363 {
9364 tree t;
5ff904cd 9365
c7e4ee3a 9366 t = ffecom_vardesc_ (ffebld_head (b));
5ff904cd 9367
c7e4ee3a
CB
9368 if (list == NULL_TREE)
9369 list = item = build_tree_list (NULL_TREE, t);
9370 else
5ff904cd 9371 {
c7e4ee3a
CB
9372 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
9373 item = TREE_CHAIN (item);
5ff904cd 9374 }
5ff904cd 9375 }
5ff904cd 9376
c7e4ee3a
CB
9377 item = build_array_type (build_pointer_type (ffecom_type_vardesc_ ()),
9378 build_range_type (integer_type_node,
9379 integer_one_node,
9380 build_int_2 (i, 0)));
9381 list = build (CONSTRUCTOR, item, NULL_TREE, list);
9382 TREE_CONSTANT (list) = 1;
9383 TREE_STATIC (list) = 1;
5ff904cd 9384
14657de8 9385 var = ffecom_get_invented_identifier ("__g77_vardesc_array_%d", mynumber++);
c7e4ee3a
CB
9386 var = build_decl (VAR_DECL, var, item);
9387 TREE_STATIC (var) = 1;
9388 DECL_INITIAL (var) = error_mark_node;
9389 var = start_decl (var, FALSE);
9390 finish_decl (var, list, FALSE);
5ff904cd 9391
c7e4ee3a
CB
9392 return var;
9393}
5ff904cd 9394
c7e4ee3a
CB
9395static tree
9396ffecom_vardesc_dims_ (ffesymbol s)
9397{
9398 if (ffesymbol_dims (s) == NULL)
9399 return convert (ffecom_f2c_ptr_to_ftnlen_type_node,
9400 integer_zero_node);
5ff904cd 9401
c7e4ee3a
CB
9402 {
9403 ffebld b;
9404 ffebld e;
9405 tree list;
9406 tree backlist;
9407 tree item = NULL_TREE;
9408 tree var;
c7e4ee3a
CB
9409 tree numdim;
9410 tree numelem;
9411 tree baseoff = NULL_TREE;
9412 static int mynumber = 0;
9413
9414 numdim = build_int_2 ((int) ffesymbol_rank (s), 0);
9415 TREE_TYPE (numdim) = ffecom_f2c_ftnlen_type_node;
9416
9417 numelem = ffecom_expr (ffesymbol_arraysize (s));
9418 TREE_TYPE (numelem) = ffecom_f2c_ftnlen_type_node;
9419
9420 list = NULL_TREE;
9421 backlist = NULL_TREE;
9422 for (b = ffesymbol_dims (s), e = ffesymbol_extents (s);
9423 b != NULL;
9424 b = ffebld_trail (b), e = ffebld_trail (e))
5ff904cd 9425 {
c7e4ee3a
CB
9426 tree t;
9427 tree low;
9428 tree back;
5ff904cd 9429
c7e4ee3a
CB
9430 if (ffebld_trail (b) == NULL)
9431 t = NULL_TREE;
9432 else
5ff904cd 9433 {
c7e4ee3a
CB
9434 t = convert (ffecom_f2c_ftnlen_type_node,
9435 ffecom_expr (ffebld_head (e)));
5ff904cd 9436
c7e4ee3a
CB
9437 if (list == NULL_TREE)
9438 list = item = build_tree_list (NULL_TREE, t);
9439 else
9440 {
9441 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
9442 item = TREE_CHAIN (item);
9443 }
9444 }
5ff904cd 9445
c7e4ee3a
CB
9446 if (ffebld_left (ffebld_head (b)) == NULL)
9447 low = ffecom_integer_one_node;
9448 else
9449 low = ffecom_expr (ffebld_left (ffebld_head (b)));
9450 low = convert (ffecom_f2c_ftnlen_type_node, low);
5ff904cd 9451
c7e4ee3a
CB
9452 back = build_tree_list (low, t);
9453 TREE_CHAIN (back) = backlist;
9454 backlist = back;
9455 }
5ff904cd 9456
c7e4ee3a
CB
9457 for (item = backlist; item != NULL_TREE; item = TREE_CHAIN (item))
9458 {
9459 if (TREE_VALUE (item) == NULL_TREE)
9460 baseoff = TREE_PURPOSE (item);
9461 else
9462 baseoff = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
9463 TREE_PURPOSE (item),
9464 ffecom_2 (MULT_EXPR,
9465 ffecom_f2c_ftnlen_type_node,
9466 TREE_VALUE (item),
9467 baseoff));
5ff904cd
JL
9468 }
9469
c7e4ee3a 9470 /* backlist now dead, along with all TREE_PURPOSEs on it. */
5ff904cd 9471
c7e4ee3a
CB
9472 baseoff = build_tree_list (NULL_TREE, baseoff);
9473 TREE_CHAIN (baseoff) = list;
5ff904cd 9474
c7e4ee3a
CB
9475 numelem = build_tree_list (NULL_TREE, numelem);
9476 TREE_CHAIN (numelem) = baseoff;
5ff904cd 9477
c7e4ee3a
CB
9478 numdim = build_tree_list (NULL_TREE, numdim);
9479 TREE_CHAIN (numdim) = numelem;
5ff904cd 9480
c7e4ee3a
CB
9481 item = build_array_type (ffecom_f2c_ftnlen_type_node,
9482 build_range_type (integer_type_node,
9483 integer_zero_node,
9484 build_int_2
9485 ((int) ffesymbol_rank (s)
9486 + 2, 0)));
9487 list = build (CONSTRUCTOR, item, NULL_TREE, numdim);
9488 TREE_CONSTANT (list) = 1;
9489 TREE_STATIC (list) = 1;
9490
14657de8 9491 var = ffecom_get_invented_identifier ("__g77_dims_%d", mynumber++);
c7e4ee3a
CB
9492 var = build_decl (VAR_DECL, var, item);
9493 TREE_STATIC (var) = 1;
9494 DECL_INITIAL (var) = error_mark_node;
9495 var = start_decl (var, FALSE);
9496 finish_decl (var, list, FALSE);
9497
9498 var = ffecom_1 (ADDR_EXPR, build_pointer_type (item), var);
9499
c7e4ee3a
CB
9500 return var;
9501 }
5ff904cd 9502}
c7e4ee3a 9503
c7e4ee3a
CB
9504/* Essentially does a "fold (build1 (code, type, node))" while checking
9505 for certain housekeeping things.
5ff904cd 9506
c7e4ee3a
CB
9507 NOTE: for building an ADDR_EXPR around a FUNCTION_DECL, use
9508 ffecom_1_fn instead. */
5ff904cd 9509
c7e4ee3a
CB
9510tree
9511ffecom_1 (enum tree_code code, tree type, tree node)
5ff904cd 9512{
c7e4ee3a
CB
9513 tree item;
9514
9515 if ((node == error_mark_node)
9516 || (type == error_mark_node))
5ff904cd
JL
9517 return error_mark_node;
9518
c7e4ee3a 9519 if (code == ADDR_EXPR)
5ff904cd 9520 {
c7e4ee3a
CB
9521 if (!mark_addressable (node))
9522 assert ("can't mark_addressable this node!" == NULL);
9523 }
5ff904cd 9524
c7e4ee3a
CB
9525 switch (ffe_is_emulate_complex () ? code : NOP_EXPR)
9526 {
9527 tree realtype;
5ff904cd 9528
c7e4ee3a
CB
9529 case REALPART_EXPR:
9530 item = build (COMPONENT_REF, type, node, TYPE_FIELDS (TREE_TYPE (node)));
5ff904cd
JL
9531 break;
9532
c7e4ee3a
CB
9533 case IMAGPART_EXPR:
9534 item = build (COMPONENT_REF, type, node, TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (node))));
9535 break;
5ff904cd 9536
5ff904cd 9537
c7e4ee3a
CB
9538 case NEGATE_EXPR:
9539 if (TREE_CODE (type) != RECORD_TYPE)
9540 {
9541 item = build1 (code, type, node);
9542 break;
9543 }
9544 node = ffecom_stabilize_aggregate_ (node);
9545 realtype = TREE_TYPE (TYPE_FIELDS (type));
9546 item =
9547 ffecom_2 (COMPLEX_EXPR, type,
9548 ffecom_1 (NEGATE_EXPR, realtype,
9549 ffecom_1 (REALPART_EXPR, realtype,
9550 node)),
9551 ffecom_1 (NEGATE_EXPR, realtype,
9552 ffecom_1 (IMAGPART_EXPR, realtype,
9553 node)));
5ff904cd
JL
9554 break;
9555
9556 default:
c7e4ee3a
CB
9557 item = build1 (code, type, node);
9558 break;
5ff904cd 9559 }
5ff904cd 9560
c7e4ee3a
CB
9561 if (TREE_SIDE_EFFECTS (node))
9562 TREE_SIDE_EFFECTS (item) = 1;
9563 if ((code == ADDR_EXPR) && staticp (node))
9564 TREE_CONSTANT (item) = 1;
9565 return fold (item);
9566}
5ff904cd 9567
c7e4ee3a
CB
9568/* Like ffecom_1 (ADDR_EXPR, TREE_TYPE (node), node), except
9569 handles TREE_CODE (node) == FUNCTION_DECL. In particular,
9570 does not set TREE_ADDRESSABLE (because calling an inline
9571 function does not mean the function needs to be separately
9572 compiled). */
5ff904cd 9573
c7e4ee3a
CB
9574tree
9575ffecom_1_fn (tree node)
5ff904cd 9576{
c7e4ee3a 9577 tree item;
5ff904cd 9578 tree type;
5ff904cd 9579
c7e4ee3a
CB
9580 if (node == error_mark_node)
9581 return error_mark_node;
5ff904cd 9582
c7e4ee3a
CB
9583 type = build_type_variant (TREE_TYPE (node),
9584 TREE_READONLY (node),
9585 TREE_THIS_VOLATILE (node));
9586 item = build1 (ADDR_EXPR,
9587 build_pointer_type (type), node);
9588 if (TREE_SIDE_EFFECTS (node))
9589 TREE_SIDE_EFFECTS (item) = 1;
9590 if (staticp (node))
9591 TREE_CONSTANT (item) = 1;
9592 return fold (item);
5ff904cd 9593}
c7e4ee3a
CB
9594
9595/* Essentially does a "fold (build (code, type, node1, node2))" while
9596 checking for certain housekeeping things. */
5ff904cd 9597
c7e4ee3a
CB
9598tree
9599ffecom_2 (enum tree_code code, tree type, tree node1,
9600 tree node2)
5ff904cd 9601{
c7e4ee3a 9602 tree item;
5ff904cd 9603
c7e4ee3a
CB
9604 if ((node1 == error_mark_node)
9605 || (node2 == error_mark_node)
9606 || (type == error_mark_node))
9607 return error_mark_node;
9608
9609 switch (ffe_is_emulate_complex () ? code : NOP_EXPR)
5ff904cd 9610 {
c7e4ee3a 9611 tree a, b, c, d, realtype;
5ff904cd 9612
c7e4ee3a
CB
9613 case CONJ_EXPR:
9614 assert ("no CONJ_EXPR support yet" == NULL);
9615 return error_mark_node;
5ff904cd 9616
c7e4ee3a
CB
9617 case COMPLEX_EXPR:
9618 item = build_tree_list (TYPE_FIELDS (type), node1);
9619 TREE_CHAIN (item) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), node2);
9620 item = build (CONSTRUCTOR, type, NULL_TREE, item);
9621 break;
5ff904cd 9622
c7e4ee3a
CB
9623 case PLUS_EXPR:
9624 if (TREE_CODE (type) != RECORD_TYPE)
9625 {
9626 item = build (code, type, node1, node2);
9627 break;
9628 }
9629 node1 = ffecom_stabilize_aggregate_ (node1);
9630 node2 = ffecom_stabilize_aggregate_ (node2);
9631 realtype = TREE_TYPE (TYPE_FIELDS (type));
9632 item =
9633 ffecom_2 (COMPLEX_EXPR, type,
9634 ffecom_2 (PLUS_EXPR, realtype,
9635 ffecom_1 (REALPART_EXPR, realtype,
9636 node1),
9637 ffecom_1 (REALPART_EXPR, realtype,
9638 node2)),
9639 ffecom_2 (PLUS_EXPR, realtype,
9640 ffecom_1 (IMAGPART_EXPR, realtype,
9641 node1),
9642 ffecom_1 (IMAGPART_EXPR, realtype,
9643 node2)));
9644 break;
5ff904cd 9645
c7e4ee3a
CB
9646 case MINUS_EXPR:
9647 if (TREE_CODE (type) != RECORD_TYPE)
9648 {
9649 item = build (code, type, node1, node2);
9650 break;
9651 }
9652 node1 = ffecom_stabilize_aggregate_ (node1);
9653 node2 = ffecom_stabilize_aggregate_ (node2);
9654 realtype = TREE_TYPE (TYPE_FIELDS (type));
9655 item =
9656 ffecom_2 (COMPLEX_EXPR, type,
9657 ffecom_2 (MINUS_EXPR, realtype,
9658 ffecom_1 (REALPART_EXPR, realtype,
9659 node1),
9660 ffecom_1 (REALPART_EXPR, realtype,
9661 node2)),
9662 ffecom_2 (MINUS_EXPR, realtype,
9663 ffecom_1 (IMAGPART_EXPR, realtype,
9664 node1),
9665 ffecom_1 (IMAGPART_EXPR, realtype,
9666 node2)));
9667 break;
5ff904cd 9668
c7e4ee3a
CB
9669 case MULT_EXPR:
9670 if (TREE_CODE (type) != RECORD_TYPE)
9671 {
9672 item = build (code, type, node1, node2);
9673 break;
9674 }
9675 node1 = ffecom_stabilize_aggregate_ (node1);
9676 node2 = ffecom_stabilize_aggregate_ (node2);
9677 realtype = TREE_TYPE (TYPE_FIELDS (type));
9678 a = save_expr (ffecom_1 (REALPART_EXPR, realtype,
9679 node1));
9680 b = save_expr (ffecom_1 (IMAGPART_EXPR, realtype,
9681 node1));
9682 c = save_expr (ffecom_1 (REALPART_EXPR, realtype,
9683 node2));
9684 d = save_expr (ffecom_1 (IMAGPART_EXPR, realtype,
9685 node2));
9686 item =
9687 ffecom_2 (COMPLEX_EXPR, type,
9688 ffecom_2 (MINUS_EXPR, realtype,
9689 ffecom_2 (MULT_EXPR, realtype,
9690 a,
9691 c),
9692 ffecom_2 (MULT_EXPR, realtype,
9693 b,
9694 d)),
9695 ffecom_2 (PLUS_EXPR, realtype,
9696 ffecom_2 (MULT_EXPR, realtype,
9697 a,
9698 d),
9699 ffecom_2 (MULT_EXPR, realtype,
9700 c,
9701 b)));
9702 break;
5ff904cd 9703
c7e4ee3a
CB
9704 case EQ_EXPR:
9705 if ((TREE_CODE (node1) != RECORD_TYPE)
9706 && (TREE_CODE (node2) != RECORD_TYPE))
9707 {
9708 item = build (code, type, node1, node2);
9709 break;
9710 }
9711 assert (TREE_CODE (node1) == RECORD_TYPE);
9712 assert (TREE_CODE (node2) == RECORD_TYPE);
9713 node1 = ffecom_stabilize_aggregate_ (node1);
9714 node2 = ffecom_stabilize_aggregate_ (node2);
9715 realtype = TREE_TYPE (TYPE_FIELDS (type));
9716 item =
9717 ffecom_2 (TRUTH_ANDIF_EXPR, type,
9718 ffecom_2 (code, type,
9719 ffecom_1 (REALPART_EXPR, realtype,
9720 node1),
9721 ffecom_1 (REALPART_EXPR, realtype,
9722 node2)),
9723 ffecom_2 (code, type,
9724 ffecom_1 (IMAGPART_EXPR, realtype,
9725 node1),
9726 ffecom_1 (IMAGPART_EXPR, realtype,
9727 node2)));
9728 break;
9729
9730 case NE_EXPR:
9731 if ((TREE_CODE (node1) != RECORD_TYPE)
9732 && (TREE_CODE (node2) != RECORD_TYPE))
9733 {
9734 item = build (code, type, node1, node2);
9735 break;
9736 }
9737 assert (TREE_CODE (node1) == RECORD_TYPE);
9738 assert (TREE_CODE (node2) == RECORD_TYPE);
9739 node1 = ffecom_stabilize_aggregate_ (node1);
9740 node2 = ffecom_stabilize_aggregate_ (node2);
9741 realtype = TREE_TYPE (TYPE_FIELDS (type));
9742 item =
9743 ffecom_2 (TRUTH_ORIF_EXPR, type,
9744 ffecom_2 (code, type,
9745 ffecom_1 (REALPART_EXPR, realtype,
9746 node1),
9747 ffecom_1 (REALPART_EXPR, realtype,
9748 node2)),
9749 ffecom_2 (code, type,
9750 ffecom_1 (IMAGPART_EXPR, realtype,
9751 node1),
9752 ffecom_1 (IMAGPART_EXPR, realtype,
9753 node2)));
9754 break;
5ff904cd 9755
c7e4ee3a
CB
9756 default:
9757 item = build (code, type, node1, node2);
9758 break;
5ff904cd
JL
9759 }
9760
c7e4ee3a
CB
9761 if (TREE_SIDE_EFFECTS (node1) || TREE_SIDE_EFFECTS (node2))
9762 TREE_SIDE_EFFECTS (item) = 1;
9763 return fold (item);
5ff904cd
JL
9764}
9765
c7e4ee3a 9766/* ffecom_2pass_advise_entrypoint -- Advise that there's this entrypoint
5ff904cd 9767
c7e4ee3a
CB
9768 ffesymbol s; // the ENTRY point itself
9769 if (ffecom_2pass_advise_entrypoint(s))
9770 // the ENTRY point has been accepted
5ff904cd 9771
c7e4ee3a
CB
9772 Does whatever compiler needs to do when it learns about the entrypoint,
9773 like determine the return type of the master function, count the
9774 number of entrypoints, etc. Returns FALSE if the return type is
9775 not compatible with the return type(s) of other entrypoint(s).
5ff904cd 9776
c7e4ee3a
CB
9777 NOTE: for every call to this fn that returns TRUE, _do_entrypoint must
9778 later (after _finish_progunit) be called with the same entrypoint(s)
9779 as passed to this fn for which TRUE was returned.
5ff904cd 9780
c7e4ee3a
CB
9781 03-Jan-92 JCB 2.0
9782 Return FALSE if the return type conflicts with previous entrypoints. */
5ff904cd 9783
c7e4ee3a
CB
9784bool
9785ffecom_2pass_advise_entrypoint (ffesymbol entry)
5ff904cd 9786{
c7e4ee3a
CB
9787 ffebld list; /* opITEM. */
9788 ffebld mlist; /* opITEM. */
9789 ffebld plist; /* opITEM. */
9790 ffebld arg; /* ffebld_head(opITEM). */
9791 ffebld item; /* opITEM. */
9792 ffesymbol s; /* ffebld_symter(arg). */
9793 ffeinfoBasictype bt = ffesymbol_basictype (entry);
9794 ffeinfoKindtype kt = ffesymbol_kindtype (entry);
9795 ffetargetCharacterSize size = ffesymbol_size (entry);
9796 bool ok;
5ff904cd 9797
c7e4ee3a
CB
9798 if (ffecom_num_entrypoints_ == 0)
9799 { /* First entrypoint, make list of main
9800 arglist's dummies. */
9801 assert (ffecom_primary_entry_ != NULL);
5ff904cd 9802
c7e4ee3a
CB
9803 ffecom_master_bt_ = ffesymbol_basictype (ffecom_primary_entry_);
9804 ffecom_master_kt_ = ffesymbol_kindtype (ffecom_primary_entry_);
9805 ffecom_master_size_ = ffesymbol_size (ffecom_primary_entry_);
5ff904cd 9806
c7e4ee3a
CB
9807 for (plist = NULL, list = ffesymbol_dummyargs (ffecom_primary_entry_);
9808 list != NULL;
9809 list = ffebld_trail (list))
9810 {
9811 arg = ffebld_head (list);
9812 if (ffebld_op (arg) != FFEBLD_opSYMTER)
9813 continue; /* Alternate return or some such thing. */
9814 item = ffebld_new_item (arg, NULL);
9815 if (plist == NULL)
9816 ffecom_master_arglist_ = item;
9817 else
9818 ffebld_set_trail (plist, item);
9819 plist = item;
9820 }
5ff904cd
JL
9821 }
9822
c7e4ee3a
CB
9823 /* If necessary, scan entry arglist for alternate returns. Do this scan
9824 apparently redundantly (it's done below to UNIONize the arglists) so
9825 that we don't complain about RETURN 1 if an offending ENTRY is the only
9826 one with an alternate return. */
5ff904cd 9827
c7e4ee3a 9828 if (!ffecom_is_altreturning_)
5ff904cd 9829 {
c7e4ee3a
CB
9830 for (list = ffesymbol_dummyargs (entry);
9831 list != NULL;
9832 list = ffebld_trail (list))
9833 {
9834 arg = ffebld_head (list);
9835 if (ffebld_op (arg) == FFEBLD_opSTAR)
9836 {
9837 ffecom_is_altreturning_ = TRUE;
9838 break;
9839 }
9840 }
9841 }
5ff904cd 9842
c7e4ee3a 9843 /* Now check type compatibility. */
5ff904cd 9844
c7e4ee3a
CB
9845 switch (ffecom_master_bt_)
9846 {
9847 case FFEINFO_basictypeNONE:
9848 ok = (bt != FFEINFO_basictypeCHARACTER);
9849 break;
5ff904cd 9850
c7e4ee3a
CB
9851 case FFEINFO_basictypeCHARACTER:
9852 ok
9853 = (bt == FFEINFO_basictypeCHARACTER)
9854 && (kt == ffecom_master_kt_)
9855 && (size == ffecom_master_size_);
9856 break;
5ff904cd 9857
c7e4ee3a
CB
9858 case FFEINFO_basictypeANY:
9859 return FALSE; /* Just don't bother. */
5ff904cd 9860
c7e4ee3a
CB
9861 default:
9862 if (bt == FFEINFO_basictypeCHARACTER)
5ff904cd 9863 {
c7e4ee3a
CB
9864 ok = FALSE;
9865 break;
5ff904cd 9866 }
c7e4ee3a
CB
9867 ok = TRUE;
9868 if ((bt != ffecom_master_bt_) || (kt != ffecom_master_kt_))
9869 {
9870 ffecom_master_bt_ = FFEINFO_basictypeNONE;
9871 ffecom_master_kt_ = FFEINFO_kindtypeNONE;
9872 }
9873 break;
9874 }
5ff904cd 9875
c7e4ee3a
CB
9876 if (!ok)
9877 {
9878 ffebad_start (FFEBAD_ENTRY_CONFLICTS);
9879 ffest_ffebad_here_current_stmt (0);
9880 ffebad_finish ();
9881 return FALSE; /* Can't handle entrypoint. */
9882 }
5ff904cd 9883
c7e4ee3a 9884 /* Entrypoint type compatible with previous types. */
5ff904cd 9885
c7e4ee3a 9886 ++ffecom_num_entrypoints_;
5ff904cd 9887
c7e4ee3a
CB
9888 /* Master-arg-list = UNION(Master-arg-list,entry-arg-list). */
9889
9890 for (list = ffesymbol_dummyargs (entry);
9891 list != NULL;
9892 list = ffebld_trail (list))
9893 {
9894 arg = ffebld_head (list);
9895 if (ffebld_op (arg) != FFEBLD_opSYMTER)
9896 continue; /* Alternate return or some such thing. */
9897 s = ffebld_symter (arg);
9898 for (plist = NULL, mlist = ffecom_master_arglist_;
9899 mlist != NULL;
9900 plist = mlist, mlist = ffebld_trail (mlist))
9901 { /* plist points to previous item for easy
9902 appending of arg. */
9903 if (ffebld_symter (ffebld_head (mlist)) == s)
9904 break; /* Already have this arg in the master list. */
9905 }
9906 if (mlist != NULL)
9907 continue; /* Already have this arg in the master list. */
5ff904cd 9908
c7e4ee3a 9909 /* Append this arg to the master list. */
5ff904cd 9910
c7e4ee3a
CB
9911 item = ffebld_new_item (arg, NULL);
9912 if (plist == NULL)
9913 ffecom_master_arglist_ = item;
9914 else
9915 ffebld_set_trail (plist, item);
5ff904cd
JL
9916 }
9917
c7e4ee3a 9918 return TRUE;
5ff904cd
JL
9919}
9920
c7e4ee3a
CB
9921/* ffecom_2pass_do_entrypoint -- Do compilation of entrypoint
9922
9923 ffesymbol s; // the ENTRY point itself
9924 ffecom_2pass_do_entrypoint(s);
9925
9926 Does whatever compiler needs to do to make the entrypoint actually
9927 happen. Must be called for each entrypoint after
9928 ffecom_finish_progunit is called. */
9929
c7e4ee3a
CB
9930void
9931ffecom_2pass_do_entrypoint (ffesymbol entry)
5ff904cd 9932{
c7e4ee3a
CB
9933 static int mfn_num = 0;
9934 static int ent_num;
5ff904cd 9935
c7e4ee3a
CB
9936 if (mfn_num != ffecom_num_fns_)
9937 { /* First entrypoint for this program unit. */
9938 ent_num = 1;
9939 mfn_num = ffecom_num_fns_;
9940 ffecom_do_entry_ (ffecom_primary_entry_, 0);
9941 }
9942 else
9943 ++ent_num;
5ff904cd 9944
c7e4ee3a 9945 --ffecom_num_entrypoints_;
5ff904cd 9946
c7e4ee3a
CB
9947 ffecom_do_entry_ (entry, ent_num);
9948}
5ff904cd 9949
c7e4ee3a
CB
9950/* Essentially does a "fold (build (code, type, node1, node2))" while
9951 checking for certain housekeeping things. Always sets
9952 TREE_SIDE_EFFECTS. */
5ff904cd 9953
c7e4ee3a
CB
9954tree
9955ffecom_2s (enum tree_code code, tree type, tree node1,
9956 tree node2)
9957{
9958 tree item;
5ff904cd 9959
c7e4ee3a
CB
9960 if ((node1 == error_mark_node)
9961 || (node2 == error_mark_node)
9962 || (type == error_mark_node))
9963 return error_mark_node;
5ff904cd 9964
c7e4ee3a
CB
9965 item = build (code, type, node1, node2);
9966 TREE_SIDE_EFFECTS (item) = 1;
9967 return fold (item);
5ff904cd
JL
9968}
9969
c7e4ee3a
CB
9970/* Essentially does a "fold (build (code, type, node1, node2, node3))" while
9971 checking for certain housekeeping things. */
9972
c7e4ee3a
CB
9973tree
9974ffecom_3 (enum tree_code code, tree type, tree node1,
9975 tree node2, tree node3)
5ff904cd 9976{
c7e4ee3a 9977 tree item;
5ff904cd 9978
c7e4ee3a
CB
9979 if ((node1 == error_mark_node)
9980 || (node2 == error_mark_node)
9981 || (node3 == error_mark_node)
9982 || (type == error_mark_node))
9983 return error_mark_node;
5ff904cd 9984
c7e4ee3a
CB
9985 item = build (code, type, node1, node2, node3);
9986 if (TREE_SIDE_EFFECTS (node1) || TREE_SIDE_EFFECTS (node2)
9987 || (node3 != NULL_TREE && TREE_SIDE_EFFECTS (node3)))
9988 TREE_SIDE_EFFECTS (item) = 1;
9989 return fold (item);
9990}
5ff904cd 9991
c7e4ee3a
CB
9992/* Essentially does a "fold (build (code, type, node1, node2, node3))" while
9993 checking for certain housekeeping things. Always sets
9994 TREE_SIDE_EFFECTS. */
5ff904cd 9995
c7e4ee3a
CB
9996tree
9997ffecom_3s (enum tree_code code, tree type, tree node1,
9998 tree node2, tree node3)
9999{
10000 tree item;
5ff904cd 10001
c7e4ee3a
CB
10002 if ((node1 == error_mark_node)
10003 || (node2 == error_mark_node)
10004 || (node3 == error_mark_node)
10005 || (type == error_mark_node))
10006 return error_mark_node;
5ff904cd 10007
c7e4ee3a
CB
10008 item = build (code, type, node1, node2, node3);
10009 TREE_SIDE_EFFECTS (item) = 1;
10010 return fold (item);
10011}
5ff904cd 10012
c7e4ee3a 10013/* ffecom_arg_expr -- Transform argument expr into gcc tree
5ff904cd 10014
c7e4ee3a 10015 See use by ffecom_list_expr.
5ff904cd 10016
c7e4ee3a
CB
10017 If expression is NULL, returns an integer zero tree. If it is not
10018 a CHARACTER expression, returns whatever ffecom_expr
10019 returns and sets the length return value to NULL_TREE. Otherwise
10020 generates code to evaluate the character expression, returns the proper
10021 pointer to the result, but does NOT set the length return value to a tree
10022 that specifies the length of the result. (In other words, the length
10023 variable is always set to NULL_TREE, because a length is never passed.)
5ff904cd 10024
c7e4ee3a
CB
10025 21-Dec-91 JCB 1.1
10026 Don't set returned length, since nobody needs it (yet; someday if
10027 we allow CHARACTER*(*) dummies to statement functions, we'll need
10028 it). */
5ff904cd 10029
c7e4ee3a
CB
10030tree
10031ffecom_arg_expr (ffebld expr, tree *length)
10032{
10033 tree ign;
5ff904cd 10034
c7e4ee3a 10035 *length = NULL_TREE;
5ff904cd 10036
c7e4ee3a
CB
10037 if (expr == NULL)
10038 return integer_zero_node;
5ff904cd 10039
c7e4ee3a
CB
10040 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10041 return ffecom_expr (expr);
5ff904cd 10042
c7e4ee3a
CB
10043 return ffecom_arg_ptr_to_expr (expr, &ign);
10044}
10045
c7e4ee3a
CB
10046/* Transform expression into constant argument-pointer-to-expression tree.
10047
10048 If the expression can be transformed into a argument-pointer-to-expression
10049 tree that is constant, that is done, and the tree returned. Else
10050 NULL_TREE is returned.
5ff904cd 10051
c7e4ee3a
CB
10052 That way, a caller can attempt to provide compile-time initialization
10053 of a variable and, if that fails, *then* choose to start a new block
10054 and resort to using temporaries, as appropriate. */
5ff904cd 10055
c7e4ee3a
CB
10056tree
10057ffecom_arg_ptr_to_const_expr (ffebld expr, tree *length)
10058{
10059 if (! expr)
10060 return integer_zero_node;
5ff904cd 10061
c7e4ee3a
CB
10062 if (ffebld_op (expr) == FFEBLD_opANY)
10063 {
10064 if (length)
10065 *length = error_mark_node;
10066 return error_mark_node;
10067 }
10068
10069 if (ffebld_arity (expr) == 0
10070 && (ffebld_op (expr) != FFEBLD_opSYMTER
10071 || ffebld_where (expr) == FFEINFO_whereCOMMON
10072 || ffebld_where (expr) == FFEINFO_whereGLOBAL
10073 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
10074 {
10075 tree t;
10076
10077 t = ffecom_arg_ptr_to_expr (expr, length);
10078 assert (TREE_CONSTANT (t));
10079 assert (! length || TREE_CONSTANT (*length));
10080 return t;
10081 }
10082
10083 if (length
10084 && ffebld_size (expr) != FFETARGET_charactersizeNONE)
10085 *length = build_int_2 (ffebld_size (expr), 0);
10086 else if (length)
10087 *length = NULL_TREE;
10088 return NULL_TREE;
5ff904cd
JL
10089}
10090
c7e4ee3a 10091/* ffecom_arg_ptr_to_expr -- Transform argument expr into gcc tree
5ff904cd 10092
c7e4ee3a
CB
10093 See use by ffecom_list_ptr_to_expr.
10094
10095 If expression is NULL, returns an integer zero tree. If it is not
10096 a CHARACTER expression, returns whatever ffecom_ptr_to_expr
10097 returns and sets the length return value to NULL_TREE. Otherwise
10098 generates code to evaluate the character expression, returns the proper
10099 pointer to the result, AND sets the length return value to a tree that
10100 specifies the length of the result.
10101
10102 If the length argument is NULL, this is a slightly special
10103 case of building a FORMAT expression, that is, an expression that
10104 will be used at run time without regard to length. For the current
10105 implementation, which uses the libf2c library, this means it is nice
10106 to append a null byte to the end of the expression, where feasible,
10107 to make sure any diagnostic about the FORMAT string terminates at
10108 some useful point.
10109
10110 For now, treat %REF(char-expr) as the same as char-expr with a NULL
10111 length argument. This might even be seen as a feature, if a null
10112 byte can always be appended. */
5ff904cd 10113
5ff904cd 10114tree
c7e4ee3a 10115ffecom_arg_ptr_to_expr (ffebld expr, tree *length)
5ff904cd
JL
10116{
10117 tree item;
c7e4ee3a
CB
10118 tree ign_length;
10119 ffecomConcatList_ catlist;
5ff904cd 10120
c7e4ee3a
CB
10121 if (length != NULL)
10122 *length = NULL_TREE;
5ff904cd 10123
c7e4ee3a
CB
10124 if (expr == NULL)
10125 return integer_zero_node;
5ff904cd 10126
c7e4ee3a 10127 switch (ffebld_op (expr))
5ff904cd 10128 {
c7e4ee3a
CB
10129 case FFEBLD_opPERCENT_VAL:
10130 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10131 return ffecom_expr (ffebld_left (expr));
10132 {
10133 tree temp_exp;
10134 tree temp_length;
5ff904cd 10135
c7e4ee3a
CB
10136 temp_exp = ffecom_arg_ptr_to_expr (ffebld_left (expr), &temp_length);
10137 if (temp_exp == error_mark_node)
10138 return error_mark_node;
5ff904cd 10139
c7e4ee3a
CB
10140 return ffecom_1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (temp_exp)),
10141 temp_exp);
10142 }
5ff904cd 10143
c7e4ee3a
CB
10144 case FFEBLD_opPERCENT_REF:
10145 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10146 return ffecom_ptr_to_expr (ffebld_left (expr));
10147 if (length != NULL)
10148 {
10149 ign_length = NULL_TREE;
10150 length = &ign_length;
10151 }
10152 expr = ffebld_left (expr);
10153 break;
5ff904cd 10154
c7e4ee3a
CB
10155 case FFEBLD_opPERCENT_DESCR:
10156 switch (ffeinfo_basictype (ffebld_info (expr)))
5ff904cd 10157 {
c7e4ee3a
CB
10158#ifdef PASS_HOLLERITH_BY_DESCRIPTOR
10159 case FFEINFO_basictypeHOLLERITH:
10160#endif
10161 case FFEINFO_basictypeCHARACTER:
10162 break; /* Passed by descriptor anyway. */
10163
10164 default:
10165 item = ffecom_ptr_to_expr (expr);
10166 if (item != error_mark_node)
10167 *length = TYPE_SIZE (TREE_TYPE (TREE_TYPE (item)));
5ff904cd
JL
10168 break;
10169 }
5ff904cd
JL
10170 break;
10171
10172 default:
5ff904cd
JL
10173 break;
10174 }
10175
c7e4ee3a
CB
10176#ifdef PASS_HOLLERITH_BY_DESCRIPTOR
10177 if ((ffeinfo_basictype (ffebld_info (expr)) == FFEINFO_basictypeHOLLERITH)
10178 && (length != NULL))
10179 { /* Pass Hollerith by descriptor. */
10180 ffetargetHollerith h;
10181
10182 assert (ffebld_op (expr) == FFEBLD_opCONTER);
10183 h = ffebld_cu_val_hollerith (ffebld_constant_union
10184 (ffebld_conter (expr)));
10185 *length
10186 = build_int_2 (h.length, 0);
10187 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
10188 }
10189#endif
10190
10191 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10192 return ffecom_ptr_to_expr (expr);
10193
10194 assert (ffeinfo_kindtype (ffebld_info (expr))
10195 == FFEINFO_kindtypeCHARACTER1);
10196
47d98fa2
CB
10197 while (ffebld_op (expr) == FFEBLD_opPAREN)
10198 expr = ffebld_left (expr);
10199
c7e4ee3a
CB
10200 catlist = ffecom_concat_list_new_ (expr, FFETARGET_charactersizeNONE);
10201 switch (ffecom_concat_list_count_ (catlist))
10202 {
10203 case 0: /* Shouldn't happen, but in case it does... */
10204 if (length != NULL)
10205 {
10206 *length = ffecom_f2c_ftnlen_zero_node;
10207 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
10208 }
10209 ffecom_concat_list_kill_ (catlist);
10210 return null_pointer_node;
10211
10212 case 1: /* The (fairly) easy case. */
10213 if (length == NULL)
10214 ffecom_char_args_with_null_ (&item, &ign_length,
10215 ffecom_concat_list_expr_ (catlist, 0));
10216 else
10217 ffecom_char_args_ (&item, length,
10218 ffecom_concat_list_expr_ (catlist, 0));
10219 ffecom_concat_list_kill_ (catlist);
10220 assert (item != NULL_TREE);
10221 return item;
10222
10223 default: /* Must actually concatenate things. */
10224 break;
10225 }
10226
10227 {
10228 int count = ffecom_concat_list_count_ (catlist);
10229 int i;
10230 tree lengths;
10231 tree items;
10232 tree length_array;
10233 tree item_array;
10234 tree citem;
10235 tree clength;
10236 tree temporary;
10237 tree num;
10238 tree known_length;
10239 ffetargetCharacterSize sz;
10240
10241 sz = ffecom_concat_list_maxlen_ (catlist);
10242 /* ~~Kludge! */
10243 assert (sz != FFETARGET_charactersizeNONE);
10244
10245#ifdef HOHO
10246 length_array
10247 = lengths
10248 = ffecom_push_tempvar (ffecom_f2c_ftnlen_type_node,
10249 FFETARGET_charactersizeNONE, count, TRUE);
10250 item_array
10251 = items
10252 = ffecom_push_tempvar (ffecom_f2c_address_type_node,
10253 FFETARGET_charactersizeNONE, count, TRUE);
10254 temporary = ffecom_push_tempvar (char_type_node,
10255 sz, -1, TRUE);
10256#else
10257 {
10258 tree hook;
10259
10260 hook = ffebld_nonter_hook (expr);
10261 assert (hook);
10262 assert (TREE_CODE (hook) == TREE_VEC);
10263 assert (TREE_VEC_LENGTH (hook) == 3);
10264 length_array = lengths = TREE_VEC_ELT (hook, 0);
10265 item_array = items = TREE_VEC_ELT (hook, 1);
10266 temporary = TREE_VEC_ELT (hook, 2);
10267 }
10268#endif
10269
10270 known_length = ffecom_f2c_ftnlen_zero_node;
10271
10272 for (i = 0; i < count; ++i)
10273 {
10274 if ((i == count)
10275 && (length == NULL))
10276 ffecom_char_args_with_null_ (&citem, &clength,
10277 ffecom_concat_list_expr_ (catlist, i));
10278 else
10279 ffecom_char_args_ (&citem, &clength,
10280 ffecom_concat_list_expr_ (catlist, i));
10281 if ((citem == error_mark_node)
10282 || (clength == error_mark_node))
10283 {
10284 ffecom_concat_list_kill_ (catlist);
10285 *length = error_mark_node;
10286 return error_mark_node;
10287 }
10288
10289 items
10290 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (items),
10291 ffecom_modify (void_type_node,
10292 ffecom_2 (ARRAY_REF,
10293 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array))),
10294 item_array,
10295 build_int_2 (i, 0)),
10296 citem),
10297 items);
10298 clength = ffecom_save_tree (clength);
10299 if (length != NULL)
10300 known_length
10301 = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
10302 known_length,
10303 clength);
10304 lengths
10305 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (lengths),
10306 ffecom_modify (void_type_node,
10307 ffecom_2 (ARRAY_REF,
10308 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array))),
10309 length_array,
10310 build_int_2 (i, 0)),
10311 clength),
10312 lengths);
10313 }
10314
10315 temporary = ffecom_1 (ADDR_EXPR,
10316 build_pointer_type (TREE_TYPE (temporary)),
10317 temporary);
10318
10319 item = build_tree_list (NULL_TREE, temporary);
10320 TREE_CHAIN (item)
10321 = build_tree_list (NULL_TREE,
10322 ffecom_1 (ADDR_EXPR,
10323 build_pointer_type (TREE_TYPE (items)),
10324 items));
10325 TREE_CHAIN (TREE_CHAIN (item))
10326 = build_tree_list (NULL_TREE,
10327 ffecom_1 (ADDR_EXPR,
10328 build_pointer_type (TREE_TYPE (lengths)),
10329 lengths));
10330 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item)))
10331 = build_tree_list
10332 (NULL_TREE,
10333 ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
10334 convert (ffecom_f2c_ftnlen_type_node,
10335 build_int_2 (count, 0))));
10336 num = build_int_2 (sz, 0);
10337 TREE_TYPE (num) = ffecom_f2c_ftnlen_type_node;
10338 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item))))
10339 = build_tree_list (NULL_TREE, num);
10340
10341 item = ffecom_call_gfrt (FFECOM_gfrtCAT, item, NULL_TREE);
5ff904cd 10342 TREE_SIDE_EFFECTS (item) = 1;
c7e4ee3a
CB
10343 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (temporary),
10344 item,
10345 temporary);
10346
10347 if (length != NULL)
10348 *length = known_length;
10349 }
10350
10351 ffecom_concat_list_kill_ (catlist);
10352 assert (item != NULL_TREE);
10353 return item;
5ff904cd 10354}
c7e4ee3a 10355
c7e4ee3a 10356/* Generate call to run-time function.
5ff904cd 10357
c7e4ee3a
CB
10358 The first arg is the GNU Fortran Run-Time function index, the second
10359 arg is the list of arguments to pass to it. Returned is the expression
10360 (WITHOUT TREE_SIDE_EFFECTS set!) that makes the call and returns the
10361 result (which may be void). */
5ff904cd 10362
5ff904cd 10363tree
c7e4ee3a 10364ffecom_call_gfrt (ffecomGfrt ix, tree args, tree hook)
5ff904cd 10365{
c7e4ee3a
CB
10366 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
10367 ffecom_gfrt_kindtype (ix),
10368 ffe_is_f2c_library () && ffecom_gfrt_complex_[ix],
10369 NULL_TREE, args, NULL_TREE, NULL,
10370 NULL, NULL_TREE, TRUE, hook);
5ff904cd 10371}
5ff904cd 10372
c7e4ee3a 10373/* Transform constant-union to tree. */
5ff904cd 10374
5ff904cd 10375tree
c7e4ee3a
CB
10376ffecom_constantunion (ffebldConstantUnion *cu, ffeinfoBasictype bt,
10377 ffeinfoKindtype kt, tree tree_type)
5ff904cd
JL
10378{
10379 tree item;
10380
c7e4ee3a 10381 switch (bt)
5ff904cd 10382 {
c7e4ee3a
CB
10383 case FFEINFO_basictypeINTEGER:
10384 {
10385 int val;
5ff904cd 10386
c7e4ee3a
CB
10387 switch (kt)
10388 {
10389#if FFETARGET_okINTEGER1
10390 case FFEINFO_kindtypeINTEGER1:
10391 val = ffebld_cu_val_integer1 (*cu);
10392 break;
10393#endif
5ff904cd 10394
c7e4ee3a
CB
10395#if FFETARGET_okINTEGER2
10396 case FFEINFO_kindtypeINTEGER2:
10397 val = ffebld_cu_val_integer2 (*cu);
10398 break;
10399#endif
5ff904cd 10400
c7e4ee3a
CB
10401#if FFETARGET_okINTEGER3
10402 case FFEINFO_kindtypeINTEGER3:
10403 val = ffebld_cu_val_integer3 (*cu);
10404 break;
10405#endif
5ff904cd 10406
c7e4ee3a
CB
10407#if FFETARGET_okINTEGER4
10408 case FFEINFO_kindtypeINTEGER4:
10409 val = ffebld_cu_val_integer4 (*cu);
10410 break;
10411#endif
5ff904cd 10412
c7e4ee3a
CB
10413 default:
10414 assert ("bad INTEGER constant kind type" == NULL);
10415 /* Fall through. */
10416 case FFEINFO_kindtypeANY:
10417 return error_mark_node;
10418 }
10419 item = build_int_2 (val, (val < 0) ? -1 : 0);
10420 TREE_TYPE (item) = tree_type;
10421 }
5ff904cd 10422 break;
5ff904cd 10423
c7e4ee3a
CB
10424 case FFEINFO_basictypeLOGICAL:
10425 {
10426 int val;
5ff904cd 10427
c7e4ee3a
CB
10428 switch (kt)
10429 {
10430#if FFETARGET_okLOGICAL1
10431 case FFEINFO_kindtypeLOGICAL1:
10432 val = ffebld_cu_val_logical1 (*cu);
10433 break;
5ff904cd 10434#endif
5ff904cd 10435
c7e4ee3a
CB
10436#if FFETARGET_okLOGICAL2
10437 case FFEINFO_kindtypeLOGICAL2:
10438 val = ffebld_cu_val_logical2 (*cu);
10439 break;
10440#endif
5ff904cd 10441
c7e4ee3a
CB
10442#if FFETARGET_okLOGICAL3
10443 case FFEINFO_kindtypeLOGICAL3:
10444 val = ffebld_cu_val_logical3 (*cu);
10445 break;
10446#endif
5ff904cd 10447
c7e4ee3a
CB
10448#if FFETARGET_okLOGICAL4
10449 case FFEINFO_kindtypeLOGICAL4:
10450 val = ffebld_cu_val_logical4 (*cu);
10451 break;
10452#endif
5ff904cd 10453
c7e4ee3a
CB
10454 default:
10455 assert ("bad LOGICAL constant kind type" == NULL);
10456 /* Fall through. */
10457 case FFEINFO_kindtypeANY:
10458 return error_mark_node;
10459 }
10460 item = build_int_2 (val, (val < 0) ? -1 : 0);
10461 TREE_TYPE (item) = tree_type;
10462 }
10463 break;
5ff904cd 10464
c7e4ee3a
CB
10465 case FFEINFO_basictypeREAL:
10466 {
10467 REAL_VALUE_TYPE val;
5ff904cd 10468
c7e4ee3a
CB
10469 switch (kt)
10470 {
10471#if FFETARGET_okREAL1
10472 case FFEINFO_kindtypeREAL1:
10473 val = ffetarget_value_real1 (ffebld_cu_val_real1 (*cu));
10474 break;
10475#endif
5ff904cd 10476
c7e4ee3a
CB
10477#if FFETARGET_okREAL2
10478 case FFEINFO_kindtypeREAL2:
10479 val = ffetarget_value_real2 (ffebld_cu_val_real2 (*cu));
10480 break;
10481#endif
5ff904cd 10482
c7e4ee3a
CB
10483#if FFETARGET_okREAL3
10484 case FFEINFO_kindtypeREAL3:
10485 val = ffetarget_value_real3 (ffebld_cu_val_real3 (*cu));
10486 break;
10487#endif
5ff904cd 10488
c7e4ee3a
CB
10489#if FFETARGET_okREAL4
10490 case FFEINFO_kindtypeREAL4:
10491 val = ffetarget_value_real4 (ffebld_cu_val_real4 (*cu));
10492 break;
10493#endif
5ff904cd 10494
c7e4ee3a
CB
10495 default:
10496 assert ("bad REAL constant kind type" == NULL);
10497 /* Fall through. */
10498 case FFEINFO_kindtypeANY:
10499 return error_mark_node;
10500 }
10501 item = build_real (tree_type, val);
10502 }
5ff904cd
JL
10503 break;
10504
c7e4ee3a
CB
10505 case FFEINFO_basictypeCOMPLEX:
10506 {
10507 REAL_VALUE_TYPE real;
10508 REAL_VALUE_TYPE imag;
10509 tree el_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
5ff904cd 10510
c7e4ee3a
CB
10511 switch (kt)
10512 {
10513#if FFETARGET_okCOMPLEX1
10514 case FFEINFO_kindtypeREAL1:
10515 real = ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu).real);
10516 imag = ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu).imaginary);
10517 break;
10518#endif
5ff904cd 10519
c7e4ee3a
CB
10520#if FFETARGET_okCOMPLEX2
10521 case FFEINFO_kindtypeREAL2:
10522 real = ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu).real);
10523 imag = ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu).imaginary);
10524 break;
10525#endif
5ff904cd 10526
c7e4ee3a
CB
10527#if FFETARGET_okCOMPLEX3
10528 case FFEINFO_kindtypeREAL3:
10529 real = ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu).real);
10530 imag = ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu).imaginary);
10531 break;
10532#endif
5ff904cd 10533
c7e4ee3a
CB
10534#if FFETARGET_okCOMPLEX4
10535 case FFEINFO_kindtypeREAL4:
10536 real = ffetarget_value_real4 (ffebld_cu_val_complex4 (*cu).real);
10537 imag = ffetarget_value_real4 (ffebld_cu_val_complex4 (*cu).imaginary);
10538 break;
10539#endif
5ff904cd 10540
c7e4ee3a
CB
10541 default:
10542 assert ("bad REAL constant kind type" == NULL);
10543 /* Fall through. */
10544 case FFEINFO_kindtypeANY:
10545 return error_mark_node;
10546 }
10547 item = ffecom_build_complex_constant_ (tree_type,
10548 build_real (el_type, real),
10549 build_real (el_type, imag));
10550 }
10551 break;
5ff904cd 10552
c7e4ee3a
CB
10553 case FFEINFO_basictypeCHARACTER:
10554 { /* Happens only in DATA and similar contexts. */
10555 ffetargetCharacter1 val;
5ff904cd 10556
c7e4ee3a
CB
10557 switch (kt)
10558 {
10559#if FFETARGET_okCHARACTER1
10560 case FFEINFO_kindtypeLOGICAL1:
10561 val = ffebld_cu_val_character1 (*cu);
10562 break;
10563#endif
10564
10565 default:
10566 assert ("bad CHARACTER constant kind type" == NULL);
10567 /* Fall through. */
10568 case FFEINFO_kindtypeANY:
10569 return error_mark_node;
10570 }
10571 item = build_string (ffetarget_length_character1 (val),
10572 ffetarget_text_character1 (val));
10573 TREE_TYPE (item)
10574 = build_type_variant (build_array_type (char_type_node,
10575 build_range_type
10576 (integer_type_node,
10577 integer_one_node,
10578 build_int_2
10579 (ffetarget_length_character1
10580 (val), 0))),
10581 1, 0);
10582 }
10583 break;
5ff904cd 10584
c7e4ee3a
CB
10585 case FFEINFO_basictypeHOLLERITH:
10586 {
10587 ffetargetHollerith h;
5ff904cd 10588
c7e4ee3a 10589 h = ffebld_cu_val_hollerith (*cu);
5ff904cd 10590
c7e4ee3a
CB
10591 /* If not at least as wide as default INTEGER, widen it. */
10592 if (h.length >= FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE)
10593 item = build_string (h.length, h.text);
10594 else
10595 {
10596 char str[FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE];
5ff904cd 10597
c7e4ee3a
CB
10598 memcpy (str, h.text, h.length);
10599 memset (&str[h.length], ' ',
10600 FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE
10601 - h.length);
10602 item = build_string (FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE,
10603 str);
10604 }
10605 TREE_TYPE (item)
10606 = build_type_variant (build_array_type (char_type_node,
10607 build_range_type
10608 (integer_type_node,
10609 integer_one_node,
10610 build_int_2
10611 (h.length, 0))),
10612 1, 0);
10613 }
10614 break;
5ff904cd 10615
c7e4ee3a
CB
10616 case FFEINFO_basictypeTYPELESS:
10617 {
10618 ffetargetInteger1 ival;
10619 ffetargetTypeless tless;
10620 ffebad error;
5ff904cd 10621
c7e4ee3a
CB
10622 tless = ffebld_cu_val_typeless (*cu);
10623 error = ffetarget_convert_integer1_typeless (&ival, tless);
10624 assert (error == FFEBAD);
5ff904cd 10625
c7e4ee3a
CB
10626 item = build_int_2 ((int) ival, 0);
10627 }
10628 break;
5ff904cd 10629
c7e4ee3a
CB
10630 default:
10631 assert ("not yet on constant type" == NULL);
10632 /* Fall through. */
10633 case FFEINFO_basictypeANY:
10634 return error_mark_node;
5ff904cd 10635 }
5ff904cd 10636
c7e4ee3a 10637 TREE_CONSTANT (item) = 1;
5ff904cd 10638
c7e4ee3a 10639 return item;
5ff904cd
JL
10640}
10641
c7e4ee3a
CB
10642/* Transform expression into constant tree.
10643
10644 If the expression can be transformed into a tree that is constant,
10645 that is done, and the tree returned. Else NULL_TREE is returned.
10646
10647 That way, a caller can attempt to provide compile-time initialization
10648 of a variable and, if that fails, *then* choose to start a new block
10649 and resort to using temporaries, as appropriate. */
5ff904cd 10650
5ff904cd 10651tree
c7e4ee3a 10652ffecom_const_expr (ffebld expr)
5ff904cd 10653{
c7e4ee3a
CB
10654 if (! expr)
10655 return integer_zero_node;
5ff904cd 10656
c7e4ee3a 10657 if (ffebld_op (expr) == FFEBLD_opANY)
5ff904cd
JL
10658 return error_mark_node;
10659
c7e4ee3a
CB
10660 if (ffebld_arity (expr) == 0
10661 && (ffebld_op (expr) != FFEBLD_opSYMTER
10662#if NEWCOMMON
10663 /* ~~Enable once common/equivalence is handled properly? */
10664 || ffebld_where (expr) == FFEINFO_whereCOMMON
5ff904cd 10665#endif
c7e4ee3a
CB
10666 || ffebld_where (expr) == FFEINFO_whereGLOBAL
10667 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
10668 {
10669 tree t;
5ff904cd 10670
c7e4ee3a
CB
10671 t = ffecom_expr (expr);
10672 assert (TREE_CONSTANT (t));
10673 return t;
10674 }
5ff904cd 10675
c7e4ee3a 10676 return NULL_TREE;
5ff904cd
JL
10677}
10678
c7e4ee3a 10679/* Handy way to make a field in a struct/union. */
5ff904cd 10680
5ff904cd 10681tree
c7e4ee3a
CB
10682ffecom_decl_field (tree context, tree prevfield,
10683 const char *name, tree type)
5ff904cd 10684{
c7e4ee3a 10685 tree field;
5ff904cd 10686
c7e4ee3a
CB
10687 field = build_decl (FIELD_DECL, get_identifier (name), type);
10688 DECL_CONTEXT (field) = context;
8ba77681 10689 DECL_ALIGN (field) = 0;
11cf4d18 10690 DECL_USER_ALIGN (field) = 0;
c7e4ee3a
CB
10691 if (prevfield != NULL_TREE)
10692 TREE_CHAIN (prevfield) = field;
5ff904cd 10693
c7e4ee3a 10694 return field;
5ff904cd
JL
10695}
10696
c7e4ee3a
CB
10697void
10698ffecom_close_include (FILE *f)
10699{
c7e4ee3a 10700 ffecom_close_include_ (f);
c7e4ee3a 10701}
5ff904cd 10702
c7e4ee3a
CB
10703int
10704ffecom_decode_include_option (char *spec)
10705{
c7e4ee3a 10706 return ffecom_decode_include_option_ (spec);
c7e4ee3a 10707}
5ff904cd 10708
c7e4ee3a 10709/* End a compound statement (block). */
5ff904cd 10710
5ff904cd 10711tree
c7e4ee3a 10712ffecom_end_compstmt (void)
5ff904cd 10713{
c7e4ee3a
CB
10714 return bison_rule_compstmt_ ();
10715}
5ff904cd 10716
c7e4ee3a 10717/* ffecom_end_transition -- Perform end transition on all symbols
5ff904cd 10718
c7e4ee3a 10719 ffecom_end_transition();
5ff904cd 10720
c7e4ee3a 10721 Calls ffecom_sym_end_transition for each global and local symbol. */
5ff904cd 10722
c7e4ee3a
CB
10723void
10724ffecom_end_transition ()
10725{
c7e4ee3a 10726 ffebld item;
5ff904cd 10727
c7e4ee3a
CB
10728 if (ffe_is_ffedebug ())
10729 fprintf (dmpout, "; end_stmt_transition\n");
86fc7a6c 10730
c7e4ee3a
CB
10731 ffecom_list_blockdata_ = NULL;
10732 ffecom_list_common_ = NULL;
86fc7a6c 10733
c7e4ee3a
CB
10734 ffesymbol_drive (ffecom_sym_end_transition);
10735 if (ffe_is_ffedebug ())
10736 {
10737 ffestorag_report ();
c7e4ee3a 10738 }
5ff904cd 10739
c7e4ee3a
CB
10740 ffecom_start_progunit_ ();
10741
10742 for (item = ffecom_list_blockdata_;
10743 item != NULL;
10744 item = ffebld_trail (item))
10745 {
10746 ffebld callee;
10747 ffesymbol s;
10748 tree dt;
10749 tree t;
10750 tree var;
c7e4ee3a
CB
10751 static int number = 0;
10752
10753 callee = ffebld_head (item);
10754 s = ffebld_symter (callee);
10755 t = ffesymbol_hook (s).decl_tree;
10756 if (t == NULL_TREE)
10757 {
10758 s = ffecom_sym_transform_ (s);
10759 t = ffesymbol_hook (s).decl_tree;
10760 }
5ff904cd 10761
c7e4ee3a 10762 dt = build_pointer_type (TREE_TYPE (t));
5ff904cd 10763
c7e4ee3a
CB
10764 var = build_decl (VAR_DECL,
10765 ffecom_get_invented_identifier ("__g77_forceload_%d",
14657de8 10766 number++),
c7e4ee3a
CB
10767 dt);
10768 DECL_EXTERNAL (var) = 0;
10769 TREE_STATIC (var) = 1;
10770 TREE_PUBLIC (var) = 0;
10771 DECL_INITIAL (var) = error_mark_node;
10772 TREE_USED (var) = 1;
5ff904cd 10773
c7e4ee3a 10774 var = start_decl (var, FALSE);
702edf1d 10775
c7e4ee3a 10776 t = ffecom_1 (ADDR_EXPR, dt, t);
5ff904cd 10777
c7e4ee3a 10778 finish_decl (var, t, FALSE);
c7e4ee3a
CB
10779 }
10780
10781 /* This handles any COMMON areas that weren't referenced but have, for
10782 example, important initial data. */
10783
10784 for (item = ffecom_list_common_;
10785 item != NULL;
10786 item = ffebld_trail (item))
10787 ffecom_transform_common_ (ffebld_symter (ffebld_head (item)));
10788
10789 ffecom_list_common_ = NULL;
c7e4ee3a 10790}
5ff904cd 10791
c7e4ee3a 10792/* ffecom_exec_transition -- Perform exec transition on all symbols
5ff904cd 10793
c7e4ee3a 10794 ffecom_exec_transition();
5ff904cd 10795
c7e4ee3a
CB
10796 Calls ffecom_sym_exec_transition for each global and local symbol.
10797 Make sure error updating not inhibited. */
5ff904cd 10798
c7e4ee3a
CB
10799void
10800ffecom_exec_transition ()
10801{
10802 bool inhibited;
5ff904cd 10803
c7e4ee3a
CB
10804 if (ffe_is_ffedebug ())
10805 fprintf (dmpout, "; exec_stmt_transition\n");
5ff904cd 10806
c7e4ee3a
CB
10807 inhibited = ffebad_inhibit ();
10808 ffebad_set_inhibit (FALSE);
5ff904cd 10809
c7e4ee3a
CB
10810 ffesymbol_drive (ffecom_sym_exec_transition); /* Don't retract! */
10811 ffeequiv_exec_transition (); /* Handle all pending EQUIVALENCEs. */
10812 if (ffe_is_ffedebug ())
5ff904cd 10813 {
c7e4ee3a 10814 ffestorag_report ();
c7e4ee3a 10815 }
5ff904cd 10816
c7e4ee3a
CB
10817 if (inhibited)
10818 ffebad_set_inhibit (TRUE);
10819}
5ff904cd 10820
c7e4ee3a 10821/* Handle assignment statement.
5ff904cd 10822
c7e4ee3a
CB
10823 Convert dest and source using ffecom_expr, then join them
10824 with an ASSIGN op and pass the whole thing to expand_expr_stmt. */
5ff904cd 10825
c7e4ee3a
CB
10826void
10827ffecom_expand_let_stmt (ffebld dest, ffebld source)
10828{
10829 tree dest_tree;
10830 tree dest_length;
10831 tree source_tree;
10832 tree expr_tree;
5ff904cd 10833
c7e4ee3a
CB
10834 if (ffeinfo_basictype (ffebld_info (dest)) != FFEINFO_basictypeCHARACTER)
10835 {
10836 bool dest_used;
d6cd84e0 10837 tree assign_temp;
5ff904cd 10838
c7e4ee3a
CB
10839 /* This attempts to replicate the test below, but must not be
10840 true when the test below is false. (Always err on the side
10841 of creating unused temporaries, to avoid ICEs.) */
10842 if (ffebld_op (dest) != FFEBLD_opSYMTER
10843 || ((dest_tree = ffesymbol_hook (ffebld_symter (dest)).decl_tree)
10844 && (TREE_CODE (dest_tree) != VAR_DECL
10845 || TREE_ADDRESSABLE (dest_tree))))
10846 {
10847 ffecom_prepare_expr_ (source, dest);
10848 dest_used = TRUE;
10849 }
10850 else
10851 {
10852 ffecom_prepare_expr_ (source, NULL);
10853 dest_used = FALSE;
10854 }
5ff904cd 10855
c7e4ee3a 10856 ffecom_prepare_expr_w (NULL_TREE, dest);
5ff904cd 10857
d6cd84e0
CB
10858 /* For COMPLEX assignment like C1=C2, if partial overlap is possible,
10859 create a temporary through which the assignment is to take place,
10860 since MODIFY_EXPR doesn't handle partial overlap properly. */
10861 if (ffebld_basictype (dest) == FFEINFO_basictypeCOMPLEX
10862 && ffecom_possible_partial_overlap_ (dest, source))
10863 {
10864 assign_temp = ffecom_make_tempvar ("complex_let",
10865 ffecom_tree_type
10866 [ffebld_basictype (dest)]
10867 [ffebld_kindtype (dest)],
10868 FFETARGET_charactersizeNONE,
10869 -1);
10870 }
10871 else
10872 assign_temp = NULL_TREE;
10873
c7e4ee3a 10874 ffecom_prepare_end ();
5ff904cd 10875
c7e4ee3a
CB
10876 dest_tree = ffecom_expr_w (NULL_TREE, dest);
10877 if (dest_tree == error_mark_node)
10878 return;
5ff904cd 10879
c7e4ee3a
CB
10880 if ((TREE_CODE (dest_tree) != VAR_DECL)
10881 || TREE_ADDRESSABLE (dest_tree))
10882 source_tree = ffecom_expr_ (source, dest_tree, dest, &dest_used,
10883 FALSE, FALSE);
10884 else
10885 {
10886 assert (! dest_used);
10887 dest_used = FALSE;
10888 source_tree = ffecom_expr (source);
10889 }
10890 if (source_tree == error_mark_node)
10891 return;
5ff904cd 10892
c7e4ee3a
CB
10893 if (dest_used)
10894 expr_tree = source_tree;
d6cd84e0
CB
10895 else if (assign_temp)
10896 {
10897#ifdef MOVE_EXPR
10898 /* The back end understands a conceptual move (evaluate source;
10899 store into dest), so use that, in case it can determine
10900 that it is going to use, say, two registers as temporaries
10901 anyway. So don't use the temp (and someday avoid generating
10902 it, once this code starts triggering regularly). */
10903 expr_tree = ffecom_2s (MOVE_EXPR, void_type_node,
10904 dest_tree,
10905 source_tree);
10906#else
10907 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
10908 assign_temp,
10909 source_tree);
10910 expand_expr_stmt (expr_tree);
10911 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
10912 dest_tree,
10913 assign_temp);
10914#endif
10915 }
c7e4ee3a
CB
10916 else
10917 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
10918 dest_tree,
10919 source_tree);
5ff904cd 10920
c7e4ee3a
CB
10921 expand_expr_stmt (expr_tree);
10922 return;
10923 }
5ff904cd 10924
c7e4ee3a
CB
10925 ffecom_prepare_let_char_ (ffebld_size_known (dest), source);
10926 ffecom_prepare_expr_w (NULL_TREE, dest);
10927
10928 ffecom_prepare_end ();
10929
10930 ffecom_char_args_ (&dest_tree, &dest_length, dest);
10931 ffecom_let_char_ (dest_tree, dest_length, ffebld_size_known (dest),
10932 source);
5ff904cd
JL
10933}
10934
c7e4ee3a 10935/* ffecom_expr -- Transform expr into gcc tree
5ff904cd 10936
c7e4ee3a
CB
10937 tree t;
10938 ffebld expr; // FFE expression.
10939 tree = ffecom_expr(expr);
5ff904cd 10940
c7e4ee3a
CB
10941 Recursive descent on expr while making corresponding tree nodes and
10942 attaching type info and such. */
5ff904cd 10943
5ff904cd 10944tree
c7e4ee3a 10945ffecom_expr (ffebld expr)
5ff904cd 10946{
c7e4ee3a 10947 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, FALSE, FALSE);
5ff904cd 10948}
c7e4ee3a 10949
c7e4ee3a 10950/* Like ffecom_expr, but return tree usable for assigned GOTO or FORMAT. */
5ff904cd 10951
c7e4ee3a
CB
10952tree
10953ffecom_expr_assign (ffebld expr)
10954{
10955 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, TRUE, FALSE);
10956}
5ff904cd 10957
c7e4ee3a 10958/* Like ffecom_expr_rw, but return tree usable for ASSIGN. */
5ff904cd 10959
5ff904cd 10960tree
c7e4ee3a 10961ffecom_expr_assign_w (ffebld expr)
5ff904cd 10962{
c7e4ee3a
CB
10963 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, TRUE, FALSE);
10964}
5ff904cd 10965
c7e4ee3a
CB
10966/* Transform expr for use as into read/write tree and stabilize the
10967 reference. Not for use on CHARACTER expressions.
5ff904cd 10968
c7e4ee3a
CB
10969 Recursive descent on expr while making corresponding tree nodes and
10970 attaching type info and such. */
5ff904cd 10971
c7e4ee3a
CB
10972tree
10973ffecom_expr_rw (tree type, ffebld expr)
10974{
10975 assert (expr != NULL);
10976 /* Different target types not yet supported. */
10977 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
10978
10979 return stabilize_reference (ffecom_expr (expr));
10980}
5ff904cd 10981
c7e4ee3a
CB
10982/* Transform expr for use as into 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_w (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/* Do global stuff. */
10999
c7e4ee3a
CB
11000void
11001ffecom_finish_compile ()
11002{
11003 assert (ffecom_outer_function_decl_ == NULL_TREE);
11004 assert (current_function_decl == NULL_TREE);
11005
11006 ffeglobal_drive (ffecom_finish_global_);
11007}
5ff904cd 11008
c7e4ee3a
CB
11009/* Public entry point for front end to access finish_decl. */
11010
c7e4ee3a
CB
11011void
11012ffecom_finish_decl (tree decl, tree init, bool is_top_level)
11013{
11014 assert (!is_top_level);
11015 finish_decl (decl, init, FALSE);
11016}
5ff904cd 11017
c7e4ee3a
CB
11018/* Finish a program unit. */
11019
c7e4ee3a
CB
11020void
11021ffecom_finish_progunit ()
11022{
11023 ffecom_end_compstmt ();
11024
11025 ffecom_previous_function_decl_ = current_function_decl;
11026 ffecom_which_entrypoint_decl_ = NULL_TREE;
11027
11028 finish_function (0);
11029}
5ff904cd 11030
14657de8 11031/* Wrapper for get_identifier. pattern is sprintf-like. */
c7e4ee3a 11032
c7e4ee3a 11033tree
14657de8 11034ffecom_get_invented_identifier (const char *pattern, ...)
c7e4ee3a
CB
11035{
11036 tree decl;
11037 char *nam;
14657de8 11038 va_list ap;
c7e4ee3a 11039
14657de8
KG
11040 va_start (ap, pattern);
11041 if (vasprintf (&nam, pattern, ap) == 0)
11042 abort ();
11043 va_end (ap);
c7e4ee3a 11044 decl = get_identifier (nam);
14657de8 11045 free (nam);
c7e4ee3a 11046 IDENTIFIER_INVENTED (decl) = 1;
c7e4ee3a
CB
11047 return decl;
11048}
11049
11050ffeinfoBasictype
11051ffecom_gfrt_basictype (ffecomGfrt gfrt)
11052{
11053 assert (gfrt < FFECOM_gfrt);
11054
11055 switch (ffecom_gfrt_type_[gfrt])
11056 {
11057 case FFECOM_rttypeVOID_:
11058 case FFECOM_rttypeVOIDSTAR_:
11059 return FFEINFO_basictypeNONE;
11060
11061 case FFECOM_rttypeFTNINT_:
11062 return FFEINFO_basictypeINTEGER;
11063
11064 case FFECOM_rttypeINTEGER_:
11065 return FFEINFO_basictypeINTEGER;
11066
11067 case FFECOM_rttypeLONGINT_:
11068 return FFEINFO_basictypeINTEGER;
11069
11070 case FFECOM_rttypeLOGICAL_:
11071 return FFEINFO_basictypeLOGICAL;
11072
11073 case FFECOM_rttypeREAL_F2C_:
11074 case FFECOM_rttypeREAL_GNU_:
11075 return FFEINFO_basictypeREAL;
11076
11077 case FFECOM_rttypeCOMPLEX_F2C_:
11078 case FFECOM_rttypeCOMPLEX_GNU_:
11079 return FFEINFO_basictypeCOMPLEX;
11080
11081 case FFECOM_rttypeDOUBLE_:
11082 case FFECOM_rttypeDOUBLEREAL_:
11083 return FFEINFO_basictypeREAL;
11084
11085 case FFECOM_rttypeDBLCMPLX_F2C_:
11086 case FFECOM_rttypeDBLCMPLX_GNU_:
11087 return FFEINFO_basictypeCOMPLEX;
11088
11089 case FFECOM_rttypeCHARACTER_:
11090 return FFEINFO_basictypeCHARACTER;
11091
11092 default:
11093 return FFEINFO_basictypeANY;
11094 }
11095}
11096
11097ffeinfoKindtype
11098ffecom_gfrt_kindtype (ffecomGfrt gfrt)
11099{
11100 assert (gfrt < FFECOM_gfrt);
11101
11102 switch (ffecom_gfrt_type_[gfrt])
11103 {
11104 case FFECOM_rttypeVOID_:
11105 case FFECOM_rttypeVOIDSTAR_:
11106 return FFEINFO_kindtypeNONE;
5ff904cd 11107
c7e4ee3a
CB
11108 case FFECOM_rttypeFTNINT_:
11109 return FFEINFO_kindtypeINTEGER1;
5ff904cd 11110
c7e4ee3a
CB
11111 case FFECOM_rttypeINTEGER_:
11112 return FFEINFO_kindtypeINTEGER1;
5ff904cd 11113
c7e4ee3a
CB
11114 case FFECOM_rttypeLONGINT_:
11115 return FFEINFO_kindtypeINTEGER4;
5ff904cd 11116
c7e4ee3a
CB
11117 case FFECOM_rttypeLOGICAL_:
11118 return FFEINFO_kindtypeLOGICAL1;
5ff904cd 11119
c7e4ee3a
CB
11120 case FFECOM_rttypeREAL_F2C_:
11121 case FFECOM_rttypeREAL_GNU_:
11122 return FFEINFO_kindtypeREAL1;
5ff904cd 11123
c7e4ee3a
CB
11124 case FFECOM_rttypeCOMPLEX_F2C_:
11125 case FFECOM_rttypeCOMPLEX_GNU_:
11126 return FFEINFO_kindtypeREAL1;
5ff904cd 11127
c7e4ee3a
CB
11128 case FFECOM_rttypeDOUBLE_:
11129 case FFECOM_rttypeDOUBLEREAL_:
11130 return FFEINFO_kindtypeREAL2;
5ff904cd 11131
c7e4ee3a
CB
11132 case FFECOM_rttypeDBLCMPLX_F2C_:
11133 case FFECOM_rttypeDBLCMPLX_GNU_:
11134 return FFEINFO_kindtypeREAL2;
5ff904cd 11135
c7e4ee3a
CB
11136 case FFECOM_rttypeCHARACTER_:
11137 return FFEINFO_kindtypeCHARACTER1;
5ff904cd 11138
c7e4ee3a
CB
11139 default:
11140 return FFEINFO_kindtypeANY;
11141 }
11142}
5ff904cd 11143
c7e4ee3a
CB
11144void
11145ffecom_init_0 ()
11146{
11147 tree endlink;
11148 int i;
11149 int j;
11150 tree t;
11151 tree field;
11152 ffetype type;
11153 ffetype base_type;
7189a4b0
GK
11154 tree double_ftype_double;
11155 tree float_ftype_float;
11156 tree ldouble_ftype_ldouble;
11157 tree ffecom_tree_ptr_to_fun_type_void;
5ff904cd 11158
c7e4ee3a
CB
11159 /* This block of code comes from the now-obsolete cktyps.c. It checks
11160 whether the compiler environment is buggy in known ways, some of which
11161 would, if not explicitly checked here, result in subtle bugs in g77. */
5ff904cd 11162
c7e4ee3a
CB
11163 if (ffe_is_do_internal_checks ())
11164 {
8b60264b 11165 static const char names[][12]
c7e4ee3a
CB
11166 =
11167 {"bar", "bletch", "foo", "foobar"};
8b60264b 11168 const char *name;
c7e4ee3a
CB
11169 unsigned long ul;
11170 double fl;
5ff904cd 11171
c7e4ee3a 11172 name = bsearch ("foo", &names[0], ARRAY_SIZE (names), sizeof (names[0]),
b0791fa9 11173 (int (*)(const void *, const void *)) strcmp);
8b60264b 11174 if (name != &names[0][2])
c7e4ee3a
CB
11175 {
11176 assert ("bsearch doesn't work, #define FFEPROJ_BSEARCH 0 in proj.h"
11177 == NULL);
11178 abort ();
11179 }
5ff904cd 11180
c7e4ee3a
CB
11181 ul = strtoul ("123456789", NULL, 10);
11182 if (ul != 123456789L)
11183 {
11184 assert ("strtoul doesn't have enough range, #define FFEPROJ_STRTOUL 0\
11185 in proj.h" == NULL);
11186 abort ();
11187 }
5ff904cd 11188
c7e4ee3a
CB
11189 fl = atof ("56.789");
11190 if ((fl < 56.788) || (fl > 56.79))
11191 {
11192 assert ("atof not type double, fix your #include <stdio.h>"
11193 == NULL);
11194 abort ();
11195 }
11196 }
5ff904cd 11197
c7e4ee3a 11198 ffecom_initialize_char_syntax_ ();
5ff904cd 11199
c7e4ee3a
CB
11200 ffecom_outer_function_decl_ = NULL_TREE;
11201 current_function_decl = NULL_TREE;
11202 named_labels = NULL_TREE;
11203 current_binding_level = NULL_BINDING_LEVEL;
11204 free_binding_level = NULL_BINDING_LEVEL;
11205 /* Make the binding_level structure for global names. */
11206 pushlevel (0);
11207 global_binding_level = current_binding_level;
11208 current_binding_level->prep_state = 2;
5ff904cd 11209
81b3411c 11210 build_common_tree_nodes (1);
5ff904cd 11211
81b3411c 11212 /* Define `int' and `char' first so that dbx will output them first. */
c7e4ee3a
CB
11213 pushdecl (build_decl (TYPE_DECL, get_identifier ("int"),
11214 integer_type_node));
a49bedaa
TM
11215 /* CHARACTER*1 is unsigned in ICHAR contexts. */
11216 char_type_node = make_unsigned_type (CHAR_TYPE_SIZE);
c7e4ee3a
CB
11217 pushdecl (build_decl (TYPE_DECL, get_identifier ("char"),
11218 char_type_node));
c7e4ee3a
CB
11219 pushdecl (build_decl (TYPE_DECL, get_identifier ("long int"),
11220 long_integer_type_node));
c7e4ee3a
CB
11221 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned int"),
11222 unsigned_type_node));
c7e4ee3a
CB
11223 pushdecl (build_decl (TYPE_DECL, get_identifier ("long unsigned int"),
11224 long_unsigned_type_node));
c7e4ee3a
CB
11225 pushdecl (build_decl (TYPE_DECL, get_identifier ("long long int"),
11226 long_long_integer_type_node));
c7e4ee3a
CB
11227 pushdecl (build_decl (TYPE_DECL, get_identifier ("long long unsigned int"),
11228 long_long_unsigned_type_node));
c7e4ee3a
CB
11229 pushdecl (build_decl (TYPE_DECL, get_identifier ("short int"),
11230 short_integer_type_node));
c7e4ee3a
CB
11231 pushdecl (build_decl (TYPE_DECL, get_identifier ("short unsigned int"),
11232 short_unsigned_type_node));
5ff904cd 11233
ff852b44
CB
11234 /* Set the sizetype before we make other types. This *should* be the
11235 first type we create. */
11236
11237 set_sizetype
11238 (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE))));
11239 ffecom_typesize_pointer_
11240 = TREE_INT_CST_LOW (TYPE_SIZE (sizetype)) / BITS_PER_UNIT;
11241
81b3411c 11242 build_common_tree_nodes_2 (0);
ff852b44 11243
c7e4ee3a 11244 /* Define both `signed char' and `unsigned char'. */
c7e4ee3a
CB
11245 pushdecl (build_decl (TYPE_DECL, get_identifier ("signed char"),
11246 signed_char_type_node));
5ff904cd 11247
c7e4ee3a
CB
11248 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned char"),
11249 unsigned_char_type_node));
5ff904cd 11250
c7e4ee3a
CB
11251 pushdecl (build_decl (TYPE_DECL, get_identifier ("float"),
11252 float_type_node));
c7e4ee3a
CB
11253 pushdecl (build_decl (TYPE_DECL, get_identifier ("double"),
11254 double_type_node));
c7e4ee3a
CB
11255 pushdecl (build_decl (TYPE_DECL, get_identifier ("long double"),
11256 long_double_type_node));
5ff904cd 11257
81b3411c 11258 /* For now, override what build_common_tree_nodes has done. */
c7e4ee3a 11259 complex_integer_type_node = ffecom_make_complex_type_ (integer_type_node);
81b3411c
BS
11260 complex_float_type_node = ffecom_make_complex_type_ (float_type_node);
11261 complex_double_type_node = ffecom_make_complex_type_ (double_type_node);
11262 complex_long_double_type_node
11263 = ffecom_make_complex_type_ (long_double_type_node);
11264
c7e4ee3a
CB
11265 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex int"),
11266 complex_integer_type_node));
c7e4ee3a
CB
11267 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex float"),
11268 complex_float_type_node));
c7e4ee3a
CB
11269 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex double"),
11270 complex_double_type_node));
c7e4ee3a
CB
11271 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex long double"),
11272 complex_long_double_type_node));
5ff904cd 11273
c7e4ee3a
CB
11274 pushdecl (build_decl (TYPE_DECL, get_identifier ("void"),
11275 void_type_node));
c7e4ee3a
CB
11276 /* We are not going to have real types in C with less than byte alignment,
11277 so we might as well not have any types that claim to have it. */
11278 TYPE_ALIGN (void_type_node) = BITS_PER_UNIT;
11cf4d18 11279 TYPE_USER_ALIGN (void_type_node) = 0;
5ff904cd 11280
c7e4ee3a 11281 string_type_node = build_pointer_type (char_type_node);
5ff904cd 11282
c7e4ee3a
CB
11283 ffecom_tree_fun_type_void
11284 = build_function_type (void_type_node, NULL_TREE);
5ff904cd 11285
c7e4ee3a
CB
11286 ffecom_tree_ptr_to_fun_type_void
11287 = build_pointer_type (ffecom_tree_fun_type_void);
5ff904cd 11288
c7e4ee3a 11289 endlink = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
5ff904cd 11290
c7e4ee3a
CB
11291 float_ftype_float
11292 = build_function_type (float_type_node,
11293 tree_cons (NULL_TREE, float_type_node, endlink));
5ff904cd 11294
c7e4ee3a
CB
11295 double_ftype_double
11296 = build_function_type (double_type_node,
11297 tree_cons (NULL_TREE, double_type_node, endlink));
5ff904cd 11298
c7e4ee3a
CB
11299 ldouble_ftype_ldouble
11300 = build_function_type (long_double_type_node,
11301 tree_cons (NULL_TREE, long_double_type_node,
11302 endlink));
5ff904cd 11303
c7e4ee3a
CB
11304 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11305 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11306 {
11307 ffecom_tree_type[i][j] = NULL_TREE;
11308 ffecom_tree_fun_type[i][j] = NULL_TREE;
11309 ffecom_tree_ptr_to_fun_type[i][j] = NULL_TREE;
11310 ffecom_f2c_typecode_[i][j] = -1;
11311 }
5ff904cd 11312
c7e4ee3a
CB
11313 /* Set up standard g77 types. Note that INTEGER and LOGICAL are set
11314 to size FLOAT_TYPE_SIZE because they have to be the same size as
11315 REAL, which also is FLOAT_TYPE_SIZE, according to the standard.
11316 Compiler options and other such stuff that change the ways these
11317 types are set should not affect this particular setup. */
5ff904cd 11318
c7e4ee3a
CB
11319 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER1]
11320 = t = make_signed_type (FLOAT_TYPE_SIZE);
11321 pushdecl (build_decl (TYPE_DECL, get_identifier ("integer"),
11322 t));
11323 type = ffetype_new ();
11324 base_type = type;
11325 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER1,
11326 type);
11327 ffetype_set_ams (type,
11328 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11329 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11330 ffetype_set_star (base_type,
11331 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11332 type);
11333 ffetype_set_kind (base_type, 1, type);
ff852b44 11334 ffecom_typesize_integer1_ = ffetype_size (type);
c7e4ee3a 11335 assert (ffetype_size (type) == sizeof (ffetargetInteger1));
5ff904cd 11336
c7e4ee3a
CB
11337 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER1]
11338 = t = make_unsigned_type (FLOAT_TYPE_SIZE); /* HOLLERITH means unsigned. */
11339 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned"),
11340 t));
5ff904cd 11341
c7e4ee3a
CB
11342 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER2]
11343 = t = make_signed_type (CHAR_TYPE_SIZE);
11344 pushdecl (build_decl (TYPE_DECL, get_identifier ("byte"),
11345 t));
11346 type = ffetype_new ();
11347 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER2,
11348 type);
11349 ffetype_set_ams (type,
11350 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11351 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11352 ffetype_set_star (base_type,
11353 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11354 type);
11355 ffetype_set_kind (base_type, 3, type);
11356 assert (ffetype_size (type) == sizeof (ffetargetInteger2));
5ff904cd 11357
c7e4ee3a
CB
11358 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER2]
11359 = t = make_unsigned_type (CHAR_TYPE_SIZE);
11360 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned byte"),
11361 t));
11362
11363 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER3]
11364 = t = make_signed_type (CHAR_TYPE_SIZE * 2);
11365 pushdecl (build_decl (TYPE_DECL, get_identifier ("word"),
11366 t));
11367 type = ffetype_new ();
11368 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER3,
11369 type);
11370 ffetype_set_ams (type,
11371 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11372 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11373 ffetype_set_star (base_type,
11374 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11375 type);
11376 ffetype_set_kind (base_type, 6, type);
11377 assert (ffetype_size (type) == sizeof (ffetargetInteger3));
5ff904cd 11378
c7e4ee3a
CB
11379 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER3]
11380 = t = make_unsigned_type (CHAR_TYPE_SIZE * 2);
11381 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned word"),
11382 t));
5ff904cd 11383
c7e4ee3a
CB
11384 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER4]
11385 = t = make_signed_type (FLOAT_TYPE_SIZE * 2);
11386 pushdecl (build_decl (TYPE_DECL, get_identifier ("integer4"),
11387 t));
11388 type = ffetype_new ();
11389 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER4,
11390 type);
11391 ffetype_set_ams (type,
11392 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11393 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11394 ffetype_set_star (base_type,
11395 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11396 type);
11397 ffetype_set_kind (base_type, 2, type);
11398 assert (ffetype_size (type) == sizeof (ffetargetInteger4));
5ff904cd 11399
c7e4ee3a
CB
11400 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER4]
11401 = t = make_unsigned_type (FLOAT_TYPE_SIZE * 2);
11402 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned4"),
11403 t));
5ff904cd 11404
c7e4ee3a
CB
11405#if 0
11406 if (ffe_is_do_internal_checks ()
11407 && LONG_TYPE_SIZE != FLOAT_TYPE_SIZE
11408 && LONG_TYPE_SIZE != CHAR_TYPE_SIZE
11409 && LONG_TYPE_SIZE != SHORT_TYPE_SIZE
11410 && LONG_TYPE_SIZE != LONG_LONG_TYPE_SIZE)
5ff904cd 11411 {
c7e4ee3a
CB
11412 fprintf (stderr, "Sorry, no g77 support for LONG_TYPE_SIZE (%d bits) yet.\n",
11413 LONG_TYPE_SIZE);
5ff904cd 11414 }
c7e4ee3a 11415#endif
5ff904cd 11416
c7e4ee3a
CB
11417 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL1]
11418 = t = make_signed_type (FLOAT_TYPE_SIZE);
11419 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical"),
11420 t));
11421 type = ffetype_new ();
11422 base_type = type;
11423 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL1,
11424 type);
11425 ffetype_set_ams (type,
11426 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11427 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11428 ffetype_set_star (base_type,
11429 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11430 type);
11431 ffetype_set_kind (base_type, 1, type);
11432 assert (ffetype_size (type) == sizeof (ffetargetLogical1));
5ff904cd 11433
c7e4ee3a
CB
11434 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL2]
11435 = t = make_signed_type (CHAR_TYPE_SIZE);
11436 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical2"),
11437 t));
11438 type = ffetype_new ();
11439 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL2,
11440 type);
11441 ffetype_set_ams (type,
11442 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11443 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11444 ffetype_set_star (base_type,
11445 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11446 type);
11447 ffetype_set_kind (base_type, 3, type);
11448 assert (ffetype_size (type) == sizeof (ffetargetLogical2));
5ff904cd 11449
c7e4ee3a
CB
11450 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL3]
11451 = t = make_signed_type (CHAR_TYPE_SIZE * 2);
11452 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical3"),
11453 t));
11454 type = ffetype_new ();
11455 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL3,
11456 type);
11457 ffetype_set_ams (type,
11458 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11459 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11460 ffetype_set_star (base_type,
11461 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11462 type);
11463 ffetype_set_kind (base_type, 6, type);
11464 assert (ffetype_size (type) == sizeof (ffetargetLogical3));
5ff904cd 11465
c7e4ee3a
CB
11466 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL4]
11467 = t = make_signed_type (FLOAT_TYPE_SIZE * 2);
11468 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical4"),
11469 t));
11470 type = ffetype_new ();
11471 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL4,
11472 type);
11473 ffetype_set_ams (type,
11474 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11475 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11476 ffetype_set_star (base_type,
11477 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11478 type);
11479 ffetype_set_kind (base_type, 2, type);
11480 assert (ffetype_size (type) == sizeof (ffetargetLogical4));
5ff904cd 11481
c7e4ee3a
CB
11482 ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]
11483 = t = make_node (REAL_TYPE);
11484 TYPE_PRECISION (t) = FLOAT_TYPE_SIZE;
11485 pushdecl (build_decl (TYPE_DECL, get_identifier ("real"),
11486 t));
11487 layout_type (t);
11488 type = ffetype_new ();
11489 base_type = type;
11490 ffeinfo_set_type (FFEINFO_basictypeREAL, FFEINFO_kindtypeREAL1,
11491 type);
11492 ffetype_set_ams (type,
11493 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11494 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11495 ffetype_set_star (base_type,
11496 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11497 type);
11498 ffetype_set_kind (base_type, 1, type);
11499 ffecom_f2c_typecode_[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]
11500 = FFETARGET_f2cTYREAL;
11501 assert (ffetype_size (type) == sizeof (ffetargetReal1));
5ff904cd 11502
c7e4ee3a
CB
11503 ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREALDOUBLE]
11504 = t = make_node (REAL_TYPE);
11505 TYPE_PRECISION (t) = FLOAT_TYPE_SIZE * 2; /* Always twice REAL. */
11506 pushdecl (build_decl (TYPE_DECL, get_identifier ("double precision"),
11507 t));
11508 layout_type (t);
11509 type = ffetype_new ();
11510 ffeinfo_set_type (FFEINFO_basictypeREAL, FFEINFO_kindtypeREALDOUBLE,
11511 type);
11512 ffetype_set_ams (type,
11513 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11514 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11515 ffetype_set_star (base_type,
11516 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11517 type);
11518 ffetype_set_kind (base_type, 2, type);
11519 ffecom_f2c_typecode_[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2]
11520 = FFETARGET_f2cTYDREAL;
11521 assert (ffetype_size (type) == sizeof (ffetargetReal2));
5ff904cd 11522
c7e4ee3a
CB
11523 ffecom_tree_type[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL1]
11524 = t = ffecom_make_complex_type_ (ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]);
11525 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex"),
11526 t));
11527 type = ffetype_new ();
11528 base_type = type;
11529 ffeinfo_set_type (FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREAL1,
11530 type);
11531 ffetype_set_ams (type,
11532 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11533 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11534 ffetype_set_star (base_type,
11535 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11536 type);
11537 ffetype_set_kind (base_type, 1, type);
11538 ffecom_f2c_typecode_[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL1]
11539 = FFETARGET_f2cTYCOMPLEX;
11540 assert (ffetype_size (type) == sizeof (ffetargetComplex1));
5ff904cd 11541
c7e4ee3a
CB
11542 ffecom_tree_type[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREALDOUBLE]
11543 = t = ffecom_make_complex_type_ (ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2]);
11544 pushdecl (build_decl (TYPE_DECL, get_identifier ("double complex"),
11545 t));
11546 type = ffetype_new ();
11547 ffeinfo_set_type (FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREALDOUBLE,
11548 type);
11549 ffetype_set_ams (type,
11550 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11551 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11552 ffetype_set_star (base_type,
11553 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11554 type);
11555 ffetype_set_kind (base_type, 2,
11556 type);
11557 ffecom_f2c_typecode_[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL2]
11558 = FFETARGET_f2cTYDCOMPLEX;
11559 assert (ffetype_size (type) == sizeof (ffetargetComplex2));
5ff904cd 11560
c7e4ee3a 11561 /* Make function and ptr-to-function types for non-CHARACTER types. */
5ff904cd 11562
c7e4ee3a
CB
11563 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11564 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11565 {
11566 if ((t = ffecom_tree_type[i][j]) != NULL_TREE)
11567 {
11568 if (i == FFEINFO_basictypeINTEGER)
11569 {
11570 /* Figure out the smallest INTEGER type that can hold
11571 a pointer on this machine. */
11572 if (GET_MODE_SIZE (TYPE_MODE (t))
11573 >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
11574 {
11575 if ((ffecom_pointer_kind_ == FFEINFO_kindtypeNONE)
11576 || (GET_MODE_SIZE (TYPE_MODE (ffecom_tree_type[i][ffecom_pointer_kind_]))
11577 > GET_MODE_SIZE (TYPE_MODE (t))))
11578 ffecom_pointer_kind_ = j;
11579 }
11580 }
11581 else if (i == FFEINFO_basictypeCOMPLEX)
11582 t = void_type_node;
11583 /* For f2c compatibility, REAL functions are really
11584 implemented as DOUBLE PRECISION. */
11585 else if ((i == FFEINFO_basictypeREAL)
11586 && (j == FFEINFO_kindtypeREAL1))
11587 t = ffecom_tree_type
11588 [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2];
5ff904cd 11589
c7e4ee3a
CB
11590 t = ffecom_tree_fun_type[i][j] = build_function_type (t,
11591 NULL_TREE);
11592 ffecom_tree_ptr_to_fun_type[i][j] = build_pointer_type (t);
11593 }
11594 }
5ff904cd 11595
c7e4ee3a 11596 /* Set up pointer types. */
5ff904cd 11597
c7e4ee3a 11598 if (ffecom_pointer_kind_ == FFEINFO_basictypeNONE)
400500c4 11599 fatal_error ("no INTEGER type can hold a pointer on this configuration");
c7e4ee3a
CB
11600 else if (0 && ffe_is_do_internal_checks ())
11601 fprintf (stderr, "Pointer type kt=%d\n", ffecom_pointer_kind_);
11602 ffetype_set_kind (ffeinfo_type (FFEINFO_basictypeINTEGER,
11603 FFEINFO_kindtypeINTEGERDEFAULT),
11604 7,
11605 ffeinfo_type (FFEINFO_basictypeINTEGER,
11606 ffecom_pointer_kind_));
5ff904cd 11607
c7e4ee3a
CB
11608 if (ffe_is_ugly_assign ())
11609 ffecom_label_kind_ = ffecom_pointer_kind_; /* Require ASSIGN etc to this. */
11610 else
11611 ffecom_label_kind_ = FFEINFO_kindtypeINTEGERDEFAULT;
11612 if (0 && ffe_is_do_internal_checks ())
11613 fprintf (stderr, "Label type kt=%d\n", ffecom_label_kind_);
5ff904cd 11614
c7e4ee3a
CB
11615 ffecom_integer_type_node
11616 = ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER1];
11617 ffecom_integer_zero_node = convert (ffecom_integer_type_node,
11618 integer_zero_node);
11619 ffecom_integer_one_node = convert (ffecom_integer_type_node,
11620 integer_one_node);
5ff904cd 11621
c7e4ee3a
CB
11622 /* Yes, the "FLOAT_TYPE_SIZE" references below are intentional.
11623 Turns out that by TYLONG, runtime/libI77/lio.h really means
11624 "whatever size an ftnint is". For consistency and sanity,
11625 com.h and runtime/f2c.h.in agree that flag, ftnint, and ftlen
11626 all are INTEGER, which we also make out of whatever back-end
11627 integer type is FLOAT_TYPE_SIZE bits wide. This change, from
11628 LONG_TYPE_SIZE, for TYLONG and TYLOGICAL, was necessary to
11629 accommodate machines like the Alpha. Note that this suggests
11630 f2c and libf2c are missing a distinction perhaps needed on
11631 some machines between "int" and "long int". -- burley 0.5.5 950215 */
5ff904cd 11632
c7e4ee3a
CB
11633 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, FLOAT_TYPE_SIZE,
11634 FFETARGET_f2cTYLONG);
11635 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, SHORT_TYPE_SIZE,
11636 FFETARGET_f2cTYSHORT);
11637 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, CHAR_TYPE_SIZE,
11638 FFETARGET_f2cTYINT1);
11639 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, LONG_LONG_TYPE_SIZE,
11640 FFETARGET_f2cTYQUAD);
11641 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, FLOAT_TYPE_SIZE,
11642 FFETARGET_f2cTYLOGICAL);
11643 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, SHORT_TYPE_SIZE,
11644 FFETARGET_f2cTYLOGICAL2);
11645 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, CHAR_TYPE_SIZE,
11646 FFETARGET_f2cTYLOGICAL1);
11647 /* ~~~Not really such a type in libf2c, e.g. I/O support? */
11648 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, LONG_LONG_TYPE_SIZE,
11649 FFETARGET_f2cTYQUAD);
5ff904cd 11650
c7e4ee3a
CB
11651 /* CHARACTER stuff is all special-cased, so it is not handled in the above
11652 loop. CHARACTER items are built as arrays of unsigned char. */
5ff904cd 11653
c7e4ee3a
CB
11654 ffecom_tree_type[FFEINFO_basictypeCHARACTER]
11655 [FFEINFO_kindtypeCHARACTER1] = t = char_type_node;
11656 type = ffetype_new ();
11657 base_type = type;
11658 ffeinfo_set_type (FFEINFO_basictypeCHARACTER,
11659 FFEINFO_kindtypeCHARACTER1,
11660 type);
11661 ffetype_set_ams (type,
11662 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11663 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11664 ffetype_set_kind (base_type, 1, type);
11665 assert (ffetype_size (type)
11666 == sizeof (((ffetargetCharacter1) { 0, NULL }).text[0]));
5ff904cd 11667
c7e4ee3a
CB
11668 ffecom_tree_fun_type[FFEINFO_basictypeCHARACTER]
11669 [FFEINFO_kindtypeCHARACTER1] = ffecom_tree_fun_type_void;
11670 ffecom_tree_ptr_to_fun_type[FFEINFO_basictypeCHARACTER]
11671 [FFEINFO_kindtypeCHARACTER1]
11672 = ffecom_tree_ptr_to_fun_type_void;
11673 ffecom_f2c_typecode_[FFEINFO_basictypeCHARACTER][FFEINFO_kindtypeCHARACTER1]
11674 = FFETARGET_f2cTYCHAR;
5ff904cd 11675
c7e4ee3a
CB
11676 ffecom_f2c_typecode_[FFEINFO_basictypeANY][FFEINFO_kindtypeANY]
11677 = 0;
5ff904cd 11678
c7e4ee3a 11679 /* Make multi-return-value type and fields. */
5ff904cd 11680
c7e4ee3a 11681 ffecom_multi_type_node_ = make_node (UNION_TYPE);
5ff904cd 11682
c7e4ee3a 11683 field = NULL_TREE;
5ff904cd 11684
c7e4ee3a
CB
11685 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11686 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11687 {
11688 char name[30];
5ff904cd 11689
c7e4ee3a
CB
11690 if (ffecom_tree_type[i][j] == NULL_TREE)
11691 continue; /* Not supported. */
11692 sprintf (&name[0], "bt_%s_kt_%s",
11693 ffeinfo_basictype_string ((ffeinfoBasictype) i),
11694 ffeinfo_kindtype_string ((ffeinfoKindtype) j));
11695 ffecom_multi_fields_[i][j] = build_decl (FIELD_DECL,
11696 get_identifier (name),
11697 ffecom_tree_type[i][j]);
11698 DECL_CONTEXT (ffecom_multi_fields_[i][j])
11699 = ffecom_multi_type_node_;
8ba77681 11700 DECL_ALIGN (ffecom_multi_fields_[i][j]) = 0;
11cf4d18 11701 DECL_USER_ALIGN (ffecom_multi_fields_[i][j]) = 0;
c7e4ee3a
CB
11702 TREE_CHAIN (ffecom_multi_fields_[i][j]) = field;
11703 field = ffecom_multi_fields_[i][j];
11704 }
5ff904cd 11705
c7e4ee3a
CB
11706 TYPE_FIELDS (ffecom_multi_type_node_) = field;
11707 layout_type (ffecom_multi_type_node_);
5ff904cd 11708
c7e4ee3a
CB
11709 /* Subroutines usually return integer because they might have alternate
11710 returns. */
5ff904cd 11711
c7e4ee3a
CB
11712 ffecom_tree_subr_type
11713 = build_function_type (integer_type_node, NULL_TREE);
11714 ffecom_tree_ptr_to_subr_type
11715 = build_pointer_type (ffecom_tree_subr_type);
11716 ffecom_tree_blockdata_type
11717 = build_function_type (void_type_node, NULL_TREE);
5ff904cd 11718
c7e4ee3a 11719 builtin_function ("__builtin_sqrtf", float_ftype_float,
26db82d8 11720 BUILT_IN_FSQRT, BUILT_IN_NORMAL, "sqrtf");
c7e4ee3a 11721 builtin_function ("__builtin_fsqrt", double_ftype_double,
26db82d8 11722 BUILT_IN_FSQRT, BUILT_IN_NORMAL, "sqrt");
c7e4ee3a 11723 builtin_function ("__builtin_sqrtl", ldouble_ftype_ldouble,
26db82d8 11724 BUILT_IN_FSQRT, BUILT_IN_NORMAL, "sqrtl");
c7e4ee3a 11725 builtin_function ("__builtin_sinf", float_ftype_float,
26db82d8 11726 BUILT_IN_SIN, BUILT_IN_NORMAL, "sinf");
c7e4ee3a 11727 builtin_function ("__builtin_sin", double_ftype_double,
26db82d8 11728 BUILT_IN_SIN, BUILT_IN_NORMAL, "sin");
c7e4ee3a 11729 builtin_function ("__builtin_sinl", ldouble_ftype_ldouble,
26db82d8 11730 BUILT_IN_SIN, BUILT_IN_NORMAL, "sinl");
c7e4ee3a 11731 builtin_function ("__builtin_cosf", float_ftype_float,
26db82d8 11732 BUILT_IN_COS, BUILT_IN_NORMAL, "cosf");
c7e4ee3a 11733 builtin_function ("__builtin_cos", double_ftype_double,
26db82d8 11734 BUILT_IN_COS, BUILT_IN_NORMAL, "cos");
c7e4ee3a 11735 builtin_function ("__builtin_cosl", ldouble_ftype_ldouble,
26db82d8 11736 BUILT_IN_COS, BUILT_IN_NORMAL, "cosl");
5ff904cd 11737
c7e4ee3a 11738 pedantic_lvalues = FALSE;
5ff904cd 11739
c7e4ee3a
CB
11740 ffecom_f2c_make_type_ (&ffecom_f2c_integer_type_node,
11741 FFECOM_f2cINTEGER,
11742 "integer");
11743 ffecom_f2c_make_type_ (&ffecom_f2c_address_type_node,
11744 FFECOM_f2cADDRESS,
11745 "address");
11746 ffecom_f2c_make_type_ (&ffecom_f2c_real_type_node,
11747 FFECOM_f2cREAL,
11748 "real");
11749 ffecom_f2c_make_type_ (&ffecom_f2c_doublereal_type_node,
11750 FFECOM_f2cDOUBLEREAL,
11751 "doublereal");
11752 ffecom_f2c_make_type_ (&ffecom_f2c_complex_type_node,
11753 FFECOM_f2cCOMPLEX,
11754 "complex");
11755 ffecom_f2c_make_type_ (&ffecom_f2c_doublecomplex_type_node,
11756 FFECOM_f2cDOUBLECOMPLEX,
11757 "doublecomplex");
11758 ffecom_f2c_make_type_ (&ffecom_f2c_longint_type_node,
11759 FFECOM_f2cLONGINT,
11760 "longint");
11761 ffecom_f2c_make_type_ (&ffecom_f2c_logical_type_node,
11762 FFECOM_f2cLOGICAL,
11763 "logical");
11764 ffecom_f2c_make_type_ (&ffecom_f2c_flag_type_node,
11765 FFECOM_f2cFLAG,
11766 "flag");
11767 ffecom_f2c_make_type_ (&ffecom_f2c_ftnlen_type_node,
11768 FFECOM_f2cFTNLEN,
11769 "ftnlen");
11770 ffecom_f2c_make_type_ (&ffecom_f2c_ftnint_type_node,
11771 FFECOM_f2cFTNINT,
11772 "ftnint");
5ff904cd 11773
c7e4ee3a
CB
11774 ffecom_f2c_ftnlen_zero_node
11775 = convert (ffecom_f2c_ftnlen_type_node, integer_zero_node);
5ff904cd 11776
c7e4ee3a
CB
11777 ffecom_f2c_ftnlen_one_node
11778 = convert (ffecom_f2c_ftnlen_type_node, integer_one_node);
5ff904cd 11779
c7e4ee3a
CB
11780 ffecom_f2c_ftnlen_two_node = build_int_2 (2, 0);
11781 TREE_TYPE (ffecom_f2c_ftnlen_two_node) = ffecom_integer_type_node;
5ff904cd 11782
c7e4ee3a
CB
11783 ffecom_f2c_ptr_to_ftnlen_type_node
11784 = build_pointer_type (ffecom_f2c_ftnlen_type_node);
5ff904cd 11785
c7e4ee3a
CB
11786 ffecom_f2c_ptr_to_ftnint_type_node
11787 = build_pointer_type (ffecom_f2c_ftnint_type_node);
5ff904cd 11788
c7e4ee3a
CB
11789 ffecom_f2c_ptr_to_integer_type_node
11790 = build_pointer_type (ffecom_f2c_integer_type_node);
5ff904cd 11791
c7e4ee3a
CB
11792 ffecom_f2c_ptr_to_real_type_node
11793 = build_pointer_type (ffecom_f2c_real_type_node);
5ff904cd 11794
c7e4ee3a
CB
11795 ffecom_float_zero_ = build_real (float_type_node, dconst0);
11796 ffecom_double_zero_ = build_real (double_type_node, dconst0);
11797 {
11798 REAL_VALUE_TYPE point_5;
5ff904cd 11799
c7e4ee3a
CB
11800#ifdef REAL_ARITHMETIC
11801 REAL_ARITHMETIC (point_5, RDIV_EXPR, dconst1, dconst2);
11802#else
11803 point_5 = .5;
11804#endif
11805 ffecom_float_half_ = build_real (float_type_node, point_5);
11806 ffecom_double_half_ = build_real (double_type_node, point_5);
11807 }
5ff904cd 11808
c7e4ee3a 11809 /* Do "extern int xargc;". */
5ff904cd 11810
c7e4ee3a
CB
11811 ffecom_tree_xargc_ = build_decl (VAR_DECL,
11812 get_identifier ("f__xargc"),
11813 integer_type_node);
11814 DECL_EXTERNAL (ffecom_tree_xargc_) = 1;
11815 TREE_STATIC (ffecom_tree_xargc_) = 1;
11816 TREE_PUBLIC (ffecom_tree_xargc_) = 1;
11817 ffecom_tree_xargc_ = start_decl (ffecom_tree_xargc_, FALSE);
11818 finish_decl (ffecom_tree_xargc_, NULL_TREE, FALSE);
5ff904cd 11819
c7e4ee3a
CB
11820#if 0 /* This is being fixed, and seems to be working now. */
11821 if ((FLOAT_TYPE_SIZE != 32)
11822 || (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node))) != 32))
5ff904cd 11823 {
c7e4ee3a
CB
11824 warning ("configuration: REAL, INTEGER, and LOGICAL are %d bits wide,",
11825 (int) FLOAT_TYPE_SIZE);
11826 warning ("and pointers are %d bits wide, but g77 doesn't yet work",
11827 (int) TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node))));
11828 warning ("properly unless they all are 32 bits wide.");
11829 warning ("Please keep this in mind before you report bugs. g77 should");
11830 warning ("support non-32-bit machines better as of version 0.6.");
11831 }
11832#endif
5ff904cd 11833
c7e4ee3a
CB
11834#if 0 /* Code in ste.c that would crash has been commented out. */
11835 if (TYPE_PRECISION (ffecom_f2c_ftnlen_type_node)
11836 < TYPE_PRECISION (string_type_node))
11837 /* I/O will probably crash. */
11838 warning ("configuration: char * holds %d bits, but ftnlen only %d",
11839 TYPE_PRECISION (string_type_node),
11840 TYPE_PRECISION (ffecom_f2c_ftnlen_type_node));
11841#endif
5ff904cd 11842
c7e4ee3a
CB
11843#if 0 /* ASSIGN-related stuff has been changed to accommodate this. */
11844 if (TYPE_PRECISION (ffecom_integer_type_node)
11845 < TYPE_PRECISION (string_type_node))
11846 /* ASSIGN 10 TO I will crash. */
11847 warning ("configuration: char * holds %d bits, but INTEGER only %d --\n\
11848 ASSIGN statement might fail",
11849 TYPE_PRECISION (string_type_node),
11850 TYPE_PRECISION (ffecom_integer_type_node));
11851#endif
11852}
5ff904cd 11853
c7e4ee3a 11854/* ffecom_init_2 -- Initialize
5ff904cd 11855
c7e4ee3a 11856 ffecom_init_2(); */
5ff904cd 11857
c7e4ee3a
CB
11858void
11859ffecom_init_2 ()
11860{
11861 assert (ffecom_outer_function_decl_ == NULL_TREE);
11862 assert (current_function_decl == NULL_TREE);
11863 assert (ffecom_which_entrypoint_decl_ == NULL_TREE);
5ff904cd 11864
c7e4ee3a
CB
11865 ffecom_master_arglist_ = NULL;
11866 ++ffecom_num_fns_;
11867 ffecom_primary_entry_ = NULL;
11868 ffecom_is_altreturning_ = FALSE;
11869 ffecom_func_result_ = NULL_TREE;
11870 ffecom_multi_retval_ = NULL_TREE;
11871}
5ff904cd 11872
c7e4ee3a 11873/* ffecom_list_expr -- Transform list of exprs into gcc tree
5ff904cd 11874
c7e4ee3a
CB
11875 tree t;
11876 ffebld expr; // FFE opITEM list.
11877 tree = ffecom_list_expr(expr);
5ff904cd 11878
c7e4ee3a 11879 List of actual args is transformed into corresponding gcc backend list. */
5ff904cd 11880
c7e4ee3a
CB
11881tree
11882ffecom_list_expr (ffebld expr)
5ff904cd 11883{
c7e4ee3a
CB
11884 tree list;
11885 tree *plist = &list;
11886 tree trail = NULL_TREE; /* Append char length args here. */
11887 tree *ptrail = &trail;
11888 tree length;
5ff904cd 11889
c7e4ee3a 11890 while (expr != NULL)
5ff904cd 11891 {
c7e4ee3a 11892 tree texpr = ffecom_arg_expr (ffebld_head (expr), &length);
5ff904cd 11893
c7e4ee3a
CB
11894 if (texpr == error_mark_node)
11895 return error_mark_node;
5ff904cd 11896
c7e4ee3a
CB
11897 *plist = build_tree_list (NULL_TREE, texpr);
11898 plist = &TREE_CHAIN (*plist);
11899 expr = ffebld_trail (expr);
11900 if (length != NULL_TREE)
5ff904cd 11901 {
c7e4ee3a
CB
11902 *ptrail = build_tree_list (NULL_TREE, length);
11903 ptrail = &TREE_CHAIN (*ptrail);
5ff904cd
JL
11904 }
11905 }
11906
c7e4ee3a 11907 *plist = trail;
5ff904cd 11908
c7e4ee3a
CB
11909 return list;
11910}
5ff904cd 11911
c7e4ee3a 11912/* ffecom_list_ptr_to_expr -- Transform list of exprs into gcc tree
5ff904cd 11913
c7e4ee3a
CB
11914 tree t;
11915 ffebld expr; // FFE opITEM list.
11916 tree = ffecom_list_ptr_to_expr(expr);
5ff904cd 11917
c7e4ee3a
CB
11918 List of actual args is transformed into corresponding gcc backend list for
11919 use in calling an external procedure (vs. a statement function). */
5ff904cd 11920
c7e4ee3a
CB
11921tree
11922ffecom_list_ptr_to_expr (ffebld expr)
11923{
11924 tree list;
11925 tree *plist = &list;
11926 tree trail = NULL_TREE; /* Append char length args here. */
11927 tree *ptrail = &trail;
11928 tree length;
5ff904cd 11929
c7e4ee3a
CB
11930 while (expr != NULL)
11931 {
11932 tree texpr = ffecom_arg_ptr_to_expr (ffebld_head (expr), &length);
5ff904cd 11933
c7e4ee3a
CB
11934 if (texpr == error_mark_node)
11935 return error_mark_node;
5ff904cd 11936
c7e4ee3a
CB
11937 *plist = build_tree_list (NULL_TREE, texpr);
11938 plist = &TREE_CHAIN (*plist);
11939 expr = ffebld_trail (expr);
11940 if (length != NULL_TREE)
11941 {
11942 *ptrail = build_tree_list (NULL_TREE, length);
11943 ptrail = &TREE_CHAIN (*ptrail);
11944 }
11945 }
5ff904cd 11946
c7e4ee3a 11947 *plist = trail;
5ff904cd 11948
c7e4ee3a
CB
11949 return list;
11950}
5ff904cd 11951
c7e4ee3a 11952/* Obtain gcc's LABEL_DECL tree for label. */
5ff904cd 11953
c7e4ee3a
CB
11954tree
11955ffecom_lookup_label (ffelab label)
11956{
11957 tree glabel;
5ff904cd 11958
c7e4ee3a
CB
11959 if (ffelab_hook (label) == NULL_TREE)
11960 {
11961 char labelname[16];
5ff904cd 11962
c7e4ee3a
CB
11963 switch (ffelab_type (label))
11964 {
11965 case FFELAB_typeLOOPEND:
11966 case FFELAB_typeNOTLOOP:
11967 case FFELAB_typeENDIF:
11968 sprintf (labelname, "%" ffelabValue_f "u", ffelab_value (label));
11969 glabel = build_decl (LABEL_DECL, get_identifier (labelname),
11970 void_type_node);
11971 DECL_CONTEXT (glabel) = current_function_decl;
11972 DECL_MODE (glabel) = VOIDmode;
11973 break;
5ff904cd 11974
c7e4ee3a 11975 case FFELAB_typeFORMAT:
c7e4ee3a
CB
11976 glabel = build_decl (VAR_DECL,
11977 ffecom_get_invented_identifier
14657de8 11978 ("__g77_format_%d", (int) ffelab_value (label)),
c7e4ee3a
CB
11979 build_type_variant (build_array_type
11980 (char_type_node,
11981 NULL_TREE),
11982 1, 0));
11983 TREE_CONSTANT (glabel) = 1;
11984 TREE_STATIC (glabel) = 1;
611081b2 11985 DECL_CONTEXT (glabel) = current_function_decl;
c7e4ee3a 11986 DECL_INITIAL (glabel) = NULL;
6c418184 11987 make_decl_rtl (glabel, NULL);
c7e4ee3a 11988 expand_decl (glabel);
5ff904cd 11989
7189a4b0 11990 ffecom_save_tree_forever (glabel);
5ff904cd 11991
c7e4ee3a 11992 break;
5ff904cd 11993
c7e4ee3a
CB
11994 case FFELAB_typeANY:
11995 glabel = error_mark_node;
11996 break;
5ff904cd 11997
c7e4ee3a
CB
11998 default:
11999 assert ("bad label type" == NULL);
12000 glabel = NULL;
12001 break;
12002 }
12003 ffelab_set_hook (label, glabel);
12004 }
12005 else
12006 {
12007 glabel = ffelab_hook (label);
12008 }
5ff904cd 12009
c7e4ee3a
CB
12010 return glabel;
12011}
5ff904cd 12012
c7e4ee3a
CB
12013/* Stabilizes the arguments. Don't use this if the lhs and rhs come from
12014 a single source specification (as in the fourth argument of MVBITS).
12015 If the type is NULL_TREE, the type of lhs is used to make the type of
12016 the MODIFY_EXPR. */
5ff904cd 12017
c7e4ee3a
CB
12018tree
12019ffecom_modify (tree newtype, tree lhs,
12020 tree rhs)
12021{
12022 if (lhs == error_mark_node || rhs == error_mark_node)
12023 return error_mark_node;
5ff904cd 12024
c7e4ee3a
CB
12025 if (newtype == NULL_TREE)
12026 newtype = TREE_TYPE (lhs);
5ff904cd 12027
c7e4ee3a
CB
12028 if (TREE_SIDE_EFFECTS (lhs))
12029 lhs = stabilize_reference (lhs);
5ff904cd 12030
c7e4ee3a
CB
12031 return ffecom_2s (MODIFY_EXPR, newtype, lhs, rhs);
12032}
5ff904cd 12033
c7e4ee3a 12034/* Register source file name. */
5ff904cd 12035
c7e4ee3a 12036void
b0791fa9 12037ffecom_file (const char *name)
c7e4ee3a 12038{
c7e4ee3a 12039 ffecom_file_ (name);
c7e4ee3a 12040}
5ff904cd 12041
c7e4ee3a 12042/* ffecom_notify_init_storage -- An aggregate storage is now fully init'ed
5ff904cd 12043
c7e4ee3a
CB
12044 ffestorag st;
12045 ffecom_notify_init_storage(st);
5ff904cd 12046
c7e4ee3a
CB
12047 Gets called when all possible units in an aggregate storage area (a LOCAL
12048 with equivalences or a COMMON) have been initialized. The initialization
12049 info either is in ffestorag_init or, if that is NULL,
12050 ffestorag_accretion:
5ff904cd 12051
c7e4ee3a
CB
12052 ffestorag_init may contain an opCONTER or opARRTER. opCONTER may occur
12053 even for an array if the array is one element in length!
5ff904cd 12054
c7e4ee3a
CB
12055 ffestorag_accretion will contain an opACCTER. It is much like an
12056 opARRTER except it has an ffebit object in it instead of just a size.
12057 The back end can use the info in the ffebit object, if it wants, to
12058 reduce the amount of actual initialization, but in any case it should
12059 kill the ffebit object when done. Also, set accretion to NULL but
12060 init to a non-NULL value.
5ff904cd 12061
c7e4ee3a
CB
12062 After performing initialization, DO NOT set init to NULL, because that'll
12063 tell the front end it is ok for more initialization to happen. Instead,
12064 set init to an opANY expression or some such thing that you can use to
12065 tell that you've already initialized the object.
5ff904cd 12066
c7e4ee3a
CB
12067 27-Oct-91 JCB 1.1
12068 Support two-pass FFE. */
5ff904cd 12069
c7e4ee3a
CB
12070void
12071ffecom_notify_init_storage (ffestorag st)
12072{
12073 ffebld init; /* The initialization expression. */
c7e4ee3a
CB
12074
12075 if (ffestorag_init (st) == NULL)
5ff904cd 12076 {
c7e4ee3a
CB
12077 init = ffestorag_accretion (st);
12078 assert (init != NULL);
12079 ffestorag_set_accretion (st, NULL);
12080 ffestorag_set_accretes (st, 0);
c7e4ee3a 12081 ffestorag_set_init (st, init);
5ff904cd 12082 }
c7e4ee3a 12083}
5ff904cd 12084
c7e4ee3a 12085/* ffecom_notify_init_symbol -- A symbol is now fully init'ed
5ff904cd 12086
c7e4ee3a
CB
12087 ffesymbol s;
12088 ffecom_notify_init_symbol(s);
5ff904cd 12089
c7e4ee3a
CB
12090 Gets called when all possible units in a symbol (not placed in COMMON
12091 or involved in EQUIVALENCE, unless it as yet has no ffestorag object)
12092 have been initialized. The initialization info either is in
12093 ffesymbol_init or, if that is NULL, ffesymbol_accretion:
5ff904cd 12094
c7e4ee3a
CB
12095 ffesymbol_init may contain an opCONTER or opARRTER. opCONTER may occur
12096 even for an array if the array is one element in length!
5ff904cd 12097
c7e4ee3a
CB
12098 ffesymbol_accretion will contain an opACCTER. It is much like an
12099 opARRTER except it has an ffebit object in it instead of just a size.
12100 The back end can use the info in the ffebit object, if it wants, to
12101 reduce the amount of actual initialization, but in any case it should
12102 kill the ffebit object when done. Also, set accretion to NULL but
12103 init to a non-NULL value.
5ff904cd 12104
c7e4ee3a
CB
12105 After performing initialization, DO NOT set init to NULL, because that'll
12106 tell the front end it is ok for more initialization to happen. Instead,
12107 set init to an opANY expression or some such thing that you can use to
12108 tell that you've already initialized the object.
5ff904cd 12109
c7e4ee3a
CB
12110 27-Oct-91 JCB 1.1
12111 Support two-pass FFE. */
5ff904cd 12112
c7e4ee3a
CB
12113void
12114ffecom_notify_init_symbol (ffesymbol s)
12115{
12116 ffebld init; /* The initialization expression. */
5ff904cd 12117
c7e4ee3a
CB
12118 if (ffesymbol_storage (s) == NULL)
12119 return; /* Do nothing until COMMON/EQUIVALENCE
12120 possibilities checked. */
5ff904cd 12121
c7e4ee3a
CB
12122 if ((ffesymbol_init (s) == NULL)
12123 && ((init = ffesymbol_accretion (s)) != NULL))
12124 {
12125 ffesymbol_set_accretion (s, NULL);
12126 ffesymbol_set_accretes (s, 0);
c7e4ee3a 12127 ffesymbol_set_init (s, init);
c7e4ee3a 12128 }
c7e4ee3a 12129}
5ff904cd 12130
c7e4ee3a 12131/* ffecom_notify_primary_entry -- Learn which is the primary entry point
5ff904cd 12132
c7e4ee3a
CB
12133 ffesymbol s;
12134 ffecom_notify_primary_entry(s);
5ff904cd 12135
c7e4ee3a
CB
12136 Gets called when implicit or explicit PROGRAM statement seen or when
12137 FUNCTION, SUBROUTINE, or BLOCK DATA statement seen, with the primary
12138 global symbol that serves as the entry point. */
5ff904cd 12139
c7e4ee3a
CB
12140void
12141ffecom_notify_primary_entry (ffesymbol s)
12142{
12143 ffecom_primary_entry_ = s;
12144 ffecom_primary_entry_kind_ = ffesymbol_kind (s);
5ff904cd 12145
c7e4ee3a
CB
12146 if ((ffecom_primary_entry_kind_ == FFEINFO_kindFUNCTION)
12147 || (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE))
12148 ffecom_primary_entry_is_proc_ = TRUE;
12149 else
12150 ffecom_primary_entry_is_proc_ = FALSE;
5ff904cd 12151
c7e4ee3a
CB
12152 if (!ffe_is_silent ())
12153 {
12154 if (ffecom_primary_entry_kind_ == FFEINFO_kindPROGRAM)
12155 fprintf (stderr, "%s:\n", ffesymbol_text (s));
12156 else
12157 fprintf (stderr, " %s:\n", ffesymbol_text (s));
12158 }
5ff904cd 12159
c7e4ee3a
CB
12160 if (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE)
12161 {
12162 ffebld list;
12163 ffebld arg;
5ff904cd 12164
c7e4ee3a
CB
12165 for (list = ffesymbol_dummyargs (s);
12166 list != NULL;
12167 list = ffebld_trail (list))
12168 {
12169 arg = ffebld_head (list);
12170 if (ffebld_op (arg) == FFEBLD_opSTAR)
12171 {
12172 ffecom_is_altreturning_ = TRUE;
12173 break;
12174 }
12175 }
12176 }
c7e4ee3a 12177}
5ff904cd 12178
c7e4ee3a
CB
12179FILE *
12180ffecom_open_include (char *name, ffewhereLine l, ffewhereColumn c)
12181{
c7e4ee3a 12182 return ffecom_open_include_ (name, l, c);
c7e4ee3a 12183}
5ff904cd 12184
c7e4ee3a 12185/* ffecom_ptr_to_expr -- Transform expr into gcc tree with & in front
5ff904cd 12186
c7e4ee3a
CB
12187 tree t;
12188 ffebld expr; // FFE expression.
12189 tree = ffecom_ptr_to_expr(expr);
5ff904cd 12190
c7e4ee3a 12191 Like ffecom_expr, but sticks address-of in front of most things. */
5ff904cd 12192
c7e4ee3a
CB
12193tree
12194ffecom_ptr_to_expr (ffebld expr)
12195{
12196 tree item;
12197 ffeinfoBasictype bt;
12198 ffeinfoKindtype kt;
12199 ffesymbol s;
5ff904cd 12200
c7e4ee3a 12201 assert (expr != NULL);
5ff904cd 12202
c7e4ee3a
CB
12203 switch (ffebld_op (expr))
12204 {
12205 case FFEBLD_opSYMTER:
12206 s = ffebld_symter (expr);
12207 if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC)
12208 {
12209 ffecomGfrt ix;
5ff904cd 12210
c7e4ee3a
CB
12211 ix = ffeintrin_gfrt_indirect (ffebld_symter_implementation (expr));
12212 assert (ix != FFECOM_gfrt);
12213 if ((item = ffecom_gfrt_[ix]) == NULL_TREE)
12214 {
12215 ffecom_make_gfrt_ (ix);
12216 item = ffecom_gfrt_[ix];
12217 }
12218 }
12219 else
12220 {
12221 item = ffesymbol_hook (s).decl_tree;
12222 if (item == NULL_TREE)
12223 {
12224 s = ffecom_sym_transform_ (s);
12225 item = ffesymbol_hook (s).decl_tree;
12226 }
12227 }
12228 assert (item != NULL);
12229 if (item == error_mark_node)
12230 return item;
12231 if (!ffesymbol_hook (s).addr)
12232 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12233 item);
12234 return item;
5ff904cd 12235
c7e4ee3a 12236 case FFEBLD_opARRAYREF:
ff852b44 12237 return ffecom_arrayref_ (NULL_TREE, expr, 1);
5ff904cd 12238
c7e4ee3a 12239 case FFEBLD_opCONTER:
5ff904cd 12240
c7e4ee3a
CB
12241 bt = ffeinfo_basictype (ffebld_info (expr));
12242 kt = ffeinfo_kindtype (ffebld_info (expr));
5ff904cd 12243
c7e4ee3a
CB
12244 item = ffecom_constantunion (&ffebld_constant_union
12245 (ffebld_conter (expr)), bt, kt,
12246 ffecom_tree_type[bt][kt]);
12247 if (item == error_mark_node)
12248 return error_mark_node;
12249 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12250 item);
12251 return item;
5ff904cd 12252
c7e4ee3a
CB
12253 case FFEBLD_opANY:
12254 return error_mark_node;
5ff904cd 12255
c7e4ee3a
CB
12256 default:
12257 bt = ffeinfo_basictype (ffebld_info (expr));
12258 kt = ffeinfo_kindtype (ffebld_info (expr));
12259
12260 item = ffecom_expr (expr);
12261 if (item == error_mark_node)
12262 return error_mark_node;
12263
12264 /* The back end currently optimizes a bit too zealously for us, in that
12265 we fail JCB001 if the following block of code is omitted. It checks
12266 to see if the transformed expression is a symbol or array reference,
12267 and encloses it in a SAVE_EXPR if that is the case. */
12268
12269 STRIP_NOPS (item);
12270 if ((TREE_CODE (item) == VAR_DECL)
12271 || (TREE_CODE (item) == PARM_DECL)
12272 || (TREE_CODE (item) == RESULT_DECL)
12273 || (TREE_CODE (item) == INDIRECT_REF)
12274 || (TREE_CODE (item) == ARRAY_REF)
12275 || (TREE_CODE (item) == COMPONENT_REF)
12276#ifdef OFFSET_REF
12277 || (TREE_CODE (item) == OFFSET_REF)
12278#endif
12279 || (TREE_CODE (item) == BUFFER_REF)
12280 || (TREE_CODE (item) == REALPART_EXPR)
12281 || (TREE_CODE (item) == IMAGPART_EXPR))
12282 {
12283 item = ffecom_save_tree (item);
12284 }
12285
12286 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12287 item);
12288 return item;
12289 }
12290
12291 assert ("fall-through error" == NULL);
12292 return error_mark_node;
5ff904cd
JL
12293}
12294
c7e4ee3a 12295/* Obtain a temp var with given data type.
5ff904cd 12296
c7e4ee3a
CB
12297 size is FFETARGET_charactersizeNONE for a non-CHARACTER type
12298 or >= 0 for a CHARACTER type.
5ff904cd 12299
c7e4ee3a 12300 elements is -1 for a scalar or > 0 for an array of type. */
5ff904cd 12301
5ff904cd 12302tree
c7e4ee3a
CB
12303ffecom_make_tempvar (const char *commentary, tree type,
12304 ffetargetCharacterSize size, int elements)
5ff904cd 12305{
c7e4ee3a
CB
12306 tree t;
12307 static int mynumber;
5ff904cd 12308
c7e4ee3a 12309 assert (current_binding_level->prep_state < 2);
702edf1d 12310
c7e4ee3a
CB
12311 if (type == error_mark_node)
12312 return error_mark_node;
702edf1d 12313
c7e4ee3a
CB
12314 if (size != FFETARGET_charactersizeNONE)
12315 type = build_array_type (type,
12316 build_range_type (ffecom_f2c_ftnlen_type_node,
12317 ffecom_f2c_ftnlen_one_node,
12318 build_int_2 (size, 0)));
12319 if (elements != -1)
12320 type = build_array_type (type,
12321 build_range_type (integer_type_node,
12322 integer_zero_node,
12323 build_int_2 (elements - 1,
12324 0)));
12325 t = build_decl (VAR_DECL,
12326 ffecom_get_invented_identifier ("__g77_%s_%d",
12327 commentary,
12328 mynumber++),
12329 type);
5ff904cd 12330
c7e4ee3a
CB
12331 t = start_decl (t, FALSE);
12332 finish_decl (t, NULL_TREE, FALSE);
12333
c7e4ee3a
CB
12334 return t;
12335}
5ff904cd 12336
c7e4ee3a 12337/* Prepare argument pointer to expression.
5ff904cd 12338
c7e4ee3a
CB
12339 Like ffecom_prepare_expr, except for expressions to be evaluated
12340 via ffecom_arg_ptr_to_expr. */
5ff904cd 12341
c7e4ee3a
CB
12342void
12343ffecom_prepare_arg_ptr_to_expr (ffebld expr)
5ff904cd 12344{
c7e4ee3a
CB
12345 /* ~~For now, it seems to be the same thing. */
12346 ffecom_prepare_expr (expr);
12347 return;
12348}
702edf1d 12349
c7e4ee3a 12350/* End of preparations. */
702edf1d 12351
c7e4ee3a
CB
12352bool
12353ffecom_prepare_end (void)
12354{
12355 int prep_state = current_binding_level->prep_state;
5ff904cd 12356
c7e4ee3a
CB
12357 assert (prep_state < 2);
12358 current_binding_level->prep_state = 2;
5ff904cd 12359
c7e4ee3a 12360 return (prep_state == 1) ? TRUE : FALSE;
5ff904cd
JL
12361}
12362
c7e4ee3a 12363/* Prepare expression.
5ff904cd 12364
c7e4ee3a
CB
12365 This is called before any code is generated for the current block.
12366 It scans the expression, declares any temporaries that might be needed
12367 during evaluation of the expression, and stores those temporaries in
12368 the appropriate "hook" fields of the expression. `dest', if not NULL,
12369 specifies the destination that ffecom_expr_ will see, in case that
12370 helps avoid generating unused temporaries.
12371
12372 ~~Improve to avoid allocating unused temporaries by taking `dest'
12373 into account vis-a-vis aliasing requirements of complex/character
12374 functions. */
12375
12376void
12377ffecom_prepare_expr_ (ffebld expr, ffebld dest UNUSED)
5ff904cd 12378{
c7e4ee3a
CB
12379 ffeinfoBasictype bt;
12380 ffeinfoKindtype kt;
12381 ffetargetCharacterSize sz;
12382 tree tempvar = NULL_TREE;
5ff904cd 12383
c7e4ee3a
CB
12384 assert (current_binding_level->prep_state < 2);
12385
12386 if (! expr)
12387 return;
12388
12389 bt = ffeinfo_basictype (ffebld_info (expr));
12390 kt = ffeinfo_kindtype (ffebld_info (expr));
12391 sz = ffeinfo_size (ffebld_info (expr));
12392
12393 /* Generate whatever temporaries are needed to represent the result
12394 of the expression. */
12395
47d98fa2
CB
12396 if (bt == FFEINFO_basictypeCHARACTER)
12397 {
12398 while (ffebld_op (expr) == FFEBLD_opPAREN)
12399 expr = ffebld_left (expr);
12400 }
12401
c7e4ee3a 12402 switch (ffebld_op (expr))
5ff904cd 12403 {
c7e4ee3a
CB
12404 default:
12405 /* Don't make temps for SYMTER, CONTER, etc. */
12406 if (ffebld_arity (expr) == 0)
12407 break;
5ff904cd 12408
c7e4ee3a 12409 switch (bt)
5ff904cd 12410 {
c7e4ee3a
CB
12411 case FFEINFO_basictypeCOMPLEX:
12412 if (ffebld_op (expr) == FFEBLD_opFUNCREF)
12413 {
12414 ffesymbol s;
5ff904cd 12415
c7e4ee3a
CB
12416 if (ffebld_op (ffebld_left (expr)) != FFEBLD_opSYMTER)
12417 break;
5ff904cd 12418
c7e4ee3a
CB
12419 s = ffebld_symter (ffebld_left (expr));
12420 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT
68779408
CB
12421 || (ffesymbol_where (s) != FFEINFO_whereINTRINSIC
12422 && ! ffesymbol_is_f2c (s))
12423 || (ffesymbol_where (s) == FFEINFO_whereINTRINSIC
12424 && ! ffe_is_f2c_library ()))
c7e4ee3a
CB
12425 break;
12426 }
12427 else if (ffebld_op (expr) == FFEBLD_opPOWER)
12428 {
12429 /* Requires special treatment. There's no POW_CC function
12430 in libg2c, so POW_ZZ is used, which means we always
12431 need a double-complex temp, not a single-complex. */
12432 kt = FFEINFO_kindtypeREAL2;
12433 }
12434 else if (ffebld_op (expr) != FFEBLD_opDIVIDE)
12435 /* The other ops don't need temps for complex operands. */
12436 break;
5ff904cd 12437
c7e4ee3a
CB
12438 /* ~~~Avoid making temps for some intrinsics, such as AIMAG(C),
12439 REAL(C). See 19990325-0.f, routine `check', for cases. */
12440 tempvar = ffecom_make_tempvar ("complex",
12441 ffecom_tree_type
12442 [FFEINFO_basictypeCOMPLEX][kt],
12443 FFETARGET_charactersizeNONE,
12444 -1);
5ff904cd
JL
12445 break;
12446
c7e4ee3a
CB
12447 case FFEINFO_basictypeCHARACTER:
12448 if (ffebld_op (expr) != FFEBLD_opFUNCREF)
12449 break;
12450
12451 if (sz == FFETARGET_charactersizeNONE)
12452 /* ~~Kludge alert! This should someday be fixed. */
12453 sz = 24;
12454
12455 tempvar = ffecom_make_tempvar ("char", char_type_node, sz, -1);
5ff904cd
JL
12456 break;
12457
12458 default:
5ff904cd
JL
12459 break;
12460 }
c7e4ee3a 12461 break;
5ff904cd 12462
c7e4ee3a
CB
12463#ifdef HAHA
12464 case FFEBLD_opPOWER:
12465 {
12466 tree rtype, ltype;
12467 tree rtmp, ltmp, result;
5ff904cd 12468
c7e4ee3a
CB
12469 ltype = ffecom_type_expr (ffebld_left (expr));
12470 rtype = ffecom_type_expr (ffebld_right (expr));
5ff904cd 12471
c7e4ee3a
CB
12472 rtmp = ffecom_make_tempvar (rtype, FFETARGET_charactersizeNONE, -1);
12473 ltmp = ffecom_make_tempvar (ltype, FFETARGET_charactersizeNONE, -1);
12474 result = ffecom_make_tempvar (ltype, FFETARGET_charactersizeNONE, -1);
5ff904cd 12475
c7e4ee3a
CB
12476 tempvar = make_tree_vec (3);
12477 TREE_VEC_ELT (tempvar, 0) = rtmp;
12478 TREE_VEC_ELT (tempvar, 1) = ltmp;
12479 TREE_VEC_ELT (tempvar, 2) = result;
12480 }
12481 break;
12482#endif /* HAHA */
5ff904cd 12483
c7e4ee3a
CB
12484 case FFEBLD_opCONCATENATE:
12485 {
12486 /* This gets special handling, because only one set of temps
12487 is needed for a tree of these -- the tree is treated as
12488 a flattened list of concatenations when generating code. */
5ff904cd 12489
c7e4ee3a
CB
12490 ffecomConcatList_ catlist;
12491 tree ltmp, itmp, result;
12492 int count;
12493 int i;
5ff904cd 12494
c7e4ee3a
CB
12495 catlist = ffecom_concat_list_new_ (expr, FFETARGET_charactersizeNONE);
12496 count = ffecom_concat_list_count_ (catlist);
5ff904cd 12497
c7e4ee3a
CB
12498 if (count >= 2)
12499 {
12500 ltmp
12501 = ffecom_make_tempvar ("concat_len",
12502 ffecom_f2c_ftnlen_type_node,
12503 FFETARGET_charactersizeNONE, count);
12504 itmp
12505 = ffecom_make_tempvar ("concat_item",
12506 ffecom_f2c_address_type_node,
12507 FFETARGET_charactersizeNONE, count);
12508 result
12509 = ffecom_make_tempvar ("concat_res",
12510 char_type_node,
12511 ffecom_concat_list_maxlen_ (catlist),
12512 -1);
12513
12514 tempvar = make_tree_vec (3);
12515 TREE_VEC_ELT (tempvar, 0) = ltmp;
12516 TREE_VEC_ELT (tempvar, 1) = itmp;
12517 TREE_VEC_ELT (tempvar, 2) = result;
12518 }
5ff904cd 12519
c7e4ee3a
CB
12520 for (i = 0; i < count; ++i)
12521 ffecom_prepare_arg_ptr_to_expr (ffecom_concat_list_expr_ (catlist,
12522 i));
5ff904cd 12523
c7e4ee3a 12524 ffecom_concat_list_kill_ (catlist);
5ff904cd 12525
c7e4ee3a
CB
12526 if (tempvar)
12527 {
12528 ffebld_nonter_set_hook (expr, tempvar);
12529 current_binding_level->prep_state = 1;
12530 }
12531 }
12532 return;
5ff904cd 12533
c7e4ee3a
CB
12534 case FFEBLD_opCONVERT:
12535 if (bt == FFEINFO_basictypeCHARACTER
12536 && ((ffebld_size_known (ffebld_left (expr))
12537 == FFETARGET_charactersizeNONE)
12538 || (ffebld_size_known (ffebld_left (expr)) >= sz)))
12539 tempvar = ffecom_make_tempvar ("convert", char_type_node, sz, -1);
12540 break;
12541 }
5ff904cd 12542
c7e4ee3a
CB
12543 if (tempvar)
12544 {
12545 ffebld_nonter_set_hook (expr, tempvar);
12546 current_binding_level->prep_state = 1;
12547 }
5ff904cd 12548
c7e4ee3a 12549 /* Prepare subexpressions for this expr. */
5ff904cd 12550
c7e4ee3a 12551 switch (ffebld_op (expr))
5ff904cd 12552 {
c7e4ee3a
CB
12553 case FFEBLD_opPERCENT_LOC:
12554 ffecom_prepare_ptr_to_expr (ffebld_left (expr));
12555 break;
5ff904cd 12556
c7e4ee3a
CB
12557 case FFEBLD_opPERCENT_VAL:
12558 case FFEBLD_opPERCENT_REF:
12559 ffecom_prepare_expr (ffebld_left (expr));
12560 break;
5ff904cd 12561
c7e4ee3a
CB
12562 case FFEBLD_opPERCENT_DESCR:
12563 ffecom_prepare_arg_ptr_to_expr (ffebld_left (expr));
12564 break;
5ff904cd 12565
c7e4ee3a
CB
12566 case FFEBLD_opITEM:
12567 {
12568 ffebld item;
5ff904cd 12569
c7e4ee3a
CB
12570 for (item = expr;
12571 item != NULL;
12572 item = ffebld_trail (item))
12573 if (ffebld_head (item) != NULL)
12574 ffecom_prepare_expr (ffebld_head (item));
12575 }
12576 break;
5ff904cd 12577
c7e4ee3a
CB
12578 default:
12579 /* Need to handle character conversion specially. */
12580 switch (ffebld_arity (expr))
12581 {
12582 case 2:
12583 ffecom_prepare_expr (ffebld_left (expr));
12584 ffecom_prepare_expr (ffebld_right (expr));
12585 break;
5ff904cd 12586
c7e4ee3a
CB
12587 case 1:
12588 ffecom_prepare_expr (ffebld_left (expr));
12589 break;
5ff904cd 12590
c7e4ee3a
CB
12591 default:
12592 break;
12593 }
12594 }
5ff904cd 12595
c7e4ee3a 12596 return;
5ff904cd
JL
12597}
12598
c7e4ee3a 12599/* Prepare expression for reading and writing.
5ff904cd 12600
c7e4ee3a
CB
12601 Like ffecom_prepare_expr, except for expressions to be evaluated
12602 via ffecom_expr_rw. */
5ff904cd 12603
c7e4ee3a
CB
12604void
12605ffecom_prepare_expr_rw (tree type, ffebld expr)
12606{
12607 /* This is all we support for now. */
12608 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
5ff904cd 12609
c7e4ee3a
CB
12610 /* ~~For now, it seems to be the same thing. */
12611 ffecom_prepare_expr (expr);
12612 return;
12613}
5ff904cd 12614
c7e4ee3a 12615/* Prepare expression for writing.
5ff904cd 12616
c7e4ee3a
CB
12617 Like ffecom_prepare_expr, except for expressions to be evaluated
12618 via ffecom_expr_w. */
5ff904cd
JL
12619
12620void
c7e4ee3a 12621ffecom_prepare_expr_w (tree type, ffebld expr)
5ff904cd 12622{
c7e4ee3a
CB
12623 /* This is all we support for now. */
12624 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
5ff904cd 12625
c7e4ee3a
CB
12626 /* ~~For now, it seems to be the same thing. */
12627 ffecom_prepare_expr (expr);
12628 return;
12629}
5ff904cd 12630
c7e4ee3a 12631/* Prepare expression for returning.
5ff904cd 12632
c7e4ee3a
CB
12633 Like ffecom_prepare_expr, except for expressions to be evaluated
12634 via ffecom_return_expr. */
5ff904cd 12635
c7e4ee3a
CB
12636void
12637ffecom_prepare_return_expr (ffebld expr)
12638{
12639 assert (current_binding_level->prep_state < 2);
5ff904cd 12640
c7e4ee3a
CB
12641 if (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE
12642 && ffecom_is_altreturning_
12643 && expr != NULL)
12644 ffecom_prepare_expr (expr);
12645}
5ff904cd 12646
c7e4ee3a 12647/* Prepare pointer to expression.
5ff904cd 12648
c7e4ee3a
CB
12649 Like ffecom_prepare_expr, except for expressions to be evaluated
12650 via ffecom_ptr_to_expr. */
5ff904cd 12651
c7e4ee3a
CB
12652void
12653ffecom_prepare_ptr_to_expr (ffebld expr)
12654{
12655 /* ~~For now, it seems to be the same thing. */
12656 ffecom_prepare_expr (expr);
12657 return;
5ff904cd
JL
12658}
12659
c7e4ee3a 12660/* Transform expression into constant pointer-to-expression tree.
5ff904cd 12661
c7e4ee3a
CB
12662 If the expression can be transformed into a pointer-to-expression tree
12663 that is constant, that is done, and the tree returned. Else NULL_TREE
12664 is returned.
5ff904cd 12665
c7e4ee3a
CB
12666 That way, a caller can attempt to provide compile-time initialization
12667 of a variable and, if that fails, *then* choose to start a new block
12668 and resort to using temporaries, as appropriate. */
5ff904cd 12669
c7e4ee3a
CB
12670tree
12671ffecom_ptr_to_const_expr (ffebld expr)
5ff904cd 12672{
c7e4ee3a
CB
12673 if (! expr)
12674 return integer_zero_node;
5ff904cd 12675
c7e4ee3a
CB
12676 if (ffebld_op (expr) == FFEBLD_opANY)
12677 return error_mark_node;
5ff904cd 12678
c7e4ee3a
CB
12679 if (ffebld_arity (expr) == 0
12680 && (ffebld_op (expr) != FFEBLD_opSYMTER
12681 || ffebld_where (expr) == FFEINFO_whereCOMMON
12682 || ffebld_where (expr) == FFEINFO_whereGLOBAL
12683 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
5ff904cd 12684 {
c7e4ee3a
CB
12685 tree t;
12686
12687 t = ffecom_ptr_to_expr (expr);
12688 assert (TREE_CONSTANT (t));
12689 return t;
5ff904cd
JL
12690 }
12691
c7e4ee3a
CB
12692 return NULL_TREE;
12693}
12694
12695/* ffecom_return_expr -- Returns return-value expr given alt return expr
12696
12697 tree rtn; // NULL_TREE means use expand_null_return()
12698 ffebld expr; // NULL if no alt return expr to RETURN stmt
12699 rtn = ffecom_return_expr(expr);
12700
12701 Based on the program unit type and other info (like return function
12702 type, return master function type when alternate ENTRY points,
12703 whether subroutine has any alternate RETURN points, etc), returns the
12704 appropriate expression to be returned to the caller, or NULL_TREE
12705 meaning no return value or the caller expects it to be returned somewhere
12706 else (which is handled by other parts of this module). */
12707
c7e4ee3a
CB
12708tree
12709ffecom_return_expr (ffebld expr)
12710{
12711 tree rtn;
12712
12713 switch (ffecom_primary_entry_kind_)
5ff904cd 12714 {
c7e4ee3a
CB
12715 case FFEINFO_kindPROGRAM:
12716 case FFEINFO_kindBLOCKDATA:
12717 rtn = NULL_TREE;
12718 break;
5ff904cd 12719
c7e4ee3a
CB
12720 case FFEINFO_kindSUBROUTINE:
12721 if (!ffecom_is_altreturning_)
12722 rtn = NULL_TREE; /* No alt returns, never an expr. */
12723 else if (expr == NULL)
12724 rtn = integer_zero_node;
12725 else
12726 rtn = ffecom_expr (expr);
12727 break;
12728
12729 case FFEINFO_kindFUNCTION:
12730 if ((ffecom_multi_retval_ != NULL_TREE)
12731 || (ffesymbol_basictype (ffecom_primary_entry_)
12732 == FFEINFO_basictypeCHARACTER)
12733 || ((ffesymbol_basictype (ffecom_primary_entry_)
12734 == FFEINFO_basictypeCOMPLEX)
12735 && (ffecom_num_entrypoints_ == 0)
12736 && ffesymbol_is_f2c (ffecom_primary_entry_)))
12737 { /* Value is returned by direct assignment
12738 into (implicit) dummy. */
12739 rtn = NULL_TREE;
12740 break;
5ff904cd 12741 }
c7e4ee3a
CB
12742 rtn = ffecom_func_result_;
12743#if 0
12744 /* Spurious error if RETURN happens before first reference! So elide
12745 this code. In particular, for debugging registry, rtn should always
12746 be non-null after all, but TREE_USED won't be set until we encounter
12747 a reference in the code. Perfectly okay (but weird) code that,
12748 e.g., has "GOTO 20;10 RETURN;20 RTN=0;GOTO 10", would result in
12749 this diagnostic for no reason. Have people use -O -Wuninitialized
12750 and leave it to the back end to find obviously weird cases. */
5ff904cd 12751
c7e4ee3a
CB
12752 /* Used to "assert(rtn != NULL_TREE);" here, but it's kind of a valid
12753 situation; if the return value has never been referenced, it won't
12754 have a tree under 2pass mode. */
12755 if ((rtn == NULL_TREE)
12756 || !TREE_USED (rtn))
12757 {
12758 ffebad_start (FFEBAD_RETURN_VALUE_UNSET);
12759 ffebad_here (0, ffesymbol_where_line (ffecom_primary_entry_),
12760 ffesymbol_where_column (ffecom_primary_entry_));
12761 ffebad_string (ffesymbol_text (ffesymbol_funcresult
12762 (ffecom_primary_entry_)));
12763 ffebad_finish ();
12764 }
5ff904cd 12765#endif
c7e4ee3a 12766 break;
5ff904cd 12767
c7e4ee3a
CB
12768 default:
12769 assert ("bad unit kind" == NULL);
12770 case FFEINFO_kindANY:
12771 rtn = error_mark_node;
12772 break;
12773 }
5ff904cd 12774
c7e4ee3a
CB
12775 return rtn;
12776}
5ff904cd 12777
c7e4ee3a 12778/* Do save_expr only if tree is not error_mark_node. */
5ff904cd 12779
c7e4ee3a
CB
12780tree
12781ffecom_save_tree (tree t)
5ff904cd 12782{
c7e4ee3a 12783 return save_expr (t);
5ff904cd 12784}
c7e4ee3a
CB
12785
12786/* Start a compound statement (block). */
5ff904cd 12787
5ff904cd 12788void
c7e4ee3a 12789ffecom_start_compstmt (void)
5ff904cd 12790{
c7e4ee3a 12791 bison_rule_pushlevel_ ();
5ff904cd
JL
12792}
12793
c7e4ee3a 12794/* Public entry point for front end to access start_decl. */
5ff904cd 12795
5ff904cd 12796tree
c7e4ee3a 12797ffecom_start_decl (tree decl, bool is_initialized)
5ff904cd 12798{
c7e4ee3a
CB
12799 DECL_INITIAL (decl) = is_initialized ? error_mark_node : NULL_TREE;
12800 return start_decl (decl, FALSE);
12801}
5ff904cd 12802
c7e4ee3a 12803/* ffecom_sym_commit -- Symbol's state being committed to reality
5ff904cd 12804
c7e4ee3a
CB
12805 ffesymbol s;
12806 ffecom_sym_commit(s);
5ff904cd 12807
c7e4ee3a
CB
12808 Does whatever the backend needs when a symbol is committed after having
12809 been backtrackable for a period of time. */
5ff904cd 12810
c7e4ee3a
CB
12811void
12812ffecom_sym_commit (ffesymbol s UNUSED)
12813{
12814 assert (!ffesymbol_retractable ());
12815}
5ff904cd 12816
c7e4ee3a 12817/* ffecom_sym_end_transition -- Perform end transition on all symbols
5ff904cd 12818
c7e4ee3a 12819 ffecom_sym_end_transition();
5ff904cd 12820
c7e4ee3a
CB
12821 Does backend-specific stuff and also calls ffest_sym_end_transition
12822 to do the necessary FFE stuff.
5ff904cd 12823
c7e4ee3a
CB
12824 Backtracking is never enabled when this fn is called, so don't worry
12825 about it. */
5ff904cd 12826
c7e4ee3a
CB
12827ffesymbol
12828ffecom_sym_end_transition (ffesymbol s)
12829{
12830 ffestorag st;
5ff904cd 12831
c7e4ee3a 12832 assert (!ffesymbol_retractable ());
5ff904cd 12833
c7e4ee3a 12834 s = ffest_sym_end_transition (s);
5ff904cd 12835
c7e4ee3a
CB
12836 if ((ffesymbol_kind (s) == FFEINFO_kindBLOCKDATA)
12837 && (ffesymbol_where (s) == FFEINFO_whereGLOBAL))
12838 {
12839 ffecom_list_blockdata_
12840 = ffebld_new_item (ffebld_new_symter (s, FFEINTRIN_genNONE,
12841 FFEINTRIN_specNONE,
12842 FFEINTRIN_impNONE),
12843 ffecom_list_blockdata_);
5ff904cd 12844 }
5ff904cd 12845
c7e4ee3a
CB
12846 /* This is where we finally notice that a symbol has partial initialization
12847 and finalize it. */
5ff904cd 12848
c7e4ee3a
CB
12849 if (ffesymbol_accretion (s) != NULL)
12850 {
12851 assert (ffesymbol_init (s) == NULL);
12852 ffecom_notify_init_symbol (s);
12853 }
12854 else if (((st = ffesymbol_storage (s)) != NULL)
12855 && ((st = ffestorag_parent (st)) != NULL)
12856 && (ffestorag_accretion (st) != NULL))
12857 {
12858 assert (ffestorag_init (st) == NULL);
12859 ffecom_notify_init_storage (st);
12860 }
5ff904cd 12861
c7e4ee3a
CB
12862 if ((ffesymbol_kind (s) == FFEINFO_kindCOMMON)
12863 && (ffesymbol_where (s) == FFEINFO_whereLOCAL)
12864 && (ffesymbol_storage (s) != NULL))
12865 {
12866 ffecom_list_common_
12867 = ffebld_new_item (ffebld_new_symter (s, FFEINTRIN_genNONE,
12868 FFEINTRIN_specNONE,
12869 FFEINTRIN_impNONE),
12870 ffecom_list_common_);
12871 }
5ff904cd 12872
c7e4ee3a
CB
12873 return s;
12874}
5ff904cd 12875
c7e4ee3a 12876/* ffecom_sym_exec_transition -- Perform exec transition on all symbols
5ff904cd 12877
c7e4ee3a 12878 ffecom_sym_exec_transition();
5ff904cd 12879
c7e4ee3a
CB
12880 Does backend-specific stuff and also calls ffest_sym_exec_transition
12881 to do the necessary FFE stuff.
5ff904cd 12882
c7e4ee3a
CB
12883 See the long-winded description in ffecom_sym_learned for info
12884 on handling the situation where backtracking is inhibited. */
5ff904cd 12885
c7e4ee3a
CB
12886ffesymbol
12887ffecom_sym_exec_transition (ffesymbol s)
12888{
12889 s = ffest_sym_exec_transition (s);
5ff904cd 12890
c7e4ee3a
CB
12891 return s;
12892}
5ff904cd 12893
c7e4ee3a 12894/* ffecom_sym_learned -- Initial or more info gained on symbol after exec
5ff904cd 12895
c7e4ee3a
CB
12896 ffesymbol s;
12897 s = ffecom_sym_learned(s);
5ff904cd 12898
c7e4ee3a
CB
12899 Called when a new symbol is seen after the exec transition or when more
12900 info (perhaps) is gained for an UNCERTAIN symbol. The symbol state when
12901 it arrives here is that all its latest info is updated already, so its
12902 state may be UNCERTAIN or UNDERSTOOD, it might already have the hook
12903 field filled in if its gone through here or exec_transition first, and
12904 so on.
5ff904cd 12905
c7e4ee3a
CB
12906 The backend probably wants to check ffesymbol_retractable() to see if
12907 backtracking is in effect. If so, the FFE's changes to the symbol may
12908 be retracted (undone) or committed (ratified), at which time the
12909 appropriate ffecom_sym_retract or _commit function will be called
12910 for that function.
5ff904cd 12911
c7e4ee3a
CB
12912 If the backend has its own backtracking mechanism, great, use it so that
12913 committal is a simple operation. Though it doesn't make much difference,
12914 I suppose: the reason for tentative symbol evolution in the FFE is to
12915 enable error detection in weird incorrect statements early and to disable
12916 incorrect error detection on a correct statement. The backend is not
12917 likely to introduce any information that'll get involved in these
12918 considerations, so it is probably just fine that the implementation
12919 model for this fn and for _exec_transition is to not do anything
12920 (besides the required FFE stuff) if ffesymbol_retractable() returns TRUE
12921 and instead wait until ffecom_sym_commit is called (which it never
12922 will be as long as we're using ambiguity-detecting statement analysis in
12923 the FFE, which we are initially to shake out the code, but don't depend
12924 on this), otherwise go ahead and do whatever is needed.
5ff904cd 12925
c7e4ee3a
CB
12926 In essence, then, when this fn and _exec_transition get called while
12927 backtracking is enabled, a general mechanism would be to flag which (or
12928 both) of these were called (and in what order? neat question as to what
12929 might happen that I'm too lame to think through right now) and then when
12930 _commit is called reproduce the original calling sequence, if any, for
12931 the two fns (at which point backtracking will, of course, be disabled). */
5ff904cd 12932
c7e4ee3a
CB
12933ffesymbol
12934ffecom_sym_learned (ffesymbol s)
12935{
12936 ffestorag_exec_layout (s);
5ff904cd 12937
c7e4ee3a 12938 return s;
5ff904cd
JL
12939}
12940
c7e4ee3a 12941/* ffecom_sym_retract -- Symbol's state being retracted from reality
5ff904cd 12942
c7e4ee3a
CB
12943 ffesymbol s;
12944 ffecom_sym_retract(s);
5ff904cd 12945
c7e4ee3a
CB
12946 Does whatever the backend needs when a symbol is retracted after having
12947 been backtrackable for a period of time. */
5ff904cd 12948
c7e4ee3a
CB
12949void
12950ffecom_sym_retract (ffesymbol s UNUSED)
5ff904cd 12951{
c7e4ee3a 12952 assert (!ffesymbol_retractable ());
5ff904cd 12953
c7e4ee3a
CB
12954#if 0 /* GCC doesn't commit any backtrackable sins,
12955 so nothing needed here. */
12956 switch (ffesymbol_hook (s).state)
5ff904cd 12957 {
c7e4ee3a 12958 case 0: /* nothing happened yet. */
5ff904cd
JL
12959 break;
12960
c7e4ee3a 12961 case 1: /* exec transition happened. */
5ff904cd
JL
12962 break;
12963
c7e4ee3a
CB
12964 case 2: /* learned happened. */
12965 break;
5ff904cd 12966
c7e4ee3a
CB
12967 case 3: /* learned then exec. */
12968 break;
12969
12970 case 4: /* exec then learned. */
5ff904cd
JL
12971 break;
12972
12973 default:
c7e4ee3a 12974 assert ("bad hook state" == NULL);
5ff904cd
JL
12975 break;
12976 }
c7e4ee3a
CB
12977#endif
12978}
5ff904cd 12979
c7e4ee3a
CB
12980/* Create temporary gcc label. */
12981
c7e4ee3a
CB
12982tree
12983ffecom_temp_label ()
12984{
12985 tree glabel;
12986 static int mynumber = 0;
12987
12988 glabel = build_decl (LABEL_DECL,
12989 ffecom_get_invented_identifier ("__g77_label_%d",
c7e4ee3a
CB
12990 mynumber++),
12991 void_type_node);
12992 DECL_CONTEXT (glabel) = current_function_decl;
12993 DECL_MODE (glabel) = VOIDmode;
12994
12995 return glabel;
5ff904cd
JL
12996}
12997
c7e4ee3a
CB
12998/* Return an expression that is usable as an arg in a conditional context
12999 (IF, DO WHILE, .NOT., and so on).
13000
13001 Use the one provided for the back end as of >2.6.0. */
5ff904cd 13002
a2977d2d 13003tree
c7e4ee3a 13004ffecom_truth_value (tree expr)
5ff904cd 13005{
c7e4ee3a 13006 return truthvalue_conversion (expr);
5ff904cd 13007}
c7e4ee3a 13008
c7e4ee3a
CB
13009/* Return the inversion of a truth value (the inversion of what
13010 ffecom_truth_value builds).
5ff904cd 13011
c7e4ee3a
CB
13012 Apparently invert_truthvalue, which is properly in the back end, is
13013 enough for now, so just use it. */
5ff904cd 13014
5ff904cd 13015tree
c7e4ee3a 13016ffecom_truth_value_invert (tree expr)
5ff904cd 13017{
c7e4ee3a 13018 return invert_truthvalue (ffecom_truth_value (expr));
5ff904cd
JL
13019}
13020
c7e4ee3a
CB
13021/* Return the tree that is the type of the expression, as would be
13022 returned in TREE_TYPE(ffecom_expr(expr)), without otherwise
13023 transforming the expression, generating temporaries, etc. */
5ff904cd 13024
c7e4ee3a
CB
13025tree
13026ffecom_type_expr (ffebld expr)
13027{
13028 ffeinfoBasictype bt;
13029 ffeinfoKindtype kt;
13030 tree tree_type;
13031
13032 assert (expr != NULL);
13033
13034 bt = ffeinfo_basictype (ffebld_info (expr));
13035 kt = ffeinfo_kindtype (ffebld_info (expr));
13036 tree_type = ffecom_tree_type[bt][kt];
13037
13038 switch (ffebld_op (expr))
13039 {
13040 case FFEBLD_opCONTER:
13041 case FFEBLD_opSYMTER:
13042 case FFEBLD_opARRAYREF:
13043 case FFEBLD_opUPLUS:
13044 case FFEBLD_opPAREN:
13045 case FFEBLD_opUMINUS:
13046 case FFEBLD_opADD:
13047 case FFEBLD_opSUBTRACT:
13048 case FFEBLD_opMULTIPLY:
13049 case FFEBLD_opDIVIDE:
13050 case FFEBLD_opPOWER:
13051 case FFEBLD_opNOT:
13052 case FFEBLD_opFUNCREF:
13053 case FFEBLD_opSUBRREF:
13054 case FFEBLD_opAND:
13055 case FFEBLD_opOR:
13056 case FFEBLD_opXOR:
13057 case FFEBLD_opNEQV:
13058 case FFEBLD_opEQV:
13059 case FFEBLD_opCONVERT:
13060 case FFEBLD_opLT:
13061 case FFEBLD_opLE:
13062 case FFEBLD_opEQ:
13063 case FFEBLD_opNE:
13064 case FFEBLD_opGT:
13065 case FFEBLD_opGE:
13066 case FFEBLD_opPERCENT_LOC:
13067 return tree_type;
13068
13069 case FFEBLD_opACCTER:
13070 case FFEBLD_opARRTER:
13071 case FFEBLD_opITEM:
13072 case FFEBLD_opSTAR:
13073 case FFEBLD_opBOUNDS:
13074 case FFEBLD_opREPEAT:
13075 case FFEBLD_opLABTER:
13076 case FFEBLD_opLABTOK:
13077 case FFEBLD_opIMPDO:
13078 case FFEBLD_opCONCATENATE:
13079 case FFEBLD_opSUBSTR:
13080 default:
13081 assert ("bad op for ffecom_type_expr" == NULL);
13082 /* Fall through. */
13083 case FFEBLD_opANY:
13084 return error_mark_node;
13085 }
13086}
13087
13088/* Return PARM_DECL for arg#1 of master fn containing alternate ENTRY points
13089
13090 If the PARM_DECL already exists, return it, else create it. It's an
13091 integer_type_node argument for the master function that implements a
13092 subroutine or function with more than one entrypoint and is bound at
13093 run time with the entrypoint number (0 for SUBROUTINE/FUNCTION, 1 for
13094 first ENTRY statement, and so on). */
5ff904cd 13095
c7e4ee3a
CB
13096tree
13097ffecom_which_entrypoint_decl ()
5ff904cd 13098{
c7e4ee3a
CB
13099 assert (ffecom_which_entrypoint_decl_ != NULL_TREE);
13100
13101 return ffecom_which_entrypoint_decl_;
5ff904cd 13102}
c7e4ee3a
CB
13103\f
13104/* The following sections consists of private and public functions
13105 that have the same names and perform roughly the same functions
13106 as counterparts in the C front end. Changes in the C front end
13107 might affect how things should be done here. Only functions
13108 needed by the back end should be public here; the rest should
13109 be private (static in the C sense). Functions needed by other
13110 g77 front-end modules should be accessed by them via public
13111 ffecom_* names, which should themselves call private versions
13112 in this section so the private versions are easy to recognize
13113 when upgrading to a new gcc and finding interesting changes
13114 in the front end.
5ff904cd 13115
c7e4ee3a
CB
13116 Functions named after rule "foo:" in c-parse.y are named
13117 "bison_rule_foo_" so they are easy to find. */
5ff904cd 13118
c7e4ee3a
CB
13119static void
13120bison_rule_pushlevel_ ()
13121{
13122 emit_line_note (input_filename, lineno);
13123 pushlevel (0);
13124 clear_last_expr ();
c7e4ee3a
CB
13125 expand_start_bindings (0);
13126}
5ff904cd 13127
c7e4ee3a
CB
13128static tree
13129bison_rule_compstmt_ ()
5ff904cd 13130{
c7e4ee3a
CB
13131 tree t;
13132 int keep = kept_level_p ();
5ff904cd 13133
c7e4ee3a
CB
13134 /* Make the temps go away. */
13135 if (! keep)
13136 current_binding_level->names = NULL_TREE;
5ff904cd 13137
c7e4ee3a
CB
13138 emit_line_note (input_filename, lineno);
13139 expand_end_bindings (getdecls (), keep, 0);
13140 t = poplevel (keep, 1, 0);
5ff904cd 13141
c7e4ee3a
CB
13142 return t;
13143}
5ff904cd 13144
c7e4ee3a
CB
13145/* Return a definition for a builtin function named NAME and whose data type
13146 is TYPE. TYPE should be a function type with argument types.
13147 FUNCTION_CODE tells later passes how to compile calls to this function.
13148 See tree.h for its possible values.
5ff904cd 13149
c7e4ee3a
CB
13150 If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME,
13151 the name to be called if we can't opencode the function. */
5ff904cd 13152
26db82d8
BS
13153tree
13154builtin_function (const char *name, tree type, int function_code,
13155 enum built_in_class class,
c7e4ee3a
CB
13156 const char *library_name)
13157{
13158 tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
13159 DECL_EXTERNAL (decl) = 1;
13160 TREE_PUBLIC (decl) = 1;
13161 if (library_name)
92643fea 13162 SET_DECL_ASSEMBLER_NAME (decl, get_identifier (library_name));
3e411c3f 13163 make_decl_rtl (decl, NULL);
c7e4ee3a 13164 pushdecl (decl);
26db82d8
BS
13165 DECL_BUILT_IN_CLASS (decl) = class;
13166 DECL_FUNCTION_CODE (decl) = function_code;
5ff904cd 13167
c7e4ee3a 13168 return decl;
5ff904cd
JL
13169}
13170
c7e4ee3a
CB
13171/* Handle when a new declaration NEWDECL
13172 has the same name as an old one OLDDECL
13173 in the same binding contour.
13174 Prints an error message if appropriate.
5ff904cd 13175
c7e4ee3a
CB
13176 If safely possible, alter OLDDECL to look like NEWDECL, and return 1.
13177 Otherwise, return 0. */
5ff904cd 13178
c7e4ee3a
CB
13179static int
13180duplicate_decls (tree newdecl, tree olddecl)
5ff904cd 13181{
c7e4ee3a
CB
13182 int types_match = 1;
13183 int new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL
13184 && DECL_INITIAL (newdecl) != 0);
13185 tree oldtype = TREE_TYPE (olddecl);
13186 tree newtype = TREE_TYPE (newdecl);
5ff904cd 13187
c7e4ee3a
CB
13188 if (olddecl == newdecl)
13189 return 1;
5ff904cd 13190
c7e4ee3a
CB
13191 if (TREE_CODE (newtype) == ERROR_MARK
13192 || TREE_CODE (oldtype) == ERROR_MARK)
13193 types_match = 0;
5ff904cd 13194
c7e4ee3a
CB
13195 /* New decl is completely inconsistent with the old one =>
13196 tell caller to replace the old one.
13197 This is always an error except in the case of shadowing a builtin. */
13198 if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
13199 return 0;
5ff904cd 13200
c7e4ee3a
CB
13201 /* For real parm decl following a forward decl,
13202 return 1 so old decl will be reused. */
13203 if (types_match && TREE_CODE (newdecl) == PARM_DECL
13204 && TREE_ASM_WRITTEN (olddecl) && ! TREE_ASM_WRITTEN (newdecl))
13205 return 1;
5ff904cd 13206
c7e4ee3a
CB
13207 /* The new declaration is the same kind of object as the old one.
13208 The declarations may partially match. Print warnings if they don't
13209 match enough. Ultimately, copy most of the information from the new
13210 decl to the old one, and keep using the old one. */
5ff904cd 13211
c7e4ee3a
CB
13212 if (TREE_CODE (olddecl) == FUNCTION_DECL
13213 && DECL_BUILT_IN (olddecl))
13214 {
13215 /* A function declaration for a built-in function. */
13216 if (!TREE_PUBLIC (newdecl))
13217 return 0;
13218 else if (!types_match)
13219 {
13220 /* Accept the return type of the new declaration if same modes. */
13221 tree oldreturntype = TREE_TYPE (TREE_TYPE (olddecl));
13222 tree newreturntype = TREE_TYPE (TREE_TYPE (newdecl));
5ff904cd 13223
c7e4ee3a
CB
13224 if (TYPE_MODE (oldreturntype) == TYPE_MODE (newreturntype))
13225 {
13226 /* Function types may be shared, so we can't just modify
13227 the return type of olddecl's function type. */
13228 tree newtype
13229 = build_function_type (newreturntype,
13230 TYPE_ARG_TYPES (TREE_TYPE (olddecl)));
5ff904cd 13231
c7e4ee3a
CB
13232 types_match = 1;
13233 if (types_match)
13234 TREE_TYPE (olddecl) = newtype;
13235 }
c7e4ee3a
CB
13236 }
13237 if (!types_match)
13238 return 0;
13239 }
13240 else if (TREE_CODE (olddecl) == FUNCTION_DECL
13241 && DECL_SOURCE_LINE (olddecl) == 0)
5ff904cd 13242 {
c7e4ee3a
CB
13243 /* A function declaration for a predeclared function
13244 that isn't actually built in. */
13245 if (!TREE_PUBLIC (newdecl))
13246 return 0;
13247 else if (!types_match)
13248 {
13249 /* If the types don't match, preserve volatility indication.
13250 Later on, we will discard everything else about the
13251 default declaration. */
13252 TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
13253 }
13254 }
5ff904cd 13255
c7e4ee3a
CB
13256 /* Copy all the DECL_... slots specified in the new decl
13257 except for any that we copy here from the old type.
5ff904cd 13258
c7e4ee3a
CB
13259 Past this point, we don't change OLDTYPE and NEWTYPE
13260 even if we change the types of NEWDECL and OLDDECL. */
5ff904cd 13261
c7e4ee3a
CB
13262 if (types_match)
13263 {
c7e4ee3a
CB
13264 /* Merge the data types specified in the two decls. */
13265 if (TREE_CODE (newdecl) != FUNCTION_DECL || !DECL_BUILT_IN (olddecl))
13266 TREE_TYPE (newdecl)
13267 = TREE_TYPE (olddecl)
13268 = TREE_TYPE (newdecl);
5ff904cd 13269
c7e4ee3a
CB
13270 /* Lay the type out, unless already done. */
13271 if (oldtype != TREE_TYPE (newdecl))
13272 {
13273 if (TREE_TYPE (newdecl) != error_mark_node)
13274 layout_type (TREE_TYPE (newdecl));
13275 if (TREE_CODE (newdecl) != FUNCTION_DECL
13276 && TREE_CODE (newdecl) != TYPE_DECL
13277 && TREE_CODE (newdecl) != CONST_DECL)
13278 layout_decl (newdecl, 0);
13279 }
13280 else
13281 {
13282 /* Since the type is OLDDECL's, make OLDDECL's size go with. */
13283 DECL_SIZE (newdecl) = DECL_SIZE (olddecl);
06ceef4e 13284 DECL_SIZE_UNIT (newdecl) = DECL_SIZE_UNIT (olddecl);
c7e4ee3a
CB
13285 if (TREE_CODE (olddecl) != FUNCTION_DECL)
13286 if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl))
11cf4d18
JJ
13287 {
13288 DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl);
13289 DECL_USER_ALIGN (newdecl) |= DECL_USER_ALIGN (olddecl);
13290 }
c7e4ee3a 13291 }
5ff904cd 13292
c7e4ee3a 13293 /* Keep the old rtl since we can safely use it. */
fe01b88e 13294 COPY_DECL_RTL (olddecl, newdecl);
5ff904cd 13295
c7e4ee3a
CB
13296 /* Merge the type qualifiers. */
13297 if (DECL_BUILT_IN_NONANSI (olddecl) && TREE_THIS_VOLATILE (olddecl)
13298 && !TREE_THIS_VOLATILE (newdecl))
13299 TREE_THIS_VOLATILE (olddecl) = 0;
13300 if (TREE_READONLY (newdecl))
13301 TREE_READONLY (olddecl) = 1;
13302 if (TREE_THIS_VOLATILE (newdecl))
13303 {
13304 TREE_THIS_VOLATILE (olddecl) = 1;
13305 if (TREE_CODE (newdecl) == VAR_DECL)
13306 make_var_volatile (newdecl);
13307 }
5ff904cd 13308
c7e4ee3a
CB
13309 /* Keep source location of definition rather than declaration.
13310 Likewise, keep decl at outer scope. */
13311 if ((DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0)
13312 || (DECL_CONTEXT (newdecl) != 0 && DECL_CONTEXT (olddecl) == 0))
13313 {
13314 DECL_SOURCE_LINE (newdecl) = DECL_SOURCE_LINE (olddecl);
13315 DECL_SOURCE_FILE (newdecl) = DECL_SOURCE_FILE (olddecl);
5ff904cd 13316
c7e4ee3a
CB
13317 if (DECL_CONTEXT (olddecl) == 0
13318 && TREE_CODE (newdecl) != FUNCTION_DECL)
13319 DECL_CONTEXT (newdecl) = 0;
13320 }
5ff904cd 13321
c7e4ee3a
CB
13322 /* Merge the unused-warning information. */
13323 if (DECL_IN_SYSTEM_HEADER (olddecl))
13324 DECL_IN_SYSTEM_HEADER (newdecl) = 1;
13325 else if (DECL_IN_SYSTEM_HEADER (newdecl))
13326 DECL_IN_SYSTEM_HEADER (olddecl) = 1;
5ff904cd 13327
c7e4ee3a
CB
13328 /* Merge the initialization information. */
13329 if (DECL_INITIAL (newdecl) == 0)
13330 DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
5ff904cd 13331
c7e4ee3a
CB
13332 /* Merge the section attribute.
13333 We want to issue an error if the sections conflict but that must be
13334 done later in decl_attributes since we are called before attributes
13335 are assigned. */
13336 if (DECL_SECTION_NAME (newdecl) == NULL_TREE)
13337 DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl);
5ff904cd 13338
c7e4ee3a
CB
13339 if (TREE_CODE (newdecl) == FUNCTION_DECL)
13340 {
13341 DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl);
13342 DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
13343 }
c7e4ee3a
CB
13344 }
13345 /* If cannot merge, then use the new type and qualifiers,
13346 and don't preserve the old rtl. */
13347 else
13348 {
13349 TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
13350 TREE_READONLY (olddecl) = TREE_READONLY (newdecl);
13351 TREE_THIS_VOLATILE (olddecl) = TREE_THIS_VOLATILE (newdecl);
13352 TREE_SIDE_EFFECTS (olddecl) = TREE_SIDE_EFFECTS (newdecl);
13353 }
5ff904cd 13354
c7e4ee3a
CB
13355 /* Merge the storage class information. */
13356 /* For functions, static overrides non-static. */
13357 if (TREE_CODE (newdecl) == FUNCTION_DECL)
13358 {
13359 TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl);
13360 /* This is since we don't automatically
13361 copy the attributes of NEWDECL into OLDDECL. */
13362 TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
13363 /* If this clears `static', clear it in the identifier too. */
13364 if (! TREE_PUBLIC (olddecl))
13365 TREE_PUBLIC (DECL_NAME (olddecl)) = 0;
13366 }
13367 if (DECL_EXTERNAL (newdecl))
13368 {
13369 TREE_STATIC (newdecl) = TREE_STATIC (olddecl);
13370 DECL_EXTERNAL (newdecl) = DECL_EXTERNAL (olddecl);
13371 /* An extern decl does not override previous storage class. */
13372 TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
13373 }
13374 else
13375 {
13376 TREE_STATIC (olddecl) = TREE_STATIC (newdecl);
13377 TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
13378 }
5ff904cd 13379
c7e4ee3a
CB
13380 /* If either decl says `inline', this fn is inline,
13381 unless its definition was passed already. */
13382 if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == 0)
13383 DECL_INLINE (olddecl) = 1;
13384 DECL_INLINE (newdecl) = DECL_INLINE (olddecl);
5ff904cd 13385
c7e4ee3a
CB
13386 /* Get rid of any built-in function if new arg types don't match it
13387 or if we have a function definition. */
13388 if (TREE_CODE (newdecl) == FUNCTION_DECL
13389 && DECL_BUILT_IN (olddecl)
13390 && (!types_match || new_is_definition))
13391 {
13392 TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
26db82d8 13393 DECL_BUILT_IN_CLASS (olddecl) = NOT_BUILT_IN;
c7e4ee3a 13394 }
5ff904cd 13395
c7e4ee3a
CB
13396 /* If redeclaring a builtin function, and not a definition,
13397 it stays built in.
13398 Also preserve various other info from the definition. */
13399 if (TREE_CODE (newdecl) == FUNCTION_DECL && !new_is_definition)
13400 {
13401 if (DECL_BUILT_IN (olddecl))
13402 {
26db82d8 13403 DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl);
c7e4ee3a
CB
13404 DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
13405 }
5ff904cd 13406
c7e4ee3a
CB
13407 DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
13408 DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
13409 DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl);
13410 DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
13411 }
5ff904cd 13412
c7e4ee3a
CB
13413 /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
13414 But preserve olddecl's DECL_UID. */
13415 {
13416 register unsigned olddecl_uid = DECL_UID (olddecl);
5ff904cd 13417
c7e4ee3a
CB
13418 memcpy ((char *) olddecl + sizeof (struct tree_common),
13419 (char *) newdecl + sizeof (struct tree_common),
13420 sizeof (struct tree_decl) - sizeof (struct tree_common));
13421 DECL_UID (olddecl) = olddecl_uid;
13422 }
5ff904cd 13423
c7e4ee3a 13424 return 1;
5ff904cd
JL
13425}
13426
c7e4ee3a
CB
13427/* Finish processing of a declaration;
13428 install its initial value.
13429 If the length of an array type is not known before,
13430 it must be determined now, from the initial value, or it is an error. */
13431
5ff904cd 13432static void
c7e4ee3a 13433finish_decl (tree decl, tree init, bool is_top_level)
5ff904cd 13434{
c7e4ee3a
CB
13435 register tree type = TREE_TYPE (decl);
13436 int was_incomplete = (DECL_SIZE (decl) == 0);
c7e4ee3a
CB
13437 bool at_top_level = (current_binding_level == global_binding_level);
13438 bool top_level = is_top_level || at_top_level;
5ff904cd 13439
c7e4ee3a
CB
13440 /* Caller should pass TRUE for is_top_level only if we wouldn't be at top
13441 level anyway. */
13442 assert (!is_top_level || !at_top_level);
5ff904cd 13443
c7e4ee3a
CB
13444 if (TREE_CODE (decl) == PARM_DECL)
13445 assert (init == NULL_TREE);
13446 /* Remember that PARM_DECL doesn't have a DECL_INITIAL field per se -- it
13447 overlaps DECL_ARG_TYPE. */
13448 else if (init == NULL_TREE)
13449 assert (DECL_INITIAL (decl) == NULL_TREE);
13450 else
13451 assert (DECL_INITIAL (decl) == error_mark_node);
5ff904cd 13452
c7e4ee3a 13453 if (init != NULL_TREE)
5ff904cd 13454 {
c7e4ee3a
CB
13455 if (TREE_CODE (decl) != TYPE_DECL)
13456 DECL_INITIAL (decl) = init;
13457 else
13458 {
13459 /* typedef foo = bar; store the type of bar as the type of foo. */
13460 TREE_TYPE (decl) = TREE_TYPE (init);
13461 DECL_INITIAL (decl) = init = 0;
13462 }
5ff904cd
JL
13463 }
13464
c7e4ee3a 13465 /* Deduce size of array from initialization, if not already known */
5ff904cd 13466
c7e4ee3a
CB
13467 if (TREE_CODE (type) == ARRAY_TYPE
13468 && TYPE_DOMAIN (type) == 0
13469 && TREE_CODE (decl) != TYPE_DECL)
13470 {
13471 assert (top_level);
13472 assert (was_incomplete);
5ff904cd 13473
c7e4ee3a
CB
13474 layout_decl (decl, 0);
13475 }
5ff904cd 13476
c7e4ee3a
CB
13477 if (TREE_CODE (decl) == VAR_DECL)
13478 {
13479 if (DECL_SIZE (decl) == NULL_TREE
13480 && TYPE_SIZE (TREE_TYPE (decl)) != NULL_TREE)
13481 layout_decl (decl, 0);
5ff904cd 13482
c7e4ee3a
CB
13483 if (DECL_SIZE (decl) == NULL_TREE
13484 && (TREE_STATIC (decl)
13485 ?
13486 /* A static variable with an incomplete type is an error if it is
13487 initialized. Also if it is not file scope. Otherwise, let it
13488 through, but if it is not `extern' then it may cause an error
13489 message later. */
13490 (DECL_INITIAL (decl) != 0 || DECL_CONTEXT (decl) != 0)
13491 :
13492 /* An automatic variable with an incomplete type is an error. */
13493 !DECL_EXTERNAL (decl)))
13494 {
13495 assert ("storage size not known" == NULL);
13496 abort ();
13497 }
5ff904cd 13498
c7e4ee3a
CB
13499 if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl))
13500 && (DECL_SIZE (decl) != 0)
13501 && (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST))
13502 {
13503 assert ("storage size not constant" == NULL);
13504 abort ();
13505 }
13506 }
5ff904cd 13507
c7e4ee3a
CB
13508 /* Output the assembler code and/or RTL code for variables and functions,
13509 unless the type is an undefined structure or union. If not, it will get
13510 done when the type is completed. */
5ff904cd 13511
c7e4ee3a 13512 if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)
5ff904cd 13513 {
c7e4ee3a
CB
13514 rest_of_decl_compilation (decl, NULL,
13515 DECL_CONTEXT (decl) == 0,
13516 0);
5ff904cd 13517
c7e4ee3a
CB
13518 if (DECL_CONTEXT (decl) != 0)
13519 {
13520 /* Recompute the RTL of a local array now if it used to be an
13521 incomplete type. */
13522 if (was_incomplete
13523 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
5ff904cd 13524 {
c7e4ee3a
CB
13525 /* If we used it already as memory, it must stay in memory. */
13526 TREE_ADDRESSABLE (decl) = TREE_USED (decl);
13527 /* If it's still incomplete now, no init will save it. */
13528 if (DECL_SIZE (decl) == 0)
13529 DECL_INITIAL (decl) = 0;
13530 expand_decl (decl);
5ff904cd 13531 }
c7e4ee3a
CB
13532 /* Compute and store the initial value. */
13533 if (TREE_CODE (decl) != FUNCTION_DECL)
13534 expand_decl_init (decl);
13535 }
13536 }
13537 else if (TREE_CODE (decl) == TYPE_DECL)
13538 {
3e411c3f 13539 rest_of_decl_compilation (decl, NULL,
c7e4ee3a
CB
13540 DECL_CONTEXT (decl) == 0,
13541 0);
13542 }
5ff904cd 13543
c7e4ee3a
CB
13544 /* At the end of a declaration, throw away any variable type sizes of types
13545 defined inside that declaration. There is no use computing them in the
13546 following function definition. */
13547 if (current_binding_level == global_binding_level)
13548 get_pending_sizes ();
13549}
5ff904cd 13550
c7e4ee3a
CB
13551/* Finish up a function declaration and compile that function
13552 all the way to assembler language output. The free the storage
13553 for the function definition.
5ff904cd 13554
c7e4ee3a 13555 This is called after parsing the body of the function definition.
5ff904cd 13556
c7e4ee3a
CB
13557 NESTED is nonzero if the function being finished is nested in another. */
13558
13559static void
13560finish_function (int nested)
13561{
13562 register tree fndecl = current_function_decl;
13563
13564 assert (fndecl != NULL_TREE);
13565 if (TREE_CODE (fndecl) != ERROR_MARK)
13566 {
13567 if (nested)
13568 assert (DECL_CONTEXT (fndecl) != NULL_TREE);
5ff904cd 13569 else
c7e4ee3a
CB
13570 assert (DECL_CONTEXT (fndecl) == NULL_TREE);
13571 }
5ff904cd 13572
c7e4ee3a
CB
13573/* TREE_READONLY (fndecl) = 1;
13574 This caused &foo to be of type ptr-to-const-function
13575 which then got a warning when stored in a ptr-to-function variable. */
5ff904cd 13576
c7e4ee3a 13577 poplevel (1, 0, 1);
5ff904cd 13578
c7e4ee3a
CB
13579 if (TREE_CODE (fndecl) != ERROR_MARK)
13580 {
13581 BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
5ff904cd 13582
c7e4ee3a 13583 /* Must mark the RESULT_DECL as being in this function. */
5ff904cd 13584
c7e4ee3a 13585 DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;
5ff904cd 13586
c7e4ee3a
CB
13587 /* Obey `register' declarations if `setjmp' is called in this fn. */
13588 /* Generate rtl for function exit. */
13589 expand_function_end (input_filename, lineno, 0);
5ff904cd 13590
7189a4b0
GK
13591 /* If this is a nested function, protect the local variables in the stack
13592 above us from being collected while we're compiling this function. */
1f8f4a0b 13593 if (nested)
7189a4b0
GK
13594 ggc_push_context ();
13595
c7e4ee3a
CB
13596 /* Run the optimizers and output the assembler code for this function. */
13597 rest_of_compilation (fndecl);
7189a4b0
GK
13598
13599 /* Undo the GC context switch. */
1f8f4a0b 13600 if (nested)
7189a4b0 13601 ggc_pop_context ();
c7e4ee3a 13602 }
5ff904cd 13603
c7e4ee3a
CB
13604 if (TREE_CODE (fndecl) != ERROR_MARK
13605 && !nested
13606 && DECL_SAVED_INSNS (fndecl) == 0)
13607 {
13608 /* Stop pointing to the local nodes about to be freed. */
13609 /* But DECL_INITIAL must remain nonzero so we know this was an actual
13610 function definition. */
13611 /* For a nested function, this is done in pop_f_function_context. */
13612 /* If rest_of_compilation set this to 0, leave it 0. */
13613 if (DECL_INITIAL (fndecl) != 0)
13614 DECL_INITIAL (fndecl) = error_mark_node;
13615 DECL_ARGUMENTS (fndecl) = 0;
5ff904cd 13616 }
c7e4ee3a
CB
13617
13618 if (!nested)
5ff904cd 13619 {
c7e4ee3a
CB
13620 /* Let the error reporting routines know that we're outside a function.
13621 For a nested function, this value is used in pop_c_function_context
13622 and then reset via pop_function_context. */
13623 ffecom_outer_function_decl_ = current_function_decl = NULL;
5ff904cd 13624 }
c7e4ee3a 13625}
5ff904cd 13626
c7e4ee3a
CB
13627/* Plug-in replacement for identifying the name of a decl and, for a
13628 function, what we call it in diagnostics. For now, "program unit"
13629 should suffice, since it's a bit of a hassle to figure out which
13630 of several kinds of things it is. Note that it could conceivably
13631 be a statement function, which probably isn't really a program unit
13632 per se, but if that comes up, it should be easy to check (being a
13633 nested function and all). */
13634
4b731ffa 13635static const char *
c7e4ee3a
CB
13636lang_printable_name (tree decl, int v)
13637{
13638 /* Just to keep GCC quiet about the unused variable.
13639 In theory, differing values of V should produce different
13640 output. */
13641 switch (v)
5ff904cd 13642 {
c7e4ee3a
CB
13643 default:
13644 if (TREE_CODE (decl) == ERROR_MARK)
13645 return "erroneous code";
13646 return IDENTIFIER_POINTER (DECL_NAME (decl));
5ff904cd 13647 }
c7e4ee3a
CB
13648}
13649
13650/* g77's function to print out name of current function that caused
13651 an error. */
13652
b0791fa9 13653static void
eae4bce3
TM
13654lang_print_error_function (diagnostic_context *context __attribute__((unused)),
13655 const char *file)
c7e4ee3a
CB
13656{
13657 static ffeglobal last_g = NULL;
13658 static ffesymbol last_s = NULL;
13659 ffeglobal g;
13660 ffesymbol s;
13661 const char *kind;
13662
13663 if ((ffecom_primary_entry_ == NULL)
13664 || (ffesymbol_global (ffecom_primary_entry_) == NULL))
5ff904cd 13665 {
c7e4ee3a
CB
13666 g = NULL;
13667 s = NULL;
13668 kind = NULL;
5ff904cd
JL
13669 }
13670 else
13671 {
c7e4ee3a
CB
13672 g = ffesymbol_global (ffecom_primary_entry_);
13673 if (ffecom_nested_entry_ == NULL)
13674 {
13675 s = ffecom_primary_entry_;
13676 switch (ffesymbol_kind (s))
13677 {
13678 case FFEINFO_kindFUNCTION:
13679 kind = "function";
13680 break;
5ff904cd 13681
c7e4ee3a
CB
13682 case FFEINFO_kindSUBROUTINE:
13683 kind = "subroutine";
13684 break;
5ff904cd 13685
c7e4ee3a
CB
13686 case FFEINFO_kindPROGRAM:
13687 kind = "program";
13688 break;
13689
13690 case FFEINFO_kindBLOCKDATA:
13691 kind = "block-data";
13692 break;
13693
13694 default:
13695 kind = ffeinfo_kind_message (ffesymbol_kind (s));
13696 break;
13697 }
13698 }
13699 else
13700 {
13701 s = ffecom_nested_entry_;
13702 kind = "statement function";
13703 }
5ff904cd
JL
13704 }
13705
c7e4ee3a 13706 if ((last_g != g) || (last_s != s))
5ff904cd 13707 {
c7e4ee3a
CB
13708 if (file)
13709 fprintf (stderr, "%s: ", file);
13710
13711 if (s == NULL)
13712 fprintf (stderr, "Outside of any program unit:\n");
13713 else
5ff904cd 13714 {
c7e4ee3a
CB
13715 const char *name = ffesymbol_text (s);
13716
13717 fprintf (stderr, "In %s `%s':\n", kind, name);
5ff904cd 13718 }
5ff904cd 13719
c7e4ee3a
CB
13720 last_g = g;
13721 last_s = s;
5ff904cd 13722 }
c7e4ee3a 13723}
5ff904cd 13724
c7e4ee3a 13725/* Similar to `lookup_name' but look only at current binding level. */
5ff904cd 13726
c7e4ee3a
CB
13727static tree
13728lookup_name_current_level (tree name)
13729{
13730 register tree t;
5ff904cd 13731
c7e4ee3a
CB
13732 if (current_binding_level == global_binding_level)
13733 return IDENTIFIER_GLOBAL_VALUE (name);
13734
13735 if (IDENTIFIER_LOCAL_VALUE (name) == 0)
13736 return 0;
13737
13738 for (t = current_binding_level->names; t; t = TREE_CHAIN (t))
13739 if (DECL_NAME (t) == name)
13740 break;
13741
13742 return t;
5ff904cd
JL
13743}
13744
c7e4ee3a 13745/* Create a new `struct binding_level'. */
5ff904cd 13746
c7e4ee3a
CB
13747static struct binding_level *
13748make_binding_level ()
5ff904cd 13749{
c7e4ee3a
CB
13750 /* NOSTRICT */
13751 return (struct binding_level *) xmalloc (sizeof (struct binding_level));
13752}
5ff904cd 13753
c7e4ee3a
CB
13754/* Save and restore the variables in this file and elsewhere
13755 that keep track of the progress of compilation of the current function.
13756 Used for nested functions. */
5ff904cd 13757
c7e4ee3a
CB
13758struct f_function
13759{
13760 struct f_function *next;
13761 tree named_labels;
13762 tree shadowed_labels;
13763 struct binding_level *binding_level;
13764};
5ff904cd 13765
c7e4ee3a 13766struct f_function *f_function_chain;
5ff904cd 13767
c7e4ee3a 13768/* Restore the variables used during compilation of a C function. */
5ff904cd 13769
c7e4ee3a
CB
13770static void
13771pop_f_function_context ()
13772{
13773 struct f_function *p = f_function_chain;
13774 tree link;
5ff904cd 13775
c7e4ee3a
CB
13776 /* Bring back all the labels that were shadowed. */
13777 for (link = shadowed_labels; link; link = TREE_CHAIN (link))
13778 if (DECL_NAME (TREE_VALUE (link)) != 0)
13779 IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link)))
13780 = TREE_VALUE (link);
5ff904cd 13781
c7e4ee3a
CB
13782 if (current_function_decl != error_mark_node
13783 && DECL_SAVED_INSNS (current_function_decl) == 0)
13784 {
13785 /* Stop pointing to the local nodes about to be freed. */
13786 /* But DECL_INITIAL must remain nonzero so we know this was an actual
13787 function definition. */
13788 DECL_INITIAL (current_function_decl) = error_mark_node;
13789 DECL_ARGUMENTS (current_function_decl) = 0;
5ff904cd
JL
13790 }
13791
c7e4ee3a 13792 pop_function_context ();
5ff904cd 13793
c7e4ee3a 13794 f_function_chain = p->next;
5ff904cd 13795
c7e4ee3a
CB
13796 named_labels = p->named_labels;
13797 shadowed_labels = p->shadowed_labels;
13798 current_binding_level = p->binding_level;
5ff904cd 13799
c7e4ee3a
CB
13800 free (p);
13801}
5ff904cd 13802
c7e4ee3a
CB
13803/* Save and reinitialize the variables
13804 used during compilation of a C function. */
5ff904cd 13805
c7e4ee3a
CB
13806static void
13807push_f_function_context ()
13808{
13809 struct f_function *p
13810 = (struct f_function *) xmalloc (sizeof (struct f_function));
5ff904cd 13811
c7e4ee3a
CB
13812 push_function_context ();
13813
13814 p->next = f_function_chain;
13815 f_function_chain = p;
13816
13817 p->named_labels = named_labels;
13818 p->shadowed_labels = shadowed_labels;
13819 p->binding_level = current_binding_level;
13820}
5ff904cd 13821
c7e4ee3a
CB
13822static void
13823push_parm_decl (tree parm)
13824{
13825 int old_immediate_size_expand = immediate_size_expand;
5ff904cd 13826
c7e4ee3a 13827 /* Don't try computing parm sizes now -- wait till fn is called. */
5ff904cd 13828
c7e4ee3a 13829 immediate_size_expand = 0;
5ff904cd 13830
c7e4ee3a 13831 /* Fill in arg stuff. */
5ff904cd 13832
c7e4ee3a
CB
13833 DECL_ARG_TYPE (parm) = TREE_TYPE (parm);
13834 DECL_ARG_TYPE_AS_WRITTEN (parm) = TREE_TYPE (parm);
13835 TREE_READONLY (parm) = 1; /* All implementation args are read-only. */
5ff904cd 13836
c7e4ee3a
CB
13837 parm = pushdecl (parm);
13838
13839 immediate_size_expand = old_immediate_size_expand;
13840
13841 finish_decl (parm, NULL_TREE, FALSE);
5ff904cd
JL
13842}
13843
c7e4ee3a 13844/* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL, if appropriate. */
5ff904cd 13845
c7e4ee3a
CB
13846static tree
13847pushdecl_top_level (x)
13848 tree x;
13849{
13850 register tree t;
13851 register struct binding_level *b = current_binding_level;
13852 register tree f = current_function_decl;
5ff904cd 13853
c7e4ee3a
CB
13854 current_binding_level = global_binding_level;
13855 current_function_decl = NULL_TREE;
13856 t = pushdecl (x);
13857 current_binding_level = b;
13858 current_function_decl = f;
13859 return t;
13860}
13861
13862/* Store the list of declarations of the current level.
13863 This is done for the parameter declarations of a function being defined,
13864 after they are modified in the light of any missing parameters. */
13865
13866static tree
13867storedecls (decls)
13868 tree decls;
13869{
13870 return current_binding_level->names = decls;
13871}
13872
13873/* Store the parameter declarations into the current function declaration.
13874 This is called after parsing the parameter declarations, before
13875 digesting the body of the function.
13876
13877 For an old-style definition, modify the function's type
13878 to specify at least the number of arguments. */
5ff904cd
JL
13879
13880static void
c7e4ee3a 13881store_parm_decls (int is_main_program UNUSED)
5ff904cd
JL
13882{
13883 register tree fndecl = current_function_decl;
13884
c7e4ee3a
CB
13885 if (fndecl == error_mark_node)
13886 return;
5ff904cd 13887
c7e4ee3a
CB
13888 /* This is a chain of PARM_DECLs from old-style parm declarations. */
13889 DECL_ARGUMENTS (fndecl) = storedecls (nreverse (getdecls ()));
5ff904cd 13890
c7e4ee3a 13891 /* Initialize the RTL code for the function. */
5ff904cd 13892
c7e4ee3a 13893 init_function_start (fndecl, input_filename, lineno);
56a0044b 13894
c7e4ee3a 13895 /* Set up parameters and prepare for return, for the function. */
5ff904cd 13896
c7e4ee3a
CB
13897 expand_function_start (fndecl, 0);
13898}
5ff904cd 13899
c7e4ee3a
CB
13900static tree
13901start_decl (tree decl, bool is_top_level)
13902{
13903 register tree tem;
13904 bool at_top_level = (current_binding_level == global_binding_level);
13905 bool top_level = is_top_level || at_top_level;
5ff904cd 13906
c7e4ee3a
CB
13907 /* Caller should pass TRUE for is_top_level only if we wouldn't be at top
13908 level anyway. */
13909 assert (!is_top_level || !at_top_level);
5ff904cd 13910
c7e4ee3a
CB
13911 if (DECL_INITIAL (decl) != NULL_TREE)
13912 {
13913 assert (DECL_INITIAL (decl) == error_mark_node);
13914 assert (!DECL_EXTERNAL (decl));
56a0044b 13915 }
c7e4ee3a
CB
13916 else if (top_level)
13917 assert ((TREE_STATIC (decl) == 1) || DECL_EXTERNAL (decl) == 1);
5ff904cd 13918
c7e4ee3a
CB
13919 /* For Fortran, we by default put things in .common when possible. */
13920 DECL_COMMON (decl) = 1;
5ff904cd 13921
c7e4ee3a
CB
13922 /* Add this decl to the current binding level. TEM may equal DECL or it may
13923 be a previous decl of the same name. */
13924 if (is_top_level)
13925 tem = pushdecl_top_level (decl);
13926 else
13927 tem = pushdecl (decl);
13928
13929 /* For a local variable, define the RTL now. */
13930 if (!top_level
13931 /* But not if this is a duplicate decl and we preserved the rtl from the
13932 previous one (which may or may not happen). */
19e7881c 13933 && !DECL_RTL_SET_P (tem))
5ff904cd 13934 {
c7e4ee3a
CB
13935 if (TYPE_SIZE (TREE_TYPE (tem)) != 0)
13936 expand_decl (tem);
13937 else if (TREE_CODE (TREE_TYPE (tem)) == ARRAY_TYPE
13938 && DECL_INITIAL (tem) != 0)
13939 expand_decl (tem);
5ff904cd
JL
13940 }
13941
c7e4ee3a 13942 return tem;
5ff904cd
JL
13943}
13944
c7e4ee3a
CB
13945/* Create the FUNCTION_DECL for a function definition.
13946 DECLSPECS and DECLARATOR are the parts of the declaration;
13947 they describe the function's name and the type it returns,
13948 but twisted together in a fashion that parallels the syntax of C.
5ff904cd 13949
c7e4ee3a
CB
13950 This function creates a binding context for the function body
13951 as well as setting up the FUNCTION_DECL in current_function_decl.
5ff904cd 13952
c7e4ee3a
CB
13953 Returns 1 on success. If the DECLARATOR is not suitable for a function
13954 (it defines a datum instead), we return 0, which tells
13955 yyparse to report a parse error.
5ff904cd 13956
c7e4ee3a
CB
13957 NESTED is nonzero for a function nested within another function. */
13958
13959static void
13960start_function (tree name, tree type, int nested, int public)
5ff904cd 13961{
c7e4ee3a
CB
13962 tree decl1;
13963 tree restype;
13964 int old_immediate_size_expand = immediate_size_expand;
5ff904cd 13965
c7e4ee3a
CB
13966 named_labels = 0;
13967 shadowed_labels = 0;
13968
13969 /* Don't expand any sizes in the return type of the function. */
13970 immediate_size_expand = 0;
13971
13972 if (nested)
5ff904cd 13973 {
c7e4ee3a
CB
13974 assert (!public);
13975 assert (current_function_decl != NULL_TREE);
13976 assert (DECL_CONTEXT (current_function_decl) == NULL_TREE);
13977 }
13978 else
13979 {
13980 assert (current_function_decl == NULL_TREE);
5ff904cd 13981 }
c7e4ee3a
CB
13982
13983 if (TREE_CODE (type) == ERROR_MARK)
13984 decl1 = current_function_decl = error_mark_node;
56a0044b 13985 else
5ff904cd 13986 {
c7e4ee3a
CB
13987 decl1 = build_decl (FUNCTION_DECL,
13988 name,
13989 type);
13990 TREE_PUBLIC (decl1) = public ? 1 : 0;
13991 if (nested)
13992 DECL_INLINE (decl1) = 1;
13993 TREE_STATIC (decl1) = 1;
13994 DECL_EXTERNAL (decl1) = 0;
5ff904cd 13995
c7e4ee3a 13996 announce_function (decl1);
5ff904cd 13997
c7e4ee3a
CB
13998 /* Make the init_value nonzero so pushdecl knows this is not tentative.
13999 error_mark_node is replaced below (in poplevel) with the BLOCK. */
14000 DECL_INITIAL (decl1) = error_mark_node;
5ff904cd 14001
c7e4ee3a
CB
14002 /* Record the decl so that the function name is defined. If we already have
14003 a decl for this name, and it is a FUNCTION_DECL, use the old decl. */
5ff904cd 14004
c7e4ee3a 14005 current_function_decl = pushdecl (decl1);
5ff904cd
JL
14006 }
14007
c7e4ee3a
CB
14008 if (!nested)
14009 ffecom_outer_function_decl_ = current_function_decl;
5ff904cd 14010
c7e4ee3a
CB
14011 pushlevel (0);
14012 current_binding_level->prep_state = 2;
5ff904cd 14013
c7e4ee3a
CB
14014 if (TREE_CODE (current_function_decl) != ERROR_MARK)
14015 {
6c418184 14016 make_decl_rtl (current_function_decl, NULL);
5ff904cd 14017
c7e4ee3a
CB
14018 restype = TREE_TYPE (TREE_TYPE (current_function_decl));
14019 DECL_RESULT (current_function_decl)
14020 = build_decl (RESULT_DECL, NULL_TREE, restype);
5ff904cd 14021 }
5ff904cd 14022
c7e4ee3a
CB
14023 if (!nested && (TREE_CODE (current_function_decl) != ERROR_MARK))
14024 TREE_ADDRESSABLE (current_function_decl) = 1;
14025
14026 immediate_size_expand = old_immediate_size_expand;
14027}
14028\f
14029/* Here are the public functions the GNU back end needs. */
14030
14031tree
14032convert (type, expr)
14033 tree type, expr;
5ff904cd 14034{
c7e4ee3a
CB
14035 register tree e = expr;
14036 register enum tree_code code = TREE_CODE (type);
5ff904cd 14037
c7e4ee3a
CB
14038 if (type == TREE_TYPE (e)
14039 || TREE_CODE (e) == ERROR_MARK)
14040 return e;
14041 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
14042 return fold (build1 (NOP_EXPR, type, e));
14043 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
14044 || code == ERROR_MARK)
14045 return error_mark_node;
14046 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
14047 {
14048 assert ("void value not ignored as it ought to be" == NULL);
14049 return error_mark_node;
14050 }
14051 if (code == VOID_TYPE)
14052 return build1 (CONVERT_EXPR, type, e);
14053 if ((code != RECORD_TYPE)
14054 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
14055 e = ffecom_1 (REALPART_EXPR, TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e))),
14056 e);
14057 if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)
14058 return fold (convert_to_integer (type, e));
14059 if (code == POINTER_TYPE)
14060 return fold (convert_to_pointer (type, e));
14061 if (code == REAL_TYPE)
14062 return fold (convert_to_real (type, e));
14063 if (code == COMPLEX_TYPE)
14064 return fold (convert_to_complex (type, e));
14065 if (code == RECORD_TYPE)
14066 return fold (ffecom_convert_to_complex_ (type, e));
5ff904cd 14067
c7e4ee3a
CB
14068 assert ("conversion to non-scalar type requested" == NULL);
14069 return error_mark_node;
14070}
5ff904cd 14071
c7e4ee3a
CB
14072/* integrate_decl_tree calls this function, but since we don't use the
14073 DECL_LANG_SPECIFIC field, this is a no-op. */
5ff904cd 14074
c7e4ee3a
CB
14075void
14076copy_lang_decl (node)
14077 tree node UNUSED;
14078{
5ff904cd
JL
14079}
14080
c7e4ee3a
CB
14081/* Return the list of declarations of the current level.
14082 Note that this list is in reverse order unless/until
14083 you nreverse it; and when you do nreverse it, you must
14084 store the result back using `storedecls' or you will lose. */
5ff904cd 14085
c7e4ee3a
CB
14086tree
14087getdecls ()
5ff904cd 14088{
c7e4ee3a 14089 return current_binding_level->names;
5ff904cd
JL
14090}
14091
c7e4ee3a 14092/* Nonzero if we are currently in the global binding level. */
5ff904cd 14093
c7e4ee3a
CB
14094int
14095global_bindings_p ()
5ff904cd 14096{
c7e4ee3a
CB
14097 return current_binding_level == global_binding_level;
14098}
5ff904cd 14099
c7e4ee3a
CB
14100/* Print an error message for invalid use of an incomplete type.
14101 VALUE is the expression that was used (or 0 if that isn't known)
14102 and TYPE is the type that was invalid. */
5ff904cd 14103
c7e4ee3a
CB
14104void
14105incomplete_type_error (value, type)
14106 tree value UNUSED;
14107 tree type;
14108{
14109 if (TREE_CODE (type) == ERROR_MARK)
14110 return;
5ff904cd 14111
c7e4ee3a
CB
14112 assert ("incomplete type?!?" == NULL);
14113}
14114
7189a4b0 14115/* Mark ARG for GC. */
516b69ff 14116static void
54551044 14117mark_binding_level (void *arg)
7189a4b0
GK
14118{
14119 struct binding_level *level = *(struct binding_level **) arg;
14120
14121 while (level)
14122 {
14123 ggc_mark_tree (level->names);
14124 ggc_mark_tree (level->blocks);
14125 ggc_mark_tree (level->this_block);
14126 level = level->level_chain;
14127 }
14128}
14129
c7e4ee3a
CB
14130void
14131init_decl_processing ()
5ff904cd 14132{
7189a4b0
GK
14133 static tree *const tree_roots[] = {
14134 &current_function_decl,
14135 &string_type_node,
14136 &ffecom_tree_fun_type_void,
14137 &ffecom_integer_zero_node,
14138 &ffecom_integer_one_node,
14139 &ffecom_tree_subr_type,
14140 &ffecom_tree_ptr_to_subr_type,
14141 &ffecom_tree_blockdata_type,
14142 &ffecom_tree_xargc_,
14143 &ffecom_f2c_integer_type_node,
14144 &ffecom_f2c_ptr_to_integer_type_node,
14145 &ffecom_f2c_address_type_node,
14146 &ffecom_f2c_real_type_node,
14147 &ffecom_f2c_ptr_to_real_type_node,
14148 &ffecom_f2c_doublereal_type_node,
14149 &ffecom_f2c_complex_type_node,
14150 &ffecom_f2c_doublecomplex_type_node,
14151 &ffecom_f2c_longint_type_node,
14152 &ffecom_f2c_logical_type_node,
14153 &ffecom_f2c_flag_type_node,
14154 &ffecom_f2c_ftnlen_type_node,
14155 &ffecom_f2c_ftnlen_zero_node,
14156 &ffecom_f2c_ftnlen_one_node,
14157 &ffecom_f2c_ftnlen_two_node,
14158 &ffecom_f2c_ptr_to_ftnlen_type_node,
14159 &ffecom_f2c_ftnint_type_node,
14160 &ffecom_f2c_ptr_to_ftnint_type_node,
14161 &ffecom_outer_function_decl_,
14162 &ffecom_previous_function_decl_,
14163 &ffecom_which_entrypoint_decl_,
14164 &ffecom_float_zero_,
14165 &ffecom_float_half_,
14166 &ffecom_double_zero_,
14167 &ffecom_double_half_,
14168 &ffecom_func_result_,
14169 &ffecom_func_length_,
14170 &ffecom_multi_type_node_,
14171 &ffecom_multi_retval_,
14172 &named_labels,
14173 &shadowed_labels
14174 };
14175 size_t i;
14176
c7e4ee3a 14177 malloc_init ();
7189a4b0
GK
14178
14179 /* Record our roots. */
75ff2ca7 14180 for (i = 0; i < ARRAY_SIZE (tree_roots); i++)
7189a4b0 14181 ggc_add_tree_root (tree_roots[i], 1);
516b69ff 14182 ggc_add_tree_root (&ffecom_tree_type[0][0],
7189a4b0 14183 FFEINFO_basictype*FFEINFO_kindtype);
516b69ff 14184 ggc_add_tree_root (&ffecom_tree_fun_type[0][0],
7189a4b0 14185 FFEINFO_basictype*FFEINFO_kindtype);
516b69ff 14186 ggc_add_tree_root (&ffecom_tree_ptr_to_fun_type[0][0],
7189a4b0
GK
14187 FFEINFO_basictype*FFEINFO_kindtype);
14188 ggc_add_tree_root (ffecom_gfrt_, FFECOM_gfrt);
14189 ggc_add_root (&current_binding_level, 1, sizeof current_binding_level,
14190 mark_binding_level);
14191 ggc_add_root (&free_binding_level, 1, sizeof current_binding_level,
14192 mark_binding_level);
14193 ggc_add_root (&tracker_head, 1, sizeof tracker_head, mark_tracker_head);
14194
c7e4ee3a
CB
14195 ffe_init_0 ();
14196}
5ff904cd 14197
3b304f5b 14198const char *
c7e4ee3a 14199init_parse (filename)
3b304f5b 14200 const char *filename;
c7e4ee3a 14201{
c7e4ee3a
CB
14202 /* Open input file. */
14203 if (filename == 0 || !strcmp (filename, "-"))
5ff904cd 14204 {
c7e4ee3a
CB
14205 finput = stdin;
14206 filename = "stdin";
5ff904cd 14207 }
c7e4ee3a
CB
14208 else
14209 finput = fopen (filename, "r");
14210 if (finput == 0)
400500c4 14211 fatal_io_error ("can't open %s", filename);
5ff904cd 14212
c7e4ee3a
CB
14213#ifdef IO_BUFFER_SIZE
14214 setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
14215#endif
5ff904cd 14216
c7e4ee3a
CB
14217 /* Make identifier nodes long enough for the language-specific slots. */
14218 set_identifier_size (sizeof (struct lang_identifier));
14219 decl_printable_name = lang_printable_name;
c7e4ee3a 14220 print_error_function = lang_print_error_function;
5ff904cd 14221
c7e4ee3a
CB
14222 return filename;
14223}
5ff904cd 14224
c7e4ee3a
CB
14225void
14226finish_parse ()
14227{
14228 fclose (finput);
14229}
14230
14231/* Delete the node BLOCK from the current binding level.
14232 This is used for the block inside a stmt expr ({...})
14233 so that the block can be reinserted where appropriate. */
14234
14235static void
14236delete_block (block)
14237 tree block;
14238{
14239 tree t;
14240 if (current_binding_level->blocks == block)
14241 current_binding_level->blocks = TREE_CHAIN (block);
14242 for (t = current_binding_level->blocks; t;)
14243 {
14244 if (TREE_CHAIN (t) == block)
14245 TREE_CHAIN (t) = TREE_CHAIN (block);
14246 else
14247 t = TREE_CHAIN (t);
14248 }
14249 TREE_CHAIN (block) = NULL;
14250 /* Clear TREE_USED which is always set by poplevel.
14251 The flag is set again if insert_block is called. */
14252 TREE_USED (block) = 0;
14253}
14254
14255void
14256insert_block (block)
14257 tree block;
14258{
14259 TREE_USED (block) = 1;
14260 current_binding_level->blocks
14261 = chainon (current_binding_level->blocks, block);
14262}
14263
cd2a3ba2 14264/* Each front end provides its own. */
ee811cfd
NB
14265static void ffe_init PARAMS ((void));
14266static void ffe_finish PARAMS ((void));
14267static void ffe_init_options PARAMS ((void));
14268
17ed6335
RH
14269#undef LANG_HOOKS_INIT
14270#define LANG_HOOKS_INIT ffe_init
14271#undef LANG_HOOKS_FINISH
14272#define LANG_HOOKS_FINISH ffe_finish
14273#undef LANG_HOOKS_INIT_OPTIONS
14274#define LANG_HOOKS_INIT_OPTIONS ffe_init_options
14275#undef LANG_HOOKS_DECODE_OPTION
14276#define LANG_HOOKS_DECODE_OPTION ffe_decode_option
14277
8ac61af7
RK
14278/* We do not wish to use alias-set based aliasing at all. Used in the
14279 extreme (every object with its own set, with equivalences recorded) it
14280 might be helpful, but there are problems when it comes to inlining. We
14281 get on ok with flag_argument_noalias, and alias-set aliasing does
14282 currently limit how stack slots can be reused, which is a lose. */
14283#undef LANG_HOOKS_GET_ALIAS_SET
14284#define LANG_HOOKS_GET_ALIAS_SET hook_get_alias_set_0
14285
17ed6335 14286struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
cd2a3ba2 14287
c7e4ee3a 14288/* used by print-tree.c */
5ff904cd 14289
c7e4ee3a
CB
14290void
14291lang_print_xnode (file, node, indent)
14292 FILE *file UNUSED;
14293 tree node UNUSED;
14294 int indent UNUSED;
5ff904cd 14295{
c7e4ee3a 14296}
5ff904cd 14297
13c61421 14298static void
ee811cfd 14299ffe_finish ()
c7e4ee3a
CB
14300{
14301 ffe_terminate_0 ();
5ff904cd 14302
c7e4ee3a
CB
14303 if (ffe_is_ffedebug ())
14304 malloc_pool_display (malloc_pool_image ());
5ff904cd
JL
14305}
14306
dafbd854 14307const char *
c7e4ee3a 14308lang_identify ()
5ff904cd 14309{
c7e4ee3a
CB
14310 return "f77";
14311}
5ff904cd 14312
ee811cfd
NB
14313static void
14314ffe_init_options ()
c7e4ee3a
CB
14315{
14316 /* Set default options for Fortran. */
14317 flag_move_all_movables = 1;
14318 flag_reduce_all_givs = 1;
14319 flag_argument_noalias = 2;
201556f0 14320 flag_merge_constants = 2;
41af162c 14321 flag_errno_math = 0;
c64f913e 14322 flag_complex_divide_method = 1;
c7e4ee3a 14323}
5ff904cd 14324
13c61421 14325static void
ee811cfd 14326ffe_init ()
c7e4ee3a
CB
14327{
14328 /* If the file is output from cpp, it should contain a first line
14329 `# 1 "real-filename"', and the current design of gcc (toplev.c
14330 in particular and the way it sets up information relied on by
14331 INCLUDE) requires that we read this now, and store the
14332 "real-filename" info in master_input_filename. Ask the lexer
14333 to try doing this. */
14334 ffelex_hash_kludge (finput);
14335}
5ff904cd 14336
c7e4ee3a
CB
14337int
14338mark_addressable (exp)
14339 tree exp;
14340{
14341 register tree x = exp;
14342 while (1)
14343 switch (TREE_CODE (x))
14344 {
14345 case ADDR_EXPR:
14346 case COMPONENT_REF:
14347 case ARRAY_REF:
14348 x = TREE_OPERAND (x, 0);
14349 break;
5ff904cd 14350
c7e4ee3a
CB
14351 case CONSTRUCTOR:
14352 TREE_ADDRESSABLE (x) = 1;
14353 return 1;
5ff904cd 14354
c7e4ee3a
CB
14355 case VAR_DECL:
14356 case CONST_DECL:
14357 case PARM_DECL:
14358 case RESULT_DECL:
14359 if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
14360 && DECL_NONLOCAL (x))
14361 {
14362 if (TREE_PUBLIC (x))
14363 {
14364 assert ("address of global register var requested" == NULL);
14365 return 0;
14366 }
14367 assert ("address of register variable requested" == NULL);
14368 }
14369 else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x))
14370 {
14371 if (TREE_PUBLIC (x))
14372 {
14373 assert ("address of global register var requested" == NULL);
14374 return 0;
14375 }
14376 assert ("address of register var requested" == NULL);
14377 }
14378 put_var_into_stack (x);
5ff904cd 14379
c7e4ee3a
CB
14380 /* drops in */
14381 case FUNCTION_DECL:
14382 TREE_ADDRESSABLE (x) = 1;
14383#if 0 /* poplevel deals with this now. */
14384 if (DECL_CONTEXT (x) == 0)
14385 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (x)) = 1;
14386#endif
5ff904cd 14387
c7e4ee3a
CB
14388 default:
14389 return 1;
14390 }
5ff904cd
JL
14391}
14392
c7e4ee3a
CB
14393/* If DECL has a cleanup, build and return that cleanup here.
14394 This is a callback called by expand_expr. */
5ff904cd 14395
c7e4ee3a
CB
14396tree
14397maybe_build_cleanup (decl)
14398 tree decl UNUSED;
5ff904cd 14399{
c7e4ee3a
CB
14400 /* There are no cleanups in Fortran. */
14401 return NULL_TREE;
5ff904cd
JL
14402}
14403
c7e4ee3a
CB
14404/* Exit a binding level.
14405 Pop the level off, and restore the state of the identifier-decl mappings
14406 that were in effect when this level was entered.
5ff904cd 14407
c7e4ee3a
CB
14408 If KEEP is nonzero, this level had explicit declarations, so
14409 and create a "block" (a BLOCK node) for the level
14410 to record its declarations and subblocks for symbol table output.
5ff904cd 14411
c7e4ee3a
CB
14412 If FUNCTIONBODY is nonzero, this level is the body of a function,
14413 so create a block as if KEEP were set and also clear out all
14414 label names.
5ff904cd 14415
c7e4ee3a
CB
14416 If REVERSE is nonzero, reverse the order of decls before putting
14417 them into the BLOCK. */
5ff904cd 14418
c7e4ee3a
CB
14419tree
14420poplevel (keep, reverse, functionbody)
14421 int keep;
14422 int reverse;
14423 int functionbody;
5ff904cd 14424{
c7e4ee3a
CB
14425 register tree link;
14426 /* The chain of decls was accumulated in reverse order.
14427 Put it into forward order, just for cleanliness. */
14428 tree decls;
14429 tree subblocks = current_binding_level->blocks;
14430 tree block = 0;
14431 tree decl;
14432 int block_previously_created;
5ff904cd 14433
c7e4ee3a
CB
14434 /* Get the decls in the order they were written.
14435 Usually current_binding_level->names is in reverse order.
14436 But parameter decls were previously put in forward order. */
702edf1d 14437
c7e4ee3a
CB
14438 if (reverse)
14439 current_binding_level->names
14440 = decls = nreverse (current_binding_level->names);
14441 else
14442 decls = current_binding_level->names;
5ff904cd 14443
c7e4ee3a
CB
14444 /* Output any nested inline functions within this block
14445 if they weren't already output. */
5ff904cd 14446
c7e4ee3a
CB
14447 for (decl = decls; decl; decl = TREE_CHAIN (decl))
14448 if (TREE_CODE (decl) == FUNCTION_DECL
14449 && ! TREE_ASM_WRITTEN (decl)
14450 && DECL_INITIAL (decl) != 0
14451 && TREE_ADDRESSABLE (decl))
14452 {
14453 /* If this decl was copied from a file-scope decl
14454 on account of a block-scope extern decl,
14455 propagate TREE_ADDRESSABLE to the file-scope decl.
14456
14457 DECL_ABSTRACT_ORIGIN can be set to itself if warn_return_type is
14458 true, since then the decl goes through save_for_inline_copying. */
14459 if (DECL_ABSTRACT_ORIGIN (decl) != 0
14460 && DECL_ABSTRACT_ORIGIN (decl) != decl)
14461 TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1;
14462 else if (DECL_SAVED_INSNS (decl) != 0)
14463 {
14464 push_function_context ();
14465 output_inline_function (decl);
14466 pop_function_context ();
14467 }
14468 }
5ff904cd 14469
c7e4ee3a
CB
14470 /* If there were any declarations or structure tags in that level,
14471 or if this level is a function body,
14472 create a BLOCK to record them for the life of this function. */
5ff904cd 14473
c7e4ee3a
CB
14474 block = 0;
14475 block_previously_created = (current_binding_level->this_block != 0);
14476 if (block_previously_created)
14477 block = current_binding_level->this_block;
14478 else if (keep || functionbody)
14479 block = make_node (BLOCK);
14480 if (block != 0)
14481 {
14482 BLOCK_VARS (block) = decls;
14483 BLOCK_SUBBLOCKS (block) = subblocks;
c7e4ee3a 14484 }
5ff904cd 14485
c7e4ee3a 14486 /* In each subblock, record that this is its superior. */
5ff904cd 14487
c7e4ee3a
CB
14488 for (link = subblocks; link; link = TREE_CHAIN (link))
14489 BLOCK_SUPERCONTEXT (link) = block;
5ff904cd 14490
c7e4ee3a 14491 /* Clear out the meanings of the local variables of this level. */
5ff904cd 14492
c7e4ee3a 14493 for (link = decls; link; link = TREE_CHAIN (link))
5ff904cd 14494 {
c7e4ee3a
CB
14495 if (DECL_NAME (link) != 0)
14496 {
14497 /* If the ident. was used or addressed via a local extern decl,
14498 don't forget that fact. */
14499 if (DECL_EXTERNAL (link))
14500 {
14501 if (TREE_USED (link))
14502 TREE_USED (DECL_NAME (link)) = 1;
14503 if (TREE_ADDRESSABLE (link))
14504 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (link)) = 1;
14505 }
14506 IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = 0;
14507 }
5ff904cd 14508 }
5ff904cd 14509
c7e4ee3a
CB
14510 /* If the level being exited is the top level of a function,
14511 check over all the labels, and clear out the current
14512 (function local) meanings of their names. */
5ff904cd 14513
c7e4ee3a 14514 if (functionbody)
5ff904cd 14515 {
c7e4ee3a
CB
14516 /* If this is the top level block of a function,
14517 the vars are the function's parameters.
14518 Don't leave them in the BLOCK because they are
14519 found in the FUNCTION_DECL instead. */
14520
14521 BLOCK_VARS (block) = 0;
5ff904cd
JL
14522 }
14523
c7e4ee3a
CB
14524 /* Pop the current level, and free the structure for reuse. */
14525
14526 {
14527 register struct binding_level *level = current_binding_level;
14528 current_binding_level = current_binding_level->level_chain;
14529
14530 level->level_chain = free_binding_level;
14531 free_binding_level = level;
14532 }
14533
14534 /* Dispose of the block that we just made inside some higher level. */
14535 if (functionbody
14536 && current_function_decl != error_mark_node)
14537 DECL_INITIAL (current_function_decl) = block;
14538 else if (block)
5ff904cd 14539 {
c7e4ee3a
CB
14540 if (!block_previously_created)
14541 current_binding_level->blocks
14542 = chainon (current_binding_level->blocks, block);
5ff904cd 14543 }
c7e4ee3a
CB
14544 /* If we did not make a block for the level just exited,
14545 any blocks made for inner levels
14546 (since they cannot be recorded as subblocks in that level)
14547 must be carried forward so they will later become subblocks
14548 of something else. */
14549 else if (subblocks)
14550 current_binding_level->blocks
14551 = chainon (current_binding_level->blocks, subblocks);
5ff904cd 14552
c7e4ee3a
CB
14553 if (block)
14554 TREE_USED (block) = 1;
14555 return block;
5ff904cd
JL
14556}
14557
c7e4ee3a
CB
14558void
14559print_lang_decl (file, node, indent)
14560 FILE *file UNUSED;
14561 tree node UNUSED;
14562 int indent UNUSED;
14563{
14564}
5ff904cd 14565
c7e4ee3a
CB
14566void
14567print_lang_identifier (file, node, indent)
14568 FILE *file;
14569 tree node;
14570 int indent;
14571{
14572 print_node (file, "global", IDENTIFIER_GLOBAL_VALUE (node), indent + 4);
14573 print_node (file, "local", IDENTIFIER_LOCAL_VALUE (node), indent + 4);
14574}
5ff904cd 14575
c7e4ee3a
CB
14576void
14577print_lang_statistics ()
14578{
14579}
5ff904cd 14580
c7e4ee3a
CB
14581void
14582print_lang_type (file, node, indent)
14583 FILE *file UNUSED;
14584 tree node UNUSED;
14585 int indent UNUSED;
5ff904cd 14586{
c7e4ee3a 14587}
5ff904cd 14588
c7e4ee3a
CB
14589/* Record a decl-node X as belonging to the current lexical scope.
14590 Check for errors (such as an incompatible declaration for the same
14591 name already seen in the same scope).
5ff904cd 14592
c7e4ee3a
CB
14593 Returns either X or an old decl for the same name.
14594 If an old decl is returned, it may have been smashed
14595 to agree with what X says. */
5ff904cd 14596
c7e4ee3a
CB
14597tree
14598pushdecl (x)
14599 tree x;
14600{
14601 register tree t;
14602 register tree name = DECL_NAME (x);
14603 register struct binding_level *b = current_binding_level;
5ff904cd 14604
c7e4ee3a
CB
14605 if ((TREE_CODE (x) == FUNCTION_DECL)
14606 && (DECL_INITIAL (x) == 0)
14607 && DECL_EXTERNAL (x))
14608 DECL_CONTEXT (x) = NULL_TREE;
56a0044b 14609 else
c7e4ee3a
CB
14610 DECL_CONTEXT (x) = current_function_decl;
14611
14612 if (name)
56a0044b 14613 {
c7e4ee3a
CB
14614 if (IDENTIFIER_INVENTED (name))
14615 {
c7e4ee3a 14616 DECL_ARTIFICIAL (x) = 1;
c7e4ee3a
CB
14617 DECL_IN_SYSTEM_HEADER (x) = 1;
14618 }
5ff904cd 14619
c7e4ee3a 14620 t = lookup_name_current_level (name);
5ff904cd 14621
c7e4ee3a 14622 assert ((t == NULL_TREE) || (DECL_CONTEXT (x) == NULL_TREE));
5ff904cd 14623
c7e4ee3a
CB
14624 /* Don't push non-parms onto list for parms until we understand
14625 why we're doing this and whether it works. */
56a0044b 14626
c7e4ee3a
CB
14627 assert ((b == global_binding_level)
14628 || !ffecom_transform_only_dummies_
14629 || TREE_CODE (x) == PARM_DECL);
5ff904cd 14630
c7e4ee3a
CB
14631 if ((t != NULL_TREE) && duplicate_decls (x, t))
14632 return t;
5ff904cd 14633
c7e4ee3a
CB
14634 /* If we are processing a typedef statement, generate a whole new
14635 ..._TYPE node (which will be just an variant of the existing
14636 ..._TYPE node with identical properties) and then install the
14637 TYPE_DECL node generated to represent the typedef name as the
14638 TYPE_NAME of this brand new (duplicate) ..._TYPE node.
5ff904cd 14639
c7e4ee3a
CB
14640 The whole point here is to end up with a situation where each and every
14641 ..._TYPE node the compiler creates will be uniquely associated with
14642 AT MOST one node representing a typedef name. This way, even though
14643 the compiler substitutes corresponding ..._TYPE nodes for TYPE_DECL
14644 (i.e. "typedef name") nodes very early on, later parts of the
14645 compiler can always do the reverse translation and get back the
14646 corresponding typedef name. For example, given:
5ff904cd 14647
c7e4ee3a 14648 typedef struct S MY_TYPE; MY_TYPE object;
5ff904cd 14649
c7e4ee3a
CB
14650 Later parts of the compiler might only know that `object' was of type
14651 `struct S' if it were not for code just below. With this code
14652 however, later parts of the compiler see something like:
5ff904cd 14653
c7e4ee3a 14654 struct S' == struct S typedef struct S' MY_TYPE; struct S' object;
5ff904cd 14655
c7e4ee3a
CB
14656 And they can then deduce (from the node for type struct S') that the
14657 original object declaration was:
5ff904cd 14658
c7e4ee3a 14659 MY_TYPE object;
5ff904cd 14660
c7e4ee3a
CB
14661 Being able to do this is important for proper support of protoize, and
14662 also for generating precise symbolic debugging information which
14663 takes full account of the programmer's (typedef) vocabulary.
5ff904cd 14664
c7e4ee3a
CB
14665 Obviously, we don't want to generate a duplicate ..._TYPE node if the
14666 TYPE_DECL node that we are now processing really represents a
14667 standard built-in type.
5ff904cd 14668
c7e4ee3a
CB
14669 Since all standard types are effectively declared at line zero in the
14670 source file, we can easily check to see if we are working on a
14671 standard type by checking the current value of lineno. */
14672
14673 if (TREE_CODE (x) == TYPE_DECL)
14674 {
14675 if (DECL_SOURCE_LINE (x) == 0)
14676 {
14677 if (TYPE_NAME (TREE_TYPE (x)) == 0)
14678 TYPE_NAME (TREE_TYPE (x)) = x;
14679 }
14680 else if (TREE_TYPE (x) != error_mark_node)
14681 {
14682 tree tt = TREE_TYPE (x);
14683
14684 tt = build_type_copy (tt);
14685 TYPE_NAME (tt) = x;
14686 TREE_TYPE (x) = tt;
14687 }
14688 }
5ff904cd 14689
c7e4ee3a
CB
14690 /* This name is new in its binding level. Install the new declaration
14691 and return it. */
14692 if (b == global_binding_level)
14693 IDENTIFIER_GLOBAL_VALUE (name) = x;
14694 else
14695 IDENTIFIER_LOCAL_VALUE (name) = x;
14696 }
5ff904cd 14697
c7e4ee3a
CB
14698 /* Put decls on list in reverse order. We will reverse them later if
14699 necessary. */
14700 TREE_CHAIN (x) = b->names;
14701 b->names = x;
5ff904cd 14702
c7e4ee3a 14703 return x;
5ff904cd
JL
14704}
14705
c7e4ee3a 14706/* Nonzero if the current level needs to have a BLOCK made. */
5ff904cd 14707
c7e4ee3a
CB
14708static int
14709kept_level_p ()
5ff904cd 14710{
c7e4ee3a
CB
14711 tree decl;
14712
14713 for (decl = current_binding_level->names;
14714 decl;
14715 decl = TREE_CHAIN (decl))
14716 {
14717 if (TREE_USED (decl) || TREE_CODE (decl) != VAR_DECL
14718 || (DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl)))
14719 /* Currently, there aren't supposed to be non-artificial names
14720 at other than the top block for a function -- they're
14721 believed to always be temps. But it's wise to check anyway. */
14722 return 1;
14723 }
14724 return 0;
5ff904cd
JL
14725}
14726
c7e4ee3a
CB
14727/* Enter a new binding level.
14728 If TAG_TRANSPARENT is nonzero, do so only for the name space of variables,
14729 not for that of tags. */
5ff904cd
JL
14730
14731void
c7e4ee3a
CB
14732pushlevel (tag_transparent)
14733 int tag_transparent;
5ff904cd 14734{
c7e4ee3a 14735 register struct binding_level *newlevel = NULL_BINDING_LEVEL;
5ff904cd 14736
c7e4ee3a 14737 assert (! tag_transparent);
5ff904cd 14738
c7e4ee3a
CB
14739 if (current_binding_level == global_binding_level)
14740 {
14741 named_labels = 0;
14742 }
5ff904cd 14743
c7e4ee3a 14744 /* Reuse or create a struct for this binding level. */
5ff904cd 14745
c7e4ee3a 14746 if (free_binding_level)
77f77701 14747 {
c7e4ee3a
CB
14748 newlevel = free_binding_level;
14749 free_binding_level = free_binding_level->level_chain;
77f77701
DB
14750 }
14751 else
c7e4ee3a
CB
14752 {
14753 newlevel = make_binding_level ();
14754 }
77f77701 14755
c7e4ee3a
CB
14756 /* Add this level to the front of the chain (stack) of levels that
14757 are active. */
71b5e532 14758
c7e4ee3a
CB
14759 *newlevel = clear_binding_level;
14760 newlevel->level_chain = current_binding_level;
14761 current_binding_level = newlevel;
5ff904cd
JL
14762}
14763
c7e4ee3a
CB
14764/* Set the BLOCK node for the innermost scope
14765 (the one we are currently in). */
77f77701 14766
5ff904cd 14767void
c7e4ee3a
CB
14768set_block (block)
14769 register tree block;
5ff904cd 14770{
c7e4ee3a 14771 current_binding_level->this_block = block;
9b58f739
RK
14772 current_binding_level->names = chainon (current_binding_level->names,
14773 BLOCK_VARS (block));
14774 current_binding_level->blocks = chainon (current_binding_level->blocks,
14775 BLOCK_SUBBLOCKS (block));
5ff904cd
JL
14776}
14777
c7e4ee3a 14778/* ~~gcc/tree.h *should* declare this, because toplev.c references it. */
5ff904cd 14779
c7e4ee3a 14780/* Can't 'yydebug' a front end not generated by yacc/bison! */
bc289659
ML
14781
14782void
c7e4ee3a
CB
14783set_yydebug (value)
14784 int value;
bc289659 14785{
c7e4ee3a
CB
14786 if (value)
14787 fprintf (stderr, "warning: no yacc/bison-generated output to debug!\n");
bc289659
ML
14788}
14789
c7e4ee3a
CB
14790tree
14791signed_or_unsigned_type (unsignedp, type)
14792 int unsignedp;
14793 tree type;
5ff904cd 14794{
c7e4ee3a 14795 tree type2;
5ff904cd 14796
c7e4ee3a
CB
14797 if (! INTEGRAL_TYPE_P (type))
14798 return type;
14799 if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node))
14800 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
14801 if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
14802 return unsignedp ? unsigned_type_node : integer_type_node;
14803 if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node))
14804 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
14805 if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node))
14806 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
14807 if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node))
14808 return (unsignedp ? long_long_unsigned_type_node
14809 : long_long_integer_type_node);
5ff904cd 14810
c7e4ee3a
CB
14811 type2 = type_for_size (TYPE_PRECISION (type), unsignedp);
14812 if (type2 == NULL_TREE)
14813 return type;
f84639ba 14814
c7e4ee3a 14815 return type2;
5ff904cd
JL
14816}
14817
c7e4ee3a
CB
14818tree
14819signed_type (type)
14820 tree type;
5ff904cd 14821{
c7e4ee3a
CB
14822 tree type1 = TYPE_MAIN_VARIANT (type);
14823 ffeinfoKindtype kt;
14824 tree type2;
5ff904cd 14825
c7e4ee3a
CB
14826 if (type1 == unsigned_char_type_node || type1 == char_type_node)
14827 return signed_char_type_node;
14828 if (type1 == unsigned_type_node)
14829 return integer_type_node;
14830 if (type1 == short_unsigned_type_node)
14831 return short_integer_type_node;
14832 if (type1 == long_unsigned_type_node)
14833 return long_integer_type_node;
14834 if (type1 == long_long_unsigned_type_node)
14835 return long_long_integer_type_node;
14836#if 0 /* gcc/c-* files only */
14837 if (type1 == unsigned_intDI_type_node)
14838 return intDI_type_node;
14839 if (type1 == unsigned_intSI_type_node)
14840 return intSI_type_node;
14841 if (type1 == unsigned_intHI_type_node)
14842 return intHI_type_node;
14843 if (type1 == unsigned_intQI_type_node)
14844 return intQI_type_node;
14845#endif
5ff904cd 14846
c7e4ee3a
CB
14847 type2 = type_for_size (TYPE_PRECISION (type1), 0);
14848 if (type2 != NULL_TREE)
14849 return type2;
5ff904cd 14850
c7e4ee3a
CB
14851 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
14852 {
14853 type2 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
5ff904cd 14854
c7e4ee3a
CB
14855 if (type1 == type2)
14856 return ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
14857 }
14858
14859 return type;
5ff904cd
JL
14860}
14861
c7e4ee3a
CB
14862/* Prepare expr to be an argument of a TRUTH_NOT_EXPR,
14863 or validate its data type for an `if' or `while' statement or ?..: exp.
14864
14865 This preparation consists of taking the ordinary
14866 representation of an expression expr and producing a valid tree
14867 boolean expression describing whether expr is nonzero. We could
14868 simply always do build_binary_op (NE_EXPR, expr, integer_zero_node, 1),
14869 but we optimize comparisons, &&, ||, and !.
14870
14871 The resulting type should always be `integer_type_node'. */
5ff904cd
JL
14872
14873tree
c7e4ee3a
CB
14874truthvalue_conversion (expr)
14875 tree expr;
5ff904cd 14876{
c7e4ee3a
CB
14877 if (TREE_CODE (expr) == ERROR_MARK)
14878 return expr;
5ff904cd 14879
c7e4ee3a
CB
14880#if 0 /* This appears to be wrong for C++. */
14881 /* These really should return error_mark_node after 2.4 is stable.
14882 But not all callers handle ERROR_MARK properly. */
14883 switch (TREE_CODE (TREE_TYPE (expr)))
14884 {
14885 case RECORD_TYPE:
14886 error ("struct type value used where scalar is required");
14887 return integer_zero_node;
5ff904cd 14888
c7e4ee3a
CB
14889 case UNION_TYPE:
14890 error ("union type value used where scalar is required");
14891 return integer_zero_node;
5ff904cd 14892
c7e4ee3a
CB
14893 case ARRAY_TYPE:
14894 error ("array type value used where scalar is required");
14895 return integer_zero_node;
5ff904cd 14896
c7e4ee3a
CB
14897 default:
14898 break;
14899 }
14900#endif /* 0 */
5ff904cd 14901
c7e4ee3a
CB
14902 switch (TREE_CODE (expr))
14903 {
14904 /* It is simpler and generates better code to have only TRUTH_*_EXPR
14905 or comparison expressions as truth values at this level. */
14906#if 0
14907 case COMPONENT_REF:
14908 /* A one-bit unsigned bit-field is already acceptable. */
14909 if (1 == TREE_INT_CST_LOW (DECL_SIZE (TREE_OPERAND (expr, 1)))
14910 && TREE_UNSIGNED (TREE_OPERAND (expr, 1)))
14911 return expr;
14912 break;
14913#endif
14914
14915 case EQ_EXPR:
14916 /* It is simpler and generates better code to have only TRUTH_*_EXPR
14917 or comparison expressions as truth values at this level. */
14918#if 0
14919 if (integer_zerop (TREE_OPERAND (expr, 1)))
14920 return build_unary_op (TRUTH_NOT_EXPR, TREE_OPERAND (expr, 0), 0);
14921#endif
14922 case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
14923 case TRUTH_ANDIF_EXPR:
14924 case TRUTH_ORIF_EXPR:
14925 case TRUTH_AND_EXPR:
14926 case TRUTH_OR_EXPR:
14927 case TRUTH_XOR_EXPR:
14928 TREE_TYPE (expr) = integer_type_node;
14929 return expr;
5ff904cd 14930
c7e4ee3a
CB
14931 case ERROR_MARK:
14932 return expr;
5ff904cd 14933
c7e4ee3a
CB
14934 case INTEGER_CST:
14935 return integer_zerop (expr) ? integer_zero_node : integer_one_node;
5ff904cd 14936
c7e4ee3a
CB
14937 case REAL_CST:
14938 return real_zerop (expr) ? integer_zero_node : integer_one_node;
5ff904cd 14939
c7e4ee3a
CB
14940 case ADDR_EXPR:
14941 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 0)))
14942 return build (COMPOUND_EXPR, integer_type_node,
14943 TREE_OPERAND (expr, 0), integer_one_node);
14944 else
14945 return integer_one_node;
5ff904cd 14946
c7e4ee3a
CB
14947 case COMPLEX_EXPR:
14948 return ffecom_2 ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))
14949 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
14950 integer_type_node,
14951 truthvalue_conversion (TREE_OPERAND (expr, 0)),
14952 truthvalue_conversion (TREE_OPERAND (expr, 1)));
5ff904cd 14953
c7e4ee3a
CB
14954 case NEGATE_EXPR:
14955 case ABS_EXPR:
14956 case FLOAT_EXPR:
14957 case FFS_EXPR:
14958 /* These don't change whether an object is non-zero or zero. */
14959 return truthvalue_conversion (TREE_OPERAND (expr, 0));
5ff904cd 14960
c7e4ee3a
CB
14961 case LROTATE_EXPR:
14962 case RROTATE_EXPR:
14963 /* These don't change whether an object is zero or non-zero, but
14964 we can't ignore them if their second arg has side-effects. */
14965 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)))
14966 return build (COMPOUND_EXPR, integer_type_node, TREE_OPERAND (expr, 1),
14967 truthvalue_conversion (TREE_OPERAND (expr, 0)));
14968 else
14969 return truthvalue_conversion (TREE_OPERAND (expr, 0));
5ff904cd 14970
c7e4ee3a
CB
14971 case COND_EXPR:
14972 /* Distribute the conversion into the arms of a COND_EXPR. */
14973 return fold (build (COND_EXPR, integer_type_node, TREE_OPERAND (expr, 0),
14974 truthvalue_conversion (TREE_OPERAND (expr, 1)),
14975 truthvalue_conversion (TREE_OPERAND (expr, 2))));
5ff904cd 14976
c7e4ee3a
CB
14977 case CONVERT_EXPR:
14978 /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
14979 since that affects how `default_conversion' will behave. */
14980 if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE
14981 || TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)
14982 break;
14983 /* fall through... */
14984 case NOP_EXPR:
14985 /* If this is widening the argument, we can ignore it. */
14986 if (TYPE_PRECISION (TREE_TYPE (expr))
14987 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
14988 return truthvalue_conversion (TREE_OPERAND (expr, 0));
14989 break;
5ff904cd 14990
c7e4ee3a
CB
14991 case MINUS_EXPR:
14992 /* With IEEE arithmetic, x - x may not equal 0, so we can't optimize
14993 this case. */
14994 if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
14995 && TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE)
14996 break;
14997 /* fall through... */
14998 case BIT_XOR_EXPR:
14999 /* This and MINUS_EXPR can be changed into a comparison of the
15000 two objects. */
15001 if (TREE_TYPE (TREE_OPERAND (expr, 0))
15002 == TREE_TYPE (TREE_OPERAND (expr, 1)))
15003 return ffecom_2 (NE_EXPR, integer_type_node,
15004 TREE_OPERAND (expr, 0),
15005 TREE_OPERAND (expr, 1));
15006 return ffecom_2 (NE_EXPR, integer_type_node,
15007 TREE_OPERAND (expr, 0),
15008 fold (build1 (NOP_EXPR,
15009 TREE_TYPE (TREE_OPERAND (expr, 0)),
15010 TREE_OPERAND (expr, 1))));
15011
15012 case BIT_AND_EXPR:
15013 if (integer_onep (TREE_OPERAND (expr, 1)))
15014 return expr;
15015 break;
15016
15017 case MODIFY_EXPR:
15018#if 0 /* No such thing in Fortran. */
15019 if (warn_parentheses && C_EXP_ORIGINAL_CODE (expr) == MODIFY_EXPR)
15020 warning ("suggest parentheses around assignment used as truth value");
15021#endif
15022 break;
15023
15024 default:
15025 break;
5ff904cd
JL
15026 }
15027
c7e4ee3a
CB
15028 if (TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE)
15029 return (ffecom_2
15030 ((TREE_SIDE_EFFECTS (expr)
15031 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
15032 integer_type_node,
15033 truthvalue_conversion (ffecom_1 (REALPART_EXPR,
15034 TREE_TYPE (TREE_TYPE (expr)),
15035 expr)),
15036 truthvalue_conversion (ffecom_1 (IMAGPART_EXPR,
15037 TREE_TYPE (TREE_TYPE (expr)),
15038 expr))));
15039
15040 return ffecom_2 (NE_EXPR, integer_type_node,
15041 expr,
15042 convert (TREE_TYPE (expr), integer_zero_node));
15043}
15044
15045tree
15046type_for_mode (mode, unsignedp)
15047 enum machine_mode mode;
15048 int unsignedp;
15049{
15050 int i;
15051 int j;
15052 tree t;
5ff904cd 15053
c7e4ee3a
CB
15054 if (mode == TYPE_MODE (integer_type_node))
15055 return unsignedp ? unsigned_type_node : integer_type_node;
5ff904cd 15056
c7e4ee3a
CB
15057 if (mode == TYPE_MODE (signed_char_type_node))
15058 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
5ff904cd 15059
c7e4ee3a
CB
15060 if (mode == TYPE_MODE (short_integer_type_node))
15061 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
5ff904cd 15062
c7e4ee3a
CB
15063 if (mode == TYPE_MODE (long_integer_type_node))
15064 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
5ff904cd 15065
c7e4ee3a
CB
15066 if (mode == TYPE_MODE (long_long_integer_type_node))
15067 return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node;
5ff904cd 15068
fed3cef0
RK
15069#if HOST_BITS_PER_WIDE_INT >= 64
15070 if (mode == TYPE_MODE (intTI_type_node))
15071 return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
15072#endif
15073
c7e4ee3a
CB
15074 if (mode == TYPE_MODE (float_type_node))
15075 return float_type_node;
5ff904cd 15076
c7e4ee3a
CB
15077 if (mode == TYPE_MODE (double_type_node))
15078 return double_type_node;
5ff904cd 15079
c7e4ee3a
CB
15080 if (mode == TYPE_MODE (build_pointer_type (char_type_node)))
15081 return build_pointer_type (char_type_node);
5ff904cd 15082
c7e4ee3a
CB
15083 if (mode == TYPE_MODE (build_pointer_type (integer_type_node)))
15084 return build_pointer_type (integer_type_node);
5ff904cd 15085
c7e4ee3a
CB
15086 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
15087 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
15088 {
15089 if (((t = ffecom_tree_type[i][j]) != NULL_TREE)
15090 && (mode == TYPE_MODE (t)))
15091 {
15092 if ((i == FFEINFO_basictypeINTEGER) && unsignedp)
15093 return ffecom_tree_type[FFEINFO_basictypeHOLLERITH][j];
15094 else
15095 return t;
15096 }
15097 }
5ff904cd 15098
c7e4ee3a 15099 return 0;
5ff904cd
JL
15100}
15101
c7e4ee3a
CB
15102tree
15103type_for_size (bits, unsignedp)
15104 unsigned bits;
15105 int unsignedp;
5ff904cd 15106{
c7e4ee3a
CB
15107 ffeinfoKindtype kt;
15108 tree type_node;
5ff904cd 15109
c7e4ee3a
CB
15110 if (bits == TYPE_PRECISION (integer_type_node))
15111 return unsignedp ? unsigned_type_node : integer_type_node;
5ff904cd 15112
c7e4ee3a
CB
15113 if (bits == TYPE_PRECISION (signed_char_type_node))
15114 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
5ff904cd 15115
c7e4ee3a
CB
15116 if (bits == TYPE_PRECISION (short_integer_type_node))
15117 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
5ff904cd 15118
c7e4ee3a
CB
15119 if (bits == TYPE_PRECISION (long_integer_type_node))
15120 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
5ff904cd 15121
c7e4ee3a
CB
15122 if (bits == TYPE_PRECISION (long_long_integer_type_node))
15123 return (unsignedp ? long_long_unsigned_type_node
15124 : long_long_integer_type_node);
5ff904cd 15125
c7e4ee3a 15126 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
5ff904cd 15127 {
c7e4ee3a 15128 type_node = ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
5ff904cd 15129
c7e4ee3a
CB
15130 if ((type_node != NULL_TREE) && (bits == TYPE_PRECISION (type_node)))
15131 return unsignedp ? ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt]
15132 : type_node;
15133 }
5ff904cd 15134
c7e4ee3a
CB
15135 return 0;
15136}
5ff904cd 15137
c7e4ee3a
CB
15138tree
15139unsigned_type (type)
15140 tree type;
15141{
15142 tree type1 = TYPE_MAIN_VARIANT (type);
15143 ffeinfoKindtype kt;
15144 tree type2;
5ff904cd 15145
c7e4ee3a
CB
15146 if (type1 == signed_char_type_node || type1 == char_type_node)
15147 return unsigned_char_type_node;
15148 if (type1 == integer_type_node)
15149 return unsigned_type_node;
15150 if (type1 == short_integer_type_node)
15151 return short_unsigned_type_node;
15152 if (type1 == long_integer_type_node)
15153 return long_unsigned_type_node;
15154 if (type1 == long_long_integer_type_node)
15155 return long_long_unsigned_type_node;
15156#if 0 /* gcc/c-* files only */
15157 if (type1 == intDI_type_node)
15158 return unsigned_intDI_type_node;
15159 if (type1 == intSI_type_node)
15160 return unsigned_intSI_type_node;
15161 if (type1 == intHI_type_node)
15162 return unsigned_intHI_type_node;
15163 if (type1 == intQI_type_node)
15164 return unsigned_intQI_type_node;
15165#endif
5ff904cd 15166
c7e4ee3a
CB
15167 type2 = type_for_size (TYPE_PRECISION (type1), 1);
15168 if (type2 != NULL_TREE)
15169 return type2;
5ff904cd 15170
c7e4ee3a
CB
15171 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
15172 {
15173 type2 = ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
5ff904cd 15174
c7e4ee3a
CB
15175 if (type1 == type2)
15176 return ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
15177 }
5ff904cd 15178
c7e4ee3a
CB
15179 return type;
15180}
5ff904cd 15181
516b69ff 15182void
7189a4b0
GK
15183lang_mark_tree (t)
15184 union tree_node *t ATTRIBUTE_UNUSED;
15185{
15186 if (TREE_CODE (t) == IDENTIFIER_NODE)
15187 {
15188 struct lang_identifier *i = (struct lang_identifier *) t;
15189 ggc_mark_tree (IDENTIFIER_GLOBAL_VALUE (i));
15190 ggc_mark_tree (IDENTIFIER_LOCAL_VALUE (i));
15191 ggc_mark_tree (IDENTIFIER_LABEL_VALUE (i));
15192 }
15193 else if (TYPE_P (t) && TYPE_LANG_SPECIFIC (t))
15194 ggc_mark (TYPE_LANG_SPECIFIC (t));
15195}
c7e4ee3a 15196\f
c7e4ee3a 15197/* From gcc/cccp.c, the code to handle -I. */
5ff904cd 15198
c7e4ee3a
CB
15199/* Skip leading "./" from a directory name.
15200 This may yield the empty string, which represents the current directory. */
5ff904cd 15201
c7e4ee3a
CB
15202static const char *
15203skip_redundant_dir_prefix (const char *dir)
15204{
15205 while (dir[0] == '.' && dir[1] == '/')
15206 for (dir += 2; *dir == '/'; dir++)
15207 continue;
15208 if (dir[0] == '.' && !dir[1])
15209 dir++;
15210 return dir;
15211}
5ff904cd 15212
c7e4ee3a
CB
15213/* The file_name_map structure holds a mapping of file names for a
15214 particular directory. This mapping is read from the file named
15215 FILE_NAME_MAP_FILE in that directory. Such a file can be used to
15216 map filenames on a file system with severe filename restrictions,
15217 such as DOS. The format of the file name map file is just a series
15218 of lines with two tokens on each line. The first token is the name
15219 to map, and the second token is the actual name to use. */
5ff904cd 15220
c7e4ee3a
CB
15221struct file_name_map
15222{
15223 struct file_name_map *map_next;
15224 char *map_from;
15225 char *map_to;
15226};
5ff904cd 15227
c7e4ee3a 15228#define FILE_NAME_MAP_FILE "header.gcc"
5ff904cd 15229
c7e4ee3a
CB
15230/* Current maximum length of directory names in the search path
15231 for include files. (Altered as we get more of them.) */
5ff904cd 15232
c7e4ee3a 15233static int max_include_len = 0;
5ff904cd 15234
c7e4ee3a
CB
15235struct file_name_list
15236 {
15237 struct file_name_list *next;
15238 char *fname;
15239 /* Mapping of file names for this directory. */
15240 struct file_name_map *name_map;
15241 /* Non-zero if name_map is valid. */
15242 int got_name_map;
15243 };
5ff904cd 15244
c7e4ee3a
CB
15245static struct file_name_list *include = NULL; /* First dir to search */
15246static struct file_name_list *last_include = NULL; /* Last in chain */
5ff904cd 15247
c7e4ee3a
CB
15248/* I/O buffer structure.
15249 The `fname' field is nonzero for source files and #include files
15250 and for the dummy text used for -D and -U.
15251 It is zero for rescanning results of macro expansion
15252 and for expanding macro arguments. */
15253#define INPUT_STACK_MAX 400
15254static struct file_buf {
b0791fa9 15255 const char *fname;
c7e4ee3a 15256 /* Filename specified with #line command. */
b0791fa9 15257 const char *nominal_fname;
c7e4ee3a
CB
15258 /* Record where in the search path this file was found.
15259 For #include_next. */
15260 struct file_name_list *dir;
15261 ffewhereLine line;
15262 ffewhereColumn column;
15263} instack[INPUT_STACK_MAX];
5ff904cd 15264
c7e4ee3a
CB
15265static int last_error_tick = 0; /* Incremented each time we print it. */
15266static int input_file_stack_tick = 0; /* Incremented when status changes. */
5ff904cd 15267
c7e4ee3a
CB
15268/* Current nesting level of input sources.
15269 `instack[indepth]' is the level currently being read. */
15270static int indepth = -1;
5ff904cd 15271
c7e4ee3a 15272typedef struct file_buf FILE_BUF;
5ff904cd 15273
c7e4ee3a 15274typedef unsigned char U_CHAR;
5ff904cd 15275
c7e4ee3a
CB
15276/* table to tell if char can be part of a C identifier. */
15277U_CHAR is_idchar[256];
15278/* table to tell if char can be first char of a c identifier. */
15279U_CHAR is_idstart[256];
15280/* table to tell if c is horizontal space. */
15281U_CHAR is_hor_space[256];
15282/* table to tell if c is horizontal or vertical space. */
15283static U_CHAR is_space[256];
5ff904cd 15284
c7e4ee3a
CB
15285#define SKIP_WHITE_SPACE(p) do { while (is_hor_space[*p]) p++; } while (0)
15286#define SKIP_ALL_WHITE_SPACE(p) do { while (is_space[*p]) p++; } while (0)
5ff904cd 15287
c7e4ee3a
CB
15288/* Nonzero means -I- has been seen,
15289 so don't look for #include "foo" the source-file directory. */
15290static int ignore_srcdir;
5ff904cd 15291
c7e4ee3a
CB
15292#ifndef INCLUDE_LEN_FUDGE
15293#define INCLUDE_LEN_FUDGE 0
15294#endif
5ff904cd 15295
c7e4ee3a
CB
15296static void append_include_chain (struct file_name_list *first,
15297 struct file_name_list *last);
15298static FILE *open_include_file (char *filename,
15299 struct file_name_list *searchptr);
15300static void print_containing_files (ffebadSeverity sev);
c7e4ee3a
CB
15301static char *read_filename_string (int ch, FILE *f);
15302static struct file_name_map *read_name_map (const char *dirname);
5ff904cd 15303
c7e4ee3a
CB
15304/* Append a chain of `struct file_name_list's
15305 to the end of the main include chain.
15306 FIRST is the beginning of the chain to append, and LAST is the end. */
5ff904cd 15307
c7e4ee3a
CB
15308static void
15309append_include_chain (first, last)
15310 struct file_name_list *first, *last;
5ff904cd 15311{
c7e4ee3a 15312 struct file_name_list *dir;
5ff904cd 15313
c7e4ee3a
CB
15314 if (!first || !last)
15315 return;
5ff904cd 15316
c7e4ee3a
CB
15317 if (include == 0)
15318 include = first;
15319 else
15320 last_include->next = first;
5ff904cd 15321
c7e4ee3a
CB
15322 for (dir = first; ; dir = dir->next) {
15323 int len = strlen (dir->fname) + INCLUDE_LEN_FUDGE;
15324 if (len > max_include_len)
15325 max_include_len = len;
15326 if (dir == last)
15327 break;
15328 }
15329
15330 last->next = NULL;
15331 last_include = last;
5ff904cd
JL
15332}
15333
c7e4ee3a
CB
15334/* Try to open include file FILENAME. SEARCHPTR is the directory
15335 being tried from the include file search path. This function maps
15336 filenames on file systems based on information read by
15337 read_name_map. */
15338
15339static FILE *
15340open_include_file (filename, searchptr)
15341 char *filename;
15342 struct file_name_list *searchptr;
5ff904cd 15343{
c7e4ee3a
CB
15344 register struct file_name_map *map;
15345 register char *from;
15346 char *p, *dir;
5ff904cd 15347
c7e4ee3a
CB
15348 if (searchptr && ! searchptr->got_name_map)
15349 {
15350 searchptr->name_map = read_name_map (searchptr->fname
15351 ? searchptr->fname : ".");
15352 searchptr->got_name_map = 1;
15353 }
5ff904cd 15354
c7e4ee3a
CB
15355 /* First check the mapping for the directory we are using. */
15356 if (searchptr && searchptr->name_map)
15357 {
15358 from = filename;
15359 if (searchptr->fname)
15360 from += strlen (searchptr->fname) + 1;
15361 for (map = searchptr->name_map; map; map = map->map_next)
15362 {
15363 if (! strcmp (map->map_from, from))
15364 {
15365 /* Found a match. */
15366 return fopen (map->map_to, "r");
15367 }
15368 }
15369 }
5ff904cd 15370
c7e4ee3a
CB
15371 /* Try to find a mapping file for the particular directory we are
15372 looking in. Thus #include <sys/types.h> will look up sys/types.h
15373 in /usr/include/header.gcc and look up types.h in
15374 /usr/include/sys/header.gcc. */
9473c522 15375 p = strrchr (filename, '/');
c7e4ee3a 15376#ifdef DIR_SEPARATOR
9473c522 15377 if (! p) p = strrchr (filename, DIR_SEPARATOR);
c7e4ee3a 15378 else {
9473c522 15379 char *tmp = strrchr (filename, DIR_SEPARATOR);
c7e4ee3a
CB
15380 if (tmp != NULL && tmp > p) p = tmp;
15381 }
15382#endif
15383 if (! p)
15384 p = filename;
15385 if (searchptr
15386 && searchptr->fname
15387 && strlen (searchptr->fname) == (size_t) (p - filename)
15388 && ! strncmp (searchptr->fname, filename, (int) (p - filename)))
15389 {
15390 /* FILENAME is in SEARCHPTR, which we've already checked. */
15391 return fopen (filename, "r");
15392 }
15393
15394 if (p == filename)
15395 {
15396 from = filename;
15397 map = read_name_map (".");
15398 }
15399 else
5ff904cd 15400 {
c7e4ee3a
CB
15401 dir = (char *) xmalloc (p - filename + 1);
15402 memcpy (dir, filename, p - filename);
15403 dir[p - filename] = '\0';
15404 from = p + 1;
15405 map = read_name_map (dir);
15406 free (dir);
5ff904cd 15407 }
c7e4ee3a
CB
15408 for (; map; map = map->map_next)
15409 if (! strcmp (map->map_from, from))
15410 return fopen (map->map_to, "r");
5ff904cd 15411
c7e4ee3a 15412 return fopen (filename, "r");
5ff904cd
JL
15413}
15414
c7e4ee3a
CB
15415/* Print the file names and line numbers of the #include
15416 commands which led to the current file. */
5ff904cd 15417
c7e4ee3a
CB
15418static void
15419print_containing_files (ffebadSeverity sev)
15420{
15421 FILE_BUF *ip = NULL;
15422 int i;
15423 int first = 1;
15424 const char *str1;
15425 const char *str2;
5ff904cd 15426
c7e4ee3a
CB
15427 /* If stack of files hasn't changed since we last printed
15428 this info, don't repeat it. */
15429 if (last_error_tick == input_file_stack_tick)
15430 return;
5ff904cd 15431
c7e4ee3a
CB
15432 for (i = indepth; i >= 0; i--)
15433 if (instack[i].fname != NULL) {
15434 ip = &instack[i];
15435 break;
15436 }
5ff904cd 15437
c7e4ee3a
CB
15438 /* Give up if we don't find a source file. */
15439 if (ip == NULL)
15440 return;
5ff904cd 15441
c7e4ee3a
CB
15442 /* Find the other, outer source files. */
15443 for (i--; i >= 0; i--)
15444 if (instack[i].fname != NULL)
15445 {
15446 ip = &instack[i];
15447 if (first)
15448 {
15449 first = 0;
15450 str1 = "In file included";
15451 }
15452 else
15453 {
15454 str1 = "... ...";
15455 }
5ff904cd 15456
c7e4ee3a
CB
15457 if (i == 1)
15458 str2 = ":";
15459 else
15460 str2 = "";
5ff904cd 15461
c7e4ee3a
CB
15462 ffebad_start_msg ("%A from %B at %0%C", sev);
15463 ffebad_here (0, ip->line, ip->column);
15464 ffebad_string (str1);
15465 ffebad_string (ip->nominal_fname);
15466 ffebad_string (str2);
15467 ffebad_finish ();
15468 }
5ff904cd 15469
c7e4ee3a
CB
15470 /* Record we have printed the status as of this time. */
15471 last_error_tick = input_file_stack_tick;
15472}
5ff904cd 15473
c7e4ee3a
CB
15474/* Read a space delimited string of unlimited length from a stdio
15475 file. */
5ff904cd 15476
c7e4ee3a
CB
15477static char *
15478read_filename_string (ch, f)
15479 int ch;
15480 FILE *f;
15481{
15482 char *alloc, *set;
15483 int len;
5ff904cd 15484
c7e4ee3a
CB
15485 len = 20;
15486 set = alloc = xmalloc (len + 1);
15487 if (! is_space[ch])
15488 {
15489 *set++ = ch;
15490 while ((ch = getc (f)) != EOF && ! is_space[ch])
15491 {
15492 if (set - alloc == len)
15493 {
15494 len *= 2;
15495 alloc = xrealloc (alloc, len + 1);
15496 set = alloc + len / 2;
15497 }
15498 *set++ = ch;
15499 }
15500 }
15501 *set = '\0';
15502 ungetc (ch, f);
15503 return alloc;
15504}
5ff904cd 15505
c7e4ee3a 15506/* Read the file name map file for DIRNAME. */
5ff904cd 15507
c7e4ee3a
CB
15508static struct file_name_map *
15509read_name_map (dirname)
15510 const char *dirname;
15511{
15512 /* This structure holds a linked list of file name maps, one per
15513 directory. */
15514 struct file_name_map_list
15515 {
15516 struct file_name_map_list *map_list_next;
15517 char *map_list_name;
15518 struct file_name_map *map_list_map;
15519 };
15520 static struct file_name_map_list *map_list;
15521 register struct file_name_map_list *map_list_ptr;
15522 char *name;
15523 FILE *f;
15524 size_t dirlen;
15525 int separator_needed;
5ff904cd 15526
c7e4ee3a 15527 dirname = skip_redundant_dir_prefix (dirname);
5ff904cd 15528
c7e4ee3a
CB
15529 for (map_list_ptr = map_list; map_list_ptr;
15530 map_list_ptr = map_list_ptr->map_list_next)
15531 if (! strcmp (map_list_ptr->map_list_name, dirname))
15532 return map_list_ptr->map_list_map;
5ff904cd 15533
c7e4ee3a
CB
15534 map_list_ptr = ((struct file_name_map_list *)
15535 xmalloc (sizeof (struct file_name_map_list)));
15536 map_list_ptr->map_list_name = xstrdup (dirname);
15537 map_list_ptr->map_list_map = NULL;
5ff904cd 15538
c7e4ee3a
CB
15539 dirlen = strlen (dirname);
15540 separator_needed = dirlen != 0 && dirname[dirlen - 1] != '/';
15541 name = (char *) xmalloc (dirlen + strlen (FILE_NAME_MAP_FILE) + 2);
15542 strcpy (name, dirname);
15543 name[dirlen] = '/';
15544 strcpy (name + dirlen + separator_needed, FILE_NAME_MAP_FILE);
15545 f = fopen (name, "r");
15546 free (name);
15547 if (!f)
15548 map_list_ptr->map_list_map = NULL;
15549 else
15550 {
15551 int ch;
5ff904cd 15552
c7e4ee3a
CB
15553 while ((ch = getc (f)) != EOF)
15554 {
15555 char *from, *to;
15556 struct file_name_map *ptr;
15557
15558 if (is_space[ch])
15559 continue;
15560 from = read_filename_string (ch, f);
15561 while ((ch = getc (f)) != EOF && is_hor_space[ch])
15562 ;
15563 to = read_filename_string (ch, f);
5ff904cd 15564
c7e4ee3a
CB
15565 ptr = ((struct file_name_map *)
15566 xmalloc (sizeof (struct file_name_map)));
15567 ptr->map_from = from;
5ff904cd 15568
c7e4ee3a
CB
15569 /* Make the real filename absolute. */
15570 if (*to == '/')
15571 ptr->map_to = to;
15572 else
15573 {
15574 ptr->map_to = xmalloc (dirlen + strlen (to) + 2);
15575 strcpy (ptr->map_to, dirname);
15576 ptr->map_to[dirlen] = '/';
15577 strcpy (ptr->map_to + dirlen + separator_needed, to);
15578 free (to);
15579 }
5ff904cd 15580
c7e4ee3a
CB
15581 ptr->map_next = map_list_ptr->map_list_map;
15582 map_list_ptr->map_list_map = ptr;
5ff904cd 15583
c7e4ee3a
CB
15584 while ((ch = getc (f)) != '\n')
15585 if (ch == EOF)
15586 break;
15587 }
15588 fclose (f);
5ff904cd
JL
15589 }
15590
c7e4ee3a
CB
15591 map_list_ptr->map_list_next = map_list;
15592 map_list = map_list_ptr;
5ff904cd 15593
c7e4ee3a 15594 return map_list_ptr->map_list_map;
5ff904cd
JL
15595}
15596
c7e4ee3a 15597static void
b0791fa9 15598ffecom_file_ (const char *name)
5ff904cd 15599{
c7e4ee3a 15600 FILE_BUF *fp;
5ff904cd 15601
c7e4ee3a
CB
15602 /* Do partial setup of input buffer for the sake of generating
15603 early #line directives (when -g is in effect). */
5ff904cd 15604
c7e4ee3a
CB
15605 fp = &instack[++indepth];
15606 memset ((char *) fp, 0, sizeof (FILE_BUF));
15607 if (name == NULL)
15608 name = "";
15609 fp->nominal_fname = fp->fname = name;
15610}
5ff904cd 15611
c7e4ee3a 15612/* Initialize syntactic classifications of characters. */
5ff904cd 15613
c7e4ee3a
CB
15614static void
15615ffecom_initialize_char_syntax_ ()
15616{
15617 register int i;
5ff904cd 15618
c7e4ee3a
CB
15619 /*
15620 * Set up is_idchar and is_idstart tables. These should be
15621 * faster than saying (is_alpha (c) || c == '_'), etc.
15622 * Set up these things before calling any routines tthat
15623 * refer to them.
15624 */
15625 for (i = 'a'; i <= 'z'; i++) {
15626 is_idchar[i - 'a' + 'A'] = 1;
15627 is_idchar[i] = 1;
15628 is_idstart[i - 'a' + 'A'] = 1;
15629 is_idstart[i] = 1;
15630 }
15631 for (i = '0'; i <= '9'; i++)
15632 is_idchar[i] = 1;
15633 is_idchar['_'] = 1;
15634 is_idstart['_'] = 1;
5ff904cd 15635
c7e4ee3a
CB
15636 /* horizontal space table */
15637 is_hor_space[' '] = 1;
15638 is_hor_space['\t'] = 1;
15639 is_hor_space['\v'] = 1;
15640 is_hor_space['\f'] = 1;
15641 is_hor_space['\r'] = 1;
5ff904cd 15642
c7e4ee3a
CB
15643 is_space[' '] = 1;
15644 is_space['\t'] = 1;
15645 is_space['\v'] = 1;
15646 is_space['\f'] = 1;
15647 is_space['\n'] = 1;
15648 is_space['\r'] = 1;
15649}
5ff904cd 15650
c7e4ee3a
CB
15651static void
15652ffecom_close_include_ (FILE *f)
15653{
15654 fclose (f);
5ff904cd 15655
c7e4ee3a
CB
15656 indepth--;
15657 input_file_stack_tick++;
5ff904cd 15658
c7e4ee3a
CB
15659 ffewhere_line_kill (instack[indepth].line);
15660 ffewhere_column_kill (instack[indepth].column);
15661}
5ff904cd 15662
c7e4ee3a
CB
15663static int
15664ffecom_decode_include_option_ (char *spec)
15665{
15666 struct file_name_list *dirtmp;
15667
15668 if (! ignore_srcdir && !strcmp (spec, "-"))
15669 ignore_srcdir = 1;
15670 else
15671 {
15672 dirtmp = (struct file_name_list *)
15673 xmalloc (sizeof (struct file_name_list));
15674 dirtmp->next = 0; /* New one goes on the end */
400500c4 15675 dirtmp->fname = spec;
c7e4ee3a 15676 dirtmp->got_name_map = 0;
400500c4
RK
15677 if (spec[0] == 0)
15678 error ("Directory name must immediately follow -I");
15679 else
15680 append_include_chain (dirtmp, dirtmp);
c7e4ee3a
CB
15681 }
15682 return 1;
5ff904cd
JL
15683}
15684
c7e4ee3a
CB
15685/* Open INCLUDEd file. */
15686
15687static FILE *
15688ffecom_open_include_ (char *name, ffewhereLine l, ffewhereColumn c)
5ff904cd 15689{
c7e4ee3a
CB
15690 char *fbeg = name;
15691 size_t flen = strlen (fbeg);
15692 struct file_name_list *search_start = include; /* Chain of dirs to search */
15693 struct file_name_list dsp[1]; /* First in chain, if #include "..." */
15694 struct file_name_list *searchptr = 0;
15695 char *fname; /* Dynamically allocated fname buffer */
15696 FILE *f;
15697 FILE_BUF *fp;
5ff904cd 15698
c7e4ee3a
CB
15699 if (flen == 0)
15700 return NULL;
5ff904cd 15701
c7e4ee3a 15702 dsp[0].fname = NULL;
5ff904cd 15703
c7e4ee3a
CB
15704 /* If -I- was specified, don't search current dir, only spec'd ones. */
15705 if (!ignore_srcdir)
15706 {
15707 for (fp = &instack[indepth]; fp >= instack; fp--)
15708 {
15709 int n;
15710 char *ep;
b0791fa9 15711 const char *nam;
5ff904cd 15712
c7e4ee3a
CB
15713 if ((nam = fp->nominal_fname) != NULL)
15714 {
15715 /* Found a named file. Figure out dir of the file,
15716 and put it in front of the search list. */
15717 dsp[0].next = search_start;
15718 search_start = dsp;
15719#ifndef VMS
9473c522 15720 ep = strrchr (nam, '/');
c7e4ee3a 15721#ifdef DIR_SEPARATOR
9473c522 15722 if (ep == NULL) ep = strrchr (nam, DIR_SEPARATOR);
c7e4ee3a 15723 else {
9473c522 15724 char *tmp = strrchr (nam, DIR_SEPARATOR);
c7e4ee3a
CB
15725 if (tmp != NULL && tmp > ep) ep = tmp;
15726 }
15727#endif
15728#else /* VMS */
9473c522
JM
15729 ep = strrchr (nam, ']');
15730 if (ep == NULL) ep = strrchr (nam, '>');
15731 if (ep == NULL) ep = strrchr (nam, ':');
c7e4ee3a
CB
15732 if (ep != NULL) ep++;
15733#endif /* VMS */
15734 if (ep != NULL)
15735 {
15736 n = ep - nam;
15737 dsp[0].fname = (char *) xmalloc (n + 1);
15738 strncpy (dsp[0].fname, nam, n);
15739 dsp[0].fname[n] = '\0';
15740 if (n + INCLUDE_LEN_FUDGE > max_include_len)
15741 max_include_len = n + INCLUDE_LEN_FUDGE;
15742 }
15743 else
15744 dsp[0].fname = NULL; /* Current directory */
15745 dsp[0].got_name_map = 0;
15746 break;
15747 }
15748 }
15749 }
5ff904cd 15750
c7e4ee3a
CB
15751 /* Allocate this permanently, because it gets stored in the definitions
15752 of macros. */
15753 fname = xmalloc (max_include_len + flen + 4);
15754 /* + 2 above for slash and terminating null. */
15755 /* + 2 added for '.h' on VMS (to support '#include filename') (NOT USED
15756 for g77 yet). */
5ff904cd 15757
c7e4ee3a 15758 /* If specified file name is absolute, just open it. */
5ff904cd 15759
c7e4ee3a
CB
15760 if (*fbeg == '/'
15761#ifdef DIR_SEPARATOR
15762 || *fbeg == DIR_SEPARATOR
15763#endif
15764 )
15765 {
15766 strncpy (fname, (char *) fbeg, flen);
15767 fname[flen] = 0;
3e411c3f 15768 f = open_include_file (fname, NULL);
5ff904cd 15769 }
c7e4ee3a
CB
15770 else
15771 {
15772 f = NULL;
5ff904cd 15773
c7e4ee3a
CB
15774 /* Search directory path, trying to open the file.
15775 Copy each filename tried into FNAME. */
5ff904cd 15776
c7e4ee3a
CB
15777 for (searchptr = search_start; searchptr; searchptr = searchptr->next)
15778 {
15779 if (searchptr->fname)
15780 {
15781 /* The empty string in a search path is ignored.
15782 This makes it possible to turn off entirely
15783 a standard piece of the list. */
15784 if (searchptr->fname[0] == 0)
15785 continue;
15786 strcpy (fname, skip_redundant_dir_prefix (searchptr->fname));
15787 if (fname[0] && fname[strlen (fname) - 1] != '/')
15788 strcat (fname, "/");
15789 fname[strlen (fname) + flen] = 0;
15790 }
15791 else
15792 fname[0] = 0;
5ff904cd 15793
c7e4ee3a
CB
15794 strncat (fname, fbeg, flen);
15795#ifdef VMS
15796 /* Change this 1/2 Unix 1/2 VMS file specification into a
15797 full VMS file specification */
15798 if (searchptr->fname && (searchptr->fname[0] != 0))
15799 {
15800 /* Fix up the filename */
15801 hack_vms_include_specification (fname);
15802 }
15803 else
15804 {
15805 /* This is a normal VMS filespec, so use it unchanged. */
15806 strncpy (fname, (char *) fbeg, flen);
15807 fname[flen] = 0;
15808#if 0 /* Not for g77. */
15809 /* if it's '#include filename', add the missing .h */
9473c522 15810 if (strchr (fname, '.') == NULL)
c7e4ee3a 15811 strcat (fname, ".h");
5ff904cd 15812#endif
c7e4ee3a
CB
15813 }
15814#endif /* VMS */
15815 f = open_include_file (fname, searchptr);
15816#ifdef EACCES
15817 if (f == NULL && errno == EACCES)
15818 {
15819 print_containing_files (FFEBAD_severityWARNING);
15820 ffebad_start_msg ("At %0, INCLUDE file %A exists, but is not readable",
15821 FFEBAD_severityWARNING);
15822 ffebad_string (fname);
15823 ffebad_here (0, l, c);
15824 ffebad_finish ();
15825 }
15826#endif
15827 if (f != NULL)
15828 break;
15829 }
15830 }
5ff904cd 15831
c7e4ee3a 15832 if (f == NULL)
5ff904cd 15833 {
c7e4ee3a 15834 /* A file that was not found. */
5ff904cd 15835
c7e4ee3a
CB
15836 strncpy (fname, (char *) fbeg, flen);
15837 fname[flen] = 0;
15838 print_containing_files (ffebad_severity (FFEBAD_OPEN_INCLUDE));
15839 ffebad_start (FFEBAD_OPEN_INCLUDE);
15840 ffebad_here (0, l, c);
15841 ffebad_string (fname);
15842 ffebad_finish ();
5ff904cd
JL
15843 }
15844
c7e4ee3a
CB
15845 if (dsp[0].fname != NULL)
15846 free (dsp[0].fname);
5ff904cd 15847
c7e4ee3a
CB
15848 if (f == NULL)
15849 return NULL;
5ff904cd 15850
c7e4ee3a
CB
15851 if (indepth >= (INPUT_STACK_MAX - 1))
15852 {
15853 print_containing_files (FFEBAD_severityFATAL);
15854 ffebad_start_msg ("At %0, INCLUDE nesting too deep",
15855 FFEBAD_severityFATAL);
15856 ffebad_string (fname);
15857 ffebad_here (0, l, c);
15858 ffebad_finish ();
15859 return NULL;
15860 }
5ff904cd 15861
c7e4ee3a
CB
15862 instack[indepth].line = ffewhere_line_use (l);
15863 instack[indepth].column = ffewhere_column_use (c);
5ff904cd 15864
c7e4ee3a
CB
15865 fp = &instack[indepth + 1];
15866 memset ((char *) fp, 0, sizeof (FILE_BUF));
15867 fp->nominal_fname = fp->fname = fname;
15868 fp->dir = searchptr;
5ff904cd 15869
c7e4ee3a
CB
15870 indepth++;
15871 input_file_stack_tick++;
5ff904cd 15872
c7e4ee3a
CB
15873 return f;
15874}
5ff904cd 15875
c7e4ee3a
CB
15876/**INDENT* (Do not reformat this comment even with -fca option.)
15877 Data-gathering files: Given the source file listed below, compiled with
15878 f2c I obtained the output file listed after that, and from the output
15879 file I derived the above code.
5ff904cd 15880
c7e4ee3a
CB
15881-------- (begin input file to f2c)
15882 implicit none
15883 character*10 A1,A2
15884 complex C1,C2
15885 integer I1,I2
15886 real R1,R2
15887 double precision D1,D2
15888C
15889 call getem(A1,A2,C1,C2,I1,I2,R1,R2,D1,D2)
15890c /
15891 call fooI(I1/I2)
15892 call fooR(R1/I1)
15893 call fooD(D1/I1)
15894 call fooC(C1/I1)
15895 call fooR(R1/R2)
15896 call fooD(R1/D1)
15897 call fooD(D1/D2)
15898 call fooD(D1/R1)
15899 call fooC(C1/C2)
15900 call fooC(C1/R1)
15901 call fooZ(C1/D1)
15902c **
15903 call fooI(I1**I2)
15904 call fooR(R1**I1)
15905 call fooD(D1**I1)
15906 call fooC(C1**I1)
15907 call fooR(R1**R2)
15908 call fooD(R1**D1)
15909 call fooD(D1**D2)
15910 call fooD(D1**R1)
15911 call fooC(C1**C2)
15912 call fooC(C1**R1)
15913 call fooZ(C1**D1)
15914c FFEINTRIN_impABS
15915 call fooR(ABS(R1))
15916c FFEINTRIN_impACOS
15917 call fooR(ACOS(R1))
15918c FFEINTRIN_impAIMAG
15919 call fooR(AIMAG(C1))
15920c FFEINTRIN_impAINT
15921 call fooR(AINT(R1))
15922c FFEINTRIN_impALOG
15923 call fooR(ALOG(R1))
15924c FFEINTRIN_impALOG10
15925 call fooR(ALOG10(R1))
15926c FFEINTRIN_impAMAX0
15927 call fooR(AMAX0(I1,I2))
15928c FFEINTRIN_impAMAX1
15929 call fooR(AMAX1(R1,R2))
15930c FFEINTRIN_impAMIN0
15931 call fooR(AMIN0(I1,I2))
15932c FFEINTRIN_impAMIN1
15933 call fooR(AMIN1(R1,R2))
15934c FFEINTRIN_impAMOD
15935 call fooR(AMOD(R1,R2))
15936c FFEINTRIN_impANINT
15937 call fooR(ANINT(R1))
15938c FFEINTRIN_impASIN
15939 call fooR(ASIN(R1))
15940c FFEINTRIN_impATAN
15941 call fooR(ATAN(R1))
15942c FFEINTRIN_impATAN2
15943 call fooR(ATAN2(R1,R2))
15944c FFEINTRIN_impCABS
15945 call fooR(CABS(C1))
15946c FFEINTRIN_impCCOS
15947 call fooC(CCOS(C1))
15948c FFEINTRIN_impCEXP
15949 call fooC(CEXP(C1))
15950c FFEINTRIN_impCHAR
15951 call fooA(CHAR(I1))
15952c FFEINTRIN_impCLOG
15953 call fooC(CLOG(C1))
15954c FFEINTRIN_impCONJG
15955 call fooC(CONJG(C1))
15956c FFEINTRIN_impCOS
15957 call fooR(COS(R1))
15958c FFEINTRIN_impCOSH
15959 call fooR(COSH(R1))
15960c FFEINTRIN_impCSIN
15961 call fooC(CSIN(C1))
15962c FFEINTRIN_impCSQRT
15963 call fooC(CSQRT(C1))
15964c FFEINTRIN_impDABS
15965 call fooD(DABS(D1))
15966c FFEINTRIN_impDACOS
15967 call fooD(DACOS(D1))
15968c FFEINTRIN_impDASIN
15969 call fooD(DASIN(D1))
15970c FFEINTRIN_impDATAN
15971 call fooD(DATAN(D1))
15972c FFEINTRIN_impDATAN2
15973 call fooD(DATAN2(D1,D2))
15974c FFEINTRIN_impDCOS
15975 call fooD(DCOS(D1))
15976c FFEINTRIN_impDCOSH
15977 call fooD(DCOSH(D1))
15978c FFEINTRIN_impDDIM
15979 call fooD(DDIM(D1,D2))
15980c FFEINTRIN_impDEXP
15981 call fooD(DEXP(D1))
15982c FFEINTRIN_impDIM
15983 call fooR(DIM(R1,R2))
15984c FFEINTRIN_impDINT
15985 call fooD(DINT(D1))
15986c FFEINTRIN_impDLOG
15987 call fooD(DLOG(D1))
15988c FFEINTRIN_impDLOG10
15989 call fooD(DLOG10(D1))
15990c FFEINTRIN_impDMAX1
15991 call fooD(DMAX1(D1,D2))
15992c FFEINTRIN_impDMIN1
15993 call fooD(DMIN1(D1,D2))
15994c FFEINTRIN_impDMOD
15995 call fooD(DMOD(D1,D2))
15996c FFEINTRIN_impDNINT
15997 call fooD(DNINT(D1))
15998c FFEINTRIN_impDPROD
15999 call fooD(DPROD(R1,R2))
16000c FFEINTRIN_impDSIGN
16001 call fooD(DSIGN(D1,D2))
16002c FFEINTRIN_impDSIN
16003 call fooD(DSIN(D1))
16004c FFEINTRIN_impDSINH
16005 call fooD(DSINH(D1))
16006c FFEINTRIN_impDSQRT
16007 call fooD(DSQRT(D1))
16008c FFEINTRIN_impDTAN
16009 call fooD(DTAN(D1))
16010c FFEINTRIN_impDTANH
16011 call fooD(DTANH(D1))
16012c FFEINTRIN_impEXP
16013 call fooR(EXP(R1))
16014c FFEINTRIN_impIABS
16015 call fooI(IABS(I1))
16016c FFEINTRIN_impICHAR
16017 call fooI(ICHAR(A1))
16018c FFEINTRIN_impIDIM
16019 call fooI(IDIM(I1,I2))
16020c FFEINTRIN_impIDNINT
16021 call fooI(IDNINT(D1))
16022c FFEINTRIN_impINDEX
16023 call fooI(INDEX(A1,A2))
16024c FFEINTRIN_impISIGN
16025 call fooI(ISIGN(I1,I2))
16026c FFEINTRIN_impLEN
16027 call fooI(LEN(A1))
16028c FFEINTRIN_impLGE
16029 call fooL(LGE(A1,A2))
16030c FFEINTRIN_impLGT
16031 call fooL(LGT(A1,A2))
16032c FFEINTRIN_impLLE
16033 call fooL(LLE(A1,A2))
16034c FFEINTRIN_impLLT
16035 call fooL(LLT(A1,A2))
16036c FFEINTRIN_impMAX0
16037 call fooI(MAX0(I1,I2))
16038c FFEINTRIN_impMAX1
16039 call fooI(MAX1(R1,R2))
16040c FFEINTRIN_impMIN0
16041 call fooI(MIN0(I1,I2))
16042c FFEINTRIN_impMIN1
16043 call fooI(MIN1(R1,R2))
16044c FFEINTRIN_impMOD
16045 call fooI(MOD(I1,I2))
16046c FFEINTRIN_impNINT
16047 call fooI(NINT(R1))
16048c FFEINTRIN_impSIGN
16049 call fooR(SIGN(R1,R2))
16050c FFEINTRIN_impSIN
16051 call fooR(SIN(R1))
16052c FFEINTRIN_impSINH
16053 call fooR(SINH(R1))
16054c FFEINTRIN_impSQRT
16055 call fooR(SQRT(R1))
16056c FFEINTRIN_impTAN
16057 call fooR(TAN(R1))
16058c FFEINTRIN_impTANH
16059 call fooR(TANH(R1))
16060c FFEINTRIN_imp_CMPLX_C
16061 call fooC(cmplx(C1,C2))
16062c FFEINTRIN_imp_CMPLX_D
16063 call fooZ(cmplx(D1,D2))
16064c FFEINTRIN_imp_CMPLX_I
16065 call fooC(cmplx(I1,I2))
16066c FFEINTRIN_imp_CMPLX_R
16067 call fooC(cmplx(R1,R2))
16068c FFEINTRIN_imp_DBLE_C
16069 call fooD(dble(C1))
16070c FFEINTRIN_imp_DBLE_D
16071 call fooD(dble(D1))
16072c FFEINTRIN_imp_DBLE_I
16073 call fooD(dble(I1))
16074c FFEINTRIN_imp_DBLE_R
16075 call fooD(dble(R1))
16076c FFEINTRIN_imp_INT_C
16077 call fooI(int(C1))
16078c FFEINTRIN_imp_INT_D
16079 call fooI(int(D1))
16080c FFEINTRIN_imp_INT_I
16081 call fooI(int(I1))
16082c FFEINTRIN_imp_INT_R
16083 call fooI(int(R1))
16084c FFEINTRIN_imp_REAL_C
16085 call fooR(real(C1))
16086c FFEINTRIN_imp_REAL_D
16087 call fooR(real(D1))
16088c FFEINTRIN_imp_REAL_I
16089 call fooR(real(I1))
16090c FFEINTRIN_imp_REAL_R
16091 call fooR(real(R1))
16092c
16093c FFEINTRIN_imp_INT_D:
16094c
16095c FFEINTRIN_specIDINT
16096 call fooI(IDINT(D1))
16097c
16098c FFEINTRIN_imp_INT_R:
16099c
16100c FFEINTRIN_specIFIX
16101 call fooI(IFIX(R1))
16102c FFEINTRIN_specINT
16103 call fooI(INT(R1))
16104c
16105c FFEINTRIN_imp_REAL_D:
16106c
16107c FFEINTRIN_specSNGL
16108 call fooR(SNGL(D1))
16109c
16110c FFEINTRIN_imp_REAL_I:
16111c
16112c FFEINTRIN_specFLOAT
16113 call fooR(FLOAT(I1))
16114c FFEINTRIN_specREAL
16115 call fooR(REAL(I1))
16116c
16117 end
16118-------- (end input file to f2c)
5ff904cd 16119
c7e4ee3a
CB
16120-------- (begin output from providing above input file as input to:
16121-------- `f2c | gcc -E -C - | sed -e "s:/[*]*://:g" -e "s:[*]*[/]://:g" \
16122-------- -e "s:^#.*$::g"')
5ff904cd 16123
c7e4ee3a
CB
16124// -- translated by f2c (version 19950223).
16125 You must link the resulting object file with the libraries:
16126 -lf2c -lm (in that order)
16127//
5ff904cd 16128
5ff904cd 16129
c7e4ee3a 16130// f2c.h -- Standard Fortran to C header file //
5ff904cd 16131
c7e4ee3a 16132/// barf [ba:rf] 2. "He suggested using FORTRAN, and everybody barfed."
5ff904cd 16133
c7e4ee3a 16134 - From The Shogakukan DICTIONARY OF NEW ENGLISH (Second edition) //
5ff904cd 16135
5ff904cd 16136
5ff904cd 16137
5ff904cd 16138
c7e4ee3a
CB
16139// F2C_INTEGER will normally be `int' but would be `long' on 16-bit systems //
16140// we assume short, float are OK //
16141typedef long int // long int // integer;
16142typedef char *address;
16143typedef short int shortint;
16144typedef float real;
16145typedef double doublereal;
16146typedef struct { real r, i; } complex;
16147typedef struct { doublereal r, i; } doublecomplex;
16148typedef long int // long int // logical;
16149typedef short int shortlogical;
16150typedef char logical1;
16151typedef char integer1;
16152// typedef long long longint; // // system-dependent //
5ff904cd 16153
5ff904cd 16154
5ff904cd 16155
5ff904cd 16156
c7e4ee3a 16157// Extern is for use with -E //
5ff904cd 16158
5ff904cd 16159
5ff904cd 16160
5ff904cd 16161
c7e4ee3a 16162// I/O stuff //
5ff904cd 16163
5ff904cd 16164
5ff904cd 16165
5ff904cd 16166
5ff904cd 16167
5ff904cd 16168
5ff904cd 16169
5ff904cd 16170
c7e4ee3a
CB
16171typedef long int // int or long int // flag;
16172typedef long int // int or long int // ftnlen;
16173typedef long int // int or long int // ftnint;
5ff904cd 16174
5ff904cd 16175
c7e4ee3a
CB
16176//external read, write//
16177typedef struct
16178{ flag cierr;
16179 ftnint ciunit;
16180 flag ciend;
16181 char *cifmt;
16182 ftnint cirec;
16183} cilist;
5ff904cd 16184
c7e4ee3a
CB
16185//internal read, write//
16186typedef struct
16187{ flag icierr;
16188 char *iciunit;
16189 flag iciend;
16190 char *icifmt;
16191 ftnint icirlen;
16192 ftnint icirnum;
16193} icilist;
5ff904cd 16194
c7e4ee3a
CB
16195//open//
16196typedef struct
16197{ flag oerr;
16198 ftnint ounit;
16199 char *ofnm;
16200 ftnlen ofnmlen;
16201 char *osta;
16202 char *oacc;
16203 char *ofm;
16204 ftnint orl;
16205 char *oblnk;
16206} olist;
5ff904cd 16207
c7e4ee3a
CB
16208//close//
16209typedef struct
16210{ flag cerr;
16211 ftnint cunit;
16212 char *csta;
16213} cllist;
5ff904cd 16214
c7e4ee3a
CB
16215//rewind, backspace, endfile//
16216typedef struct
16217{ flag aerr;
16218 ftnint aunit;
16219} alist;
5ff904cd 16220
c7e4ee3a
CB
16221// inquire //
16222typedef struct
16223{ flag inerr;
16224 ftnint inunit;
16225 char *infile;
16226 ftnlen infilen;
16227 ftnint *inex; //parameters in standard's order//
16228 ftnint *inopen;
16229 ftnint *innum;
16230 ftnint *innamed;
16231 char *inname;
16232 ftnlen innamlen;
16233 char *inacc;
16234 ftnlen inacclen;
16235 char *inseq;
16236 ftnlen inseqlen;
16237 char *indir;
16238 ftnlen indirlen;
16239 char *infmt;
16240 ftnlen infmtlen;
16241 char *inform;
16242 ftnint informlen;
16243 char *inunf;
16244 ftnlen inunflen;
16245 ftnint *inrecl;
16246 ftnint *innrec;
16247 char *inblank;
16248 ftnlen inblanklen;
16249} inlist;
5ff904cd 16250
5ff904cd 16251
5ff904cd 16252
c7e4ee3a
CB
16253union Multitype { // for multiple entry points //
16254 integer1 g;
16255 shortint h;
16256 integer i;
16257 // longint j; //
16258 real r;
16259 doublereal d;
16260 complex c;
16261 doublecomplex z;
16262 };
16263
16264typedef union Multitype Multitype;
5ff904cd 16265
c7e4ee3a 16266typedef long Long; // No longer used; formerly in Namelist //
5ff904cd 16267
c7e4ee3a
CB
16268struct Vardesc { // for Namelist //
16269 char *name;
16270 char *addr;
16271 ftnlen *dims;
16272 int type;
16273 };
16274typedef struct Vardesc Vardesc;
5ff904cd 16275
c7e4ee3a
CB
16276struct Namelist {
16277 char *name;
16278 Vardesc **vars;
16279 int nvars;
16280 };
16281typedef struct Namelist Namelist;
5ff904cd 16282
5ff904cd 16283
5ff904cd 16284
5ff904cd 16285
5ff904cd 16286
5ff904cd 16287
5ff904cd 16288
5ff904cd 16289
c7e4ee3a 16290// procedure parameter types for -A and -C++ //
5ff904cd 16291
5ff904cd 16292
5ff904cd 16293
5ff904cd 16294
c7e4ee3a
CB
16295typedef int // Unknown procedure type // (*U_fp)();
16296typedef shortint (*J_fp)();
16297typedef integer (*I_fp)();
16298typedef real (*R_fp)();
16299typedef doublereal (*D_fp)(), (*E_fp)();
16300typedef // Complex // void (*C_fp)();
16301typedef // Double Complex // void (*Z_fp)();
16302typedef logical (*L_fp)();
16303typedef shortlogical (*K_fp)();
16304typedef // Character // void (*H_fp)();
16305typedef // Subroutine // int (*S_fp)();
5ff904cd 16306
c7e4ee3a
CB
16307// E_fp is for real functions when -R is not specified //
16308typedef void C_f; // complex function //
16309typedef void H_f; // character function //
16310typedef void Z_f; // double complex function //
16311typedef doublereal E_f; // real function with -R not specified //
5ff904cd 16312
c7e4ee3a 16313// undef any lower-case symbols that your C compiler predefines, e.g.: //
5ff904cd 16314
5ff904cd 16315
c7e4ee3a
CB
16316// (No such symbols should be defined in a strict ANSI C compiler.
16317 We can avoid trouble with f2c-translated code by using
16318 gcc -ansi [-traditional].) //
16319
5ff904cd 16320
5ff904cd 16321
5ff904cd 16322
5ff904cd 16323
5ff904cd 16324
5ff904cd 16325
5ff904cd 16326
5ff904cd 16327
5ff904cd 16328
5ff904cd 16329
5ff904cd 16330
5ff904cd 16331
5ff904cd 16332
5ff904cd 16333
5ff904cd 16334
5ff904cd 16335
5ff904cd 16336
5ff904cd 16337
5ff904cd 16338
5ff904cd 16339
5ff904cd 16340
5ff904cd 16341
c7e4ee3a
CB
16342// Main program // MAIN__()
16343{
16344 // System generated locals //
16345 integer i__1;
16346 real r__1, r__2;
16347 doublereal d__1, d__2;
16348 complex q__1;
16349 doublecomplex z__1, z__2, z__3;
16350 logical L__1;
16351 char ch__1[1];
16352
16353 // Builtin functions //
16354 void c_div();
16355 integer pow_ii();
16356 double pow_ri(), pow_di();
16357 void pow_ci();
16358 double pow_dd();
16359 void pow_zz();
516b69ff 16360 double acos(), r_imag(), r_int(), log(), r_lg10(), r_mod(), r_nint(),
c7e4ee3a
CB
16361 asin(), atan(), atan2(), c_abs();
16362 void c_cos(), c_exp(), c_log(), r_cnjg();
16363 double cos(), cosh();
16364 void c_sin(), c_sqrt();
516b69ff 16365 double d_dim(), exp(), r_dim(), d_int(), d_lg10(), d_mod(), d_nint(),
c7e4ee3a
CB
16366 d_sign(), sin(), sinh(), sqrt(), tan(), tanh();
16367 integer i_dim(), i_dnnt(), i_indx(), i_sign(), i_len();
16368 logical l_ge(), l_gt(), l_le(), l_lt();
16369 integer i_nint();
16370 double r_sign();
16371
16372 // Local variables //
516b69ff 16373 extern // Subroutine // int fooa_(), fooc_(), food_(), fooi_(), foor_(),
c7e4ee3a
CB
16374 fool_(), fooz_(), getem_();
16375 static char a1[10], a2[10];
16376 static complex c1, c2;
16377 static doublereal d1, d2;
16378 static integer i1, i2;
16379 static real r1, r2;
16380
16381
16382 getem_(a1, a2, &c1, &c2, &i1, &i2, &r1, &r2, &d1, &d2, 10L, 10L);
16383// / //
16384 i__1 = i1 / i2;
16385 fooi_(&i__1);
16386 r__1 = r1 / i1;
16387 foor_(&r__1);
16388 d__1 = d1 / i1;
16389 food_(&d__1);
16390 d__1 = (doublereal) i1;
16391 q__1.r = c1.r / d__1, q__1.i = c1.i / d__1;
16392 fooc_(&q__1);
16393 r__1 = r1 / r2;
16394 foor_(&r__1);
16395 d__1 = r1 / d1;
16396 food_(&d__1);
16397 d__1 = d1 / d2;
16398 food_(&d__1);
16399 d__1 = d1 / r1;
16400 food_(&d__1);
16401 c_div(&q__1, &c1, &c2);
16402 fooc_(&q__1);
16403 q__1.r = c1.r / r1, q__1.i = c1.i / r1;
16404 fooc_(&q__1);
16405 z__1.r = c1.r / d1, z__1.i = c1.i / d1;
16406 fooz_(&z__1);
16407// ** //
16408 i__1 = pow_ii(&i1, &i2);
16409 fooi_(&i__1);
16410 r__1 = pow_ri(&r1, &i1);
16411 foor_(&r__1);
16412 d__1 = pow_di(&d1, &i1);
16413 food_(&d__1);
16414 pow_ci(&q__1, &c1, &i1);
16415 fooc_(&q__1);
16416 d__1 = (doublereal) r1;
16417 d__2 = (doublereal) r2;
16418 r__1 = pow_dd(&d__1, &d__2);
16419 foor_(&r__1);
16420 d__2 = (doublereal) r1;
16421 d__1 = pow_dd(&d__2, &d1);
16422 food_(&d__1);
16423 d__1 = pow_dd(&d1, &d2);
16424 food_(&d__1);
16425 d__2 = (doublereal) r1;
16426 d__1 = pow_dd(&d1, &d__2);
16427 food_(&d__1);
16428 z__2.r = c1.r, z__2.i = c1.i;
16429 z__3.r = c2.r, z__3.i = c2.i;
16430 pow_zz(&z__1, &z__2, &z__3);
16431 q__1.r = z__1.r, q__1.i = z__1.i;
16432 fooc_(&q__1);
16433 z__2.r = c1.r, z__2.i = c1.i;
16434 z__3.r = r1, z__3.i = 0.;
16435 pow_zz(&z__1, &z__2, &z__3);
16436 q__1.r = z__1.r, q__1.i = z__1.i;
16437 fooc_(&q__1);
16438 z__2.r = c1.r, z__2.i = c1.i;
16439 z__3.r = d1, z__3.i = 0.;
16440 pow_zz(&z__1, &z__2, &z__3);
16441 fooz_(&z__1);
16442// FFEINTRIN_impABS //
16443 r__1 = (doublereal)(( r1 ) >= 0 ? ( r1 ) : -( r1 )) ;
16444 foor_(&r__1);
16445// FFEINTRIN_impACOS //
16446 r__1 = acos(r1);
16447 foor_(&r__1);
16448// FFEINTRIN_impAIMAG //
16449 r__1 = r_imag(&c1);
16450 foor_(&r__1);
16451// FFEINTRIN_impAINT //
16452 r__1 = r_int(&r1);
16453 foor_(&r__1);
16454// FFEINTRIN_impALOG //
16455 r__1 = log(r1);
16456 foor_(&r__1);
16457// FFEINTRIN_impALOG10 //
16458 r__1 = r_lg10(&r1);
16459 foor_(&r__1);
16460// FFEINTRIN_impAMAX0 //
16461 r__1 = (real) (( i1 ) >= ( i2 ) ? ( i1 ) : ( i2 )) ;
16462 foor_(&r__1);
16463// FFEINTRIN_impAMAX1 //
16464 r__1 = (doublereal)(( r1 ) >= ( r2 ) ? ( r1 ) : ( r2 )) ;
16465 foor_(&r__1);
16466// FFEINTRIN_impAMIN0 //
16467 r__1 = (real) (( i1 ) <= ( i2 ) ? ( i1 ) : ( i2 )) ;
16468 foor_(&r__1);
16469// FFEINTRIN_impAMIN1 //
16470 r__1 = (doublereal)(( r1 ) <= ( r2 ) ? ( r1 ) : ( r2 )) ;
16471 foor_(&r__1);
16472// FFEINTRIN_impAMOD //
16473 r__1 = r_mod(&r1, &r2);
16474 foor_(&r__1);
16475// FFEINTRIN_impANINT //
16476 r__1 = r_nint(&r1);
16477 foor_(&r__1);
16478// FFEINTRIN_impASIN //
16479 r__1 = asin(r1);
16480 foor_(&r__1);
16481// FFEINTRIN_impATAN //
16482 r__1 = atan(r1);
16483 foor_(&r__1);
16484// FFEINTRIN_impATAN2 //
16485 r__1 = atan2(r1, r2);
16486 foor_(&r__1);
16487// FFEINTRIN_impCABS //
16488 r__1 = c_abs(&c1);
16489 foor_(&r__1);
16490// FFEINTRIN_impCCOS //
16491 c_cos(&q__1, &c1);
16492 fooc_(&q__1);
16493// FFEINTRIN_impCEXP //
16494 c_exp(&q__1, &c1);
16495 fooc_(&q__1);
16496// FFEINTRIN_impCHAR //
16497 *(unsigned char *)&ch__1[0] = i1;
16498 fooa_(ch__1, 1L);
16499// FFEINTRIN_impCLOG //
16500 c_log(&q__1, &c1);
16501 fooc_(&q__1);
16502// FFEINTRIN_impCONJG //
16503 r_cnjg(&q__1, &c1);
16504 fooc_(&q__1);
16505// FFEINTRIN_impCOS //
16506 r__1 = cos(r1);
16507 foor_(&r__1);
16508// FFEINTRIN_impCOSH //
16509 r__1 = cosh(r1);
16510 foor_(&r__1);
16511// FFEINTRIN_impCSIN //
16512 c_sin(&q__1, &c1);
16513 fooc_(&q__1);
16514// FFEINTRIN_impCSQRT //
16515 c_sqrt(&q__1, &c1);
16516 fooc_(&q__1);
16517// FFEINTRIN_impDABS //
16518 d__1 = (( d1 ) >= 0 ? ( d1 ) : -( d1 )) ;
16519 food_(&d__1);
16520// FFEINTRIN_impDACOS //
16521 d__1 = acos(d1);
16522 food_(&d__1);
16523// FFEINTRIN_impDASIN //
16524 d__1 = asin(d1);
16525 food_(&d__1);
16526// FFEINTRIN_impDATAN //
16527 d__1 = atan(d1);
16528 food_(&d__1);
16529// FFEINTRIN_impDATAN2 //
16530 d__1 = atan2(d1, d2);
16531 food_(&d__1);
16532// FFEINTRIN_impDCOS //
16533 d__1 = cos(d1);
16534 food_(&d__1);
16535// FFEINTRIN_impDCOSH //
16536 d__1 = cosh(d1);
16537 food_(&d__1);
16538// FFEINTRIN_impDDIM //
16539 d__1 = d_dim(&d1, &d2);
16540 food_(&d__1);
16541// FFEINTRIN_impDEXP //
16542 d__1 = exp(d1);
16543 food_(&d__1);
16544// FFEINTRIN_impDIM //
16545 r__1 = r_dim(&r1, &r2);
16546 foor_(&r__1);
16547// FFEINTRIN_impDINT //
16548 d__1 = d_int(&d1);
16549 food_(&d__1);
16550// FFEINTRIN_impDLOG //
16551 d__1 = log(d1);
16552 food_(&d__1);
16553// FFEINTRIN_impDLOG10 //
16554 d__1 = d_lg10(&d1);
16555 food_(&d__1);
16556// FFEINTRIN_impDMAX1 //
16557 d__1 = (( d1 ) >= ( d2 ) ? ( d1 ) : ( d2 )) ;
16558 food_(&d__1);
16559// FFEINTRIN_impDMIN1 //
16560 d__1 = (( d1 ) <= ( d2 ) ? ( d1 ) : ( d2 )) ;
16561 food_(&d__1);
16562// FFEINTRIN_impDMOD //
16563 d__1 = d_mod(&d1, &d2);
16564 food_(&d__1);
16565// FFEINTRIN_impDNINT //
16566 d__1 = d_nint(&d1);
16567 food_(&d__1);
16568// FFEINTRIN_impDPROD //
16569 d__1 = (doublereal) r1 * r2;
16570 food_(&d__1);
16571// FFEINTRIN_impDSIGN //
16572 d__1 = d_sign(&d1, &d2);
16573 food_(&d__1);
16574// FFEINTRIN_impDSIN //
16575 d__1 = sin(d1);
16576 food_(&d__1);
16577// FFEINTRIN_impDSINH //
16578 d__1 = sinh(d1);
16579 food_(&d__1);
16580// FFEINTRIN_impDSQRT //
16581 d__1 = sqrt(d1);
16582 food_(&d__1);
16583// FFEINTRIN_impDTAN //
16584 d__1 = tan(d1);
16585 food_(&d__1);
16586// FFEINTRIN_impDTANH //
16587 d__1 = tanh(d1);
16588 food_(&d__1);
16589// FFEINTRIN_impEXP //
16590 r__1 = exp(r1);
16591 foor_(&r__1);
16592// FFEINTRIN_impIABS //
16593 i__1 = (( i1 ) >= 0 ? ( i1 ) : -( i1 )) ;
16594 fooi_(&i__1);
16595// FFEINTRIN_impICHAR //
16596 i__1 = *(unsigned char *)a1;
16597 fooi_(&i__1);
16598// FFEINTRIN_impIDIM //
16599 i__1 = i_dim(&i1, &i2);
16600 fooi_(&i__1);
16601// FFEINTRIN_impIDNINT //
16602 i__1 = i_dnnt(&d1);
16603 fooi_(&i__1);
16604// FFEINTRIN_impINDEX //
16605 i__1 = i_indx(a1, a2, 10L, 10L);
16606 fooi_(&i__1);
16607// FFEINTRIN_impISIGN //
16608 i__1 = i_sign(&i1, &i2);
16609 fooi_(&i__1);
16610// FFEINTRIN_impLEN //
16611 i__1 = i_len(a1, 10L);
16612 fooi_(&i__1);
16613// FFEINTRIN_impLGE //
16614 L__1 = l_ge(a1, a2, 10L, 10L);
16615 fool_(&L__1);
16616// FFEINTRIN_impLGT //
16617 L__1 = l_gt(a1, a2, 10L, 10L);
16618 fool_(&L__1);
16619// FFEINTRIN_impLLE //
16620 L__1 = l_le(a1, a2, 10L, 10L);
16621 fool_(&L__1);
16622// FFEINTRIN_impLLT //
16623 L__1 = l_lt(a1, a2, 10L, 10L);
16624 fool_(&L__1);
16625// FFEINTRIN_impMAX0 //
16626 i__1 = (( i1 ) >= ( i2 ) ? ( i1 ) : ( i2 )) ;
16627 fooi_(&i__1);
16628// FFEINTRIN_impMAX1 //
16629 i__1 = (integer) (doublereal)(( r1 ) >= ( r2 ) ? ( r1 ) : ( r2 )) ;
16630 fooi_(&i__1);
16631// FFEINTRIN_impMIN0 //
16632 i__1 = (( i1 ) <= ( i2 ) ? ( i1 ) : ( i2 )) ;
16633 fooi_(&i__1);
16634// FFEINTRIN_impMIN1 //
16635 i__1 = (integer) (doublereal)(( r1 ) <= ( r2 ) ? ( r1 ) : ( r2 )) ;
16636 fooi_(&i__1);
16637// FFEINTRIN_impMOD //
16638 i__1 = i1 % i2;
16639 fooi_(&i__1);
16640// FFEINTRIN_impNINT //
16641 i__1 = i_nint(&r1);
16642 fooi_(&i__1);
16643// FFEINTRIN_impSIGN //
16644 r__1 = r_sign(&r1, &r2);
16645 foor_(&r__1);
16646// FFEINTRIN_impSIN //
16647 r__1 = sin(r1);
16648 foor_(&r__1);
16649// FFEINTRIN_impSINH //
16650 r__1 = sinh(r1);
16651 foor_(&r__1);
16652// FFEINTRIN_impSQRT //
16653 r__1 = sqrt(r1);
16654 foor_(&r__1);
16655// FFEINTRIN_impTAN //
16656 r__1 = tan(r1);
16657 foor_(&r__1);
16658// FFEINTRIN_impTANH //
16659 r__1 = tanh(r1);
16660 foor_(&r__1);
16661// FFEINTRIN_imp_CMPLX_C //
16662 r__1 = c1.r;
16663 r__2 = c2.r;
16664 q__1.r = r__1, q__1.i = r__2;
16665 fooc_(&q__1);
16666// FFEINTRIN_imp_CMPLX_D //
16667 z__1.r = d1, z__1.i = d2;
16668 fooz_(&z__1);
16669// FFEINTRIN_imp_CMPLX_I //
16670 r__1 = (real) i1;
16671 r__2 = (real) i2;
16672 q__1.r = r__1, q__1.i = r__2;
16673 fooc_(&q__1);
16674// FFEINTRIN_imp_CMPLX_R //
16675 q__1.r = r1, q__1.i = r2;
16676 fooc_(&q__1);
16677// FFEINTRIN_imp_DBLE_C //
16678 d__1 = (doublereal) c1.r;
16679 food_(&d__1);
16680// FFEINTRIN_imp_DBLE_D //
16681 d__1 = d1;
16682 food_(&d__1);
16683// FFEINTRIN_imp_DBLE_I //
16684 d__1 = (doublereal) i1;
16685 food_(&d__1);
16686// FFEINTRIN_imp_DBLE_R //
16687 d__1 = (doublereal) r1;
16688 food_(&d__1);
16689// FFEINTRIN_imp_INT_C //
16690 i__1 = (integer) c1.r;
16691 fooi_(&i__1);
16692// FFEINTRIN_imp_INT_D //
16693 i__1 = (integer) d1;
16694 fooi_(&i__1);
16695// FFEINTRIN_imp_INT_I //
16696 i__1 = i1;
16697 fooi_(&i__1);
16698// FFEINTRIN_imp_INT_R //
16699 i__1 = (integer) r1;
16700 fooi_(&i__1);
16701// FFEINTRIN_imp_REAL_C //
16702 r__1 = c1.r;
16703 foor_(&r__1);
16704// FFEINTRIN_imp_REAL_D //
16705 r__1 = (real) d1;
16706 foor_(&r__1);
16707// FFEINTRIN_imp_REAL_I //
16708 r__1 = (real) i1;
16709 foor_(&r__1);
16710// FFEINTRIN_imp_REAL_R //
16711 r__1 = r1;
16712 foor_(&r__1);
16713
16714// FFEINTRIN_imp_INT_D: //
16715
16716// FFEINTRIN_specIDINT //
16717 i__1 = (integer) d1;
16718 fooi_(&i__1);
16719
16720// FFEINTRIN_imp_INT_R: //
16721
16722// FFEINTRIN_specIFIX //
16723 i__1 = (integer) r1;
16724 fooi_(&i__1);
16725// FFEINTRIN_specINT //
16726 i__1 = (integer) r1;
16727 fooi_(&i__1);
16728
16729// FFEINTRIN_imp_REAL_D: //
5ff904cd 16730
c7e4ee3a
CB
16731// FFEINTRIN_specSNGL //
16732 r__1 = (real) d1;
16733 foor_(&r__1);
5ff904cd 16734
c7e4ee3a 16735// FFEINTRIN_imp_REAL_I: //
5ff904cd 16736
c7e4ee3a
CB
16737// FFEINTRIN_specFLOAT //
16738 r__1 = (real) i1;
16739 foor_(&r__1);
16740// FFEINTRIN_specREAL //
16741 r__1 = (real) i1;
16742 foor_(&r__1);
5ff904cd 16743
c7e4ee3a 16744} // MAIN__ //
5ff904cd 16745
c7e4ee3a 16746-------- (end output file from f2c)
5ff904cd 16747
c7e4ee3a 16748*/
This page took 3.086775 seconds and 5 git commands to generate.