]> gcc.gnu.org Git - gcc.git/blame - gcc/f/com.c
* gcc.dg/noncompile/label-lineno-1.c: New test.
[gcc.git] / gcc / f / com.c
CommitLineData
5ff904cd 1/* com.c -- Implementation File (module.c template V1.0)
06ceef4e
RK
2 Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000
3 Free Software Foundation, Inc.
25d7717e 4 Contributed by James Craig Burley.
5ff904cd
JL
5
6This file is part of GNU Fortran.
7
8GNU Fortran is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2, or (at your option)
11any later version.
12
13GNU Fortran is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with GNU Fortran; see the file COPYING. If not, write to
20the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2102111-1307, USA.
22
23 Related Modules:
24 None
25
26 Description:
27 Contains compiler-specific functions.
28
29 Modifications:
30*/
31
32/* Understanding this module means understanding the interface between
33 the g77 front end and the gcc back end (or, perhaps, some other
34 back end). In here are the functions called by the front end proper
35 to notify whatever back end is in place about certain things, and
36 also the back-end-specific functions. It's a bear to deal with, so
37 lately I've been trying to simplify things, especially with regard
38 to the gcc-back-end-specific stuff.
39
40 Building expressions generally seems quite easy, but building decls
41 has been challenging and is undergoing revision. gcc has several
42 kinds of decls:
43
44 TYPE_DECL -- a type (int, float, struct, function, etc.)
45 CONST_DECL -- a constant of some type other than function
46 LABEL_DECL -- a variable or a constant?
47 PARM_DECL -- an argument to a function (a variable that is a dummy)
48 RESULT_DECL -- the return value of a function (a variable)
49 VAR_DECL -- other variable (can hold a ptr-to-function, struct, int, etc.)
50 FUNCTION_DECL -- a function (either the actual function or an extern ref)
51 FIELD_DECL -- a field in a struct or union (goes into types)
52
53 g77 has a set of functions that somewhat parallels the gcc front end
54 when it comes to building decls:
55
56 Internal Function (one we define, not just declare as extern):
57 int yes;
58 yes = suspend_momentary ();
59 if (is_nested) push_f_function_context ();
60 start_function (get_identifier ("function_name"), function_type,
61 is_nested, is_public);
62 // for each arg, build PARM_DECL and call push_parm_decl (decl) with it;
63 store_parm_decls (is_main_program);
c7e4ee3a 64 ffecom_start_compstmt ();
5ff904cd 65 // for stmts and decls inside function, do appropriate things;
c7e4ee3a 66 ffecom_end_compstmt ();
5ff904cd
JL
67 finish_function (is_nested);
68 if (is_nested) pop_f_function_context ();
69 if (is_nested) resume_momentary (yes);
70
71 Everything Else:
72 int yes;
73 tree d;
74 tree init;
75 yes = suspend_momentary ();
76 // fill in external, public, static, &c for decl, and
77 // set DECL_INITIAL to error_mark_node if going to initialize
78 // set is_top_level TRUE only if not at top level and decl
79 // must go in top level (i.e. not within current function decl context)
80 d = start_decl (decl, is_top_level);
81 init = ...; // if have initializer
82 finish_decl (d, init, is_top_level);
83 resume_momentary (yes);
84
85*/
86
87/* Include files. */
88
95a1b676 89#include "proj.h"
5ff904cd 90#if FFECOM_targetCURRENT == FFECOM_targetGCC
15a40ced
ZW
91#include "flags.h"
92#include "rtl.h"
93#include "toplev.h"
94#include "tree.h"
95#include "output.h" /* Must follow tree.h so TREE_CODE is defined! */
96#include "convert.h"
97#include "ggc.h"
5ff904cd
JL
98#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
99
100#define FFECOM_GCC_INCLUDE 1 /* Enable -I. */
101
102/* BEGIN stuff from gcc/cccp.c. */
103
104/* The following symbols should be autoconfigured:
105 HAVE_FCNTL_H
106 HAVE_STDLIB_H
107 HAVE_SYS_TIME_H
108 HAVE_UNISTD_H
109 STDC_HEADERS
110 TIME_WITH_SYS_TIME
111 In the mean time, we'll get by with approximations based
112 on existing GCC configuration symbols. */
113
114#ifdef POSIX
115# ifndef HAVE_STDLIB_H
116# define HAVE_STDLIB_H 1
117# endif
118# ifndef HAVE_UNISTD_H
119# define HAVE_UNISTD_H 1
120# endif
121# ifndef STDC_HEADERS
122# define STDC_HEADERS 1
123# endif
124#endif /* defined (POSIX) */
125
126#if defined (POSIX) || (defined (USG) && !defined (VMS))
127# ifndef HAVE_FCNTL_H
128# define HAVE_FCNTL_H 1
129# endif
130#endif
131
132#ifndef RLIMIT_STACK
133# include <time.h>
134#else
135# if TIME_WITH_SYS_TIME
136# include <sys/time.h>
137# include <time.h>
138# else
139# if HAVE_SYS_TIME_H
140# include <sys/time.h>
141# else
142# include <time.h>
143# endif
144# endif
145# include <sys/resource.h>
146#endif
147
148#if HAVE_FCNTL_H
149# include <fcntl.h>
150#endif
151
152/* This defines "errno" properly for VMS, and gives us EACCES. */
153#include <errno.h>
154
155#if HAVE_STDLIB_H
156# include <stdlib.h>
157#else
158char *getenv ();
159#endif
160
5ff904cd
JL
161#if HAVE_UNISTD_H
162# include <unistd.h>
163#endif
164
165/* VMS-specific definitions */
166#ifdef VMS
167#include <descrip.h>
168#define O_RDONLY 0 /* Open arg for Read/Only */
169#define O_WRONLY 1 /* Open arg for Write/Only */
170#define read(fd,buf,size) VMS_read (fd,buf,size)
171#define write(fd,buf,size) VMS_write (fd,buf,size)
172#define open(fname,mode,prot) VMS_open (fname,mode,prot)
173#define fopen(fname,mode) VMS_fopen (fname,mode)
174#define freopen(fname,mode,ofile) VMS_freopen (fname,mode,ofile)
175#define strncat(dst,src,cnt) VMS_strncat (dst,src,cnt)
176#define fstat(fd,stbuf) VMS_fstat (fd,stbuf)
177static int VMS_fstat (), VMS_stat ();
178static char * VMS_strncat ();
179static int VMS_read ();
180static int VMS_write ();
181static int VMS_open ();
182static FILE * VMS_fopen ();
183static FILE * VMS_freopen ();
184static void hack_vms_include_specification ();
185typedef struct { unsigned :16, :16, :16; } vms_ino_t;
186#define ino_t vms_ino_t
187#define INCLUDE_LEN_FUDGE 10 /* leave room for VMS syntax conversion */
188#ifdef __GNUC__
189#define BSTRING /* VMS/GCC supplies the bstring routines */
190#endif /* __GNUC__ */
191#endif /* VMS */
192
193#ifndef O_RDONLY
194#define O_RDONLY 0
195#endif
196
197/* END stuff from gcc/cccp.c. */
198
5ff904cd
JL
199#define FFECOM_DETERMINE_TYPES 1 /* for com.h */
200#include "com.h"
201#include "bad.h"
202#include "bld.h"
203#include "equiv.h"
204#include "expr.h"
205#include "implic.h"
206#include "info.h"
207#include "malloc.h"
208#include "src.h"
209#include "st.h"
210#include "storag.h"
211#include "symbol.h"
212#include "target.h"
213#include "top.h"
214#include "type.h"
215
216/* Externals defined here. */
217
5ff904cd
JL
218#if FFECOM_targetCURRENT == FFECOM_targetGCC
219
c7e4ee3a
CB
220/* ~~gcc/tree.h *should* declare this, because toplev.c and dwarfout.c
221 reference it. */
5ff904cd 222
f425a887 223const char * const language_string = "GNU F77";
5ff904cd 224
77f77701
DB
225/* Stream for reading from the input file. */
226FILE *finput;
227
5ff904cd
JL
228/* These definitions parallel those in c-decl.c so that code from that
229 module can be used pretty much as is. Much of these defs aren't
230 otherwise used, i.e. by g77 code per se, except some of them are used
231 to build some of them that are. The ones that are global (i.e. not
232 "static") are those that ste.c and such might use (directly
233 or by using com macros that reference them in their definitions). */
234
5ff904cd
JL
235tree string_type_node;
236
5ff904cd
JL
237/* The rest of these are inventions for g77, though there might be
238 similar things in the C front end. As they are found, these
239 inventions should be renamed to be canonical. Note that only
240 the ones currently required to be global are so. */
241
242static tree ffecom_tree_fun_type_void;
5ff904cd
JL
243
244tree ffecom_integer_type_node; /* Abbrev for _tree_type[blah][blah]. */
245tree ffecom_integer_zero_node; /* Like *_*_* with g77's integer type. */
246tree ffecom_integer_one_node; /* " */
247tree ffecom_tree_type[FFEINFO_basictype][FFEINFO_kindtype];
248
249/* _fun_type things are the f2c-specific versions. For -fno-f2c,
250 just use build_function_type and build_pointer_type on the
251 appropriate _tree_type array element. */
252
253static tree ffecom_tree_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
254static tree ffecom_tree_ptr_to_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
255static tree ffecom_tree_subr_type;
256static tree ffecom_tree_ptr_to_subr_type;
257static tree ffecom_tree_blockdata_type;
258
259static tree ffecom_tree_xargc_;
260
261ffecomSymbol ffecom_symbol_null_
262=
263{
264 NULL_TREE,
265 NULL_TREE,
266 NULL_TREE,
0816ebdd
KG
267 NULL_TREE,
268 false
5ff904cd
JL
269};
270ffeinfoKindtype ffecom_pointer_kind_ = FFEINFO_basictypeNONE;
271ffeinfoKindtype ffecom_label_kind_ = FFEINFO_basictypeNONE;
272
273int ffecom_f2c_typecode_[FFEINFO_basictype][FFEINFO_kindtype];
274tree ffecom_f2c_integer_type_node;
275tree ffecom_f2c_ptr_to_integer_type_node;
276tree ffecom_f2c_address_type_node;
277tree ffecom_f2c_real_type_node;
278tree ffecom_f2c_ptr_to_real_type_node;
279tree ffecom_f2c_doublereal_type_node;
280tree ffecom_f2c_complex_type_node;
281tree ffecom_f2c_doublecomplex_type_node;
282tree ffecom_f2c_longint_type_node;
283tree ffecom_f2c_logical_type_node;
284tree ffecom_f2c_flag_type_node;
285tree ffecom_f2c_ftnlen_type_node;
286tree ffecom_f2c_ftnlen_zero_node;
287tree ffecom_f2c_ftnlen_one_node;
288tree ffecom_f2c_ftnlen_two_node;
289tree ffecom_f2c_ptr_to_ftnlen_type_node;
290tree ffecom_f2c_ftnint_type_node;
291tree ffecom_f2c_ptr_to_ftnint_type_node;
292#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
293
294/* Simple definitions and enumerations. */
295
296#ifndef FFECOM_sizeMAXSTACKITEM
297#define FFECOM_sizeMAXSTACKITEM 32*1024 /* Keep user-declared things
298 larger than this # bytes
299 off stack if possible. */
300#endif
301
302/* For systems that have large enough stacks, they should define
303 this to 0, and here, for ease of use later on, we just undefine
304 it if it is 0. */
305
306#if FFECOM_sizeMAXSTACKITEM == 0
307#undef FFECOM_sizeMAXSTACKITEM
308#endif
309
310typedef enum
311 {
312 FFECOM_rttypeVOID_,
6d433196 313 FFECOM_rttypeVOIDSTAR_, /* C's `void *' type. */
795232f7
JL
314 FFECOM_rttypeFTNINT_, /* f2c's `ftnint' type. */
315 FFECOM_rttypeINTEGER_, /* f2c's `integer' type. */
316 FFECOM_rttypeLONGINT_, /* f2c's `longint' type. */
317 FFECOM_rttypeLOGICAL_, /* f2c's `logical' type. */
318 FFECOM_rttypeREAL_F2C_, /* f2c's `real' returned as `double'. */
319 FFECOM_rttypeREAL_GNU_, /* `real' returned as such. */
5ff904cd 320 FFECOM_rttypeCOMPLEX_F2C_, /* f2c's `complex' returned via 1st arg. */
795232f7 321 FFECOM_rttypeCOMPLEX_GNU_, /* f2c's `complex' returned directly. */
5ff904cd 322 FFECOM_rttypeDOUBLE_, /* C's `double' type. */
795232f7 323 FFECOM_rttypeDOUBLEREAL_, /* f2c's `doublereal' type. */
5ff904cd 324 FFECOM_rttypeDBLCMPLX_F2C_, /* f2c's `doublecomplex' returned via 1st arg. */
795232f7 325 FFECOM_rttypeDBLCMPLX_GNU_, /* f2c's `doublecomplex' returned directly. */
5ff904cd
JL
326 FFECOM_rttypeCHARACTER_, /* f2c `char *'/`ftnlen' pair. */
327 FFECOM_rttype_
328 } ffecomRttype_;
329
330/* Internal typedefs. */
331
332#if FFECOM_targetCURRENT == FFECOM_targetGCC
333typedef struct _ffecom_concat_list_ ffecomConcatList_;
5ff904cd
JL
334#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
335
336/* Private include files. */
337
338
339/* Internal structure definitions. */
340
341#if FFECOM_targetCURRENT == FFECOM_targetGCC
342struct _ffecom_concat_list_
343 {
344 ffebld *exprs;
345 int count;
346 int max;
347 ffetargetCharacterSize minlen;
348 ffetargetCharacterSize maxlen;
349 };
5ff904cd
JL
350#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
351
352/* Static functions (internal). */
353
354#if FFECOM_targetCURRENT == FFECOM_targetGCC
26f096f9 355static tree ffecom_arglist_expr_ (const char *argstring, ffebld args);
5ff904cd
JL
356static tree ffecom_widest_expr_type_ (ffebld list);
357static bool ffecom_overlap_ (tree dest_decl, tree dest_offset,
358 tree dest_size, tree source_tree,
359 ffebld source, bool scalar_arg);
360static bool ffecom_args_overlapping_ (tree dest_tree, ffebld dest,
361 tree args, tree callee_commons,
362 bool scalar_args);
26f096f9 363static tree ffecom_build_f2c_string_ (int i, const char *s);
5ff904cd
JL
364static tree ffecom_call_ (tree fn, ffeinfoKindtype kt,
365 bool is_f2c_complex, tree type,
366 tree args, tree dest_tree,
367 ffebld dest, bool *dest_used,
c7e4ee3a 368 tree callee_commons, bool scalar_args, tree hook);
5ff904cd
JL
369static tree ffecom_call_binop_ (tree fn, ffeinfoKindtype kt,
370 bool is_f2c_complex, tree type,
371 ffebld left, ffebld right,
372 tree dest_tree, ffebld dest,
373 bool *dest_used, tree callee_commons,
c7e4ee3a 374 bool scalar_args, tree hook);
86fc7a6c
CB
375static void ffecom_char_args_x_ (tree *xitem, tree *length,
376 ffebld expr, bool with_null);
5ff904cd
JL
377static tree ffecom_check_size_overflow_ (ffesymbol s, tree type, bool dummy);
378static tree ffecom_char_enhance_arg_ (tree *xtype, ffesymbol s);
379static ffecomConcatList_
380 ffecom_concat_list_gather_ (ffecomConcatList_ catlist,
381 ffebld expr,
382 ffetargetCharacterSize max);
383static void ffecom_concat_list_kill_ (ffecomConcatList_ catlist);
384static ffecomConcatList_ ffecom_concat_list_new_ (ffebld expr,
385 ffetargetCharacterSize max);
26f096f9
KG
386static void ffecom_debug_kludge_ (tree aggr, const char *aggr_type,
387 ffesymbol member, tree member_type,
388 ffetargetOffset offset);
5ff904cd 389static void ffecom_do_entry_ (ffesymbol fn, int entrynum);
092a4ef8
RH
390static tree ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest,
391 bool *dest_used, bool assignp, bool widenp);
5ff904cd
JL
392static tree ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree,
393 ffebld dest, bool *dest_used);
c7e4ee3a 394static tree ffecom_expr_power_integer_ (ffebld expr);
5ff904cd 395static void ffecom_expr_transform_ (ffebld expr);
26f096f9 396static void ffecom_f2c_make_type_ (tree *type, int tcode, const char *name);
5ff904cd
JL
397static void ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size,
398 int code);
399static ffeglobal ffecom_finish_global_ (ffeglobal global);
400static ffesymbol ffecom_finish_symbol_transform_ (ffesymbol s);
26f096f9 401static tree ffecom_get_appended_identifier_ (char us, const char *text);
5ff904cd 402static tree ffecom_get_external_identifier_ (ffesymbol s);
26f096f9 403static tree ffecom_get_identifier_ (const char *text);
5ff904cd
JL
404static tree ffecom_gen_sfuncdef_ (ffesymbol s,
405 ffeinfoBasictype bt,
406 ffeinfoKindtype kt);
26f096f9 407static const char *ffecom_gfrt_args_ (ffecomGfrt ix);
5ff904cd
JL
408static tree ffecom_gfrt_tree_ (ffecomGfrt ix);
409static tree ffecom_init_zero_ (tree decl);
410static tree ffecom_intrinsic_ichar_ (tree tree_type, ffebld arg,
411 tree *maybe_tree);
412static tree ffecom_intrinsic_len_ (ffebld expr);
413static void ffecom_let_char_ (tree dest_tree,
414 tree dest_length,
415 ffetargetCharacterSize dest_size,
416 ffebld source);
417static void ffecom_make_gfrt_ (ffecomGfrt ix);
418static void ffecom_member_phase1_ (ffestorag mst, ffestorag st);
5ff904cd 419static void ffecom_member_phase2_ (ffestorag mst, ffestorag st);
c7e4ee3a
CB
420static void ffecom_prepare_let_char_ (ffetargetCharacterSize dest_size,
421 ffebld source);
5ff904cd
JL
422static void ffecom_push_dummy_decls_ (ffebld dumlist,
423 bool stmtfunc);
424static void ffecom_start_progunit_ (void);
425static ffesymbol ffecom_sym_transform_ (ffesymbol s);
426static ffesymbol ffecom_sym_transform_assign_ (ffesymbol s);
427static void ffecom_transform_common_ (ffesymbol s);
428static void ffecom_transform_equiv_ (ffestorag st);
429static tree ffecom_transform_namelist_ (ffesymbol s);
430static void ffecom_tree_canonize_ptr_ (tree *decl, tree *offset,
431 tree t);
432static void ffecom_tree_canonize_ref_ (tree *decl, tree *offset,
433 tree *size, tree tree);
434static tree ffecom_tree_divide_ (tree tree_type, tree left, tree right,
435 tree dest_tree, ffebld dest,
c7e4ee3a 436 bool *dest_used, tree hook);
5ff904cd
JL
437static tree ffecom_type_localvar_ (ffesymbol s,
438 ffeinfoBasictype bt,
439 ffeinfoKindtype kt);
440static tree ffecom_type_namelist_ (void);
5ff904cd
JL
441static tree ffecom_type_vardesc_ (void);
442static tree ffecom_vardesc_ (ffebld expr);
443static tree ffecom_vardesc_array_ (ffesymbol s);
444static tree ffecom_vardesc_dims_ (ffesymbol s);
26f096f9
KG
445static tree ffecom_convert_narrow_ (tree type, tree expr);
446static tree ffecom_convert_widen_ (tree type, tree expr);
5ff904cd
JL
447#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
448
449/* These are static functions that parallel those found in the C front
450 end and thus have the same names. */
451
452#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a 453static tree bison_rule_compstmt_ (void);
5ff904cd 454static void bison_rule_pushlevel_ (void);
c7e4ee3a 455static void delete_block (tree block);
5ff904cd
JL
456static int duplicate_decls (tree newdecl, tree olddecl);
457static void finish_decl (tree decl, tree init, bool is_top_level);
458static void finish_function (int nested);
4b731ffa 459static const char *lang_printable_name (tree decl, int v);
5ff904cd
JL
460static tree lookup_name_current_level (tree name);
461static struct binding_level *make_binding_level (void);
462static void pop_f_function_context (void);
463static void push_f_function_context (void);
464static void push_parm_decl (tree parm);
465static tree pushdecl_top_level (tree decl);
c7e4ee3a 466static int kept_level_p (void);
5ff904cd
JL
467static tree storedecls (tree decls);
468static void store_parm_decls (int is_main_program);
469static tree start_decl (tree decl, bool is_top_level);
470static void start_function (tree name, tree type, int nested, int public);
471#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
472#if FFECOM_GCC_INCLUDE
b0791fa9 473static void ffecom_file_ (const char *name);
5ff904cd
JL
474static void ffecom_initialize_char_syntax_ (void);
475static void ffecom_close_include_ (FILE *f);
476static int ffecom_decode_include_option_ (char *spec);
477static FILE *ffecom_open_include_ (char *name, ffewhereLine l,
478 ffewhereColumn c);
479#endif /* FFECOM_GCC_INCLUDE */
480
481/* Static objects accessed by functions in this module. */
482
483static ffesymbol ffecom_primary_entry_ = NULL;
484static ffesymbol ffecom_nested_entry_ = NULL;
485static ffeinfoKind ffecom_primary_entry_kind_;
486static bool ffecom_primary_entry_is_proc_;
487#if FFECOM_targetCURRENT == FFECOM_targetGCC
488static tree ffecom_outer_function_decl_;
489static tree ffecom_previous_function_decl_;
490static tree ffecom_which_entrypoint_decl_;
5ff904cd
JL
491static tree ffecom_float_zero_ = NULL_TREE;
492static tree ffecom_float_half_ = NULL_TREE;
493static tree ffecom_double_zero_ = NULL_TREE;
494static tree ffecom_double_half_ = NULL_TREE;
495static tree ffecom_func_result_;/* For functions. */
496static tree ffecom_func_length_;/* For CHARACTER fns. */
497static ffebld ffecom_list_blockdata_;
498static ffebld ffecom_list_common_;
499static ffebld ffecom_master_arglist_;
500static ffeinfoBasictype ffecom_master_bt_;
501static ffeinfoKindtype ffecom_master_kt_;
502static ffetargetCharacterSize ffecom_master_size_;
503static int ffecom_num_fns_ = 0;
504static int ffecom_num_entrypoints_ = 0;
505static bool ffecom_is_altreturning_ = FALSE;
506static tree ffecom_multi_type_node_;
507static tree ffecom_multi_retval_;
508static tree
509 ffecom_multi_fields_[FFEINFO_basictype][FFEINFO_kindtype];
510static bool ffecom_member_namelisted_; /* _member_phase1_ namelisted? */
511static bool ffecom_doing_entry_ = FALSE;
512static bool ffecom_transform_only_dummies_ = FALSE;
ff852b44
CB
513static int ffecom_typesize_pointer_;
514static int ffecom_typesize_integer1_;
5ff904cd
JL
515
516/* Holds pointer-to-function expressions. */
517
518static tree ffecom_gfrt_[FFECOM_gfrt]
519=
520{
521#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) NULL_TREE,
522#include "com-rt.def"
523#undef DEFGFRT
524};
525
526/* Holds the external names of the functions. */
527
26f096f9 528static const char *ffecom_gfrt_name_[FFECOM_gfrt]
5ff904cd
JL
529=
530{
531#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) NAME,
532#include "com-rt.def"
533#undef DEFGFRT
534};
535
536/* Whether the function returns. */
537
538static bool ffecom_gfrt_volatile_[FFECOM_gfrt]
539=
540{
541#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) VOLATILE,
542#include "com-rt.def"
543#undef DEFGFRT
544};
545
546/* Whether the function returns type complex. */
547
548static bool ffecom_gfrt_complex_[FFECOM_gfrt]
549=
550{
551#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) COMPLEX,
552#include "com-rt.def"
553#undef DEFGFRT
554};
555
556/* Type code for the function return value. */
557
558static ffecomRttype_ ffecom_gfrt_type_[FFECOM_gfrt]
559=
560{
561#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) TYPE,
562#include "com-rt.def"
563#undef DEFGFRT
564};
565
566/* String of codes for the function's arguments. */
567
26f096f9 568static const char *ffecom_gfrt_argstring_[FFECOM_gfrt]
5ff904cd
JL
569=
570{
571#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) ARGS,
572#include "com-rt.def"
573#undef DEFGFRT
574};
575#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
576
577/* Internal macros. */
578
579#if FFECOM_targetCURRENT == FFECOM_targetGCC
580
581/* We let tm.h override the types used here, to handle trivial differences
582 such as the choice of unsigned int or long unsigned int for size_t.
583 When machines start needing nontrivial differences in the size type,
584 it would be best to do something here to figure out automatically
585 from other information what type to use. */
586
ff852b44
CB
587#ifndef SIZE_TYPE
588#define SIZE_TYPE "long unsigned int"
589#endif
5ff904cd 590
5ff904cd
JL
591#define ffecom_concat_list_count_(catlist) ((catlist).count)
592#define ffecom_concat_list_expr_(catlist,i) ((catlist).exprs[(i)])
593#define ffecom_concat_list_maxlen_(catlist) ((catlist).maxlen)
594#define ffecom_concat_list_minlen_(catlist) ((catlist).minlen)
595
86fc7a6c
CB
596#define ffecom_char_args_(i,l,e) ffecom_char_args_x_((i),(l),(e),FALSE)
597#define ffecom_char_args_with_null_(i,l,e) ffecom_char_args_x_((i),(l),(e),TRUE)
598
5ff904cd
JL
599/* For each binding contour we allocate a binding_level structure
600 * which records the names defined in that contour.
601 * Contours include:
602 * 0) the global one
603 * 1) one for each function definition,
604 * where internal declarations of the parameters appear.
605 *
606 * The current meaning of a name can be found by searching the levels from
607 * the current one out to the global one.
608 */
609
610/* Note that the information in the `names' component of the global contour
611 is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */
612
613struct binding_level
614 {
c7e4ee3a
CB
615 /* A chain of _DECL nodes for all variables, constants, functions,
616 and typedef types. These are in the reverse of the order supplied.
617 */
5ff904cd
JL
618 tree names;
619
c7e4ee3a
CB
620 /* For each level (except not the global one),
621 a chain of BLOCK nodes for all the levels
622 that were entered and exited one level down. */
5ff904cd
JL
623 tree blocks;
624
c7e4ee3a
CB
625 /* The BLOCK node for this level, if one has been preallocated.
626 If 0, the BLOCK is allocated (if needed) when the level is popped. */
5ff904cd
JL
627 tree this_block;
628
629 /* The binding level which this one is contained in (inherits from). */
630 struct binding_level *level_chain;
c7e4ee3a
CB
631
632 /* 0: no ffecom_prepare_* functions called at this level yet;
633 1: ffecom_prepare* functions called, except not ffecom_prepare_end;
634 2: ffecom_prepare_end called. */
635 int prep_state;
5ff904cd
JL
636 };
637
638#define NULL_BINDING_LEVEL (struct binding_level *) NULL
639
640/* The binding level currently in effect. */
641
642static struct binding_level *current_binding_level;
643
644/* A chain of binding_level structures awaiting reuse. */
645
646static struct binding_level *free_binding_level;
647
648/* The outermost binding level, for names of file scope.
649 This is created when the compiler is started and exists
650 through the entire run. */
651
652static struct binding_level *global_binding_level;
653
654/* Binding level structures are initialized by copying this one. */
655
656static struct binding_level clear_binding_level
657=
c7e4ee3a 658{NULL, NULL, NULL, NULL_BINDING_LEVEL, 0};
5ff904cd
JL
659
660/* Language-dependent contents of an identifier. */
661
662struct lang_identifier
663 {
664 struct tree_identifier ignore;
665 tree global_value, local_value, label_value;
666 bool invented;
667 };
668
669/* Macros for access to language-specific slots in an identifier. */
670/* Each of these slots contains a DECL node or null. */
671
672/* This represents the value which the identifier has in the
673 file-scope namespace. */
674#define IDENTIFIER_GLOBAL_VALUE(NODE) \
675 (((struct lang_identifier *)(NODE))->global_value)
676/* This represents the value which the identifier has in the current
677 scope. */
678#define IDENTIFIER_LOCAL_VALUE(NODE) \
679 (((struct lang_identifier *)(NODE))->local_value)
680/* This represents the value which the identifier has as a label in
681 the current label scope. */
682#define IDENTIFIER_LABEL_VALUE(NODE) \
683 (((struct lang_identifier *)(NODE))->label_value)
684/* This is nonzero if the identifier was "made up" by g77 code. */
685#define IDENTIFIER_INVENTED(NODE) \
686 (((struct lang_identifier *)(NODE))->invented)
687
688/* In identifiers, C uses the following fields in a special way:
689 TREE_PUBLIC to record that there was a previous local extern decl.
690 TREE_USED to record that such a decl was used.
691 TREE_ADDRESSABLE to record that the address of such a decl was used. */
692
693/* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function
694 that have names. Here so we can clear out their names' definitions
695 at the end of the function. */
696
697static tree named_labels;
698
699/* A list of LABEL_DECLs from outer contexts that are currently shadowed. */
700
701static tree shadowed_labels;
702
703#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
704\f
6b55276e
CB
705/* Return the subscript expression, modified to do range-checking.
706
707 `array' is the array to be checked against.
708 `element' is the subscript expression to check.
709 `dim' is the dimension number (starting at 0).
710 `total_dims' is the total number of dimensions (0 for CHARACTER substring).
711*/
712
713static tree
714ffecom_subscript_check_ (tree array, tree element, int dim, int total_dims,
3b304f5b 715 const char *array_name)
6b55276e
CB
716{
717 tree low = TYPE_MIN_VALUE (TYPE_DOMAIN (array));
718 tree high = TYPE_MAX_VALUE (TYPE_DOMAIN (array));
719 tree cond;
720 tree die;
721 tree args;
722
723 if (element == error_mark_node)
724 return element;
725
ff852b44
CB
726 if (TREE_TYPE (low) != TREE_TYPE (element))
727 {
728 if (TYPE_PRECISION (TREE_TYPE (low))
729 > TYPE_PRECISION (TREE_TYPE (element)))
730 element = convert (TREE_TYPE (low), element);
731 else
732 {
733 low = convert (TREE_TYPE (element), low);
734 if (high)
735 high = convert (TREE_TYPE (element), high);
736 }
737 }
738
6b55276e
CB
739 element = ffecom_save_tree (element);
740 cond = ffecom_2 (LE_EXPR, integer_type_node,
741 low,
742 element);
743 if (high)
744 {
745 cond = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
746 cond,
747 ffecom_2 (LE_EXPR, integer_type_node,
748 element,
749 high));
750 }
751
752 {
753 int len;
754 char *proc;
755 char *var;
756 tree arg3;
757 tree arg2;
758 tree arg1;
759 tree arg4;
760
761 switch (total_dims)
762 {
763 case 0:
764 var = xmalloc (strlen (array_name) + 20);
3b304f5b 765 sprintf (var, "%s[%s-substring]",
6b55276e
CB
766 array_name,
767 dim ? "end" : "start");
768 len = strlen (var) + 1;
3b304f5b
ZW
769 arg1 = build_string (len, var);
770 free (var);
6b55276e
CB
771 break;
772
773 case 1:
774 len = strlen (array_name) + 1;
3b304f5b 775 arg1 = build_string (len, array_name);
6b55276e
CB
776 break;
777
778 default:
779 var = xmalloc (strlen (array_name) + 40);
3b304f5b 780 sprintf (var, "%s[subscript-%d-of-%d]",
6b55276e
CB
781 array_name,
782 dim + 1, total_dims);
783 len = strlen (var) + 1;
3b304f5b
ZW
784 arg1 = build_string (len, var);
785 free (var);
6b55276e
CB
786 break;
787 }
788
6b55276e
CB
789 TREE_TYPE (arg1)
790 = build_type_variant (build_array_type (char_type_node,
791 build_range_type
792 (integer_type_node,
793 integer_one_node,
794 build_int_2 (len, 0))),
795 1, 0);
796 TREE_CONSTANT (arg1) = 1;
797 TREE_STATIC (arg1) = 1;
798 arg1 = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg1)),
799 arg1);
800
801 /* s_rnge adds one to the element to print it, so bias against
802 that -- want to print a faithful *subscript* value. */
803 arg2 = convert (ffecom_f2c_ftnint_type_node,
804 ffecom_2 (MINUS_EXPR,
805 TREE_TYPE (element),
806 element,
807 convert (TREE_TYPE (element),
808 integer_one_node)));
809
810 proc = xmalloc ((len = strlen (input_filename)
811 + IDENTIFIER_LENGTH (DECL_NAME (current_function_decl))
812 + 2));
813
814 sprintf (&proc[0], "%s/%s",
815 input_filename,
816 IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));
817 arg3 = build_string (len, proc);
818
819 free (proc);
820
821 TREE_TYPE (arg3)
822 = build_type_variant (build_array_type (char_type_node,
823 build_range_type
824 (integer_type_node,
825 integer_one_node,
826 build_int_2 (len, 0))),
827 1, 0);
828 TREE_CONSTANT (arg3) = 1;
829 TREE_STATIC (arg3) = 1;
830 arg3 = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg3)),
831 arg3);
832
833 arg4 = convert (ffecom_f2c_ftnint_type_node,
834 build_int_2 (lineno, 0));
835
836 arg1 = build_tree_list (NULL_TREE, arg1);
837 arg2 = build_tree_list (NULL_TREE, arg2);
838 arg3 = build_tree_list (NULL_TREE, arg3);
839 arg4 = build_tree_list (NULL_TREE, arg4);
840 TREE_CHAIN (arg3) = arg4;
841 TREE_CHAIN (arg2) = arg3;
842 TREE_CHAIN (arg1) = arg2;
843
844 args = arg1;
845 }
846 die = ffecom_call_gfrt (FFECOM_gfrtRANGE,
847 args, NULL_TREE);
848 TREE_SIDE_EFFECTS (die) = 1;
849
850 element = ffecom_3 (COND_EXPR,
851 TREE_TYPE (element),
852 cond,
853 element,
854 die);
855
856 return element;
857}
858
859/* Return the computed element of an array reference.
860
ff852b44
CB
861 `item' is NULL_TREE, or the transformed pointer to the array.
862 `expr' is the original opARRAYREF expression, which is transformed
863 if `item' is NULL_TREE.
864 `want_ptr' is non-zero if a pointer to the element, instead of
6b55276e
CB
865 the element itself, is to be returned. */
866
867static tree
868ffecom_arrayref_ (tree item, ffebld expr, int want_ptr)
869{
870 ffebld dims[FFECOM_dimensionsMAX];
871 int i;
872 int total_dims;
ff852b44
CB
873 int flatten = ffe_is_flatten_arrays ();
874 int need_ptr;
6b55276e
CB
875 tree array;
876 tree element;
ff852b44
CB
877 tree tree_type;
878 tree tree_type_x;
3b304f5b 879 const char *array_name;
ff852b44
CB
880 ffetype type;
881 ffebld list;
6b55276e
CB
882
883 if (ffebld_op (ffebld_left (expr)) == FFEBLD_opSYMTER)
884 array_name = ffesymbol_text (ffebld_symter (ffebld_left (expr)));
885 else
886 array_name = "[expr?]";
887
888 /* Build up ARRAY_REFs in reverse order (since we're column major
889 here in Fortran land). */
890
ff852b44
CB
891 for (i = 0, list = ffebld_right (expr);
892 list != NULL;
893 ++i, list = ffebld_trail (list))
894 {
895 dims[i] = ffebld_head (list);
896 type = ffeinfo_type (ffebld_basictype (dims[i]),
897 ffebld_kindtype (dims[i]));
898 if (! flatten
899 && ffecom_typesize_pointer_ > ffecom_typesize_integer1_
900 && ffetype_size (type) > ffecom_typesize_integer1_)
901 /* E.g. ARRAY(INDEX), given INTEGER*8 INDEX, on a system with 64-bit
902 pointers and 32-bit integers. Do the full 64-bit pointer
903 arithmetic, for codes using arrays for nonstandard heap-like
904 work. */
905 flatten = 1;
906 }
6b55276e
CB
907
908 total_dims = i;
909
ff852b44
CB
910 need_ptr = want_ptr || flatten;
911
912 if (! item)
913 {
914 if (need_ptr)
915 item = ffecom_ptr_to_expr (ffebld_left (expr));
916 else
917 item = ffecom_expr (ffebld_left (expr));
918
919 if (item == error_mark_node)
920 return item;
921
922 if (ffeinfo_where (ffebld_info (expr)) == FFEINFO_whereFLEETING
923 && ! mark_addressable (item))
924 return error_mark_node;
925 }
926
927 if (item == error_mark_node)
928 return item;
929
6b55276e
CB
930 if (need_ptr)
931 {
ff852b44
CB
932 tree min;
933
6b55276e
CB
934 for (--i, array = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item)));
935 i >= 0;
936 --i, array = TYPE_MAIN_VARIANT (TREE_TYPE (array)))
937 {
ff852b44
CB
938 min = TYPE_MIN_VALUE (TYPE_DOMAIN (array));
939 element = ffecom_expr_ (dims[i], NULL, NULL, NULL, FALSE, TRUE);
02f06e64 940 if (flag_bounds_check)
6b55276e
CB
941 element = ffecom_subscript_check_ (array, element, i, total_dims,
942 array_name);
ff852b44
CB
943 if (element == error_mark_node)
944 return element;
945
946 /* Widen integral arithmetic as desired while preserving
947 signedness. */
948 tree_type = TREE_TYPE (element);
949 tree_type_x = tree_type;
950 if (tree_type
951 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
952 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
953 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
954
955 if (TREE_TYPE (min) != tree_type_x)
956 min = convert (tree_type_x, min);
957 if (TREE_TYPE (element) != tree_type_x)
958 element = convert (tree_type_x, element);
959
6b55276e
CB
960 item = ffecom_2 (PLUS_EXPR,
961 build_pointer_type (TREE_TYPE (array)),
962 item,
963 size_binop (MULT_EXPR,
964 size_in_bytes (TREE_TYPE (array)),
fed3cef0
RK
965 convert (sizetype,
966 fold (build (MINUS_EXPR,
967 tree_type_x,
968 element, min)))));
6b55276e
CB
969 }
970 if (! want_ptr)
971 {
972 item = ffecom_1 (INDIRECT_REF,
973 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item))),
974 item);
975 }
976 }
977 else
978 {
979 for (--i;
980 i >= 0;
981 --i)
982 {
983 array = TYPE_MAIN_VARIANT (TREE_TYPE (item));
984
985 element = ffecom_expr_ (dims[i], NULL, NULL, NULL, FALSE, TRUE);
02f06e64 986 if (flag_bounds_check)
6b55276e
CB
987 element = ffecom_subscript_check_ (array, element, i, total_dims,
988 array_name);
ff852b44
CB
989 if (element == error_mark_node)
990 return element;
991
992 /* Widen integral arithmetic as desired while preserving
993 signedness. */
994 tree_type = TREE_TYPE (element);
995 tree_type_x = tree_type;
996 if (tree_type
997 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
998 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
999 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
1000
1001 element = convert (tree_type_x, element);
1002
6b55276e
CB
1003 item = ffecom_2 (ARRAY_REF,
1004 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item))),
1005 item,
1006 element);
1007 }
1008 }
1009
1010 return item;
1011}
1012
5ff904cd
JL
1013/* This is like gcc's stabilize_reference -- in fact, most of the code
1014 comes from that -- but it handles the situation where the reference
1015 is going to have its subparts picked at, and it shouldn't change
1016 (or trigger extra invocations of functions in the subtrees) due to
1017 this. save_expr is a bit overzealous, because we don't need the
1018 entire thing calculated and saved like a temp. So, for DECLs, no
1019 change is needed, because these are stable aggregates, and ARRAY_REF
1020 and such might well be stable too, but for things like calculations,
1021 we do need to calculate a snapshot of a value before picking at it. */
1022
1023#if FFECOM_targetCURRENT == FFECOM_targetGCC
1024static tree
1025ffecom_stabilize_aggregate_ (tree ref)
1026{
1027 tree result;
1028 enum tree_code code = TREE_CODE (ref);
1029
1030 switch (code)
1031 {
1032 case VAR_DECL:
1033 case PARM_DECL:
1034 case RESULT_DECL:
1035 /* No action is needed in this case. */
1036 return ref;
1037
1038 case NOP_EXPR:
1039 case CONVERT_EXPR:
1040 case FLOAT_EXPR:
1041 case FIX_TRUNC_EXPR:
1042 case FIX_FLOOR_EXPR:
1043 case FIX_ROUND_EXPR:
1044 case FIX_CEIL_EXPR:
1045 result = build_nt (code, stabilize_reference (TREE_OPERAND (ref, 0)));
1046 break;
1047
1048 case INDIRECT_REF:
1049 result = build_nt (INDIRECT_REF,
1050 stabilize_reference_1 (TREE_OPERAND (ref, 0)));
1051 break;
1052
1053 case COMPONENT_REF:
1054 result = build_nt (COMPONENT_REF,
1055 stabilize_reference (TREE_OPERAND (ref, 0)),
1056 TREE_OPERAND (ref, 1));
1057 break;
1058
1059 case BIT_FIELD_REF:
1060 result = build_nt (BIT_FIELD_REF,
1061 stabilize_reference (TREE_OPERAND (ref, 0)),
1062 stabilize_reference_1 (TREE_OPERAND (ref, 1)),
1063 stabilize_reference_1 (TREE_OPERAND (ref, 2)));
1064 break;
1065
1066 case ARRAY_REF:
1067 result = build_nt (ARRAY_REF,
1068 stabilize_reference (TREE_OPERAND (ref, 0)),
1069 stabilize_reference_1 (TREE_OPERAND (ref, 1)));
1070 break;
1071
1072 case COMPOUND_EXPR:
1073 result = build_nt (COMPOUND_EXPR,
1074 stabilize_reference_1 (TREE_OPERAND (ref, 0)),
1075 stabilize_reference (TREE_OPERAND (ref, 1)));
1076 break;
1077
1078 case RTL_EXPR:
1079 result = build1 (INDIRECT_REF, TREE_TYPE (ref),
1080 save_expr (build1 (ADDR_EXPR,
1081 build_pointer_type (TREE_TYPE (ref)),
1082 ref)));
1083 break;
1084
1085
1086 default:
1087 return save_expr (ref);
1088
1089 case ERROR_MARK:
1090 return error_mark_node;
1091 }
1092
1093 TREE_TYPE (result) = TREE_TYPE (ref);
1094 TREE_READONLY (result) = TREE_READONLY (ref);
1095 TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (ref);
1096 TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (ref);
5ff904cd
JL
1097
1098 return result;
1099}
1100#endif
1101
1102/* A rip-off of gcc's convert.c convert_to_complex function,
1103 reworked to handle complex implemented as C structures
1104 (RECORD_TYPE with two fields, real and imaginary `r' and `i'). */
1105
1106#if FFECOM_targetCURRENT == FFECOM_targetGCC
1107static tree
1108ffecom_convert_to_complex_ (tree type, tree expr)
1109{
1110 register enum tree_code form = TREE_CODE (TREE_TYPE (expr));
1111 tree subtype;
1112
1113 assert (TREE_CODE (type) == RECORD_TYPE);
1114
1115 subtype = TREE_TYPE (TYPE_FIELDS (type));
1116
1117 if (form == REAL_TYPE || form == INTEGER_TYPE || form == ENUMERAL_TYPE)
1118 {
1119 expr = convert (subtype, expr);
1120 return ffecom_2 (COMPLEX_EXPR, type, expr,
1121 convert (subtype, integer_zero_node));
1122 }
1123
1124 if (form == RECORD_TYPE)
1125 {
1126 tree elt_type = TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr)));
1127 if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype))
1128 return expr;
1129 else
1130 {
1131 expr = save_expr (expr);
1132 return ffecom_2 (COMPLEX_EXPR,
1133 type,
1134 convert (subtype,
1135 ffecom_1 (REALPART_EXPR,
1136 TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))),
1137 expr)),
1138 convert (subtype,
1139 ffecom_1 (IMAGPART_EXPR,
1140 TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))),
1141 expr)));
1142 }
1143 }
1144
1145 if (form == POINTER_TYPE || form == REFERENCE_TYPE)
1146 error ("pointer value used where a complex was expected");
1147 else
1148 error ("aggregate value used where a complex was expected");
1149
1150 return ffecom_2 (COMPLEX_EXPR, type,
1151 convert (subtype, integer_zero_node),
1152 convert (subtype, integer_zero_node));
1153}
1154#endif
1155
1156/* Like gcc's convert(), but crashes if widening might happen. */
1157
1158#if FFECOM_targetCURRENT == FFECOM_targetGCC
1159static tree
1160ffecom_convert_narrow_ (type, expr)
1161 tree type, expr;
1162{
1163 register tree e = expr;
1164 register enum tree_code code = TREE_CODE (type);
1165
1166 if (type == TREE_TYPE (e)
1167 || TREE_CODE (e) == ERROR_MARK)
1168 return e;
1169 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
1170 return fold (build1 (NOP_EXPR, type, e));
1171 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
1172 || code == ERROR_MARK)
1173 return error_mark_node;
1174 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
1175 {
1176 assert ("void value not ignored as it ought to be" == NULL);
1177 return error_mark_node;
1178 }
1179 assert (code != VOID_TYPE);
1180 if ((code != RECORD_TYPE)
1181 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
1182 assert ("converting COMPLEX to REAL" == NULL);
1183 assert (code != ENUMERAL_TYPE);
1184 if (code == INTEGER_TYPE)
1185 {
a74de6ea
CB
1186 assert ((TREE_CODE (TREE_TYPE (e)) == INTEGER_TYPE
1187 && TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (e)))
1188 || (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE
1189 && (TYPE_PRECISION (type)
1190 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e))))));
5ff904cd
JL
1191 return fold (convert_to_integer (type, e));
1192 }
1193 if (code == POINTER_TYPE)
1194 {
1195 assert (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE);
1196 return fold (convert_to_pointer (type, e));
1197 }
1198 if (code == REAL_TYPE)
1199 {
1200 assert (TREE_CODE (TREE_TYPE (e)) == REAL_TYPE);
1201 assert (TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (e)));
1202 return fold (convert_to_real (type, e));
1203 }
1204 if (code == COMPLEX_TYPE)
1205 {
1206 assert (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE);
1207 assert (TYPE_PRECISION (TREE_TYPE (type)) <= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e))));
1208 return fold (convert_to_complex (type, e));
1209 }
1210 if (code == RECORD_TYPE)
1211 {
1212 assert (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE);
270fc4e8
CB
1213 /* Check that at least the first field name agrees. */
1214 assert (DECL_NAME (TYPE_FIELDS (type))
1215 == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e))));
5ff904cd
JL
1216 assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1217 <= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))));
270fc4e8
CB
1218 if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1219 == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))))
1220 return e;
5ff904cd
JL
1221 return fold (ffecom_convert_to_complex_ (type, e));
1222 }
1223
1224 assert ("conversion to non-scalar type requested" == NULL);
1225 return error_mark_node;
1226}
1227#endif
1228
1229/* Like gcc's convert(), but crashes if narrowing might happen. */
1230
1231#if FFECOM_targetCURRENT == FFECOM_targetGCC
1232static tree
1233ffecom_convert_widen_ (type, expr)
1234 tree type, expr;
1235{
1236 register tree e = expr;
1237 register enum tree_code code = TREE_CODE (type);
1238
1239 if (type == TREE_TYPE (e)
1240 || TREE_CODE (e) == ERROR_MARK)
1241 return e;
1242 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
1243 return fold (build1 (NOP_EXPR, type, e));
1244 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
1245 || code == ERROR_MARK)
1246 return error_mark_node;
1247 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
1248 {
1249 assert ("void value not ignored as it ought to be" == NULL);
1250 return error_mark_node;
1251 }
1252 assert (code != VOID_TYPE);
1253 if ((code != RECORD_TYPE)
1254 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
1255 assert ("narrowing COMPLEX to REAL" == NULL);
1256 assert (code != ENUMERAL_TYPE);
1257 if (code == INTEGER_TYPE)
1258 {
a74de6ea
CB
1259 assert ((TREE_CODE (TREE_TYPE (e)) == INTEGER_TYPE
1260 && TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (e)))
1261 || (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE
1262 && (TYPE_PRECISION (type)
1263 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e))))));
5ff904cd
JL
1264 return fold (convert_to_integer (type, e));
1265 }
1266 if (code == POINTER_TYPE)
1267 {
1268 assert (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE);
1269 return fold (convert_to_pointer (type, e));
1270 }
1271 if (code == REAL_TYPE)
1272 {
1273 assert (TREE_CODE (TREE_TYPE (e)) == REAL_TYPE);
1274 assert (TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (e)));
1275 return fold (convert_to_real (type, e));
1276 }
1277 if (code == COMPLEX_TYPE)
1278 {
1279 assert (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE);
1280 assert (TYPE_PRECISION (TREE_TYPE (type)) >= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e))));
1281 return fold (convert_to_complex (type, e));
1282 }
1283 if (code == RECORD_TYPE)
1284 {
1285 assert (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE);
270fc4e8
CB
1286 /* Check that at least the first field name agrees. */
1287 assert (DECL_NAME (TYPE_FIELDS (type))
1288 == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e))));
5ff904cd
JL
1289 assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1290 >= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))));
270fc4e8
CB
1291 if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1292 == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))))
1293 return e;
5ff904cd
JL
1294 return fold (ffecom_convert_to_complex_ (type, e));
1295 }
1296
1297 assert ("conversion to non-scalar type requested" == NULL);
1298 return error_mark_node;
1299}
1300#endif
1301
1302/* Handles making a COMPLEX type, either the standard
1303 (but buggy?) gbe way, or the safer (but less elegant?)
1304 f2c way. */
1305
1306#if FFECOM_targetCURRENT == FFECOM_targetGCC
1307static tree
1308ffecom_make_complex_type_ (tree subtype)
1309{
1310 tree type;
1311 tree realfield;
1312 tree imagfield;
1313
1314 if (ffe_is_emulate_complex ())
1315 {
1316 type = make_node (RECORD_TYPE);
1317 realfield = ffecom_decl_field (type, NULL_TREE, "r", subtype);
1318 imagfield = ffecom_decl_field (type, realfield, "i", subtype);
1319 TYPE_FIELDS (type) = realfield;
1320 layout_type (type);
1321 }
1322 else
1323 {
1324 type = make_node (COMPLEX_TYPE);
1325 TREE_TYPE (type) = subtype;
1326 layout_type (type);
1327 }
1328
1329 return type;
1330}
1331#endif
1332
1333/* Chooses either the gbe or the f2c way to build a
1334 complex constant. */
1335
1336#if FFECOM_targetCURRENT == FFECOM_targetGCC
1337static tree
1338ffecom_build_complex_constant_ (tree type, tree realpart, tree imagpart)
1339{
1340 tree bothparts;
1341
1342 if (ffe_is_emulate_complex ())
1343 {
1344 bothparts = build_tree_list (TYPE_FIELDS (type), realpart);
1345 TREE_CHAIN (bothparts) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), imagpart);
1346 bothparts = build (CONSTRUCTOR, type, NULL_TREE, bothparts);
1347 }
1348 else
1349 {
1350 bothparts = build_complex (type, realpart, imagpart);
1351 }
1352
1353 return bothparts;
1354}
1355#endif
1356
1357#if FFECOM_targetCURRENT == FFECOM_targetGCC
1358static tree
26f096f9 1359ffecom_arglist_expr_ (const char *c, ffebld expr)
5ff904cd
JL
1360{
1361 tree list;
1362 tree *plist = &list;
1363 tree trail = NULL_TREE; /* Append char length args here. */
1364 tree *ptrail = &trail;
1365 tree length;
1366 ffebld exprh;
1367 tree item;
1368 bool ptr = FALSE;
1369 tree wanted = NULL_TREE;
e2fa159e
JL
1370 static char zed[] = "0";
1371
1372 if (c == NULL)
1373 c = &zed[0];
5ff904cd
JL
1374
1375 while (expr != NULL)
1376 {
1377 if (*c != '\0')
1378 {
1379 ptr = FALSE;
1380 if (*c == '&')
1381 {
1382 ptr = TRUE;
1383 ++c;
1384 }
1385 switch (*(c++))
1386 {
1387 case '\0':
1388 ptr = TRUE;
1389 wanted = NULL_TREE;
1390 break;
1391
1392 case 'a':
1393 assert (ptr);
1394 wanted = NULL_TREE;
1395 break;
1396
1397 case 'c':
1398 wanted = ffecom_f2c_complex_type_node;
1399 break;
1400
1401 case 'd':
1402 wanted = ffecom_f2c_doublereal_type_node;
1403 break;
1404
1405 case 'e':
1406 wanted = ffecom_f2c_doublecomplex_type_node;
1407 break;
1408
1409 case 'f':
1410 wanted = ffecom_f2c_real_type_node;
1411 break;
1412
1413 case 'i':
1414 wanted = ffecom_f2c_integer_type_node;
1415 break;
1416
1417 case 'j':
1418 wanted = ffecom_f2c_longint_type_node;
1419 break;
1420
1421 default:
1422 assert ("bad argstring code" == NULL);
1423 wanted = NULL_TREE;
1424 break;
1425 }
1426 }
1427
1428 exprh = ffebld_head (expr);
1429 if (exprh == NULL)
1430 wanted = NULL_TREE;
1431
1432 if ((wanted == NULL_TREE)
1433 || (ptr
1434 && (TYPE_MODE
1435 (ffecom_tree_type[ffeinfo_basictype (ffebld_info (exprh))]
1436 [ffeinfo_kindtype (ffebld_info (exprh))])
1437 == TYPE_MODE (wanted))))
1438 *plist
1439 = build_tree_list (NULL_TREE,
1440 ffecom_arg_ptr_to_expr (exprh,
1441 &length));
1442 else
1443 {
1444 item = ffecom_arg_expr (exprh, &length);
1445 item = ffecom_convert_widen_ (wanted, item);
1446 if (ptr)
1447 {
1448 item = ffecom_1 (ADDR_EXPR,
1449 build_pointer_type (TREE_TYPE (item)),
1450 item);
1451 }
1452 *plist
1453 = build_tree_list (NULL_TREE,
1454 item);
1455 }
1456
1457 plist = &TREE_CHAIN (*plist);
1458 expr = ffebld_trail (expr);
1459 if (length != NULL_TREE)
1460 {
1461 *ptrail = build_tree_list (NULL_TREE, length);
1462 ptrail = &TREE_CHAIN (*ptrail);
1463 }
1464 }
1465
e2fa159e
JL
1466 /* We've run out of args in the call; if the implementation expects
1467 more, supply null pointers for them, which the implementation can
1468 check to see if an arg was omitted. */
1469
1470 while (*c != '\0' && *c != '0')
1471 {
1472 if (*c == '&')
1473 ++c;
1474 else
1475 assert ("missing arg to run-time routine!" == NULL);
1476
1477 switch (*(c++))
1478 {
1479 case '\0':
1480 case 'a':
1481 case 'c':
1482 case 'd':
1483 case 'e':
1484 case 'f':
1485 case 'i':
1486 case 'j':
1487 break;
1488
1489 default:
1490 assert ("bad arg string code" == NULL);
1491 break;
1492 }
1493 *plist
1494 = build_tree_list (NULL_TREE,
1495 null_pointer_node);
1496 plist = &TREE_CHAIN (*plist);
1497 }
1498
5ff904cd
JL
1499 *plist = trail;
1500
1501 return list;
1502}
1503#endif
1504
1505#if FFECOM_targetCURRENT == FFECOM_targetGCC
1506static tree
1507ffecom_widest_expr_type_ (ffebld list)
1508{
1509 ffebld item;
1510 ffebld widest = NULL;
1511 ffetype type;
1512 ffetype widest_type = NULL;
1513 tree t;
1514
1515 for (; list != NULL; list = ffebld_trail (list))
1516 {
1517 item = ffebld_head (list);
1518 if (item == NULL)
1519 continue;
1520 if ((widest != NULL)
1521 && (ffeinfo_basictype (ffebld_info (item))
1522 != ffeinfo_basictype (ffebld_info (widest))))
1523 continue;
1524 type = ffeinfo_type (ffeinfo_basictype (ffebld_info (item)),
1525 ffeinfo_kindtype (ffebld_info (item)));
1526 if ((widest == FFEINFO_kindtypeNONE)
1527 || (ffetype_size (type)
1528 > ffetype_size (widest_type)))
1529 {
1530 widest = item;
1531 widest_type = type;
1532 }
1533 }
1534
1535 assert (widest != NULL);
1536 t = ffecom_tree_type[ffeinfo_basictype (ffebld_info (widest))]
1537 [ffeinfo_kindtype (ffebld_info (widest))];
1538 assert (t != NULL_TREE);
1539 return t;
1540}
1541#endif
1542
d6cd84e0
CB
1543/* Check whether a partial overlap between two expressions is possible.
1544
1545 Can *starting* to write a portion of expr1 change the value
1546 computed (perhaps already, *partially*) by expr2?
1547
1548 Currently, this is a concern only for a COMPLEX expr1. But if it
1549 isn't in COMMON or local EQUIVALENCE, since we don't support
1550 aliasing of arguments, it isn't a concern. */
1551
1552static bool
b0791fa9 1553ffecom_possible_partial_overlap_ (ffebld expr1, ffebld expr2 ATTRIBUTE_UNUSED)
d6cd84e0
CB
1554{
1555 ffesymbol sym;
1556 ffestorag st;
1557
1558 switch (ffebld_op (expr1))
1559 {
1560 case FFEBLD_opSYMTER:
1561 sym = ffebld_symter (expr1);
1562 break;
1563
1564 case FFEBLD_opARRAYREF:
1565 if (ffebld_op (ffebld_left (expr1)) != FFEBLD_opSYMTER)
1566 return FALSE;
1567 sym = ffebld_symter (ffebld_left (expr1));
1568 break;
1569
1570 default:
1571 return FALSE;
1572 }
1573
1574 if (ffesymbol_where (sym) != FFEINFO_whereCOMMON
1575 && (ffesymbol_where (sym) != FFEINFO_whereLOCAL
1576 || ! (st = ffesymbol_storage (sym))
1577 || ! ffestorag_parent (st)))
1578 return FALSE;
1579
1580 /* It's in COMMON or local EQUIVALENCE. */
1581
1582 return TRUE;
1583}
1584
5ff904cd
JL
1585/* Check whether dest and source might overlap. ffebld versions of these
1586 might or might not be passed, will be NULL if not.
1587
1588 The test is really whether source_tree is modifiable and, if modified,
1589 might overlap destination such that the value(s) in the destination might
1590 change before it is finally modified. dest_* are the canonized
1591 destination itself. */
1592
1593#if FFECOM_targetCURRENT == FFECOM_targetGCC
1594static bool
1595ffecom_overlap_ (tree dest_decl, tree dest_offset, tree dest_size,
1596 tree source_tree, ffebld source UNUSED,
1597 bool scalar_arg)
1598{
1599 tree source_decl;
1600 tree source_offset;
1601 tree source_size;
1602 tree t;
1603
1604 if (source_tree == NULL_TREE)
1605 return FALSE;
1606
1607 switch (TREE_CODE (source_tree))
1608 {
1609 case ERROR_MARK:
1610 case IDENTIFIER_NODE:
1611 case INTEGER_CST:
1612 case REAL_CST:
1613 case COMPLEX_CST:
1614 case STRING_CST:
1615 case CONST_DECL:
1616 case VAR_DECL:
1617 case RESULT_DECL:
1618 case FIELD_DECL:
1619 case MINUS_EXPR:
1620 case MULT_EXPR:
1621 case TRUNC_DIV_EXPR:
1622 case CEIL_DIV_EXPR:
1623 case FLOOR_DIV_EXPR:
1624 case ROUND_DIV_EXPR:
1625 case TRUNC_MOD_EXPR:
1626 case CEIL_MOD_EXPR:
1627 case FLOOR_MOD_EXPR:
1628 case ROUND_MOD_EXPR:
1629 case RDIV_EXPR:
1630 case EXACT_DIV_EXPR:
1631 case FIX_TRUNC_EXPR:
1632 case FIX_CEIL_EXPR:
1633 case FIX_FLOOR_EXPR:
1634 case FIX_ROUND_EXPR:
1635 case FLOAT_EXPR:
1636 case EXPON_EXPR:
1637 case NEGATE_EXPR:
1638 case MIN_EXPR:
1639 case MAX_EXPR:
1640 case ABS_EXPR:
1641 case FFS_EXPR:
1642 case LSHIFT_EXPR:
1643 case RSHIFT_EXPR:
1644 case LROTATE_EXPR:
1645 case RROTATE_EXPR:
1646 case BIT_IOR_EXPR:
1647 case BIT_XOR_EXPR:
1648 case BIT_AND_EXPR:
1649 case BIT_ANDTC_EXPR:
1650 case BIT_NOT_EXPR:
1651 case TRUTH_ANDIF_EXPR:
1652 case TRUTH_ORIF_EXPR:
1653 case TRUTH_AND_EXPR:
1654 case TRUTH_OR_EXPR:
1655 case TRUTH_XOR_EXPR:
1656 case TRUTH_NOT_EXPR:
1657 case LT_EXPR:
1658 case LE_EXPR:
1659 case GT_EXPR:
1660 case GE_EXPR:
1661 case EQ_EXPR:
1662 case NE_EXPR:
1663 case COMPLEX_EXPR:
1664 case CONJ_EXPR:
1665 case REALPART_EXPR:
1666 case IMAGPART_EXPR:
1667 case LABEL_EXPR:
1668 case COMPONENT_REF:
1669 return FALSE;
1670
1671 case COMPOUND_EXPR:
1672 return ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1673 TREE_OPERAND (source_tree, 1), NULL,
1674 scalar_arg);
1675
1676 case MODIFY_EXPR:
1677 return ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1678 TREE_OPERAND (source_tree, 0), NULL,
1679 scalar_arg);
1680
1681 case CONVERT_EXPR:
1682 case NOP_EXPR:
1683 case NON_LVALUE_EXPR:
1684 case PLUS_EXPR:
1685 if (TREE_CODE (TREE_TYPE (source_tree)) != POINTER_TYPE)
1686 return TRUE;
1687
1688 ffecom_tree_canonize_ptr_ (&source_decl, &source_offset,
1689 source_tree);
1690 source_size = TYPE_SIZE (TREE_TYPE (TREE_TYPE (source_tree)));
1691 break;
1692
1693 case COND_EXPR:
1694 return
1695 ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1696 TREE_OPERAND (source_tree, 1), NULL,
1697 scalar_arg)
1698 || ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1699 TREE_OPERAND (source_tree, 2), NULL,
1700 scalar_arg);
1701
1702
1703 case ADDR_EXPR:
1704 ffecom_tree_canonize_ref_ (&source_decl, &source_offset,
1705 &source_size,
1706 TREE_OPERAND (source_tree, 0));
1707 break;
1708
1709 case PARM_DECL:
1710 if (TREE_CODE (TREE_TYPE (source_tree)) != POINTER_TYPE)
1711 return TRUE;
1712
1713 source_decl = source_tree;
76fa6b3b 1714 source_offset = bitsize_zero_node;
5ff904cd
JL
1715 source_size = TYPE_SIZE (TREE_TYPE (TREE_TYPE (source_tree)));
1716 break;
1717
1718 case SAVE_EXPR:
1719 case REFERENCE_EXPR:
1720 case PREDECREMENT_EXPR:
1721 case PREINCREMENT_EXPR:
1722 case POSTDECREMENT_EXPR:
1723 case POSTINCREMENT_EXPR:
1724 case INDIRECT_REF:
1725 case ARRAY_REF:
1726 case CALL_EXPR:
1727 default:
1728 return TRUE;
1729 }
1730
1731 /* Come here when source_decl, source_offset, and source_size filled
1732 in appropriately. */
1733
1734 if (source_decl == NULL_TREE)
1735 return FALSE; /* No decl involved, so no overlap. */
1736
1737 if (source_decl != dest_decl)
1738 return FALSE; /* Different decl, no overlap. */
1739
1740 if (TREE_CODE (dest_size) == ERROR_MARK)
1741 return TRUE; /* Assignment into entire assumed-size
1742 array? Shouldn't happen.... */
1743
1744 t = ffecom_2 (LE_EXPR, integer_type_node,
1745 ffecom_2 (PLUS_EXPR, TREE_TYPE (dest_offset),
1746 dest_offset,
1747 convert (TREE_TYPE (dest_offset),
1748 dest_size)),
1749 convert (TREE_TYPE (dest_offset),
1750 source_offset));
1751
1752 if (integer_onep (t))
1753 return FALSE; /* Destination precedes source. */
1754
1755 if (!scalar_arg
1756 || (source_size == NULL_TREE)
1757 || (TREE_CODE (source_size) == ERROR_MARK)
1758 || integer_zerop (source_size))
1759 return TRUE; /* No way to tell if dest follows source. */
1760
1761 t = ffecom_2 (LE_EXPR, integer_type_node,
1762 ffecom_2 (PLUS_EXPR, TREE_TYPE (source_offset),
1763 source_offset,
1764 convert (TREE_TYPE (source_offset),
1765 source_size)),
1766 convert (TREE_TYPE (source_offset),
1767 dest_offset));
1768
1769 if (integer_onep (t))
1770 return FALSE; /* Destination follows source. */
1771
1772 return TRUE; /* Destination and source overlap. */
1773}
1774#endif
1775
1776/* Check whether dest might overlap any of a list of arguments or is
1777 in a COMMON area the callee might know about (and thus modify). */
1778
1779#if FFECOM_targetCURRENT == FFECOM_targetGCC
1780static bool
1781ffecom_args_overlapping_ (tree dest_tree, ffebld dest UNUSED,
1782 tree args, tree callee_commons,
1783 bool scalar_args)
1784{
1785 tree arg;
1786 tree dest_decl;
1787 tree dest_offset;
1788 tree dest_size;
1789
1790 ffecom_tree_canonize_ref_ (&dest_decl, &dest_offset, &dest_size,
1791 dest_tree);
1792
1793 if (dest_decl == NULL_TREE)
1794 return FALSE; /* Seems unlikely! */
1795
1796 /* If the decl cannot be determined reliably, or if its in COMMON
1797 and the callee isn't known to not futz with COMMON via other
1798 means, overlap might happen. */
1799
1800 if ((TREE_CODE (dest_decl) == ERROR_MARK)
1801 || ((callee_commons != NULL_TREE)
1802 && TREE_PUBLIC (dest_decl)))
1803 return TRUE;
1804
1805 for (; args != NULL_TREE; args = TREE_CHAIN (args))
1806 {
1807 if (((arg = TREE_VALUE (args)) != NULL_TREE)
1808 && ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1809 arg, NULL, scalar_args))
1810 return TRUE;
1811 }
1812
1813 return FALSE;
1814}
1815#endif
1816
1817/* Build a string for a variable name as used by NAMELIST. This means that
1818 if we're using the f2c library, we build an uppercase string, since
1819 f2c does this. */
1820
1821#if FFECOM_targetCURRENT == FFECOM_targetGCC
1822static tree
26f096f9 1823ffecom_build_f2c_string_ (int i, const char *s)
5ff904cd
JL
1824{
1825 if (!ffe_is_f2c_library ())
1826 return build_string (i, s);
1827
1828 {
1829 char *tmp;
26f096f9 1830 const char *p;
5ff904cd
JL
1831 char *q;
1832 char space[34];
1833 tree t;
1834
1835 if (((size_t) i) > ARRAY_SIZE (space))
1836 tmp = malloc_new_ks (malloc_pool_image (), "f2c_string", i);
1837 else
1838 tmp = &space[0];
1839
1840 for (p = s, q = tmp; *p != '\0'; ++p, ++q)
1841 *q = ffesrc_toupper (*p);
1842 *q = '\0';
1843
1844 t = build_string (i, tmp);
1845
1846 if (((size_t) i) > ARRAY_SIZE (space))
1847 malloc_kill_ks (malloc_pool_image (), tmp, i);
1848
1849 return t;
1850 }
1851}
1852
1853#endif
1854/* Returns CALL_EXPR or equivalent with given type (pass NULL_TREE for
1855 type to just get whatever the function returns), handling the
1856 f2c value-returning convention, if required, by prepending
1857 to the arglist a pointer to a temporary to receive the return value. */
1858
1859#if FFECOM_targetCURRENT == FFECOM_targetGCC
1860static tree
1861ffecom_call_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex,
1862 tree type, tree args, tree dest_tree,
1863 ffebld dest, bool *dest_used, tree callee_commons,
c7e4ee3a 1864 bool scalar_args, tree hook)
5ff904cd
JL
1865{
1866 tree item;
1867 tree tempvar;
1868
1869 if (dest_used != NULL)
1870 *dest_used = FALSE;
1871
1872 if (is_f2c_complex)
1873 {
1874 if ((dest_used == NULL)
1875 || (dest == NULL)
1876 || (ffeinfo_basictype (ffebld_info (dest))
1877 != FFEINFO_basictypeCOMPLEX)
1878 || (ffeinfo_kindtype (ffebld_info (dest)) != kt)
1879 || ((type != NULL_TREE) && (TREE_TYPE (dest_tree) != type))
1880 || ffecom_args_overlapping_ (dest_tree, dest, args,
1881 callee_commons,
1882 scalar_args))
1883 {
c7e4ee3a
CB
1884#ifdef HOHO
1885 tempvar = ffecom_make_tempvar (ffecom_tree_type
5ff904cd
JL
1886 [FFEINFO_basictypeCOMPLEX][kt],
1887 FFETARGET_charactersizeNONE,
c7e4ee3a
CB
1888 -1);
1889#else
1890 tempvar = hook;
1891 assert (tempvar);
1892#endif
5ff904cd
JL
1893 }
1894 else
1895 {
1896 *dest_used = TRUE;
1897 tempvar = dest_tree;
1898 type = NULL_TREE;
1899 }
1900
1901 item
1902 = build_tree_list (NULL_TREE,
1903 ffecom_1 (ADDR_EXPR,
c7e4ee3a 1904 build_pointer_type (TREE_TYPE (tempvar)),
5ff904cd
JL
1905 tempvar));
1906 TREE_CHAIN (item) = args;
1907
1908 item = ffecom_3s (CALL_EXPR, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), fn,
1909 item, NULL_TREE);
1910
1911 if (tempvar != dest_tree)
1912 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), item, tempvar);
1913 }
1914 else
1915 item = ffecom_3s (CALL_EXPR, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), fn,
1916 args, NULL_TREE);
1917
1918 if ((type != NULL_TREE) && (TREE_TYPE (item) != type))
1919 item = ffecom_convert_narrow_ (type, item);
1920
1921 return item;
1922}
1923#endif
1924
1925/* Given two arguments, transform them and make a call to the given
1926 function via ffecom_call_. */
1927
1928#if FFECOM_targetCURRENT == FFECOM_targetGCC
1929static tree
1930ffecom_call_binop_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex,
1931 tree type, ffebld left, ffebld right,
1932 tree dest_tree, ffebld dest, bool *dest_used,
c7e4ee3a 1933 tree callee_commons, bool scalar_args, tree hook)
5ff904cd
JL
1934{
1935 tree left_tree;
1936 tree right_tree;
1937 tree left_length;
1938 tree right_length;
1939
5ff904cd
JL
1940 left_tree = ffecom_arg_ptr_to_expr (left, &left_length);
1941 right_tree = ffecom_arg_ptr_to_expr (right, &right_length);
5ff904cd
JL
1942
1943 left_tree = build_tree_list (NULL_TREE, left_tree);
1944 right_tree = build_tree_list (NULL_TREE, right_tree);
1945 TREE_CHAIN (left_tree) = right_tree;
1946
1947 if (left_length != NULL_TREE)
1948 {
1949 left_length = build_tree_list (NULL_TREE, left_length);
1950 TREE_CHAIN (right_tree) = left_length;
1951 }
1952
1953 if (right_length != NULL_TREE)
1954 {
1955 right_length = build_tree_list (NULL_TREE, right_length);
1956 if (left_length != NULL_TREE)
1957 TREE_CHAIN (left_length) = right_length;
1958 else
1959 TREE_CHAIN (right_tree) = right_length;
1960 }
1961
1962 return ffecom_call_ (fn, kt, is_f2c_complex, type, left_tree,
1963 dest_tree, dest, dest_used, callee_commons,
c7e4ee3a 1964 scalar_args, hook);
5ff904cd
JL
1965}
1966#endif
1967
c7e4ee3a 1968/* Return ptr/length args for char subexpression
5ff904cd
JL
1969
1970 Handles CHARACTER-type CONTER, SYMTER, SUBSTR, ARRAYREF, and FUNCREF
1971 subexpressions by constructing the appropriate trees for the ptr-to-
1972 character-text and length-of-character-text arguments in a calling
86fc7a6c
CB
1973 sequence.
1974
1975 Note that if with_null is TRUE, and the expression is an opCONTER,
1976 a null byte is appended to the string. */
5ff904cd
JL
1977
1978#if FFECOM_targetCURRENT == FFECOM_targetGCC
1979static void
86fc7a6c 1980ffecom_char_args_x_ (tree *xitem, tree *length, ffebld expr, bool with_null)
5ff904cd
JL
1981{
1982 tree item;
1983 tree high;
1984 ffetargetCharacter1 val;
86fc7a6c 1985 ffetargetCharacterSize newlen;
5ff904cd
JL
1986
1987 switch (ffebld_op (expr))
1988 {
1989 case FFEBLD_opCONTER:
1990 val = ffebld_constant_character1 (ffebld_conter (expr));
86fc7a6c
CB
1991 newlen = ffetarget_length_character1 (val);
1992 if (with_null)
1993 {
c7e4ee3a 1994 /* Begin FFETARGET-NULL-KLUDGE. */
86fc7a6c 1995 if (newlen != 0)
c7e4ee3a 1996 ++newlen;
86fc7a6c
CB
1997 }
1998 *length = build_int_2 (newlen, 0);
5ff904cd 1999 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
86fc7a6c 2000 high = build_int_2 (newlen, 0);
5ff904cd 2001 TREE_TYPE (high) = ffecom_f2c_ftnlen_type_node;
c7e4ee3a 2002 item = build_string (newlen,
5ff904cd 2003 ffetarget_text_character1 (val));
c7e4ee3a 2004 /* End FFETARGET-NULL-KLUDGE. */
5ff904cd
JL
2005 TREE_TYPE (item)
2006 = build_type_variant
2007 (build_array_type
2008 (char_type_node,
2009 build_range_type
2010 (ffecom_f2c_ftnlen_type_node,
2011 ffecom_f2c_ftnlen_one_node,
2012 high)),
2013 1, 0);
2014 TREE_CONSTANT (item) = 1;
2015 TREE_STATIC (item) = 1;
2016 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
2017 item);
2018 break;
2019
2020 case FFEBLD_opSYMTER:
2021 {
2022 ffesymbol s = ffebld_symter (expr);
2023
2024 item = ffesymbol_hook (s).decl_tree;
2025 if (item == NULL_TREE)
2026 {
2027 s = ffecom_sym_transform_ (s);
2028 item = ffesymbol_hook (s).decl_tree;
2029 }
2030 if (ffesymbol_kind (s) == FFEINFO_kindENTITY)
2031 {
2032 if (ffesymbol_size (s) == FFETARGET_charactersizeNONE)
2033 *length = ffesymbol_hook (s).length_tree;
2034 else
2035 {
2036 *length = build_int_2 (ffesymbol_size (s), 0);
2037 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
2038 }
2039 }
2040 else if (item == error_mark_node)
2041 *length = error_mark_node;
c7e4ee3a
CB
2042 else
2043 /* FFEINFO_kindFUNCTION. */
5ff904cd
JL
2044 *length = NULL_TREE;
2045 if (!ffesymbol_hook (s).addr
2046 && (item != error_mark_node))
2047 item = ffecom_1 (ADDR_EXPR,
2048 build_pointer_type (TREE_TYPE (item)),
2049 item);
2050 }
2051 break;
2052
2053 case FFEBLD_opARRAYREF:
2054 {
5ff904cd 2055 ffecom_char_args_ (&item, length, ffebld_left (expr));
5ff904cd
JL
2056
2057 if (item == error_mark_node || *length == error_mark_node)
2058 {
2059 item = *length = error_mark_node;
2060 break;
2061 }
2062
6b55276e 2063 item = ffecom_arrayref_ (item, expr, 1);
5ff904cd
JL
2064 }
2065 break;
2066
2067 case FFEBLD_opSUBSTR:
2068 {
2069 ffebld start;
2070 ffebld end;
2071 ffebld thing = ffebld_right (expr);
2072 tree start_tree;
2073 tree end_tree;
3b304f5b 2074 const char *char_name;
6b55276e
CB
2075 ffebld left_symter;
2076 tree array;
5ff904cd
JL
2077
2078 assert (ffebld_op (thing) == FFEBLD_opITEM);
2079 start = ffebld_head (thing);
2080 thing = ffebld_trail (thing);
2081 assert (ffebld_trail (thing) == NULL);
2082 end = ffebld_head (thing);
2083
6b55276e
CB
2084 /* Determine name for pretty-printing range-check errors. */
2085 for (left_symter = ffebld_left (expr);
2086 left_symter && ffebld_op (left_symter) == FFEBLD_opARRAYREF;
2087 left_symter = ffebld_left (left_symter))
2088 ;
2089 if (ffebld_op (left_symter) == FFEBLD_opSYMTER)
2090 char_name = ffesymbol_text (ffebld_symter (left_symter));
2091 else
2092 char_name = "[expr?]";
2093
5ff904cd 2094 ffecom_char_args_ (&item, length, ffebld_left (expr));
5ff904cd
JL
2095
2096 if (item == error_mark_node || *length == error_mark_node)
2097 {
2098 item = *length = error_mark_node;
2099 break;
2100 }
2101
6b55276e
CB
2102 array = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item)));
2103
ff852b44
CB
2104 /* ~~~~Handle INTEGER*8 start/end, a la FFEBLD_opARRAYREF. */
2105
5ff904cd
JL
2106 if (start == NULL)
2107 {
2108 if (end == NULL)
2109 ;
2110 else
2111 {
6b55276e 2112 end_tree = ffecom_expr (end);
02f06e64 2113 if (flag_bounds_check)
6b55276e
CB
2114 end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0,
2115 char_name);
5ff904cd 2116 end_tree = convert (ffecom_f2c_ftnlen_type_node,
6b55276e 2117 end_tree);
5ff904cd
JL
2118
2119 if (end_tree == error_mark_node)
2120 {
2121 item = *length = error_mark_node;
2122 break;
2123 }
2124
2125 *length = end_tree;
2126 }
2127 }
2128 else
2129 {
6b55276e 2130 start_tree = ffecom_expr (start);
02f06e64 2131 if (flag_bounds_check)
6b55276e
CB
2132 start_tree = ffecom_subscript_check_ (array, start_tree, 0, 0,
2133 char_name);
5ff904cd 2134 start_tree = convert (ffecom_f2c_ftnlen_type_node,
6b55276e 2135 start_tree);
5ff904cd
JL
2136
2137 if (start_tree == error_mark_node)
2138 {
2139 item = *length = error_mark_node;
2140 break;
2141 }
2142
2143 start_tree = ffecom_save_tree (start_tree);
2144
2145 item = ffecom_2 (PLUS_EXPR, TREE_TYPE (item),
2146 item,
2147 ffecom_2 (MINUS_EXPR,
2148 TREE_TYPE (start_tree),
2149 start_tree,
2150 ffecom_f2c_ftnlen_one_node));
2151
2152 if (end == NULL)
2153 {
2154 *length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
2155 ffecom_f2c_ftnlen_one_node,
2156 ffecom_2 (MINUS_EXPR,
2157 ffecom_f2c_ftnlen_type_node,
2158 *length,
2159 start_tree));
2160 }
2161 else
2162 {
6b55276e 2163 end_tree = ffecom_expr (end);
02f06e64 2164 if (flag_bounds_check)
6b55276e
CB
2165 end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0,
2166 char_name);
5ff904cd 2167 end_tree = convert (ffecom_f2c_ftnlen_type_node,
6b55276e 2168 end_tree);
5ff904cd
JL
2169
2170 if (end_tree == error_mark_node)
2171 {
2172 item = *length = error_mark_node;
2173 break;
2174 }
2175
2176 *length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
2177 ffecom_f2c_ftnlen_one_node,
2178 ffecom_2 (MINUS_EXPR,
2179 ffecom_f2c_ftnlen_type_node,
2180 end_tree, start_tree));
2181 }
2182 }
2183 }
2184 break;
2185
2186 case FFEBLD_opFUNCREF:
2187 {
2188 ffesymbol s = ffebld_symter (ffebld_left (expr));
2189 tree tempvar;
2190 tree args;
2191 ffetargetCharacterSize size = ffeinfo_size (ffebld_info (expr));
2192 ffecomGfrt ix;
2193
2194 if (size == FFETARGET_charactersizeNONE)
c7e4ee3a
CB
2195 /* ~~Kludge alert! This should someday be fixed. */
2196 size = 24;
5ff904cd
JL
2197
2198 *length = build_int_2 (size, 0);
2199 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
2200
2201 if (ffeinfo_where (ffebld_info (ffebld_left (expr)))
2202 == FFEINFO_whereINTRINSIC)
2203 {
2204 if (size == 1)
c7e4ee3a
CB
2205 {
2206 /* Invocation of an intrinsic returning CHARACTER*1. */
5ff904cd
JL
2207 item = ffecom_expr_intrinsic_ (expr, NULL_TREE,
2208 NULL, NULL);
2209 break;
2210 }
2211 ix = ffeintrin_gfrt_direct (ffebld_symter_implementation (ffebld_left (expr)));
2212 assert (ix != FFECOM_gfrt);
2213 item = ffecom_gfrt_tree_ (ix);
2214 }
2215 else
2216 {
2217 ix = FFECOM_gfrt;
2218 item = ffesymbol_hook (s).decl_tree;
2219 if (item == NULL_TREE)
2220 {
2221 s = ffecom_sym_transform_ (s);
2222 item = ffesymbol_hook (s).decl_tree;
2223 }
2224 if (item == error_mark_node)
2225 {
2226 item = *length = error_mark_node;
2227 break;
2228 }
2229
2230 if (!ffesymbol_hook (s).addr)
2231 item = ffecom_1_fn (item);
2232 }
2233
c7e4ee3a 2234#ifdef HOHO
5ff904cd 2235 tempvar = ffecom_push_tempvar (char_type_node, size, -1, TRUE);
c7e4ee3a
CB
2236#else
2237 tempvar = ffebld_nonter_hook (expr);
2238 assert (tempvar);
2239#endif
5ff904cd
JL
2240 tempvar = ffecom_1 (ADDR_EXPR,
2241 build_pointer_type (TREE_TYPE (tempvar)),
2242 tempvar);
2243
5ff904cd
JL
2244 args = build_tree_list (NULL_TREE, tempvar);
2245
2246 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT) /* Sfunc args by value. */
2247 TREE_CHAIN (args) = ffecom_list_expr (ffebld_right (expr));
2248 else
2249 {
2250 TREE_CHAIN (args) = build_tree_list (NULL_TREE, *length);
2251 if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC)
2252 {
2253 TREE_CHAIN (TREE_CHAIN (args))
2254 = ffecom_arglist_expr_ (ffecom_gfrt_args_ (ix),
2255 ffebld_right (expr));
2256 }
2257 else
2258 {
2259 TREE_CHAIN (TREE_CHAIN (args))
2260 = ffecom_list_ptr_to_expr (ffebld_right (expr));
2261 }
2262 }
2263
2264 item = ffecom_3s (CALL_EXPR,
2265 TREE_TYPE (TREE_TYPE (TREE_TYPE (item))),
2266 item, args, NULL_TREE);
2267 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), item,
2268 tempvar);
5ff904cd
JL
2269 }
2270 break;
2271
2272 case FFEBLD_opCONVERT:
2273
5ff904cd 2274 ffecom_char_args_ (&item, length, ffebld_left (expr));
5ff904cd
JL
2275
2276 if (item == error_mark_node || *length == error_mark_node)
2277 {
2278 item = *length = error_mark_node;
2279 break;
2280 }
2281
2282 if ((ffebld_size_known (ffebld_left (expr))
2283 == FFETARGET_charactersizeNONE)
2284 || (ffebld_size_known (ffebld_left (expr)) < (ffebld_size (expr))))
2285 { /* Possible blank-padding needed, copy into
2286 temporary. */
2287 tree tempvar;
2288 tree args;
2289 tree newlen;
2290
c7e4ee3a
CB
2291#ifdef HOHO
2292 tempvar = ffecom_make_tempvar (char_type_node,
2293 ffebld_size (expr), -1);
2294#else
2295 tempvar = ffebld_nonter_hook (expr);
2296 assert (tempvar);
2297#endif
5ff904cd
JL
2298 tempvar = ffecom_1 (ADDR_EXPR,
2299 build_pointer_type (TREE_TYPE (tempvar)),
2300 tempvar);
2301
2302 newlen = build_int_2 (ffebld_size (expr), 0);
2303 TREE_TYPE (newlen) = ffecom_f2c_ftnlen_type_node;
2304
2305 args = build_tree_list (NULL_TREE, tempvar);
2306 TREE_CHAIN (args) = build_tree_list (NULL_TREE, item);
2307 TREE_CHAIN (TREE_CHAIN (args)) = build_tree_list (NULL_TREE, newlen);
2308 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (args)))
2309 = build_tree_list (NULL_TREE, *length);
2310
c7e4ee3a 2311 item = ffecom_call_gfrt (FFECOM_gfrtCOPY, args, NULL_TREE);
5ff904cd
JL
2312 TREE_SIDE_EFFECTS (item) = 1;
2313 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), fold (item),
2314 tempvar);
2315 *length = newlen;
2316 }
2317 else
2318 { /* Just truncate the length. */
2319 *length = build_int_2 (ffebld_size (expr), 0);
2320 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
2321 }
2322 break;
2323
2324 default:
2325 assert ("bad op for single char arg expr" == NULL);
2326 item = NULL_TREE;
2327 break;
2328 }
2329
2330 *xitem = item;
2331}
2332#endif
2333
2334/* Check the size of the type to be sure it doesn't overflow the
2335 "portable" capacities of the compiler back end. `dummy' types
2336 can generally overflow the normal sizes as long as the computations
2337 themselves don't overflow. A particular target of the back end
2338 must still enforce its size requirements, though, and the back
2339 end takes care of this in stor-layout.c. */
2340
2341#if FFECOM_targetCURRENT == FFECOM_targetGCC
2342static tree
2343ffecom_check_size_overflow_ (ffesymbol s, tree type, bool dummy)
2344{
2345 if (TREE_CODE (type) == ERROR_MARK)
2346 return type;
2347
2348 if (TYPE_SIZE (type) == NULL_TREE)
2349 return type;
2350
2351 if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
2352 return type;
2353
2354 if ((tree_int_cst_sgn (TYPE_SIZE (type)) < 0)
2b0c2df0
CB
2355 || (!dummy && (((TREE_INT_CST_HIGH (TYPE_SIZE (type)) != 0))
2356 || TREE_OVERFLOW (TYPE_SIZE (type)))))
5ff904cd
JL
2357 {
2358 ffebad_start (FFEBAD_ARRAY_LARGE);
2359 ffebad_string (ffesymbol_text (s));
2360 ffebad_here (0, ffesymbol_where_line (s), ffesymbol_where_column (s));
2361 ffebad_finish ();
2362
2363 return error_mark_node;
2364 }
2365
2366 return type;
2367}
2368#endif
2369
2370/* Builds a length argument (PARM_DECL). Also wraps type in an array type
2371 where the dimension info is (1:size) where <size> is ffesymbol_size(s) if
2372 known, length_arg if not known (FFETARGET_charactersizeNONE). */
2373
2374#if FFECOM_targetCURRENT == FFECOM_targetGCC
2375static tree
2376ffecom_char_enhance_arg_ (tree *xtype, ffesymbol s)
2377{
2378 ffetargetCharacterSize sz = ffesymbol_size (s);
2379 tree highval;
2380 tree tlen;
2381 tree type = *xtype;
2382
2383 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT)
2384 tlen = NULL_TREE; /* A statement function, no length passed. */
2385 else
2386 {
2387 if (ffesymbol_where (s) == FFEINFO_whereDUMMY)
2388 tlen = ffecom_get_invented_identifier ("__g77_length_%s",
14657de8 2389 ffesymbol_text (s));
5ff904cd 2390 else
14657de8 2391 tlen = ffecom_get_invented_identifier ("__g77_%s", "length");
5ff904cd
JL
2392 tlen = build_decl (PARM_DECL, tlen, ffecom_f2c_ftnlen_type_node);
2393#if BUILT_FOR_270
2394 DECL_ARTIFICIAL (tlen) = 1;
2395#endif
2396 }
2397
2398 if (sz == FFETARGET_charactersizeNONE)
2399 {
2400 assert (tlen != NULL_TREE);
2b0c2df0 2401 highval = variable_size (tlen);
5ff904cd
JL
2402 }
2403 else
2404 {
2405 highval = build_int_2 (sz, 0);
2406 TREE_TYPE (highval) = ffecom_f2c_ftnlen_type_node;
2407 }
2408
2409 type = build_array_type (type,
2410 build_range_type (ffecom_f2c_ftnlen_type_node,
2411 ffecom_f2c_ftnlen_one_node,
2412 highval));
2413
2414 *xtype = type;
2415 return tlen;
2416}
2417
2418#endif
2419/* ffecom_concat_list_gather_ -- Gather list of concatenated string exprs
2420
2421 ffecomConcatList_ catlist;
2422 ffebld expr; // expr of CHARACTER basictype.
2423 ffetargetCharacterSize max; // max chars to gather or _...NONE if no max
2424 catlist = ffecom_concat_list_gather_(catlist,expr,max);
2425
2426 Scans expr for character subexpressions, updates and returns catlist
2427 accordingly. */
2428
2429#if FFECOM_targetCURRENT == FFECOM_targetGCC
2430static ffecomConcatList_
2431ffecom_concat_list_gather_ (ffecomConcatList_ catlist, ffebld expr,
2432 ffetargetCharacterSize max)
2433{
2434 ffetargetCharacterSize sz;
2435
2436recurse: /* :::::::::::::::::::: */
2437
2438 if (expr == NULL)
2439 return catlist;
2440
2441 if ((max != FFETARGET_charactersizeNONE) && (catlist.minlen >= max))
2442 return catlist; /* Don't append any more items. */
2443
2444 switch (ffebld_op (expr))
2445 {
2446 case FFEBLD_opCONTER:
2447 case FFEBLD_opSYMTER:
2448 case FFEBLD_opARRAYREF:
2449 case FFEBLD_opFUNCREF:
2450 case FFEBLD_opSUBSTR:
2451 case FFEBLD_opCONVERT: /* Callers should strip this off beforehand
2452 if they don't need to preserve it. */
2453 if (catlist.count == catlist.max)
2454 { /* Make a (larger) list. */
2455 ffebld *newx;
2456 int newmax;
2457
2458 newmax = (catlist.max == 0) ? 8 : catlist.max * 2;
2459 newx = malloc_new_ks (malloc_pool_image (), "catlist",
2460 newmax * sizeof (newx[0]));
2461 if (catlist.max != 0)
2462 {
2463 memcpy (newx, catlist.exprs, catlist.max * sizeof (newx[0]));
2464 malloc_kill_ks (malloc_pool_image (), catlist.exprs,
2465 catlist.max * sizeof (newx[0]));
2466 }
2467 catlist.max = newmax;
2468 catlist.exprs = newx;
2469 }
2470 if ((sz = ffebld_size_known (expr)) != FFETARGET_charactersizeNONE)
2471 catlist.minlen += sz;
2472 else
2473 ++catlist.minlen; /* Not true for F90; can be 0 length. */
2474 if ((sz = ffebld_size_max (expr)) == FFETARGET_charactersizeNONE)
2475 catlist.maxlen = sz;
2476 else
2477 catlist.maxlen += sz;
2478 if ((max != FFETARGET_charactersizeNONE) && (catlist.minlen > max))
2479 { /* This item overlaps (or is beyond) the end
2480 of the destination. */
2481 switch (ffebld_op (expr))
2482 {
2483 case FFEBLD_opCONTER:
2484 case FFEBLD_opSYMTER:
2485 case FFEBLD_opARRAYREF:
2486 case FFEBLD_opFUNCREF:
2487 case FFEBLD_opSUBSTR:
c7e4ee3a
CB
2488 /* ~~Do useful truncations here. */
2489 break;
5ff904cd
JL
2490
2491 default:
2492 assert ("op changed or inconsistent switches!" == NULL);
2493 break;
2494 }
2495 }
2496 catlist.exprs[catlist.count++] = expr;
2497 return catlist;
2498
2499 case FFEBLD_opPAREN:
2500 expr = ffebld_left (expr);
2501 goto recurse; /* :::::::::::::::::::: */
2502
2503 case FFEBLD_opCONCATENATE:
2504 catlist = ffecom_concat_list_gather_ (catlist, ffebld_left (expr), max);
2505 expr = ffebld_right (expr);
2506 goto recurse; /* :::::::::::::::::::: */
2507
2508#if 0 /* Breaks passing small actual arg to larger
2509 dummy arg of sfunc */
2510 case FFEBLD_opCONVERT:
2511 expr = ffebld_left (expr);
2512 {
2513 ffetargetCharacterSize cmax;
2514
2515 cmax = catlist.len + ffebld_size_known (expr);
2516
2517 if ((max == FFETARGET_charactersizeNONE) || (max > cmax))
2518 max = cmax;
2519 }
2520 goto recurse; /* :::::::::::::::::::: */
2521#endif
2522
2523 case FFEBLD_opANY:
2524 return catlist;
2525
2526 default:
2527 assert ("bad op in _gather_" == NULL);
2528 return catlist;
2529 }
2530}
2531
2532#endif
2533/* ffecom_concat_list_kill_ -- Kill list of concatenated string exprs
2534
2535 ffecomConcatList_ catlist;
2536 ffecom_concat_list_kill_(catlist);
2537
2538 Anything allocated within the list info is deallocated. */
2539
2540#if FFECOM_targetCURRENT == FFECOM_targetGCC
2541static void
2542ffecom_concat_list_kill_ (ffecomConcatList_ catlist)
2543{
2544 if (catlist.max != 0)
2545 malloc_kill_ks (malloc_pool_image (), catlist.exprs,
2546 catlist.max * sizeof (catlist.exprs[0]));
2547}
2548
2549#endif
c7e4ee3a 2550/* Make list of concatenated string exprs.
5ff904cd
JL
2551
2552 Returns a flattened list of concatenated subexpressions given a
2553 tree of such expressions. */
2554
2555#if FFECOM_targetCURRENT == FFECOM_targetGCC
2556static ffecomConcatList_
2557ffecom_concat_list_new_ (ffebld expr, ffetargetCharacterSize max)
2558{
2559 ffecomConcatList_ catlist;
2560
2561 catlist.maxlen = catlist.minlen = catlist.max = catlist.count = 0;
2562 return ffecom_concat_list_gather_ (catlist, expr, max);
2563}
2564
2565#endif
2566
2567/* Provide some kind of useful info on member of aggregate area,
2568 since current g77/gcc technology does not provide debug info
2569 on these members. */
2570
2571#if FFECOM_targetCURRENT == FFECOM_targetGCC
2572static void
26f096f9 2573ffecom_debug_kludge_ (tree aggr, const char *aggr_type, ffesymbol member,
5ff904cd
JL
2574 tree member_type UNUSED, ffetargetOffset offset)
2575{
2576 tree value;
2577 tree decl;
2578 int len;
2579 char *buff;
2580 char space[120];
2581#if 0
2582 tree type_id;
2583
2584 for (type_id = member_type;
2585 TREE_CODE (type_id) != IDENTIFIER_NODE;
2586 )
2587 {
2588 switch (TREE_CODE (type_id))
2589 {
2590 case INTEGER_TYPE:
2591 case REAL_TYPE:
2592 type_id = TYPE_NAME (type_id);
2593 break;
2594
2595 case ARRAY_TYPE:
2596 case COMPLEX_TYPE:
2597 type_id = TREE_TYPE (type_id);
2598 break;
2599
2600 default:
2601 assert ("no IDENTIFIER_NODE for type!" == NULL);
2602 type_id = error_mark_node;
2603 break;
2604 }
2605 }
2606#endif
2607
2608 if (ffecom_transform_only_dummies_
2609 || !ffe_is_debug_kludge ())
2610 return; /* Can't do this yet, maybe later. */
2611
2612 len = 60
2613 + strlen (aggr_type)
2614 + IDENTIFIER_LENGTH (DECL_NAME (aggr));
2615#if 0
2616 + IDENTIFIER_LENGTH (type_id);
2617#endif
2618
2619 if (((size_t) len) >= ARRAY_SIZE (space))
2620 buff = malloc_new_ks (malloc_pool_image (), "debug_kludge", len + 1);
2621 else
2622 buff = &space[0];
2623
2624 sprintf (&buff[0], "At (%s) `%s' plus %ld bytes",
2625 aggr_type,
2626 IDENTIFIER_POINTER (DECL_NAME (aggr)),
2627 (long int) offset);
2628
2629 value = build_string (len, buff);
2630 TREE_TYPE (value)
2631 = build_type_variant (build_array_type (char_type_node,
2632 build_range_type
2633 (integer_type_node,
2634 integer_one_node,
2635 build_int_2 (strlen (buff), 0))),
2636 1, 0);
2637 decl = build_decl (VAR_DECL,
2638 ffecom_get_identifier_ (ffesymbol_text (member)),
2639 TREE_TYPE (value));
2640 TREE_CONSTANT (decl) = 1;
2641 TREE_STATIC (decl) = 1;
2642 DECL_INITIAL (decl) = error_mark_node;
2643 DECL_IN_SYSTEM_HEADER (decl) = 1; /* Don't let -Wunused complain. */
2644 decl = start_decl (decl, FALSE);
2645 finish_decl (decl, value, FALSE);
2646
2647 if (buff != &space[0])
2648 malloc_kill_ks (malloc_pool_image (), buff, len + 1);
2649}
2650#endif
2651
2652/* ffecom_do_entry_ -- Do compilation of a particular entrypoint
2653
2654 ffesymbol fn; // the SUBROUTINE, FUNCTION, or ENTRY symbol itself
2655 int i; // entry# for this entrypoint (used by master fn)
2656 ffecom_do_entrypoint_(s,i);
2657
2658 Makes a public entry point that calls our private master fn (already
2659 compiled). */
2660
2661#if FFECOM_targetCURRENT == FFECOM_targetGCC
2662static void
2663ffecom_do_entry_ (ffesymbol fn, int entrynum)
2664{
2665 ffebld item;
2666 tree type; /* Type of function. */
2667 tree multi_retval; /* Var holding return value (union). */
2668 tree result; /* Var holding result. */
2669 ffeinfoBasictype bt;
2670 ffeinfoKindtype kt;
2671 ffeglobal g;
2672 ffeglobalType gt;
2673 bool charfunc; /* All entry points return same type
2674 CHARACTER. */
2675 bool cmplxfunc; /* Use f2c way of returning COMPLEX. */
2676 bool multi; /* Master fn has multiple return types. */
2677 bool altreturning = FALSE; /* This entry point has alternate returns. */
2678 int yes;
44d2eabc 2679 int old_lineno = lineno;
3b304f5b 2680 const char *old_input_filename = input_filename;
44d2eabc
JL
2681
2682 input_filename = ffesymbol_where_filename (fn);
2683 lineno = ffesymbol_where_filelinenum (fn);
5ff904cd
JL
2684
2685 /* c-parse.y indeed does call suspend_momentary and not only ignores the
2686 return value, but also never calls resume_momentary, when starting an
2687 outer function (see "fndef:", "setspecs:", and so on). So g77 does the
2688 same thing. It shouldn't be a problem since start_function calls
2689 temporary_allocation, but it might be necessary. If it causes a problem
2690 here, then maybe there's a bug lurking in gcc. NOTE: This identical
2691 comment appears twice in thist file. */
2692
2693 suspend_momentary ();
2694
2695 ffecom_doing_entry_ = TRUE; /* Don't bother with array dimensions. */
2696
2697 switch (ffecom_primary_entry_kind_)
2698 {
2699 case FFEINFO_kindFUNCTION:
2700
2701 /* Determine actual return type for function. */
2702
2703 gt = FFEGLOBAL_typeFUNC;
2704 bt = ffesymbol_basictype (fn);
2705 kt = ffesymbol_kindtype (fn);
2706 if (bt == FFEINFO_basictypeNONE)
2707 {
2708 ffeimplic_establish_symbol (fn);
2709 if (ffesymbol_funcresult (fn) != NULL)
2710 ffeimplic_establish_symbol (ffesymbol_funcresult (fn));
2711 bt = ffesymbol_basictype (fn);
2712 kt = ffesymbol_kindtype (fn);
2713 }
2714
2715 if (bt == FFEINFO_basictypeCHARACTER)
2716 charfunc = TRUE, cmplxfunc = FALSE;
2717 else if ((bt == FFEINFO_basictypeCOMPLEX)
2718 && ffesymbol_is_f2c (fn))
2719 charfunc = FALSE, cmplxfunc = TRUE;
2720 else
2721 charfunc = cmplxfunc = FALSE;
2722
2723 if (charfunc)
2724 type = ffecom_tree_fun_type_void;
2725 else if (ffesymbol_is_f2c (fn))
2726 type = ffecom_tree_fun_type[bt][kt];
2727 else
2728 type = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
2729
2730 if ((type == NULL_TREE)
2731 || (TREE_TYPE (type) == NULL_TREE))
2732 type = ffecom_tree_fun_type_void; /* _sym_exec_transition. */
2733
2734 multi = (ffecom_master_bt_ == FFEINFO_basictypeNONE);
2735 break;
2736
2737 case FFEINFO_kindSUBROUTINE:
2738 gt = FFEGLOBAL_typeSUBR;
2739 bt = FFEINFO_basictypeNONE;
2740 kt = FFEINFO_kindtypeNONE;
2741 if (ffecom_is_altreturning_)
2742 { /* Am _I_ altreturning? */
2743 for (item = ffesymbol_dummyargs (fn);
2744 item != NULL;
2745 item = ffebld_trail (item))
2746 {
2747 if (ffebld_op (ffebld_head (item)) == FFEBLD_opSTAR)
2748 {
2749 altreturning = TRUE;
2750 break;
2751 }
2752 }
2753 if (altreturning)
2754 type = ffecom_tree_subr_type;
2755 else
2756 type = ffecom_tree_fun_type_void;
2757 }
2758 else
2759 type = ffecom_tree_fun_type_void;
2760 charfunc = FALSE;
2761 cmplxfunc = FALSE;
2762 multi = FALSE;
2763 break;
2764
2765 default:
2766 assert ("say what??" == NULL);
2767 /* Fall through. */
2768 case FFEINFO_kindANY:
2769 gt = FFEGLOBAL_typeANY;
2770 bt = FFEINFO_basictypeNONE;
2771 kt = FFEINFO_kindtypeNONE;
2772 type = error_mark_node;
2773 charfunc = FALSE;
2774 cmplxfunc = FALSE;
2775 multi = FALSE;
2776 break;
2777 }
2778
2779 /* build_decl uses the current lineno and input_filename to set the decl
2780 source info. So, I've putzed with ffestd and ffeste code to update that
2781 source info to point to the appropriate statement just before calling
2782 ffecom_do_entrypoint (which calls this fn). */
2783
2784 start_function (ffecom_get_external_identifier_ (fn),
2785 type,
2786 0, /* nested/inline */
2787 1); /* TREE_PUBLIC */
2788
2789 if (((g = ffesymbol_global (fn)) != NULL)
2790 && ((ffeglobal_type (g) == gt)
2791 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
2792 {
2793 ffeglobal_set_hook (g, current_function_decl);
2794 }
2795
2796 /* Reset args in master arg list so they get retransitioned. */
2797
2798 for (item = ffecom_master_arglist_;
2799 item != NULL;
2800 item = ffebld_trail (item))
2801 {
2802 ffebld arg;
2803 ffesymbol s;
2804
2805 arg = ffebld_head (item);
2806 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2807 continue; /* Alternate return or some such thing. */
2808 s = ffebld_symter (arg);
2809 ffesymbol_hook (s).decl_tree = NULL_TREE;
2810 ffesymbol_hook (s).length_tree = NULL_TREE;
2811 }
2812
2813 /* Build dummy arg list for this entry point. */
2814
2815 yes = suspend_momentary ();
2816
2817 if (charfunc || cmplxfunc)
2818 { /* Prepend arg for where result goes. */
2819 tree type;
2820 tree length;
2821
2822 if (charfunc)
2823 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
2824 else
2825 type = ffecom_tree_type[FFEINFO_basictypeCOMPLEX][kt];
2826
14657de8 2827 result = ffecom_get_invented_identifier ("__g77_%s", "result");
5ff904cd
JL
2828
2829 /* Make length arg _and_ enhance type info for CHAR arg itself. */
2830
2831 if (charfunc)
2832 length = ffecom_char_enhance_arg_ (&type, fn);
2833 else
2834 length = NULL_TREE; /* Not ref'd if !charfunc. */
2835
2836 type = build_pointer_type (type);
2837 result = build_decl (PARM_DECL, result, type);
2838
2839 push_parm_decl (result);
2840 ffecom_func_result_ = result;
2841
2842 if (charfunc)
2843 {
2844 push_parm_decl (length);
2845 ffecom_func_length_ = length;
2846 }
2847 }
2848 else
2849 result = DECL_RESULT (current_function_decl);
2850
2851 ffecom_push_dummy_decls_ (ffesymbol_dummyargs (fn), FALSE);
2852
2853 resume_momentary (yes);
2854
2855 store_parm_decls (0);
2856
c7e4ee3a
CB
2857 ffecom_start_compstmt ();
2858 /* Disallow temp vars at this level. */
2859 current_binding_level->prep_state = 2;
5ff904cd
JL
2860
2861 /* Make local var to hold return type for multi-type master fn. */
2862
2863 if (multi)
2864 {
2865 yes = suspend_momentary ();
2866
2867 multi_retval = ffecom_get_invented_identifier ("__g77_%s",
14657de8 2868 "multi_retval");
5ff904cd
JL
2869 multi_retval = build_decl (VAR_DECL, multi_retval,
2870 ffecom_multi_type_node_);
2871 multi_retval = start_decl (multi_retval, FALSE);
2872 finish_decl (multi_retval, NULL_TREE, FALSE);
2873
2874 resume_momentary (yes);
2875 }
2876 else
2877 multi_retval = NULL_TREE; /* Not actually ref'd if !multi. */
2878
2879 /* Here we emit the actual code for the entry point. */
2880
2881 {
2882 ffebld list;
2883 ffebld arg;
2884 ffesymbol s;
2885 tree arglist = NULL_TREE;
2886 tree *plist = &arglist;
2887 tree prepend;
2888 tree call;
2889 tree actarg;
2890 tree master_fn;
2891
2892 /* Prepare actual arg list based on master arg list. */
2893
2894 for (list = ffecom_master_arglist_;
2895 list != NULL;
2896 list = ffebld_trail (list))
2897 {
2898 arg = ffebld_head (list);
2899 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2900 continue;
2901 s = ffebld_symter (arg);
702edf1d
CB
2902 if (ffesymbol_hook (s).decl_tree == NULL_TREE
2903 || ffesymbol_hook (s).decl_tree == error_mark_node)
5ff904cd
JL
2904 actarg = null_pointer_node; /* We don't have this arg. */
2905 else
2906 actarg = ffesymbol_hook (s).decl_tree;
2907 *plist = build_tree_list (NULL_TREE, actarg);
2908 plist = &TREE_CHAIN (*plist);
2909 }
2910
2911 /* This code appends the length arguments for character
2912 variables/arrays. */
2913
2914 for (list = ffecom_master_arglist_;
2915 list != NULL;
2916 list = ffebld_trail (list))
2917 {
2918 arg = ffebld_head (list);
2919 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2920 continue;
2921 s = ffebld_symter (arg);
2922 if (ffesymbol_basictype (s) != FFEINFO_basictypeCHARACTER)
2923 continue; /* Only looking for CHARACTER arguments. */
2924 if (ffesymbol_kind (s) != FFEINFO_kindENTITY)
2925 continue; /* Only looking for variables and arrays. */
702edf1d
CB
2926 if (ffesymbol_hook (s).length_tree == NULL_TREE
2927 || ffesymbol_hook (s).length_tree == error_mark_node)
5ff904cd
JL
2928 actarg = ffecom_f2c_ftnlen_zero_node; /* We don't have this arg. */
2929 else
2930 actarg = ffesymbol_hook (s).length_tree;
2931 *plist = build_tree_list (NULL_TREE, actarg);
2932 plist = &TREE_CHAIN (*plist);
2933 }
2934
2935 /* Prepend character-value return info to actual arg list. */
2936
2937 if (charfunc)
2938 {
2939 prepend = build_tree_list (NULL_TREE, ffecom_func_result_);
2940 TREE_CHAIN (prepend)
2941 = build_tree_list (NULL_TREE, ffecom_func_length_);
2942 TREE_CHAIN (TREE_CHAIN (prepend)) = arglist;
2943 arglist = prepend;
2944 }
2945
2946 /* Prepend multi-type return value to actual arg list. */
2947
2948 if (multi)
2949 {
2950 prepend
2951 = build_tree_list (NULL_TREE,
2952 ffecom_1 (ADDR_EXPR,
2953 build_pointer_type (TREE_TYPE (multi_retval)),
2954 multi_retval));
2955 TREE_CHAIN (prepend) = arglist;
2956 arglist = prepend;
2957 }
2958
2959 /* Prepend my entry-point number to the actual arg list. */
2960
2961 prepend = build_tree_list (NULL_TREE, build_int_2 (entrynum, 0));
2962 TREE_CHAIN (prepend) = arglist;
2963 arglist = prepend;
2964
2965 /* Build the call to the master function. */
2966
2967 master_fn = ffecom_1_fn (ffecom_previous_function_decl_);
2968 call = ffecom_3s (CALL_EXPR,
2969 TREE_TYPE (TREE_TYPE (TREE_TYPE (master_fn))),
2970 master_fn, arglist, NULL_TREE);
2971
2972 /* Decide whether the master function is a function or subroutine, and
2973 handle the return value for my entry point. */
2974
2975 if (charfunc || ((ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE)
2976 && !altreturning))
2977 {
2978 expand_expr_stmt (call);
2979 expand_null_return ();
2980 }
2981 else if (multi && cmplxfunc)
2982 {
2983 expand_expr_stmt (call);
2984 result
2985 = ffecom_1 (INDIRECT_REF,
2986 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result))),
2987 result);
2988 result = ffecom_modify (NULL_TREE, result,
2989 ffecom_2 (COMPONENT_REF, TREE_TYPE (result),
2990 multi_retval,
2991 ffecom_multi_fields_[bt][kt]));
2992 expand_expr_stmt (result);
2993 expand_null_return ();
2994 }
2995 else if (multi)
2996 {
2997 expand_expr_stmt (call);
2998 result
2999 = ffecom_modify (NULL_TREE, result,
3000 convert (TREE_TYPE (result),
3001 ffecom_2 (COMPONENT_REF,
3002 ffecom_tree_type[bt][kt],
3003 multi_retval,
3004 ffecom_multi_fields_[bt][kt])));
3005 expand_return (result);
3006 }
3007 else if (cmplxfunc)
3008 {
3009 result
3010 = ffecom_1 (INDIRECT_REF,
3011 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result))),
3012 result);
3013 result = ffecom_modify (NULL_TREE, result, call);
3014 expand_expr_stmt (result);
3015 expand_null_return ();
3016 }
3017 else
3018 {
3019 result = ffecom_modify (NULL_TREE,
3020 result,
3021 convert (TREE_TYPE (result),
3022 call));
3023 expand_return (result);
3024 }
3025
3026 clear_momentary ();
3027 }
3028
c7e4ee3a 3029 ffecom_end_compstmt ();
5ff904cd
JL
3030
3031 finish_function (0);
3032
44d2eabc
JL
3033 lineno = old_lineno;
3034 input_filename = old_input_filename;
3035
5ff904cd
JL
3036 ffecom_doing_entry_ = FALSE;
3037}
3038
3039#endif
3040/* Transform expr into gcc tree with possible destination
3041
3042 Recursive descent on expr while making corresponding tree nodes and
3043 attaching type info and such. If destination supplied and compatible
3044 with temporary that would be made in certain cases, temporary isn't
092a4ef8 3045 made, destination used instead, and dest_used flag set TRUE. */
5ff904cd
JL
3046
3047#if FFECOM_targetCURRENT == FFECOM_targetGCC
3048static tree
092a4ef8
RH
3049ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest,
3050 bool *dest_used, bool assignp, bool widenp)
5ff904cd
JL
3051{
3052 tree item;
3053 tree list;
3054 tree args;
3055 ffeinfoBasictype bt;
3056 ffeinfoKindtype kt;
3057 tree t;
5ff904cd 3058 tree dt; /* decl_tree for an ffesymbol. */
092a4ef8 3059 tree tree_type, tree_type_x;
af752698 3060 tree left, right;
5ff904cd
JL
3061 ffesymbol s;
3062 enum tree_code code;
3063
3064 assert (expr != NULL);
3065
3066 if (dest_used != NULL)
3067 *dest_used = FALSE;
3068
3069 bt = ffeinfo_basictype (ffebld_info (expr));
3070 kt = ffeinfo_kindtype (ffebld_info (expr));
af752698 3071 tree_type = ffecom_tree_type[bt][kt];
5ff904cd 3072
092a4ef8
RH
3073 /* Widen integral arithmetic as desired while preserving signedness. */
3074 tree_type_x = NULL_TREE;
3075 if (widenp && tree_type
3076 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
3077 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
3078 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
3079
5ff904cd
JL
3080 switch (ffebld_op (expr))
3081 {
3082 case FFEBLD_opACCTER:
5ff904cd
JL
3083 {
3084 ffebitCount i;
3085 ffebit bits = ffebld_accter_bits (expr);
3086 ffetargetOffset source_offset = 0;
a6fa6420 3087 ffetargetOffset dest_offset = ffebld_accter_pad (expr);
5ff904cd
JL
3088 tree purpose;
3089
a6fa6420
CB
3090 assert (dest_offset == 0
3091 || (bt == FFEINFO_basictypeCHARACTER
3092 && kt == FFEINFO_kindtypeCHARACTER1));
5ff904cd
JL
3093
3094 list = item = NULL;
3095 for (;;)
3096 {
3097 ffebldConstantUnion cu;
3098 ffebitCount length;
3099 bool value;
3100 ffebldConstantArray ca = ffebld_accter (expr);
3101
3102 ffebit_test (bits, source_offset, &value, &length);
3103 if (length == 0)
3104 break;
3105
3106 if (value)
3107 {
3108 for (i = 0; i < length; ++i)
3109 {
3110 cu = ffebld_constantarray_get (ca, bt, kt,
3111 source_offset + i);
3112
3113 t = ffecom_constantunion (&cu, bt, kt, tree_type);
3114
a6fa6420
CB
3115 if (i == 0
3116 && dest_offset != 0)
3117 purpose = build_int_2 (dest_offset, 0);
5ff904cd
JL
3118 else
3119 purpose = NULL_TREE;
3120
3121 if (list == NULL_TREE)
3122 list = item = build_tree_list (purpose, t);
3123 else
3124 {
3125 TREE_CHAIN (item) = build_tree_list (purpose, t);
3126 item = TREE_CHAIN (item);
3127 }
3128 }
3129 }
3130 source_offset += length;
a6fa6420 3131 dest_offset += length;
5ff904cd
JL
3132 }
3133 }
3134
a6fa6420
CB
3135 item = build_int_2 ((ffebld_accter_size (expr)
3136 + ffebld_accter_pad (expr)) - 1, 0);
5ff904cd
JL
3137 ffebit_kill (ffebld_accter_bits (expr));
3138 TREE_TYPE (item) = ffecom_integer_type_node;
3139 item
3140 = build_array_type
3141 (tree_type,
3142 build_range_type (ffecom_integer_type_node,
3143 ffecom_integer_zero_node,
3144 item));
3145 list = build (CONSTRUCTOR, item, NULL_TREE, list);
3146 TREE_CONSTANT (list) = 1;
3147 TREE_STATIC (list) = 1;
3148 return list;
3149
3150 case FFEBLD_opARRTER:
5ff904cd
JL
3151 {
3152 ffetargetOffset i;
3153
a6fa6420
CB
3154 list = NULL_TREE;
3155 if (ffebld_arrter_pad (expr) == 0)
3156 item = NULL_TREE;
3157 else
3158 {
3159 assert (bt == FFEINFO_basictypeCHARACTER
3160 && kt == FFEINFO_kindtypeCHARACTER1);
3161
3162 /* Becomes PURPOSE first time through loop. */
3163 item = build_int_2 (ffebld_arrter_pad (expr), 0);
3164 }
3165
5ff904cd
JL
3166 for (i = 0; i < ffebld_arrter_size (expr); ++i)
3167 {
3168 ffebldConstantUnion cu
3169 = ffebld_constantarray_get (ffebld_arrter (expr), bt, kt, i);
3170
3171 t = ffecom_constantunion (&cu, bt, kt, tree_type);
3172
3173 if (list == NULL_TREE)
a6fa6420
CB
3174 /* Assume item is PURPOSE first time through loop. */
3175 list = item = build_tree_list (item, t);
5ff904cd
JL
3176 else
3177 {
3178 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
3179 item = TREE_CHAIN (item);
3180 }
3181 }
3182 }
3183
a6fa6420
CB
3184 item = build_int_2 ((ffebld_arrter_size (expr)
3185 + ffebld_arrter_pad (expr)) - 1, 0);
5ff904cd
JL
3186 TREE_TYPE (item) = ffecom_integer_type_node;
3187 item
3188 = build_array_type
3189 (tree_type,
3190 build_range_type (ffecom_integer_type_node,
a6fa6420 3191 ffecom_integer_zero_node,
5ff904cd
JL
3192 item));
3193 list = build (CONSTRUCTOR, item, NULL_TREE, list);
3194 TREE_CONSTANT (list) = 1;
3195 TREE_STATIC (list) = 1;
3196 return list;
3197
3198 case FFEBLD_opCONTER:
c264f113 3199 assert (ffebld_conter_pad (expr) == 0);
5ff904cd
JL
3200 item
3201 = ffecom_constantunion (&ffebld_constant_union (ffebld_conter (expr)),
3202 bt, kt, tree_type);
3203 return item;
3204
3205 case FFEBLD_opSYMTER:
3206 if ((ffebld_symter_generic (expr) != FFEINTRIN_genNONE)
3207 || (ffebld_symter_specific (expr) != FFEINTRIN_specNONE))
3208 return ffecom_ptr_to_expr (expr); /* Same as %REF(intrinsic). */
3209 s = ffebld_symter (expr);
3210 t = ffesymbol_hook (s).decl_tree;
3211
3212 if (assignp)
3213 { /* ASSIGN'ed-label expr. */
3214 if (ffe_is_ugly_assign ())
3215 {
3216 /* User explicitly wants ASSIGN'ed variables to be at the same
3217 memory address as the variables when used in non-ASSIGN
3218 contexts. That can make old, arcane, non-standard code
3219 work, but don't try to do it when a pointer wouldn't fit
3220 in the normal variable (take other approach, and warn,
3221 instead). */
3222
3223 if (t == NULL_TREE)
3224 {
3225 s = ffecom_sym_transform_ (s);
3226 t = ffesymbol_hook (s).decl_tree;
3227 assert (t != NULL_TREE);
3228 }
3229
3230 if (t == error_mark_node)
3231 return t;
3232
3233 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (t)))
3234 >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
3235 {
3236 if (ffesymbol_hook (s).addr)
3237 t = ffecom_1 (INDIRECT_REF,
3238 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), t);
3239 return t;
3240 }
3241
3242 if (ffesymbol_hook (s).assign_tree == NULL_TREE)
3243 {
3244 ffebad_start_msg ("ASSIGN'ed label cannot fit into `%A' at %0 -- using wider sibling",
3245 FFEBAD_severityWARNING);
3246 ffebad_string (ffesymbol_text (s));
3247 ffebad_here (0, ffesymbol_where_line (s),
3248 ffesymbol_where_column (s));
3249 ffebad_finish ();
3250 }
3251 }
3252
3253 /* Don't use the normal variable's tree for ASSIGN, though mark
3254 it as in the system header (housekeeping). Use an explicit,
3255 specially created sibling that is known to be wide enough
3256 to hold pointers to labels. */
3257
3258 if (t != NULL_TREE
3259 && TREE_CODE (t) == VAR_DECL)
3260 DECL_IN_SYSTEM_HEADER (t) = 1; /* Don't let -Wunused complain. */
3261
3262 t = ffesymbol_hook (s).assign_tree;
3263 if (t == NULL_TREE)
3264 {
3265 s = ffecom_sym_transform_assign_ (s);
3266 t = ffesymbol_hook (s).assign_tree;
3267 assert (t != NULL_TREE);
3268 }
3269 }
3270 else
3271 {
3272 if (t == NULL_TREE)
3273 {
3274 s = ffecom_sym_transform_ (s);
3275 t = ffesymbol_hook (s).decl_tree;
3276 assert (t != NULL_TREE);
3277 }
3278 if (ffesymbol_hook (s).addr)
3279 t = ffecom_1 (INDIRECT_REF,
3280 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), t);
3281 }
3282 return t;
3283
3284 case FFEBLD_opARRAYREF:
ff852b44 3285 return ffecom_arrayref_ (NULL_TREE, expr, 0);
5ff904cd
JL
3286
3287 case FFEBLD_opUPLUS:
092a4ef8 3288 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
af752698 3289 return ffecom_1 (NOP_EXPR, tree_type, left);
5ff904cd 3290
c7e4ee3a
CB
3291 case FFEBLD_opPAREN:
3292 /* ~~~Make sure Fortran rules respected here */
092a4ef8 3293 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
af752698 3294 return ffecom_1 (NOP_EXPR, tree_type, left);
5ff904cd
JL
3295
3296 case FFEBLD_opUMINUS:
092a4ef8 3297 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
af752698
RH
3298 if (tree_type_x)
3299 {
3300 tree_type = tree_type_x;
3301 left = convert (tree_type, left);
3302 }
3303 return ffecom_1 (NEGATE_EXPR, tree_type, left);
5ff904cd
JL
3304
3305 case FFEBLD_opADD:
092a4ef8
RH
3306 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3307 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
af752698
RH
3308 if (tree_type_x)
3309 {
3310 tree_type = tree_type_x;
3311 left = convert (tree_type, left);
3312 right = convert (tree_type, right);
3313 }
3314 return ffecom_2 (PLUS_EXPR, tree_type, left, right);
5ff904cd
JL
3315
3316 case FFEBLD_opSUBTRACT:
092a4ef8
RH
3317 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3318 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
af752698
RH
3319 if (tree_type_x)
3320 {
3321 tree_type = tree_type_x;
3322 left = convert (tree_type, left);
3323 right = convert (tree_type, right);
3324 }
3325 return ffecom_2 (MINUS_EXPR, tree_type, left, right);
5ff904cd
JL
3326
3327 case FFEBLD_opMULTIPLY:
092a4ef8
RH
3328 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3329 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
af752698
RH
3330 if (tree_type_x)
3331 {
3332 tree_type = tree_type_x;
3333 left = convert (tree_type, left);
3334 right = convert (tree_type, right);
3335 }
3336 return ffecom_2 (MULT_EXPR, tree_type, left, right);
5ff904cd
JL
3337
3338 case FFEBLD_opDIVIDE:
092a4ef8
RH
3339 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3340 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
af752698
RH
3341 if (tree_type_x)
3342 {
3343 tree_type = tree_type_x;
3344 left = convert (tree_type, left);
3345 right = convert (tree_type, right);
3346 }
3347 return ffecom_tree_divide_ (tree_type, left, right,
c7e4ee3a
CB
3348 dest_tree, dest, dest_used,
3349 ffebld_nonter_hook (expr));
5ff904cd
JL
3350
3351 case FFEBLD_opPOWER:
5ff904cd
JL
3352 {
3353 ffebld left = ffebld_left (expr);
3354 ffebld right = ffebld_right (expr);
3355 ffecomGfrt code;
3356 ffeinfoKindtype rtkt;
270fc4e8 3357 ffeinfoKindtype ltkt;
5ff904cd
JL
3358
3359 switch (ffeinfo_basictype (ffebld_info (right)))
3360 {
3361 case FFEINFO_basictypeINTEGER:
3362 if (1 || optimize)
3363 {
c7e4ee3a 3364 item = ffecom_expr_power_integer_ (expr);
5ff904cd
JL
3365 if (item != NULL_TREE)
3366 return item;
3367 }
3368
3369 rtkt = FFEINFO_kindtypeINTEGER1;
3370 switch (ffeinfo_basictype (ffebld_info (left)))
3371 {
3372 case FFEINFO_basictypeINTEGER:
3373 if ((ffeinfo_kindtype (ffebld_info (left))
3374 == FFEINFO_kindtypeINTEGER4)
3375 || (ffeinfo_kindtype (ffebld_info (right))
3376 == FFEINFO_kindtypeINTEGER4))
3377 {
3378 code = FFECOM_gfrtPOW_QQ;
270fc4e8 3379 ltkt = FFEINFO_kindtypeINTEGER4;
5ff904cd
JL
3380 rtkt = FFEINFO_kindtypeINTEGER4;
3381 }
3382 else
6a047254
CB
3383 {
3384 code = FFECOM_gfrtPOW_II;
3385 ltkt = FFEINFO_kindtypeINTEGER1;
3386 }
5ff904cd
JL
3387 break;
3388
3389 case FFEINFO_basictypeREAL:
3390 if (ffeinfo_kindtype (ffebld_info (left))
3391 == FFEINFO_kindtypeREAL1)
6a047254
CB
3392 {
3393 code = FFECOM_gfrtPOW_RI;
3394 ltkt = FFEINFO_kindtypeREAL1;
3395 }
5ff904cd 3396 else
6a047254
CB
3397 {
3398 code = FFECOM_gfrtPOW_DI;
3399 ltkt = FFEINFO_kindtypeREAL2;
3400 }
5ff904cd
JL
3401 break;
3402
3403 case FFEINFO_basictypeCOMPLEX:
3404 if (ffeinfo_kindtype (ffebld_info (left))
3405 == FFEINFO_kindtypeREAL1)
6a047254
CB
3406 {
3407 code = FFECOM_gfrtPOW_CI; /* Overlapping result okay. */
3408 ltkt = FFEINFO_kindtypeREAL1;
3409 }
5ff904cd 3410 else
6a047254
CB
3411 {
3412 code = FFECOM_gfrtPOW_ZI; /* Overlapping result okay. */
3413 ltkt = FFEINFO_kindtypeREAL2;
3414 }
5ff904cd
JL
3415 break;
3416
3417 default:
3418 assert ("bad pow_*i" == NULL);
3419 code = FFECOM_gfrtPOW_CI; /* Overlapping result okay. */
6a047254 3420 ltkt = FFEINFO_kindtypeREAL1;
5ff904cd
JL
3421 break;
3422 }
270fc4e8 3423 if (ffeinfo_kindtype (ffebld_info (left)) != ltkt)
5ff904cd 3424 left = ffeexpr_convert (left, NULL, NULL,
6a047254 3425 ffeinfo_basictype (ffebld_info (left)),
270fc4e8 3426 ltkt, 0,
5ff904cd
JL
3427 FFETARGET_charactersizeNONE,
3428 FFEEXPR_contextLET);
3429 if (ffeinfo_kindtype (ffebld_info (right)) != rtkt)
3430 right = ffeexpr_convert (right, NULL, NULL,
3431 FFEINFO_basictypeINTEGER,
3432 rtkt, 0,
3433 FFETARGET_charactersizeNONE,
3434 FFEEXPR_contextLET);
3435 break;
3436
3437 case FFEINFO_basictypeREAL:
3438 if (ffeinfo_kindtype (ffebld_info (left)) == FFEINFO_kindtypeREAL1)
3439 left = ffeexpr_convert (left, NULL, NULL, FFEINFO_basictypeREAL,
3440 FFEINFO_kindtypeREALDOUBLE, 0,
3441 FFETARGET_charactersizeNONE,
3442 FFEEXPR_contextLET);
3443 if (ffeinfo_kindtype (ffebld_info (right))
3444 == FFEINFO_kindtypeREAL1)
3445 right = ffeexpr_convert (right, NULL, NULL,
3446 FFEINFO_basictypeREAL,
3447 FFEINFO_kindtypeREALDOUBLE, 0,
3448 FFETARGET_charactersizeNONE,
3449 FFEEXPR_contextLET);
3450 code = FFECOM_gfrtPOW_DD;
3451 break;
3452
3453 case FFEINFO_basictypeCOMPLEX:
3454 if (ffeinfo_kindtype (ffebld_info (left)) == FFEINFO_kindtypeREAL1)
3455 left = ffeexpr_convert (left, NULL, NULL,
3456 FFEINFO_basictypeCOMPLEX,
3457 FFEINFO_kindtypeREALDOUBLE, 0,
3458 FFETARGET_charactersizeNONE,
3459 FFEEXPR_contextLET);
3460 if (ffeinfo_kindtype (ffebld_info (right))
3461 == FFEINFO_kindtypeREAL1)
3462 right = ffeexpr_convert (right, NULL, NULL,
3463 FFEINFO_basictypeCOMPLEX,
3464 FFEINFO_kindtypeREALDOUBLE, 0,
3465 FFETARGET_charactersizeNONE,
3466 FFEEXPR_contextLET);
3467 code = FFECOM_gfrtPOW_ZZ; /* Overlapping result okay. */
3468 break;
3469
3470 default:
3471 assert ("bad pow_x*" == NULL);
3472 code = FFECOM_gfrtPOW_II;
3473 break;
3474 }
3475 return ffecom_call_binop_ (ffecom_gfrt_tree_ (code),
3476 ffecom_gfrt_kindtype (code),
3477 (ffe_is_f2c_library ()
3478 && ffecom_gfrt_complex_[code]),
3479 tree_type, left, right,
3480 dest_tree, dest, dest_used,
c7e4ee3a
CB
3481 NULL_TREE, FALSE,
3482 ffebld_nonter_hook (expr));
5ff904cd
JL
3483 }
3484
3485 case FFEBLD_opNOT:
5ff904cd
JL
3486 switch (bt)
3487 {
3488 case FFEINFO_basictypeLOGICAL:
83ffecd2 3489 item = ffecom_truth_value_invert (ffecom_expr (ffebld_left (expr)));
5ff904cd
JL
3490 return convert (tree_type, item);
3491
3492 case FFEINFO_basictypeINTEGER:
3493 return ffecom_1 (BIT_NOT_EXPR, tree_type,
3494 ffecom_expr (ffebld_left (expr)));
3495
3496 default:
3497 assert ("NOT bad basictype" == NULL);
3498 /* Fall through. */
3499 case FFEINFO_basictypeANY:
3500 return error_mark_node;
3501 }
3502 break;
3503
3504 case FFEBLD_opFUNCREF:
3505 assert (ffeinfo_basictype (ffebld_info (expr))
3506 != FFEINFO_basictypeCHARACTER);
3507 /* Fall through. */
3508 case FFEBLD_opSUBRREF:
5ff904cd
JL
3509 if (ffeinfo_where (ffebld_info (ffebld_left (expr)))
3510 == FFEINFO_whereINTRINSIC)
3511 { /* Invocation of an intrinsic. */
3512 item = ffecom_expr_intrinsic_ (expr, dest_tree, dest,
3513 dest_used);
3514 return item;
3515 }
3516 s = ffebld_symter (ffebld_left (expr));
3517 dt = ffesymbol_hook (s).decl_tree;
3518 if (dt == NULL_TREE)
3519 {
3520 s = ffecom_sym_transform_ (s);
3521 dt = ffesymbol_hook (s).decl_tree;
3522 }
3523 if (dt == error_mark_node)
3524 return dt;
3525
3526 if (ffesymbol_hook (s).addr)
3527 item = dt;
3528 else
3529 item = ffecom_1_fn (dt);
3530
5ff904cd
JL
3531 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT)
3532 args = ffecom_list_expr (ffebld_right (expr));
3533 else
3534 args = ffecom_list_ptr_to_expr (ffebld_right (expr));
5ff904cd 3535
702edf1d
CB
3536 if (args == error_mark_node)
3537 return error_mark_node;
3538
5ff904cd
JL
3539 item = ffecom_call_ (item, kt,
3540 ffesymbol_is_f2c (s)
3541 && (bt == FFEINFO_basictypeCOMPLEX)
3542 && (ffesymbol_where (s)
3543 != FFEINFO_whereCONSTANT),
3544 tree_type,
3545 args,
3546 dest_tree, dest, dest_used,
c7e4ee3a
CB
3547 error_mark_node, FALSE,
3548 ffebld_nonter_hook (expr));
5ff904cd
JL
3549 TREE_SIDE_EFFECTS (item) = 1;
3550 return item;
3551
3552 case FFEBLD_opAND:
5ff904cd
JL
3553 switch (bt)
3554 {
3555 case FFEINFO_basictypeLOGICAL:
3556 item
3557 = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
3558 ffecom_truth_value (ffecom_expr (ffebld_left (expr))),
3559 ffecom_truth_value (ffecom_expr (ffebld_right (expr))));
3560 return convert (tree_type, item);
3561
3562 case FFEINFO_basictypeINTEGER:
3563 return ffecom_2 (BIT_AND_EXPR, tree_type,
3564 ffecom_expr (ffebld_left (expr)),
3565 ffecom_expr (ffebld_right (expr)));
3566
3567 default:
3568 assert ("AND bad basictype" == NULL);
3569 /* Fall through. */
3570 case FFEINFO_basictypeANY:
3571 return error_mark_node;
3572 }
3573 break;
3574
3575 case FFEBLD_opOR:
5ff904cd
JL
3576 switch (bt)
3577 {
3578 case FFEINFO_basictypeLOGICAL:
3579 item
3580 = ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
3581 ffecom_truth_value (ffecom_expr (ffebld_left (expr))),
3582 ffecom_truth_value (ffecom_expr (ffebld_right (expr))));
3583 return convert (tree_type, item);
3584
3585 case FFEINFO_basictypeINTEGER:
3586 return ffecom_2 (BIT_IOR_EXPR, tree_type,
3587 ffecom_expr (ffebld_left (expr)),
3588 ffecom_expr (ffebld_right (expr)));
3589
3590 default:
3591 assert ("OR bad basictype" == NULL);
3592 /* Fall through. */
3593 case FFEINFO_basictypeANY:
3594 return error_mark_node;
3595 }
3596 break;
3597
3598 case FFEBLD_opXOR:
3599 case FFEBLD_opNEQV:
5ff904cd
JL
3600 switch (bt)
3601 {
3602 case FFEINFO_basictypeLOGICAL:
3603 item
3604 = ffecom_2 (NE_EXPR, integer_type_node,
3605 ffecom_expr (ffebld_left (expr)),
3606 ffecom_expr (ffebld_right (expr)));
3607 return convert (tree_type, ffecom_truth_value (item));
3608
3609 case FFEINFO_basictypeINTEGER:
3610 return ffecom_2 (BIT_XOR_EXPR, tree_type,
3611 ffecom_expr (ffebld_left (expr)),
3612 ffecom_expr (ffebld_right (expr)));
3613
3614 default:
3615 assert ("XOR/NEQV bad basictype" == NULL);
3616 /* Fall through. */
3617 case FFEINFO_basictypeANY:
3618 return error_mark_node;
3619 }
3620 break;
3621
3622 case FFEBLD_opEQV:
5ff904cd
JL
3623 switch (bt)
3624 {
3625 case FFEINFO_basictypeLOGICAL:
3626 item
3627 = ffecom_2 (EQ_EXPR, integer_type_node,
3628 ffecom_expr (ffebld_left (expr)),
3629 ffecom_expr (ffebld_right (expr)));
3630 return convert (tree_type, ffecom_truth_value (item));
3631
3632 case FFEINFO_basictypeINTEGER:
3633 return
3634 ffecom_1 (BIT_NOT_EXPR, tree_type,
3635 ffecom_2 (BIT_XOR_EXPR, tree_type,
3636 ffecom_expr (ffebld_left (expr)),
3637 ffecom_expr (ffebld_right (expr))));
3638
3639 default:
3640 assert ("EQV bad basictype" == NULL);
3641 /* Fall through. */
3642 case FFEINFO_basictypeANY:
3643 return error_mark_node;
3644 }
3645 break;
3646
3647 case FFEBLD_opCONVERT:
3648 if (ffebld_op (ffebld_left (expr)) == FFEBLD_opANY)
3649 return error_mark_node;
3650
5ff904cd
JL
3651 switch (bt)
3652 {
3653 case FFEINFO_basictypeLOGICAL:
3654 case FFEINFO_basictypeINTEGER:
3655 case FFEINFO_basictypeREAL:
3656 return convert (tree_type, ffecom_expr (ffebld_left (expr)));
3657
3658 case FFEINFO_basictypeCOMPLEX:
3659 switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr))))
3660 {
3661 case FFEINFO_basictypeINTEGER:
3662 case FFEINFO_basictypeLOGICAL:
3663 case FFEINFO_basictypeREAL:
3664 item = ffecom_expr (ffebld_left (expr));
3665 if (item == error_mark_node)
3666 return error_mark_node;
3667 /* convert() takes care of converting to the subtype first,
3668 at least in gcc-2.7.2. */
3669 item = convert (tree_type, item);
3670 return item;
3671
3672 case FFEINFO_basictypeCOMPLEX:
3673 return convert (tree_type, ffecom_expr (ffebld_left (expr)));
3674
3675 default:
3676 assert ("CONVERT COMPLEX bad basictype" == NULL);
3677 /* Fall through. */
3678 case FFEINFO_basictypeANY:
3679 return error_mark_node;
3680 }
3681 break;
3682
3683 default:
3684 assert ("CONVERT bad basictype" == NULL);
3685 /* Fall through. */
3686 case FFEINFO_basictypeANY:
3687 return error_mark_node;
3688 }
3689 break;
3690
3691 case FFEBLD_opLT:
3692 code = LT_EXPR;
3693 goto relational; /* :::::::::::::::::::: */
3694
3695 case FFEBLD_opLE:
3696 code = LE_EXPR;
3697 goto relational; /* :::::::::::::::::::: */
3698
3699 case FFEBLD_opEQ:
3700 code = EQ_EXPR;
3701 goto relational; /* :::::::::::::::::::: */
3702
3703 case FFEBLD_opNE:
3704 code = NE_EXPR;
3705 goto relational; /* :::::::::::::::::::: */
3706
3707 case FFEBLD_opGT:
3708 code = GT_EXPR;
3709 goto relational; /* :::::::::::::::::::: */
3710
3711 case FFEBLD_opGE:
3712 code = GE_EXPR;
3713
3714 relational: /* :::::::::::::::::::: */
5ff904cd
JL
3715 switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr))))
3716 {
3717 case FFEINFO_basictypeLOGICAL:
3718 case FFEINFO_basictypeINTEGER:
3719 case FFEINFO_basictypeREAL:
3720 item = ffecom_2 (code, integer_type_node,
3721 ffecom_expr (ffebld_left (expr)),
3722 ffecom_expr (ffebld_right (expr)));
3723 return convert (tree_type, item);
3724
3725 case FFEINFO_basictypeCOMPLEX:
3726 assert (code == EQ_EXPR || code == NE_EXPR);
3727 {
3728 tree real_type;
3729 tree arg1 = ffecom_expr (ffebld_left (expr));
3730 tree arg2 = ffecom_expr (ffebld_right (expr));
3731
3732 if (arg1 == error_mark_node || arg2 == error_mark_node)
3733 return error_mark_node;
3734
3735 arg1 = ffecom_save_tree (arg1);
3736 arg2 = ffecom_save_tree (arg2);
3737
3738 if (TREE_CODE (TREE_TYPE (arg1)) == COMPLEX_TYPE)
3739 {
3740 real_type = TREE_TYPE (TREE_TYPE (arg1));
3741 assert (real_type == TREE_TYPE (TREE_TYPE (arg2)));
3742 }
3743 else
3744 {
3745 real_type = TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg1)));
3746 assert (real_type == TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg2))));
3747 }
3748
3749 item
3750 = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
3751 ffecom_2 (EQ_EXPR, integer_type_node,
3752 ffecom_1 (REALPART_EXPR, real_type, arg1),
3753 ffecom_1 (REALPART_EXPR, real_type, arg2)),
3754 ffecom_2 (EQ_EXPR, integer_type_node,
3755 ffecom_1 (IMAGPART_EXPR, real_type, arg1),
3756 ffecom_1 (IMAGPART_EXPR, real_type,
3757 arg2)));
3758 if (code == EQ_EXPR)
3759 item = ffecom_truth_value (item);
3760 else
3761 item = ffecom_truth_value_invert (item);
3762 return convert (tree_type, item);
3763 }
3764
3765 case FFEINFO_basictypeCHARACTER:
5ff904cd
JL
3766 {
3767 ffebld left = ffebld_left (expr);
3768 ffebld right = ffebld_right (expr);
3769 tree left_tree;
3770 tree right_tree;
3771 tree left_length;
3772 tree right_length;
3773
3774 /* f2c run-time functions do the implicit blank-padding for us,
3775 so we don't usually have to implement blank-padding ourselves.
3776 (The exception is when we pass an argument to a separately
3777 compiled statement function -- if we know the arg is not the
3778 same length as the dummy, we must truncate or extend it. If
3779 we "inline" statement functions, that necessity goes away as
3780 well.)
3781
3782 Strip off the CONVERT operators that blank-pad. (Truncation by
3783 CONVERT shouldn't happen here, but it can happen in
3784 assignments.) */
3785
3786 while (ffebld_op (left) == FFEBLD_opCONVERT)
3787 left = ffebld_left (left);
3788 while (ffebld_op (right) == FFEBLD_opCONVERT)
3789 right = ffebld_left (right);
3790
3791 left_tree = ffecom_arg_ptr_to_expr (left, &left_length);
3792 right_tree = ffecom_arg_ptr_to_expr (right, &right_length);
3793
3794 if (left_tree == error_mark_node || left_length == error_mark_node
3795 || right_tree == error_mark_node
3796 || right_length == error_mark_node)
c7e4ee3a 3797 return error_mark_node;
5ff904cd
JL
3798
3799 if ((ffebld_size_known (left) == 1)
3800 && (ffebld_size_known (right) == 1))
3801 {
3802 left_tree
3803 = ffecom_1 (INDIRECT_REF,
3804 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree))),
3805 left_tree);
3806 right_tree
3807 = ffecom_1 (INDIRECT_REF,
3808 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree))),
3809 right_tree);
3810
3811 item
3812 = ffecom_2 (code, integer_type_node,
3813 ffecom_2 (ARRAY_REF,
3814 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree))),
3815 left_tree,
3816 integer_one_node),
3817 ffecom_2 (ARRAY_REF,
3818 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree))),
3819 right_tree,
3820 integer_one_node));
3821 }
3822 else
3823 {
3824 item = build_tree_list (NULL_TREE, left_tree);
3825 TREE_CHAIN (item) = build_tree_list (NULL_TREE, right_tree);
3826 TREE_CHAIN (TREE_CHAIN (item)) = build_tree_list (NULL_TREE,
3827 left_length);
3828 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item)))
3829 = build_tree_list (NULL_TREE, right_length);
c7e4ee3a 3830 item = ffecom_call_gfrt (FFECOM_gfrtCMP, item, NULL_TREE);
5ff904cd
JL
3831 item = ffecom_2 (code, integer_type_node,
3832 item,
3833 convert (TREE_TYPE (item),
3834 integer_zero_node));
3835 }
3836 item = convert (tree_type, item);
3837 }
3838
5ff904cd
JL
3839 return item;
3840
3841 default:
3842 assert ("relational bad basictype" == NULL);
3843 /* Fall through. */
3844 case FFEINFO_basictypeANY:
3845 return error_mark_node;
3846 }
3847 break;
3848
3849 case FFEBLD_opPERCENT_LOC:
5ff904cd
JL
3850 item = ffecom_arg_ptr_to_expr (ffebld_left (expr), &list);
3851 return convert (tree_type, item);
3852
3853 case FFEBLD_opITEM:
3854 case FFEBLD_opSTAR:
3855 case FFEBLD_opBOUNDS:
3856 case FFEBLD_opREPEAT:
3857 case FFEBLD_opLABTER:
3858 case FFEBLD_opLABTOK:
3859 case FFEBLD_opIMPDO:
3860 case FFEBLD_opCONCATENATE:
3861 case FFEBLD_opSUBSTR:
3862 default:
3863 assert ("bad op" == NULL);
3864 /* Fall through. */
3865 case FFEBLD_opANY:
3866 return error_mark_node;
3867 }
3868
3869#if 1
3870 assert ("didn't think anything got here anymore!!" == NULL);
3871#else
3872 switch (ffebld_arity (expr))
3873 {
3874 case 2:
3875 TREE_OPERAND (item, 0) = ffecom_expr (ffebld_left (expr));
3876 TREE_OPERAND (item, 1) = ffecom_expr (ffebld_right (expr));
3877 if (TREE_OPERAND (item, 0) == error_mark_node
3878 || TREE_OPERAND (item, 1) == error_mark_node)
3879 return error_mark_node;
3880 break;
3881
3882 case 1:
3883 TREE_OPERAND (item, 0) = ffecom_expr (ffebld_left (expr));
3884 if (TREE_OPERAND (item, 0) == error_mark_node)
3885 return error_mark_node;
3886 break;
3887
3888 default:
3889 break;
3890 }
3891
3892 return fold (item);
3893#endif
3894}
3895
3896#endif
3897/* Returns the tree that does the intrinsic invocation.
3898
3899 Note: this function applies only to intrinsics returning
3900 CHARACTER*1 or non-CHARACTER results, and to intrinsic
3901 subroutines. */
3902
3903#if FFECOM_targetCURRENT == FFECOM_targetGCC
3904static tree
3905ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree,
3906 ffebld dest, bool *dest_used)
3907{
3908 tree expr_tree;
3909 tree saved_expr1; /* For those who need it. */
3910 tree saved_expr2; /* For those who need it. */
3911 ffeinfoBasictype bt;
3912 ffeinfoKindtype kt;
3913 tree tree_type;
3914 tree arg1_type;
3915 tree real_type; /* REAL type corresponding to COMPLEX. */
3916 tree tempvar;
3917 ffebld list = ffebld_right (expr); /* List of (some) args. */
3918 ffebld arg1; /* For handy reference. */
3919 ffebld arg2;
3920 ffebld arg3;
3921 ffeintrinImp codegen_imp;
3922 ffecomGfrt gfrt;
3923
3924 assert (ffebld_op (ffebld_left (expr)) == FFEBLD_opSYMTER);
3925
3926 if (dest_used != NULL)
3927 *dest_used = FALSE;
3928
3929 bt = ffeinfo_basictype (ffebld_info (expr));
3930 kt = ffeinfo_kindtype (ffebld_info (expr));
3931 tree_type = ffecom_tree_type[bt][kt];
3932
3933 if (list != NULL)
3934 {
3935 arg1 = ffebld_head (list);
3936 if (arg1 != NULL && ffebld_op (arg1) == FFEBLD_opANY)
3937 return error_mark_node;
3938 if ((list = ffebld_trail (list)) != NULL)
3939 {
3940 arg2 = ffebld_head (list);
3941 if (arg2 != NULL && ffebld_op (arg2) == FFEBLD_opANY)
3942 return error_mark_node;
3943 if ((list = ffebld_trail (list)) != NULL)
3944 {
3945 arg3 = ffebld_head (list);
3946 if (arg3 != NULL && ffebld_op (arg3) == FFEBLD_opANY)
3947 return error_mark_node;
3948 }
3949 else
3950 arg3 = NULL;
3951 }
3952 else
3953 arg2 = arg3 = NULL;
3954 }
3955 else
3956 arg1 = arg2 = arg3 = NULL;
3957
3958 /* <list> ends up at the opITEM of the 3rd arg, or NULL if there are < 3
3959 args. This is used by the MAX/MIN expansions. */
3960
3961 if (arg1 != NULL)
3962 arg1_type = ffecom_tree_type
3963 [ffeinfo_basictype (ffebld_info (arg1))]
3964 [ffeinfo_kindtype (ffebld_info (arg1))];
3965 else
3966 arg1_type = NULL_TREE; /* Really not needed, but might catch bugs
3967 here. */
3968
3969 /* There are several ways for each of the cases in the following switch
3970 statements to exit (from simplest to use to most complicated):
3971
3972 break; (when expr_tree == NULL)
3973
3974 A standard call is made to the specific intrinsic just as if it had been
3975 passed in as a dummy procedure and called as any old procedure. This
3976 method can produce slower code but in some cases it's the easiest way for
3977 now. However, if a (presumably faster) direct call is available,
3978 that is used, so this is the easiest way in many more cases now.
3979
3980 gfrt = FFECOM_gfrtWHATEVER;
3981 break;
3982
3983 gfrt contains the gfrt index of a library function to call, passing the
3984 argument(s) by value rather than by reference. Used when a more
3985 careful choice of library function is needed than that provided
3986 by the vanilla `break;'.
3987
3988 return expr_tree;
3989
3990 The expr_tree has been completely set up and is ready to be returned
3991 as is. No further actions are taken. Use this when the tree is not
3992 in the simple form for one of the arity_n labels. */
3993
3994 /* For info on how the switch statement cases were written, see the files
3995 enclosed in comments below the switch statement. */
3996
3997 codegen_imp = ffebld_symter_implementation (ffebld_left (expr));
3998 gfrt = ffeintrin_gfrt_direct (codegen_imp);
3999 if (gfrt == FFECOM_gfrt)
4000 gfrt = ffeintrin_gfrt_indirect (codegen_imp);
4001
4002 switch (codegen_imp)
4003 {
4004 case FFEINTRIN_impABS:
4005 case FFEINTRIN_impCABS:
4006 case FFEINTRIN_impCDABS:
4007 case FFEINTRIN_impDABS:
4008 case FFEINTRIN_impIABS:
4009 if (ffeinfo_basictype (ffebld_info (arg1))
4010 == FFEINFO_basictypeCOMPLEX)
4011 {
4012 if (kt == FFEINFO_kindtypeREAL1)
4013 gfrt = FFECOM_gfrtCABS;
4014 else if (kt == FFEINFO_kindtypeREAL2)
4015 gfrt = FFECOM_gfrtCDABS;
4016 break;
4017 }
4018 return ffecom_1 (ABS_EXPR, tree_type,
4019 convert (tree_type, ffecom_expr (arg1)));
4020
4021 case FFEINTRIN_impACOS:
4022 case FFEINTRIN_impDACOS:
4023 break;
4024
4025 case FFEINTRIN_impAIMAG:
4026 case FFEINTRIN_impDIMAG:
4027 case FFEINTRIN_impIMAGPART:
4028 if (TREE_CODE (arg1_type) == COMPLEX_TYPE)
4029 arg1_type = TREE_TYPE (arg1_type);
4030 else
4031 arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type));
4032
4033 return
4034 convert (tree_type,
4035 ffecom_1 (IMAGPART_EXPR, arg1_type,
4036 ffecom_expr (arg1)));
4037
4038 case FFEINTRIN_impAINT:
4039 case FFEINTRIN_impDINT:
c7e4ee3a
CB
4040#if 0
4041 /* ~~Someday implement FIX_TRUNC_EXPR yielding same type as arg. */
5ff904cd
JL
4042 return ffecom_1 (FIX_TRUNC_EXPR, tree_type, ffecom_expr (arg1));
4043#else /* in the meantime, must use floor to avoid range problems with ints */
4044 /* r__1 = r1 >= 0 ? floor(r1) : -floor(-r1); */
4045 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
4046 return
4047 convert (tree_type,
4048 ffecom_3 (COND_EXPR, double_type_node,
4049 ffecom_truth_value
4050 (ffecom_2 (GE_EXPR, integer_type_node,
4051 saved_expr1,
4052 convert (arg1_type,
4053 ffecom_float_zero_))),
4054 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
4055 build_tree_list (NULL_TREE,
4056 convert (double_type_node,
c7e4ee3a
CB
4057 saved_expr1)),
4058 NULL_TREE),
5ff904cd
JL
4059 ffecom_1 (NEGATE_EXPR, double_type_node,
4060 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
4061 build_tree_list (NULL_TREE,
4062 convert (double_type_node,
4063 ffecom_1 (NEGATE_EXPR,
4064 arg1_type,
c7e4ee3a
CB
4065 saved_expr1))),
4066 NULL_TREE)
5ff904cd
JL
4067 ))
4068 );
4069#endif
4070
4071 case FFEINTRIN_impANINT:
4072 case FFEINTRIN_impDNINT:
4073#if 0 /* This way of doing it won't handle real
4074 numbers of large magnitudes. */
4075 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
4076 expr_tree = convert (tree_type,
4077 convert (integer_type_node,
4078 ffecom_3 (COND_EXPR, tree_type,
4079 ffecom_truth_value
4080 (ffecom_2 (GE_EXPR,
4081 integer_type_node,
4082 saved_expr1,
4083 ffecom_float_zero_)),
4084 ffecom_2 (PLUS_EXPR,
4085 tree_type,
4086 saved_expr1,
4087 ffecom_float_half_),
4088 ffecom_2 (MINUS_EXPR,
4089 tree_type,
4090 saved_expr1,
4091 ffecom_float_half_))));
4092 return expr_tree;
4093#else /* So we instead call floor. */
4094 /* r__1 = r1 >= 0 ? floor(r1 + .5) : -floor(.5 - r1) */
4095 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
4096 return
4097 convert (tree_type,
4098 ffecom_3 (COND_EXPR, double_type_node,
4099 ffecom_truth_value
4100 (ffecom_2 (GE_EXPR, integer_type_node,
4101 saved_expr1,
4102 convert (arg1_type,
4103 ffecom_float_zero_))),
4104 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
4105 build_tree_list (NULL_TREE,
4106 convert (double_type_node,
4107 ffecom_2 (PLUS_EXPR,
4108 arg1_type,
4109 saved_expr1,
4110 convert (arg1_type,
c7e4ee3a
CB
4111 ffecom_float_half_)))),
4112 NULL_TREE),
5ff904cd
JL
4113 ffecom_1 (NEGATE_EXPR, double_type_node,
4114 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
4115 build_tree_list (NULL_TREE,
4116 convert (double_type_node,
4117 ffecom_2 (MINUS_EXPR,
4118 arg1_type,
4119 convert (arg1_type,
4120 ffecom_float_half_),
c7e4ee3a
CB
4121 saved_expr1))),
4122 NULL_TREE))
5ff904cd
JL
4123 )
4124 );
4125#endif
4126
4127 case FFEINTRIN_impASIN:
4128 case FFEINTRIN_impDASIN:
4129 case FFEINTRIN_impATAN:
4130 case FFEINTRIN_impDATAN:
4131 case FFEINTRIN_impATAN2:
4132 case FFEINTRIN_impDATAN2:
4133 break;
4134
4135 case FFEINTRIN_impCHAR:
4136 case FFEINTRIN_impACHAR:
c7e4ee3a
CB
4137#ifdef HOHO
4138 tempvar = ffecom_make_tempvar (char_type_node, 1, -1);
4139#else
4140 tempvar = ffebld_nonter_hook (expr);
4141 assert (tempvar);
4142#endif
5ff904cd
JL
4143 {
4144 tree tmv = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (tempvar)));
4145
4146 expr_tree = ffecom_modify (tmv,
4147 ffecom_2 (ARRAY_REF, tmv, tempvar,
4148 integer_one_node),
4149 convert (tmv, ffecom_expr (arg1)));
4150 }
4151 expr_tree = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar),
4152 expr_tree,
4153 tempvar);
4154 expr_tree = ffecom_1 (ADDR_EXPR,
4155 build_pointer_type (TREE_TYPE (expr_tree)),
4156 expr_tree);
4157 return expr_tree;
4158
4159 case FFEINTRIN_impCMPLX:
4160 case FFEINTRIN_impDCMPLX:
4161 if (arg2 == NULL)
4162 return
4163 convert (tree_type, ffecom_expr (arg1));
4164
4165 real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
4166 return
4167 ffecom_2 (COMPLEX_EXPR, tree_type,
4168 convert (real_type, ffecom_expr (arg1)),
4169 convert (real_type,
4170 ffecom_expr (arg2)));
4171
4172 case FFEINTRIN_impCOMPLEX:
4173 return
4174 ffecom_2 (COMPLEX_EXPR, tree_type,
4175 ffecom_expr (arg1),
4176 ffecom_expr (arg2));
4177
4178 case FFEINTRIN_impCONJG:
4179 case FFEINTRIN_impDCONJG:
4180 {
4181 tree arg1_tree;
4182
4183 real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
4184 arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4185 return
4186 ffecom_2 (COMPLEX_EXPR, tree_type,
4187 ffecom_1 (REALPART_EXPR, real_type, arg1_tree),
4188 ffecom_1 (NEGATE_EXPR, real_type,
4189 ffecom_1 (IMAGPART_EXPR, real_type, arg1_tree)));
4190 }
4191
4192 case FFEINTRIN_impCOS:
4193 case FFEINTRIN_impCCOS:
4194 case FFEINTRIN_impCDCOS:
4195 case FFEINTRIN_impDCOS:
4196 if (bt == FFEINFO_basictypeCOMPLEX)
4197 {
4198 if (kt == FFEINFO_kindtypeREAL1)
4199 gfrt = FFECOM_gfrtCCOS; /* Overlapping result okay. */
4200 else if (kt == FFEINFO_kindtypeREAL2)
4201 gfrt = FFECOM_gfrtCDCOS; /* Overlapping result okay. */
4202 }
4203 break;
4204
4205 case FFEINTRIN_impCOSH:
4206 case FFEINTRIN_impDCOSH:
4207 break;
4208
4209 case FFEINTRIN_impDBLE:
4210 case FFEINTRIN_impDFLOAT:
4211 case FFEINTRIN_impDREAL:
4212 case FFEINTRIN_impFLOAT:
4213 case FFEINTRIN_impIDINT:
4214 case FFEINTRIN_impIFIX:
4215 case FFEINTRIN_impINT2:
4216 case FFEINTRIN_impINT8:
4217 case FFEINTRIN_impINT:
4218 case FFEINTRIN_impLONG:
4219 case FFEINTRIN_impREAL:
4220 case FFEINTRIN_impSHORT:
4221 case FFEINTRIN_impSNGL:
4222 return convert (tree_type, ffecom_expr (arg1));
4223
4224 case FFEINTRIN_impDIM:
4225 case FFEINTRIN_impDDIM:
4226 case FFEINTRIN_impIDIM:
4227 saved_expr1 = ffecom_save_tree (convert (tree_type,
4228 ffecom_expr (arg1)));
4229 saved_expr2 = ffecom_save_tree (convert (tree_type,
4230 ffecom_expr (arg2)));
4231 return
4232 ffecom_3 (COND_EXPR, tree_type,
4233 ffecom_truth_value
4234 (ffecom_2 (GT_EXPR, integer_type_node,
4235 saved_expr1,
4236 saved_expr2)),
4237 ffecom_2 (MINUS_EXPR, tree_type,
4238 saved_expr1,
4239 saved_expr2),
4240 convert (tree_type, ffecom_float_zero_));
4241
4242 case FFEINTRIN_impDPROD:
4243 return
4244 ffecom_2 (MULT_EXPR, tree_type,
4245 convert (tree_type, ffecom_expr (arg1)),
4246 convert (tree_type, ffecom_expr (arg2)));
4247
4248 case FFEINTRIN_impEXP:
4249 case FFEINTRIN_impCDEXP:
4250 case FFEINTRIN_impCEXP:
4251 case FFEINTRIN_impDEXP:
4252 if (bt == FFEINFO_basictypeCOMPLEX)
4253 {
4254 if (kt == FFEINFO_kindtypeREAL1)
4255 gfrt = FFECOM_gfrtCEXP; /* Overlapping result okay. */
4256 else if (kt == FFEINFO_kindtypeREAL2)
4257 gfrt = FFECOM_gfrtCDEXP; /* Overlapping result okay. */
4258 }
4259 break;
4260
4261 case FFEINTRIN_impICHAR:
4262 case FFEINTRIN_impIACHAR:
4263#if 0 /* The simple approach. */
4264 ffecom_char_args_ (&expr_tree, &saved_expr1 /* Ignored */ , arg1);
4265 expr_tree
4266 = ffecom_1 (INDIRECT_REF,
4267 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
4268 expr_tree);
4269 expr_tree
4270 = ffecom_2 (ARRAY_REF,
4271 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
4272 expr_tree,
4273 integer_one_node);
4274 return convert (tree_type, expr_tree);
4275#else /* The more interesting (and more optimal) approach. */
4276 expr_tree = ffecom_intrinsic_ichar_ (tree_type, arg1, &saved_expr1);
4277 expr_tree = ffecom_3 (COND_EXPR, tree_type,
4278 saved_expr1,
4279 expr_tree,
4280 convert (tree_type, integer_zero_node));
4281 return expr_tree;
4282#endif
4283
4284 case FFEINTRIN_impINDEX:
4285 break;
4286
4287 case FFEINTRIN_impLEN:
4288#if 0
4289 break; /* The simple approach. */
4290#else
4291 return ffecom_intrinsic_len_ (arg1); /* The more optimal approach. */
4292#endif
4293
4294 case FFEINTRIN_impLGE:
4295 case FFEINTRIN_impLGT:
4296 case FFEINTRIN_impLLE:
4297 case FFEINTRIN_impLLT:
4298 break;
4299
4300 case FFEINTRIN_impLOG:
4301 case FFEINTRIN_impALOG:
4302 case FFEINTRIN_impCDLOG:
4303 case FFEINTRIN_impCLOG:
4304 case FFEINTRIN_impDLOG:
4305 if (bt == FFEINFO_basictypeCOMPLEX)
4306 {
4307 if (kt == FFEINFO_kindtypeREAL1)
4308 gfrt = FFECOM_gfrtCLOG; /* Overlapping result okay. */
4309 else if (kt == FFEINFO_kindtypeREAL2)
4310 gfrt = FFECOM_gfrtCDLOG; /* Overlapping result okay. */
4311 }
4312 break;
4313
4314 case FFEINTRIN_impLOG10:
4315 case FFEINTRIN_impALOG10:
4316 case FFEINTRIN_impDLOG10:
4317 if (gfrt != FFECOM_gfrt)
4318 break; /* Already picked one, stick with it. */
4319
4320 if (kt == FFEINFO_kindtypeREAL1)
4321 gfrt = FFECOM_gfrtALOG10;
4322 else if (kt == FFEINFO_kindtypeREAL2)
4323 gfrt = FFECOM_gfrtDLOG10;
4324 break;
4325
4326 case FFEINTRIN_impMAX:
4327 case FFEINTRIN_impAMAX0:
4328 case FFEINTRIN_impAMAX1:
4329 case FFEINTRIN_impDMAX1:
4330 case FFEINTRIN_impMAX0:
4331 case FFEINTRIN_impMAX1:
4332 if (bt != ffeinfo_basictype (ffebld_info (arg1)))
4333 arg1_type = ffecom_widest_expr_type_ (ffebld_right (expr));
4334 else
4335 arg1_type = tree_type;
4336 expr_tree = ffecom_2 (MAX_EXPR, arg1_type,
4337 convert (arg1_type, ffecom_expr (arg1)),
4338 convert (arg1_type, ffecom_expr (arg2)));
4339 for (; list != NULL; list = ffebld_trail (list))
4340 {
4341 if ((ffebld_head (list) == NULL)
4342 || (ffebld_op (ffebld_head (list)) == FFEBLD_opANY))
4343 continue;
4344 expr_tree = ffecom_2 (MAX_EXPR, arg1_type,
4345 expr_tree,
4346 convert (arg1_type,
4347 ffecom_expr (ffebld_head (list))));
4348 }
4349 return convert (tree_type, expr_tree);
4350
4351 case FFEINTRIN_impMIN:
4352 case FFEINTRIN_impAMIN0:
4353 case FFEINTRIN_impAMIN1:
4354 case FFEINTRIN_impDMIN1:
4355 case FFEINTRIN_impMIN0:
4356 case FFEINTRIN_impMIN1:
4357 if (bt != ffeinfo_basictype (ffebld_info (arg1)))
4358 arg1_type = ffecom_widest_expr_type_ (ffebld_right (expr));
4359 else
4360 arg1_type = tree_type;
4361 expr_tree = ffecom_2 (MIN_EXPR, arg1_type,
4362 convert (arg1_type, ffecom_expr (arg1)),
4363 convert (arg1_type, ffecom_expr (arg2)));
4364 for (; list != NULL; list = ffebld_trail (list))
4365 {
4366 if ((ffebld_head (list) == NULL)
4367 || (ffebld_op (ffebld_head (list)) == FFEBLD_opANY))
4368 continue;
4369 expr_tree = ffecom_2 (MIN_EXPR, arg1_type,
4370 expr_tree,
4371 convert (arg1_type,
4372 ffecom_expr (ffebld_head (list))));
4373 }
4374 return convert (tree_type, expr_tree);
4375
4376 case FFEINTRIN_impMOD:
4377 case FFEINTRIN_impAMOD:
4378 case FFEINTRIN_impDMOD:
4379 if (bt != FFEINFO_basictypeREAL)
4380 return ffecom_2 (TRUNC_MOD_EXPR, tree_type,
4381 convert (tree_type, ffecom_expr (arg1)),
4382 convert (tree_type, ffecom_expr (arg2)));
4383
4384 if (kt == FFEINFO_kindtypeREAL1)
4385 gfrt = FFECOM_gfrtAMOD;
4386 else if (kt == FFEINFO_kindtypeREAL2)
4387 gfrt = FFECOM_gfrtDMOD;
4388 break;
4389
4390 case FFEINTRIN_impNINT:
4391 case FFEINTRIN_impIDNINT:
c7e4ee3a
CB
4392#if 0
4393 /* ~~Ideally FIX_ROUND_EXPR would be implemented, but it ain't yet. */
5ff904cd
JL
4394 return ffecom_1 (FIX_ROUND_EXPR, tree_type, ffecom_expr (arg1));
4395#else
4396 /* i__1 = r1 >= 0 ? floor(r1 + .5) : -floor(.5 - r1); */
4397 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
4398 return
4399 convert (ffecom_integer_type_node,
4400 ffecom_3 (COND_EXPR, arg1_type,
4401 ffecom_truth_value
4402 (ffecom_2 (GE_EXPR, integer_type_node,
4403 saved_expr1,
4404 convert (arg1_type,
4405 ffecom_float_zero_))),
4406 ffecom_2 (PLUS_EXPR, arg1_type,
4407 saved_expr1,
4408 convert (arg1_type,
4409 ffecom_float_half_)),
4410 ffecom_2 (MINUS_EXPR, arg1_type,
4411 saved_expr1,
4412 convert (arg1_type,
4413 ffecom_float_half_))));
4414#endif
4415
4416 case FFEINTRIN_impSIGN:
4417 case FFEINTRIN_impDSIGN:
4418 case FFEINTRIN_impISIGN:
4419 {
4420 tree arg2_tree = ffecom_expr (arg2);
4421
4422 saved_expr1
4423 = ffecom_save_tree
4424 (ffecom_1 (ABS_EXPR, tree_type,
4425 convert (tree_type,
4426 ffecom_expr (arg1))));
4427 expr_tree
4428 = ffecom_3 (COND_EXPR, tree_type,
4429 ffecom_truth_value
4430 (ffecom_2 (GE_EXPR, integer_type_node,
4431 arg2_tree,
4432 convert (TREE_TYPE (arg2_tree),
4433 integer_zero_node))),
4434 saved_expr1,
4435 ffecom_1 (NEGATE_EXPR, tree_type, saved_expr1));
4436 /* Make sure SAVE_EXPRs get referenced early enough. */
4437 expr_tree
4438 = ffecom_2 (COMPOUND_EXPR, tree_type,
4439 convert (void_type_node, saved_expr1),
4440 expr_tree);
4441 }
4442 return expr_tree;
4443
4444 case FFEINTRIN_impSIN:
4445 case FFEINTRIN_impCDSIN:
4446 case FFEINTRIN_impCSIN:
4447 case FFEINTRIN_impDSIN:
4448 if (bt == FFEINFO_basictypeCOMPLEX)
4449 {
4450 if (kt == FFEINFO_kindtypeREAL1)
4451 gfrt = FFECOM_gfrtCSIN; /* Overlapping result okay. */
4452 else if (kt == FFEINFO_kindtypeREAL2)
4453 gfrt = FFECOM_gfrtCDSIN; /* Overlapping result okay. */
4454 }
4455 break;
4456
4457 case FFEINTRIN_impSINH:
4458 case FFEINTRIN_impDSINH:
4459 break;
4460
4461 case FFEINTRIN_impSQRT:
4462 case FFEINTRIN_impCDSQRT:
4463 case FFEINTRIN_impCSQRT:
4464 case FFEINTRIN_impDSQRT:
4465 if (bt == FFEINFO_basictypeCOMPLEX)
4466 {
4467 if (kt == FFEINFO_kindtypeREAL1)
4468 gfrt = FFECOM_gfrtCSQRT; /* Overlapping result okay. */
4469 else if (kt == FFEINFO_kindtypeREAL2)
4470 gfrt = FFECOM_gfrtCDSQRT; /* Overlapping result okay. */
4471 }
4472 break;
4473
4474 case FFEINTRIN_impTAN:
4475 case FFEINTRIN_impDTAN:
4476 case FFEINTRIN_impTANH:
4477 case FFEINTRIN_impDTANH:
4478 break;
4479
4480 case FFEINTRIN_impREALPART:
4481 if (TREE_CODE (arg1_type) == COMPLEX_TYPE)
4482 arg1_type = TREE_TYPE (arg1_type);
4483 else
4484 arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type));
4485
4486 return
4487 convert (tree_type,
4488 ffecom_1 (REALPART_EXPR, arg1_type,
4489 ffecom_expr (arg1)));
4490
4491 case FFEINTRIN_impIAND:
4492 case FFEINTRIN_impAND:
4493 return ffecom_2 (BIT_AND_EXPR, tree_type,
4494 convert (tree_type,
4495 ffecom_expr (arg1)),
4496 convert (tree_type,
4497 ffecom_expr (arg2)));
4498
4499 case FFEINTRIN_impIOR:
4500 case FFEINTRIN_impOR:
4501 return ffecom_2 (BIT_IOR_EXPR, tree_type,
4502 convert (tree_type,
4503 ffecom_expr (arg1)),
4504 convert (tree_type,
4505 ffecom_expr (arg2)));
4506
4507 case FFEINTRIN_impIEOR:
4508 case FFEINTRIN_impXOR:
4509 return ffecom_2 (BIT_XOR_EXPR, tree_type,
4510 convert (tree_type,
4511 ffecom_expr (arg1)),
4512 convert (tree_type,
4513 ffecom_expr (arg2)));
4514
4515 case FFEINTRIN_impLSHIFT:
4516 return ffecom_2 (LSHIFT_EXPR, tree_type,
4517 ffecom_expr (arg1),
4518 convert (integer_type_node,
4519 ffecom_expr (arg2)));
4520
4521 case FFEINTRIN_impRSHIFT:
4522 return ffecom_2 (RSHIFT_EXPR, tree_type,
4523 ffecom_expr (arg1),
4524 convert (integer_type_node,
4525 ffecom_expr (arg2)));
4526
4527 case FFEINTRIN_impNOT:
4528 return ffecom_1 (BIT_NOT_EXPR, tree_type, ffecom_expr (arg1));
4529
4530 case FFEINTRIN_impBIT_SIZE:
4531 return convert (tree_type, TYPE_SIZE (arg1_type));
4532
4533 case FFEINTRIN_impBTEST:
4534 {
4535 ffetargetLogical1 true;
4536 ffetargetLogical1 false;
4537 tree true_tree;
4538 tree false_tree;
4539
4540 ffetarget_logical1 (&true, TRUE);
4541 ffetarget_logical1 (&false, FALSE);
4542 if (true == 1)
4543 true_tree = convert (tree_type, integer_one_node);
4544 else
4545 true_tree = convert (tree_type, build_int_2 (true, 0));
4546 if (false == 0)
4547 false_tree = convert (tree_type, integer_zero_node);
4548 else
4549 false_tree = convert (tree_type, build_int_2 (false, 0));
4550
4551 return
4552 ffecom_3 (COND_EXPR, tree_type,
4553 ffecom_truth_value
4554 (ffecom_2 (EQ_EXPR, integer_type_node,
4555 ffecom_2 (BIT_AND_EXPR, arg1_type,
4556 ffecom_expr (arg1),
4557 ffecom_2 (LSHIFT_EXPR, arg1_type,
4558 convert (arg1_type,
4559 integer_one_node),
4560 convert (integer_type_node,
4561 ffecom_expr (arg2)))),
4562 convert (arg1_type,
4563 integer_zero_node))),
4564 false_tree,
4565 true_tree);
4566 }
4567
4568 case FFEINTRIN_impIBCLR:
4569 return
4570 ffecom_2 (BIT_AND_EXPR, tree_type,
4571 ffecom_expr (arg1),
4572 ffecom_1 (BIT_NOT_EXPR, tree_type,
4573 ffecom_2 (LSHIFT_EXPR, tree_type,
4574 convert (tree_type,
4575 integer_one_node),
4576 convert (integer_type_node,
4577 ffecom_expr (arg2)))));
4578
4579 case FFEINTRIN_impIBITS:
4580 {
4581 tree arg3_tree = ffecom_save_tree (convert (integer_type_node,
4582 ffecom_expr (arg3)));
4583 tree uns_type
4584 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4585
4586 expr_tree
4587 = ffecom_2 (BIT_AND_EXPR, tree_type,
4588 ffecom_2 (RSHIFT_EXPR, tree_type,
4589 ffecom_expr (arg1),
4590 convert (integer_type_node,
4591 ffecom_expr (arg2))),
4592 convert (tree_type,
4593 ffecom_2 (RSHIFT_EXPR, uns_type,
4594 ffecom_1 (BIT_NOT_EXPR,
4595 uns_type,
4596 convert (uns_type,
4597 integer_zero_node)),
4598 ffecom_2 (MINUS_EXPR,
4599 integer_type_node,
4600 TYPE_SIZE (uns_type),
4601 arg3_tree))));
4602#if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4603 expr_tree
4604 = ffecom_3 (COND_EXPR, tree_type,
4605 ffecom_truth_value
4606 (ffecom_2 (NE_EXPR, integer_type_node,
4607 arg3_tree,
4608 integer_zero_node)),
4609 expr_tree,
4610 convert (tree_type, integer_zero_node));
4611#endif
4612 }
4613 return expr_tree;
4614
4615 case FFEINTRIN_impIBSET:
4616 return
4617 ffecom_2 (BIT_IOR_EXPR, tree_type,
4618 ffecom_expr (arg1),
4619 ffecom_2 (LSHIFT_EXPR, tree_type,
4620 convert (tree_type, integer_one_node),
4621 convert (integer_type_node,
4622 ffecom_expr (arg2))));
4623
4624 case FFEINTRIN_impISHFT:
4625 {
4626 tree arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4627 tree arg2_tree = ffecom_save_tree (convert (integer_type_node,
4628 ffecom_expr (arg2)));
4629 tree uns_type
4630 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4631
4632 expr_tree
4633 = ffecom_3 (COND_EXPR, tree_type,
4634 ffecom_truth_value
4635 (ffecom_2 (GE_EXPR, integer_type_node,
4636 arg2_tree,
4637 integer_zero_node)),
4638 ffecom_2 (LSHIFT_EXPR, tree_type,
4639 arg1_tree,
4640 arg2_tree),
4641 convert (tree_type,
4642 ffecom_2 (RSHIFT_EXPR, uns_type,
4643 convert (uns_type, arg1_tree),
4644 ffecom_1 (NEGATE_EXPR,
4645 integer_type_node,
4646 arg2_tree))));
4647#if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4648 expr_tree
4649 = ffecom_3 (COND_EXPR, tree_type,
4650 ffecom_truth_value
4651 (ffecom_2 (NE_EXPR, integer_type_node,
4652 arg2_tree,
4653 TYPE_SIZE (uns_type))),
4654 expr_tree,
4655 convert (tree_type, integer_zero_node));
4656#endif
4657 /* Make sure SAVE_EXPRs get referenced early enough. */
4658 expr_tree
4659 = ffecom_2 (COMPOUND_EXPR, tree_type,
4660 convert (void_type_node, arg1_tree),
4661 ffecom_2 (COMPOUND_EXPR, tree_type,
4662 convert (void_type_node, arg2_tree),
4663 expr_tree));
4664 }
4665 return expr_tree;
4666
4667 case FFEINTRIN_impISHFTC:
4668 {
4669 tree arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4670 tree arg2_tree = ffecom_save_tree (convert (integer_type_node,
4671 ffecom_expr (arg2)));
4672 tree arg3_tree = (arg3 == NULL) ? TYPE_SIZE (tree_type)
4673 : ffecom_save_tree (convert (integer_type_node, ffecom_expr (arg3)));
4674 tree shift_neg;
4675 tree shift_pos;
4676 tree mask_arg1;
4677 tree masked_arg1;
4678 tree uns_type
4679 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4680
4681 mask_arg1
4682 = ffecom_2 (LSHIFT_EXPR, tree_type,
4683 ffecom_1 (BIT_NOT_EXPR, tree_type,
4684 convert (tree_type, integer_zero_node)),
4685 arg3_tree);
4686#if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4687 mask_arg1
4688 = ffecom_3 (COND_EXPR, tree_type,
4689 ffecom_truth_value
4690 (ffecom_2 (NE_EXPR, integer_type_node,
4691 arg3_tree,
4692 TYPE_SIZE (uns_type))),
4693 mask_arg1,
4694 convert (tree_type, integer_zero_node));
4695#endif
4696 mask_arg1 = ffecom_save_tree (mask_arg1);
4697 masked_arg1
4698 = ffecom_2 (BIT_AND_EXPR, tree_type,
4699 arg1_tree,
4700 ffecom_1 (BIT_NOT_EXPR, tree_type,
4701 mask_arg1));
4702 masked_arg1 = ffecom_save_tree (masked_arg1);
4703 shift_neg
4704 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4705 convert (tree_type,
4706 ffecom_2 (RSHIFT_EXPR, uns_type,
4707 convert (uns_type, masked_arg1),
4708 ffecom_1 (NEGATE_EXPR,
4709 integer_type_node,
4710 arg2_tree))),
4711 ffecom_2 (LSHIFT_EXPR, tree_type,
4712 arg1_tree,
4713 ffecom_2 (PLUS_EXPR, integer_type_node,
4714 arg2_tree,
4715 arg3_tree)));
4716 shift_pos
4717 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4718 ffecom_2 (LSHIFT_EXPR, tree_type,
4719 arg1_tree,
4720 arg2_tree),
4721 convert (tree_type,
4722 ffecom_2 (RSHIFT_EXPR, uns_type,
4723 convert (uns_type, masked_arg1),
4724 ffecom_2 (MINUS_EXPR,
4725 integer_type_node,
4726 arg3_tree,
4727 arg2_tree))));
4728 expr_tree
4729 = ffecom_3 (COND_EXPR, tree_type,
4730 ffecom_truth_value
4731 (ffecom_2 (LT_EXPR, integer_type_node,
4732 arg2_tree,
4733 integer_zero_node)),
4734 shift_neg,
4735 shift_pos);
4736 expr_tree
4737 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4738 ffecom_2 (BIT_AND_EXPR, tree_type,
4739 mask_arg1,
4740 arg1_tree),
4741 ffecom_2 (BIT_AND_EXPR, tree_type,
4742 ffecom_1 (BIT_NOT_EXPR, tree_type,
4743 mask_arg1),
4744 expr_tree));
4745 expr_tree
4746 = ffecom_3 (COND_EXPR, tree_type,
4747 ffecom_truth_value
4748 (ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
4749 ffecom_2 (EQ_EXPR, integer_type_node,
4750 ffecom_1 (ABS_EXPR,
4751 integer_type_node,
4752 arg2_tree),
4753 arg3_tree),
4754 ffecom_2 (EQ_EXPR, integer_type_node,
4755 arg2_tree,
4756 integer_zero_node))),
4757 arg1_tree,
4758 expr_tree);
4759 /* Make sure SAVE_EXPRs get referenced early enough. */
4760 expr_tree
4761 = ffecom_2 (COMPOUND_EXPR, tree_type,
4762 convert (void_type_node, arg1_tree),
4763 ffecom_2 (COMPOUND_EXPR, tree_type,
4764 convert (void_type_node, arg2_tree),
4765 ffecom_2 (COMPOUND_EXPR, tree_type,
4766 convert (void_type_node,
4767 mask_arg1),
4768 ffecom_2 (COMPOUND_EXPR, tree_type,
4769 convert (void_type_node,
4770 masked_arg1),
4771 expr_tree))));
4772 expr_tree
4773 = ffecom_2 (COMPOUND_EXPR, tree_type,
4774 convert (void_type_node,
4775 arg3_tree),
4776 expr_tree);
4777 }
4778 return expr_tree;
4779
4780 case FFEINTRIN_impLOC:
4781 {
4782 tree arg1_tree = ffecom_expr (arg1);
4783
4784 expr_tree
4785 = convert (tree_type,
4786 ffecom_1 (ADDR_EXPR,
4787 build_pointer_type (TREE_TYPE (arg1_tree)),
4788 arg1_tree));
4789 }
4790 return expr_tree;
4791
4792 case FFEINTRIN_impMVBITS:
4793 {
4794 tree arg1_tree;
4795 tree arg2_tree;
4796 tree arg3_tree;
4797 ffebld arg4 = ffebld_head (ffebld_trail (list));
4798 tree arg4_tree;
4799 tree arg4_type;
4800 ffebld arg5 = ffebld_head (ffebld_trail (ffebld_trail (list)));
4801 tree arg5_tree;
4802 tree prep_arg1;
4803 tree prep_arg4;
4804 tree arg5_plus_arg3;
4805
5ff904cd
JL
4806 arg2_tree = convert (integer_type_node,
4807 ffecom_expr (arg2));
4808 arg3_tree = ffecom_save_tree (convert (integer_type_node,
4809 ffecom_expr (arg3)));
c7e4ee3a 4810 arg4_tree = ffecom_expr_rw (NULL_TREE, arg4);
5ff904cd
JL
4811 arg4_type = TREE_TYPE (arg4_tree);
4812
4813 arg1_tree = ffecom_save_tree (convert (arg4_type,
4814 ffecom_expr (arg1)));
4815
4816 arg5_tree = ffecom_save_tree (convert (integer_type_node,
4817 ffecom_expr (arg5)));
4818
5ff904cd
JL
4819 prep_arg1
4820 = ffecom_2 (LSHIFT_EXPR, arg4_type,
4821 ffecom_2 (BIT_AND_EXPR, arg4_type,
4822 ffecom_2 (RSHIFT_EXPR, arg4_type,
4823 arg1_tree,
4824 arg2_tree),
4825 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4826 ffecom_2 (LSHIFT_EXPR, arg4_type,
4827 ffecom_1 (BIT_NOT_EXPR,
4828 arg4_type,
4829 convert
4830 (arg4_type,
4831 integer_zero_node)),
4832 arg3_tree))),
4833 arg5_tree);
4834 arg5_plus_arg3
4835 = ffecom_save_tree (ffecom_2 (PLUS_EXPR, arg4_type,
4836 arg5_tree,
4837 arg3_tree));
4838 prep_arg4
4839 = ffecom_2 (LSHIFT_EXPR, arg4_type,
4840 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4841 convert (arg4_type,
4842 integer_zero_node)),
4843 arg5_plus_arg3);
4844#if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4845 prep_arg4
4846 = ffecom_3 (COND_EXPR, arg4_type,
4847 ffecom_truth_value
4848 (ffecom_2 (NE_EXPR, integer_type_node,
4849 arg5_plus_arg3,
4850 convert (TREE_TYPE (arg5_plus_arg3),
4851 TYPE_SIZE (arg4_type)))),
4852 prep_arg4,
4853 convert (arg4_type, integer_zero_node));
4854#endif
4855 prep_arg4
4856 = ffecom_2 (BIT_AND_EXPR, arg4_type,
4857 arg4_tree,
4858 ffecom_2 (BIT_IOR_EXPR, arg4_type,
4859 prep_arg4,
4860 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4861 ffecom_2 (LSHIFT_EXPR, arg4_type,
4862 ffecom_1 (BIT_NOT_EXPR,
4863 arg4_type,
4864 convert
4865 (arg4_type,
4866 integer_zero_node)),
4867 arg5_tree))));
4868 prep_arg1
4869 = ffecom_2 (BIT_IOR_EXPR, arg4_type,
4870 prep_arg1,
4871 prep_arg4);
4872#if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4873 prep_arg1
4874 = ffecom_3 (COND_EXPR, arg4_type,
4875 ffecom_truth_value
4876 (ffecom_2 (NE_EXPR, integer_type_node,
4877 arg3_tree,
4878 convert (TREE_TYPE (arg3_tree),
4879 integer_zero_node))),
4880 prep_arg1,
4881 arg4_tree);
4882 prep_arg1
4883 = ffecom_3 (COND_EXPR, arg4_type,
4884 ffecom_truth_value
4885 (ffecom_2 (NE_EXPR, integer_type_node,
4886 arg3_tree,
4887 convert (TREE_TYPE (arg3_tree),
4888 TYPE_SIZE (arg4_type)))),
4889 prep_arg1,
4890 arg1_tree);
4891#endif
4892 expr_tree
4893 = ffecom_2s (MODIFY_EXPR, void_type_node,
4894 arg4_tree,
4895 prep_arg1);
4896 /* Make sure SAVE_EXPRs get referenced early enough. */
4897 expr_tree
4898 = ffecom_2 (COMPOUND_EXPR, void_type_node,
4899 arg1_tree,
4900 ffecom_2 (COMPOUND_EXPR, void_type_node,
4901 arg3_tree,
4902 ffecom_2 (COMPOUND_EXPR, void_type_node,
4903 arg5_tree,
4904 ffecom_2 (COMPOUND_EXPR, void_type_node,
4905 arg5_plus_arg3,
4906 expr_tree))));
4907 expr_tree
4908 = ffecom_2 (COMPOUND_EXPR, void_type_node,
4909 arg4_tree,
4910 expr_tree);
4911
4912 }
4913 return expr_tree;
4914
4915 case FFEINTRIN_impDERF:
4916 case FFEINTRIN_impERF:
4917 case FFEINTRIN_impDERFC:
4918 case FFEINTRIN_impERFC:
4919 break;
4920
4921 case FFEINTRIN_impIARGC:
4922 /* extern int xargc; i__1 = xargc - 1; */
4923 expr_tree = ffecom_2 (MINUS_EXPR, TREE_TYPE (ffecom_tree_xargc_),
4924 ffecom_tree_xargc_,
4925 convert (TREE_TYPE (ffecom_tree_xargc_),
4926 integer_one_node));
4927 return expr_tree;
4928
4929 case FFEINTRIN_impSIGNAL_func:
4930 case FFEINTRIN_impSIGNAL_subr:
4931 {
4932 tree arg1_tree;
4933 tree arg2_tree;
4934 tree arg3_tree;
4935
5ff904cd
JL
4936 arg1_tree = convert (ffecom_f2c_integer_type_node,
4937 ffecom_expr (arg1));
4938 arg1_tree = ffecom_1 (ADDR_EXPR,
4939 build_pointer_type (TREE_TYPE (arg1_tree)),
4940 arg1_tree);
4941
4942 /* Pass procedure as a pointer to it, anything else by value. */
4943 if (ffeinfo_kind (ffebld_info (arg2)) == FFEINFO_kindENTITY)
4944 arg2_tree = convert (integer_type_node, ffecom_expr (arg2));
4945 else
4946 arg2_tree = ffecom_ptr_to_expr (arg2);
4947 arg2_tree = convert (TREE_TYPE (null_pointer_node),
4948 arg2_tree);
4949
4950 if (arg3 != NULL)
c7e4ee3a 4951 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
4952 else
4953 arg3_tree = NULL_TREE;
4954
5ff904cd
JL
4955 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4956 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
4957 TREE_CHAIN (arg1_tree) = arg2_tree;
4958
4959 expr_tree
4960 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4961 ffecom_gfrt_kindtype (gfrt),
4962 FALSE,
4963 ((codegen_imp == FFEINTRIN_impSIGNAL_subr) ?
4964 NULL_TREE :
4965 tree_type),
4966 arg1_tree,
c7e4ee3a
CB
4967 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4968 ffebld_nonter_hook (expr));
5ff904cd
JL
4969
4970 if (arg3_tree != NULL_TREE)
4971 expr_tree
4972 = ffecom_modify (NULL_TREE, arg3_tree,
4973 convert (TREE_TYPE (arg3_tree),
4974 expr_tree));
4975 }
4976 return expr_tree;
4977
4978 case FFEINTRIN_impALARM:
4979 {
4980 tree arg1_tree;
4981 tree arg2_tree;
4982 tree arg3_tree;
4983
5ff904cd
JL
4984 arg1_tree = convert (ffecom_f2c_integer_type_node,
4985 ffecom_expr (arg1));
4986 arg1_tree = ffecom_1 (ADDR_EXPR,
4987 build_pointer_type (TREE_TYPE (arg1_tree)),
4988 arg1_tree);
4989
4990 /* Pass procedure as a pointer to it, anything else by value. */
4991 if (ffeinfo_kind (ffebld_info (arg2)) == FFEINFO_kindENTITY)
4992 arg2_tree = convert (integer_type_node, ffecom_expr (arg2));
4993 else
4994 arg2_tree = ffecom_ptr_to_expr (arg2);
4995 arg2_tree = convert (TREE_TYPE (null_pointer_node),
4996 arg2_tree);
4997
4998 if (arg3 != NULL)
c7e4ee3a 4999 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
5000 else
5001 arg3_tree = NULL_TREE;
5002
5ff904cd
JL
5003 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5004 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5005 TREE_CHAIN (arg1_tree) = arg2_tree;
5006
5007 expr_tree
5008 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5009 ffecom_gfrt_kindtype (gfrt),
5010 FALSE,
5011 NULL_TREE,
5012 arg1_tree,
c7e4ee3a
CB
5013 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5014 ffebld_nonter_hook (expr));
5ff904cd
JL
5015
5016 if (arg3_tree != NULL_TREE)
5017 expr_tree
5018 = ffecom_modify (NULL_TREE, arg3_tree,
5019 convert (TREE_TYPE (arg3_tree),
5020 expr_tree));
5021 }
5022 return expr_tree;
5023
5024 case FFEINTRIN_impCHDIR_subr:
5025 case FFEINTRIN_impFDATE_subr:
5026 case FFEINTRIN_impFGET_subr:
5027 case FFEINTRIN_impFPUT_subr:
5028 case FFEINTRIN_impGETCWD_subr:
5029 case FFEINTRIN_impHOSTNM_subr:
5030 case FFEINTRIN_impSYSTEM_subr:
5031 case FFEINTRIN_impUNLINK_subr:
5032 {
5033 tree arg1_len = integer_zero_node;
5034 tree arg1_tree;
5035 tree arg2_tree;
5036
5ff904cd
JL
5037 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
5038
5039 if (arg2 != NULL)
c7e4ee3a 5040 arg2_tree = ffecom_expr_w (NULL_TREE, arg2);
5ff904cd
JL
5041 else
5042 arg2_tree = NULL_TREE;
5043
5ff904cd
JL
5044 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5045 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5046 TREE_CHAIN (arg1_tree) = arg1_len;
5047
5048 expr_tree
5049 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5050 ffecom_gfrt_kindtype (gfrt),
5051 FALSE,
5052 NULL_TREE,
5053 arg1_tree,
c7e4ee3a
CB
5054 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5055 ffebld_nonter_hook (expr));
5ff904cd
JL
5056
5057 if (arg2_tree != NULL_TREE)
5058 expr_tree
5059 = ffecom_modify (NULL_TREE, arg2_tree,
5060 convert (TREE_TYPE (arg2_tree),
5061 expr_tree));
5062 }
5063 return expr_tree;
5064
5065 case FFEINTRIN_impEXIT:
5066 if (arg1 != NULL)
5067 break;
5068
5069 expr_tree = build_tree_list (NULL_TREE,
5070 ffecom_1 (ADDR_EXPR,
5071 build_pointer_type
5072 (ffecom_integer_type_node),
5073 integer_zero_node));
5074
5075 return
5076 ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5077 ffecom_gfrt_kindtype (gfrt),
5078 FALSE,
5079 void_type_node,
5080 expr_tree,
c7e4ee3a
CB
5081 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5082 ffebld_nonter_hook (expr));
5ff904cd
JL
5083
5084 case FFEINTRIN_impFLUSH:
5085 if (arg1 == NULL)
5086 gfrt = FFECOM_gfrtFLUSH;
5087 else
5088 gfrt = FFECOM_gfrtFLUSH1;
5089 break;
5090
5091 case FFEINTRIN_impCHMOD_subr:
5092 case FFEINTRIN_impLINK_subr:
5093 case FFEINTRIN_impRENAME_subr:
5094 case FFEINTRIN_impSYMLNK_subr:
5095 {
5096 tree arg1_len = integer_zero_node;
5097 tree arg1_tree;
5098 tree arg2_len = integer_zero_node;
5099 tree arg2_tree;
5100 tree arg3_tree;
5101
5ff904cd
JL
5102 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
5103 arg2_tree = ffecom_arg_ptr_to_expr (arg2, &arg2_len);
5104 if (arg3 != NULL)
c7e4ee3a 5105 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
5106 else
5107 arg3_tree = NULL_TREE;
5108
5ff904cd
JL
5109 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5110 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5111 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5112 arg2_len = build_tree_list (NULL_TREE, arg2_len);
5113 TREE_CHAIN (arg1_tree) = arg2_tree;
5114 TREE_CHAIN (arg2_tree) = arg1_len;
5115 TREE_CHAIN (arg1_len) = arg2_len;
5116 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5117 ffecom_gfrt_kindtype (gfrt),
5118 FALSE,
5119 NULL_TREE,
5120 arg1_tree,
c7e4ee3a
CB
5121 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5122 ffebld_nonter_hook (expr));
5ff904cd
JL
5123 if (arg3_tree != NULL_TREE)
5124 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5125 convert (TREE_TYPE (arg3_tree),
5126 expr_tree));
5127 }
5128 return expr_tree;
5129
5130 case FFEINTRIN_impLSTAT_subr:
5131 case FFEINTRIN_impSTAT_subr:
5132 {
5133 tree arg1_len = integer_zero_node;
5134 tree arg1_tree;
5135 tree arg2_tree;
5136 tree arg3_tree;
5137
5ff904cd
JL
5138 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
5139
5140 arg2_tree = ffecom_ptr_to_expr (arg2);
5141
5142 if (arg3 != NULL)
c7e4ee3a 5143 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
5144 else
5145 arg3_tree = NULL_TREE;
5146
5ff904cd
JL
5147 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5148 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5149 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5150 TREE_CHAIN (arg1_tree) = arg2_tree;
5151 TREE_CHAIN (arg2_tree) = arg1_len;
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 return expr_tree;
5165
5166 case FFEINTRIN_impFGETC_subr:
5167 case FFEINTRIN_impFPUTC_subr:
5168 {
5169 tree arg1_tree;
5170 tree arg2_tree;
5171 tree arg2_len = integer_zero_node;
5172 tree arg3_tree;
5173
5ff904cd
JL
5174 arg1_tree = convert (ffecom_f2c_integer_type_node,
5175 ffecom_expr (arg1));
5176 arg1_tree = ffecom_1 (ADDR_EXPR,
5177 build_pointer_type (TREE_TYPE (arg1_tree)),
5178 arg1_tree);
5179
5180 arg2_tree = ffecom_arg_ptr_to_expr (arg2, &arg2_len);
62b3b9db
TM
5181 if (arg3 != NULL)
5182 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5183 else
5184 arg3_tree = NULL_TREE;
5ff904cd
JL
5185
5186 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5187 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5188 arg2_len = build_tree_list (NULL_TREE, arg2_len);
5189 TREE_CHAIN (arg1_tree) = arg2_tree;
5190 TREE_CHAIN (arg2_tree) = arg2_len;
5191
5192 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5193 ffecom_gfrt_kindtype (gfrt),
5194 FALSE,
5195 NULL_TREE,
5196 arg1_tree,
c7e4ee3a
CB
5197 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5198 ffebld_nonter_hook (expr));
62b3b9db
TM
5199 if (arg3_tree != NULL_TREE)
5200 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5201 convert (TREE_TYPE (arg3_tree),
5202 expr_tree));
5ff904cd
JL
5203 }
5204 return expr_tree;
5205
5206 case FFEINTRIN_impFSTAT_subr:
5207 {
5208 tree arg1_tree;
5209 tree arg2_tree;
5210 tree arg3_tree;
5211
5ff904cd
JL
5212 arg1_tree = convert (ffecom_f2c_integer_type_node,
5213 ffecom_expr (arg1));
5214 arg1_tree = ffecom_1 (ADDR_EXPR,
5215 build_pointer_type (TREE_TYPE (arg1_tree)),
5216 arg1_tree);
5217
5218 arg2_tree = convert (ffecom_f2c_ptr_to_integer_type_node,
5219 ffecom_ptr_to_expr (arg2));
5220
5221 if (arg3 == NULL)
5222 arg3_tree = NULL_TREE;
5223 else
c7e4ee3a 5224 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
5225
5226 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5227 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5228 TREE_CHAIN (arg1_tree) = arg2_tree;
5229 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5230 ffecom_gfrt_kindtype (gfrt),
5231 FALSE,
5232 NULL_TREE,
5233 arg1_tree,
c7e4ee3a
CB
5234 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5235 ffebld_nonter_hook (expr));
5ff904cd
JL
5236 if (arg3_tree != NULL_TREE) {
5237 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5238 convert (TREE_TYPE (arg3_tree),
5239 expr_tree));
5240 }
5241 }
5242 return expr_tree;
5243
5244 case FFEINTRIN_impKILL_subr:
5245 {
5246 tree arg1_tree;
5247 tree arg2_tree;
5248 tree arg3_tree;
5249
5ff904cd
JL
5250 arg1_tree = convert (ffecom_f2c_integer_type_node,
5251 ffecom_expr (arg1));
5252 arg1_tree = ffecom_1 (ADDR_EXPR,
5253 build_pointer_type (TREE_TYPE (arg1_tree)),
5254 arg1_tree);
5255
5256 arg2_tree = convert (ffecom_f2c_integer_type_node,
5257 ffecom_expr (arg2));
5258 arg2_tree = ffecom_1 (ADDR_EXPR,
5259 build_pointer_type (TREE_TYPE (arg2_tree)),
5260 arg2_tree);
5261
5262 if (arg3 == NULL)
5263 arg3_tree = NULL_TREE;
5264 else
c7e4ee3a 5265 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
5266
5267 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5268 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5269 TREE_CHAIN (arg1_tree) = arg2_tree;
5270 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5271 ffecom_gfrt_kindtype (gfrt),
5272 FALSE,
5273 NULL_TREE,
5274 arg1_tree,
c7e4ee3a
CB
5275 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5276 ffebld_nonter_hook (expr));
5ff904cd
JL
5277 if (arg3_tree != NULL_TREE) {
5278 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5279 convert (TREE_TYPE (arg3_tree),
5280 expr_tree));
5281 }
5282 }
5283 return expr_tree;
5284
5285 case FFEINTRIN_impCTIME_subr:
5286 case FFEINTRIN_impTTYNAM_subr:
5287 {
5288 tree arg1_len = integer_zero_node;
5289 tree arg1_tree;
5290 tree arg2_tree;
5291
2b0bdd9a 5292 arg1_tree = ffecom_arg_ptr_to_expr (arg2, &arg1_len);
5ff904cd 5293
c56f65d6 5294 arg2_tree = convert (((codegen_imp == FFEINTRIN_impCTIME_subr) ?
5ff904cd
JL
5295 ffecom_f2c_longint_type_node :
5296 ffecom_f2c_integer_type_node),
2b0bdd9a 5297 ffecom_expr (arg1));
5ff904cd
JL
5298 arg2_tree = ffecom_1 (ADDR_EXPR,
5299 build_pointer_type (TREE_TYPE (arg2_tree)),
5300 arg2_tree);
5301
5ff904cd
JL
5302 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5303 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5304 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5305 TREE_CHAIN (arg1_len) = arg2_tree;
5306 TREE_CHAIN (arg1_tree) = arg1_len;
5307
5308 expr_tree
5309 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5310 ffecom_gfrt_kindtype (gfrt),
5311 FALSE,
5312 NULL_TREE,
5313 arg1_tree,
c7e4ee3a
CB
5314 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5315 ffebld_nonter_hook (expr));
2b0bdd9a 5316 TREE_SIDE_EFFECTS (expr_tree) = 1;
5ff904cd
JL
5317 }
5318 return expr_tree;
5319
5320 case FFEINTRIN_impIRAND:
5321 case FFEINTRIN_impRAND:
5322 /* Arg defaults to 0 (normal random case) */
5323 {
5324 tree arg1_tree;
5325
5326 if (arg1 == NULL)
5327 arg1_tree = ffecom_integer_zero_node;
5328 else
5329 arg1_tree = ffecom_expr (arg1);
5330 arg1_tree = convert (ffecom_f2c_integer_type_node,
5331 arg1_tree);
5332 arg1_tree = ffecom_1 (ADDR_EXPR,
5333 build_pointer_type (TREE_TYPE (arg1_tree)),
5334 arg1_tree);
5335 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5336
5337 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5338 ffecom_gfrt_kindtype (gfrt),
5339 FALSE,
5340 ((codegen_imp == FFEINTRIN_impIRAND) ?
5341 ffecom_f2c_integer_type_node :
de7f278a 5342 ffecom_f2c_real_type_node),
5ff904cd
JL
5343 arg1_tree,
5344 dest_tree, dest, dest_used,
c7e4ee3a
CB
5345 NULL_TREE, TRUE,
5346 ffebld_nonter_hook (expr));
5ff904cd
JL
5347 }
5348 return expr_tree;
5349
5350 case FFEINTRIN_impFTELL_subr:
5351 case FFEINTRIN_impUMASK_subr:
5352 {
5353 tree arg1_tree;
5354 tree arg2_tree;
5355
5ff904cd
JL
5356 arg1_tree = convert (ffecom_f2c_integer_type_node,
5357 ffecom_expr (arg1));
5358 arg1_tree = ffecom_1 (ADDR_EXPR,
5359 build_pointer_type (TREE_TYPE (arg1_tree)),
5360 arg1_tree);
5361
5362 if (arg2 == NULL)
5363 arg2_tree = NULL_TREE;
5364 else
c7e4ee3a 5365 arg2_tree = ffecom_expr_w (NULL_TREE, arg2);
5ff904cd
JL
5366
5367 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5368 ffecom_gfrt_kindtype (gfrt),
5369 FALSE,
5370 NULL_TREE,
5371 build_tree_list (NULL_TREE, arg1_tree),
5372 NULL_TREE, NULL, NULL, NULL_TREE,
c7e4ee3a
CB
5373 TRUE,
5374 ffebld_nonter_hook (expr));
5ff904cd
JL
5375 if (arg2_tree != NULL_TREE) {
5376 expr_tree = ffecom_modify (NULL_TREE, arg2_tree,
5377 convert (TREE_TYPE (arg2_tree),
5378 expr_tree));
5379 }
5380 }
5381 return expr_tree;
5382
5383 case FFEINTRIN_impCPU_TIME:
5384 case FFEINTRIN_impSECOND_subr:
5385 {
5386 tree arg1_tree;
5387
c7e4ee3a 5388 arg1_tree = ffecom_expr_w (NULL_TREE, arg1);
5ff904cd
JL
5389
5390 expr_tree
5391 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5392 ffecom_gfrt_kindtype (gfrt),
5393 FALSE,
5394 NULL_TREE,
5395 NULL_TREE,
c7e4ee3a
CB
5396 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5397 ffebld_nonter_hook (expr));
5ff904cd
JL
5398
5399 expr_tree
5400 = ffecom_modify (NULL_TREE, arg1_tree,
5401 convert (TREE_TYPE (arg1_tree),
5402 expr_tree));
5403 }
5404 return expr_tree;
5405
5406 case FFEINTRIN_impDTIME_subr:
5407 case FFEINTRIN_impETIME_subr:
5408 {
5409 tree arg1_tree;
2b0bdd9a 5410 tree result_tree;
5ff904cd 5411
2b0bdd9a 5412 result_tree = ffecom_expr_w (NULL_TREE, arg2);
5ff904cd 5413
2b0bdd9a 5414 arg1_tree = ffecom_ptr_to_expr (arg1);
5ff904cd 5415
5ff904cd
JL
5416 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5417 ffecom_gfrt_kindtype (gfrt),
5418 FALSE,
5419 NULL_TREE,
2b0bdd9a 5420 build_tree_list (NULL_TREE, arg1_tree),
5ff904cd 5421 NULL_TREE, NULL, NULL, NULL_TREE,
c7e4ee3a
CB
5422 TRUE,
5423 ffebld_nonter_hook (expr));
2b0bdd9a
CB
5424 expr_tree = ffecom_modify (NULL_TREE, result_tree,
5425 convert (TREE_TYPE (result_tree),
5ff904cd
JL
5426 expr_tree));
5427 }
5428 return expr_tree;
5429
c7e4ee3a 5430 /* Straightforward calls of libf2c routines: */
5ff904cd
JL
5431 case FFEINTRIN_impABORT:
5432 case FFEINTRIN_impACCESS:
5433 case FFEINTRIN_impBESJ0:
5434 case FFEINTRIN_impBESJ1:
5435 case FFEINTRIN_impBESJN:
5436 case FFEINTRIN_impBESY0:
5437 case FFEINTRIN_impBESY1:
5438 case FFEINTRIN_impBESYN:
5439 case FFEINTRIN_impCHDIR_func:
5440 case FFEINTRIN_impCHMOD_func:
5441 case FFEINTRIN_impDATE:
9e8e701d 5442 case FFEINTRIN_impDATE_AND_TIME:
5ff904cd
JL
5443 case FFEINTRIN_impDBESJ0:
5444 case FFEINTRIN_impDBESJ1:
5445 case FFEINTRIN_impDBESJN:
5446 case FFEINTRIN_impDBESY0:
5447 case FFEINTRIN_impDBESY1:
5448 case FFEINTRIN_impDBESYN:
5449 case FFEINTRIN_impDTIME_func:
5450 case FFEINTRIN_impETIME_func:
5451 case FFEINTRIN_impFGETC_func:
5452 case FFEINTRIN_impFGET_func:
5453 case FFEINTRIN_impFNUM:
5454 case FFEINTRIN_impFPUTC_func:
5455 case FFEINTRIN_impFPUT_func:
5456 case FFEINTRIN_impFSEEK:
5457 case FFEINTRIN_impFSTAT_func:
5458 case FFEINTRIN_impFTELL_func:
5459 case FFEINTRIN_impGERROR:
5460 case FFEINTRIN_impGETARG:
5461 case FFEINTRIN_impGETCWD_func:
5462 case FFEINTRIN_impGETENV:
5463 case FFEINTRIN_impGETGID:
5464 case FFEINTRIN_impGETLOG:
5465 case FFEINTRIN_impGETPID:
5466 case FFEINTRIN_impGETUID:
5467 case FFEINTRIN_impGMTIME:
5468 case FFEINTRIN_impHOSTNM_func:
5469 case FFEINTRIN_impIDATE_unix:
5470 case FFEINTRIN_impIDATE_vxt:
5471 case FFEINTRIN_impIERRNO:
5472 case FFEINTRIN_impISATTY:
5473 case FFEINTRIN_impITIME:
5474 case FFEINTRIN_impKILL_func:
5475 case FFEINTRIN_impLINK_func:
5476 case FFEINTRIN_impLNBLNK:
5477 case FFEINTRIN_impLSTAT_func:
5478 case FFEINTRIN_impLTIME:
5479 case FFEINTRIN_impMCLOCK8:
5480 case FFEINTRIN_impMCLOCK:
5481 case FFEINTRIN_impPERROR:
5482 case FFEINTRIN_impRENAME_func:
5483 case FFEINTRIN_impSECNDS:
5484 case FFEINTRIN_impSECOND_func:
5485 case FFEINTRIN_impSLEEP:
5486 case FFEINTRIN_impSRAND:
5487 case FFEINTRIN_impSTAT_func:
5488 case FFEINTRIN_impSYMLNK_func:
5489 case FFEINTRIN_impSYSTEM_CLOCK:
5490 case FFEINTRIN_impSYSTEM_func:
5491 case FFEINTRIN_impTIME8:
5492 case FFEINTRIN_impTIME_unix:
5493 case FFEINTRIN_impTIME_vxt:
5494 case FFEINTRIN_impUMASK_func:
5495 case FFEINTRIN_impUNLINK_func:
5496 break;
5497
5498 case FFEINTRIN_impCTIME_func: /* CHARACTER functions not handled here. */
5499 case FFEINTRIN_impFDATE_func: /* CHARACTER functions not handled here. */
5500 case FFEINTRIN_impTTYNAM_func: /* CHARACTER functions not handled here. */
5501 case FFEINTRIN_impNONE:
5502 case FFEINTRIN_imp: /* Hush up gcc warning. */
5503 fprintf (stderr, "No %s implementation.\n",
5504 ffeintrin_name_implementation (ffebld_symter_implementation (ffebld_left (expr))));
5505 assert ("unimplemented intrinsic" == NULL);
5506 return error_mark_node;
5507 }
5508
5509 assert (gfrt != FFECOM_gfrt); /* Must have an implementation! */
5510
5ff904cd
JL
5511 expr_tree = ffecom_arglist_expr_ (ffecom_gfrt_args_ (gfrt),
5512 ffebld_right (expr));
5ff904cd
JL
5513
5514 return ffecom_call_ (ffecom_gfrt_tree_ (gfrt), ffecom_gfrt_kindtype (gfrt),
5515 (ffe_is_f2c_library () && ffecom_gfrt_complex_[gfrt]),
5516 tree_type,
5517 expr_tree, dest_tree, dest, dest_used,
c7e4ee3a
CB
5518 NULL_TREE, TRUE,
5519 ffebld_nonter_hook (expr));
5ff904cd 5520
c7e4ee3a
CB
5521 /* See bottom of this file for f2c transforms used to determine
5522 many of the above implementations. The info seems to confuse
5523 Emacs's C mode indentation, which is why it's been moved to
5524 the bottom of this source file. */
5525}
5ff904cd 5526
c7e4ee3a
CB
5527#endif
5528/* For power (exponentiation) where right-hand operand is type INTEGER,
5529 generate in-line code to do it the fast way (which, if the operand
5530 is a constant, might just mean a series of multiplies). */
5ff904cd 5531
c7e4ee3a
CB
5532#if FFECOM_targetCURRENT == FFECOM_targetGCC
5533static tree
5534ffecom_expr_power_integer_ (ffebld expr)
5535{
5536 tree l = ffecom_expr (ffebld_left (expr));
5537 tree r = ffecom_expr (ffebld_right (expr));
5538 tree ltype = TREE_TYPE (l);
5539 tree rtype = TREE_TYPE (r);
5540 tree result = NULL_TREE;
5ff904cd 5541
c7e4ee3a
CB
5542 if (l == error_mark_node
5543 || r == error_mark_node)
5544 return error_mark_node;
5ff904cd 5545
c7e4ee3a
CB
5546 if (TREE_CODE (r) == INTEGER_CST)
5547 {
5548 int sgn = tree_int_cst_sgn (r);
5ff904cd 5549
c7e4ee3a
CB
5550 if (sgn == 0)
5551 return convert (ltype, integer_one_node);
5ff904cd 5552
c7e4ee3a
CB
5553 if ((TREE_CODE (ltype) == INTEGER_TYPE)
5554 && (sgn < 0))
5555 {
5556 /* Reciprocal of integer is either 0, -1, or 1, so after
5557 calculating that (which we leave to the back end to do
5558 or not do optimally), don't bother with any multiplying. */
5ff904cd 5559
c7e4ee3a
CB
5560 result = ffecom_tree_divide_ (ltype,
5561 convert (ltype, integer_one_node),
5562 l,
5563 NULL_TREE, NULL, NULL, NULL_TREE);
5564 r = ffecom_1 (NEGATE_EXPR,
5565 rtype,
5566 r);
5567 if ((TREE_INT_CST_LOW (r) & 1) == 0)
5568 result = ffecom_1 (ABS_EXPR, rtype,
5569 result);
5570 }
5ff904cd 5571
c7e4ee3a
CB
5572 /* Generate appropriate series of multiplies, preceded
5573 by divide if the exponent is negative. */
5ff904cd 5574
c7e4ee3a 5575 l = save_expr (l);
5ff904cd 5576
c7e4ee3a
CB
5577 if (sgn < 0)
5578 {
5579 l = ffecom_tree_divide_ (ltype,
5580 convert (ltype, integer_one_node),
5581 l,
5582 NULL_TREE, NULL, NULL,
5583 ffebld_nonter_hook (expr));
5584 r = ffecom_1 (NEGATE_EXPR, rtype, r);
5585 assert (TREE_CODE (r) == INTEGER_CST);
5ff904cd 5586
c7e4ee3a
CB
5587 if (tree_int_cst_sgn (r) < 0)
5588 { /* The "most negative" number. */
5589 r = ffecom_1 (NEGATE_EXPR, rtype,
5590 ffecom_2 (RSHIFT_EXPR, rtype,
5591 r,
5592 integer_one_node));
5593 l = save_expr (l);
5594 l = ffecom_2 (MULT_EXPR, ltype,
5595 l,
5596 l);
5597 }
5598 }
5ff904cd 5599
c7e4ee3a
CB
5600 for (;;)
5601 {
5602 if (TREE_INT_CST_LOW (r) & 1)
5603 {
5604 if (result == NULL_TREE)
5605 result = l;
5606 else
5607 result = ffecom_2 (MULT_EXPR, ltype,
5608 result,
5609 l);
5610 }
5ff904cd 5611
c7e4ee3a
CB
5612 r = ffecom_2 (RSHIFT_EXPR, rtype,
5613 r,
5614 integer_one_node);
5615 if (integer_zerop (r))
5616 break;
5617 assert (TREE_CODE (r) == INTEGER_CST);
5ff904cd 5618
c7e4ee3a
CB
5619 l = save_expr (l);
5620 l = ffecom_2 (MULT_EXPR, ltype,
5621 l,
5622 l);
5623 }
5624 return result;
5625 }
5ff904cd 5626
c7e4ee3a
CB
5627 /* Though rhs isn't a constant, in-line code cannot be expanded
5628 while transforming dummies
5629 because the back end cannot be easily convinced to generate
5630 stores (MODIFY_EXPR), handle temporaries, and so on before
5631 all the appropriate rtx's have been generated for things like
5632 dummy args referenced in rhs -- which doesn't happen until
5633 store_parm_decls() is called (expand_function_start, I believe,
5634 does the actual rtx-stuffing of PARM_DECLs).
5ff904cd 5635
c7e4ee3a
CB
5636 So, in this case, let the caller generate the call to the
5637 run-time-library function to evaluate the power for us. */
5ff904cd 5638
c7e4ee3a
CB
5639 if (ffecom_transform_only_dummies_)
5640 return NULL_TREE;
5ff904cd 5641
c7e4ee3a
CB
5642 /* Right-hand operand not a constant, expand in-line code to figure
5643 out how to do the multiplies, &c.
5ff904cd 5644
c7e4ee3a
CB
5645 The returned expression is expressed this way in GNU C, where l and
5646 r are the "inputs":
5ff904cd 5647
c7e4ee3a
CB
5648 ({ typeof (r) rtmp = r;
5649 typeof (l) ltmp = l;
5650 typeof (l) result;
5ff904cd 5651
c7e4ee3a
CB
5652 if (rtmp == 0)
5653 result = 1;
5654 else
5655 {
5656 if ((basetypeof (l) == basetypeof (int))
5657 && (rtmp < 0))
5658 {
5659 result = ((typeof (l)) 1) / ltmp;
5660 if ((ltmp < 0) && (((-rtmp) & 1) == 0))
5661 result = -result;
5662 }
5663 else
5664 {
5665 result = 1;
5666 if ((basetypeof (l) != basetypeof (int))
5667 && (rtmp < 0))
5668 {
5669 ltmp = ((typeof (l)) 1) / ltmp;
5670 rtmp = -rtmp;
5671 if (rtmp < 0)
5672 {
5673 rtmp = -(rtmp >> 1);
5674 ltmp *= ltmp;
5675 }
5676 }
5677 for (;;)
5678 {
5679 if (rtmp & 1)
5680 result *= ltmp;
5681 if ((rtmp >>= 1) == 0)
5682 break;
5683 ltmp *= ltmp;
5684 }
5685 }
5686 }
5687 result;
5688 })
5ff904cd 5689
c7e4ee3a
CB
5690 Note that some of the above is compile-time collapsable, such as
5691 the first part of the if statements that checks the base type of
5692 l against int. The if statements are phrased that way to suggest
5693 an easy way to generate the if/else constructs here, knowing that
5694 the back end should (and probably does) eliminate the resulting
5695 dead code (either the int case or the non-int case), something
5696 it couldn't do without the redundant phrasing, requiring explicit
5697 dead-code elimination here, which would be kind of difficult to
5698 read. */
5ff904cd 5699
c7e4ee3a
CB
5700 {
5701 tree rtmp;
5702 tree ltmp;
5703 tree divide;
5704 tree basetypeof_l_is_int;
5705 tree se;
5706 tree t;
5ff904cd 5707
c7e4ee3a
CB
5708 basetypeof_l_is_int
5709 = build_int_2 ((TREE_CODE (ltype) == INTEGER_TYPE), 0);
5ff904cd 5710
c7e4ee3a 5711 se = expand_start_stmt_expr ();
5ff904cd 5712
c7e4ee3a
CB
5713 ffecom_start_compstmt ();
5714
5715#ifndef HAHA
5716 rtmp = ffecom_make_tempvar ("power_r", rtype,
5717 FFETARGET_charactersizeNONE, -1);
5718 ltmp = ffecom_make_tempvar ("power_l", ltype,
5719 FFETARGET_charactersizeNONE, -1);
5720 result = ffecom_make_tempvar ("power_res", ltype,
5721 FFETARGET_charactersizeNONE, -1);
5722 if (TREE_CODE (ltype) == COMPLEX_TYPE
5723 || TREE_CODE (ltype) == RECORD_TYPE)
5724 divide = ffecom_make_tempvar ("power_div", ltype,
5725 FFETARGET_charactersizeNONE, -1);
5726 else
5727 divide = NULL_TREE;
5728#else /* HAHA */
5729 {
5730 tree hook;
5731
5732 hook = ffebld_nonter_hook (expr);
5733 assert (hook);
5734 assert (TREE_CODE (hook) == TREE_VEC);
5735 assert (TREE_VEC_LENGTH (hook) == 4);
5736 rtmp = TREE_VEC_ELT (hook, 0);
5737 ltmp = TREE_VEC_ELT (hook, 1);
5738 result = TREE_VEC_ELT (hook, 2);
5739 divide = TREE_VEC_ELT (hook, 3);
5740 if (TREE_CODE (ltype) == COMPLEX_TYPE
5741 || TREE_CODE (ltype) == RECORD_TYPE)
5742 assert (divide);
5743 else
5744 assert (! divide);
5745 }
5746#endif /* HAHA */
5ff904cd 5747
c7e4ee3a
CB
5748 expand_expr_stmt (ffecom_modify (void_type_node,
5749 rtmp,
5750 r));
5751 expand_expr_stmt (ffecom_modify (void_type_node,
5752 ltmp,
5753 l));
5754 expand_start_cond (ffecom_truth_value
5755 (ffecom_2 (EQ_EXPR, integer_type_node,
5756 rtmp,
5757 convert (rtype, integer_zero_node))),
5758 0);
5759 expand_expr_stmt (ffecom_modify (void_type_node,
5760 result,
5761 convert (ltype, integer_one_node)));
5762 expand_start_else ();
5763 if (! integer_zerop (basetypeof_l_is_int))
5764 {
5765 expand_start_cond (ffecom_2 (LT_EXPR, integer_type_node,
5766 rtmp,
5767 convert (rtype,
5768 integer_zero_node)),
5769 0);
5770 expand_expr_stmt (ffecom_modify (void_type_node,
5771 result,
5772 ffecom_tree_divide_
5773 (ltype,
5774 convert (ltype, integer_one_node),
5775 ltmp,
5776 NULL_TREE, NULL, NULL,
5777 divide)));
5778 expand_start_cond (ffecom_truth_value
5779 (ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
5780 ffecom_2 (LT_EXPR, integer_type_node,
5781 ltmp,
5782 convert (ltype,
5783 integer_zero_node)),
5784 ffecom_2 (EQ_EXPR, integer_type_node,
5785 ffecom_2 (BIT_AND_EXPR,
5786 rtype,
5787 ffecom_1 (NEGATE_EXPR,
5788 rtype,
5789 rtmp),
5790 convert (rtype,
5791 integer_one_node)),
5792 convert (rtype,
5793 integer_zero_node)))),
5794 0);
5795 expand_expr_stmt (ffecom_modify (void_type_node,
5796 result,
5797 ffecom_1 (NEGATE_EXPR,
5798 ltype,
5799 result)));
5800 expand_end_cond ();
5801 expand_start_else ();
5802 }
5803 expand_expr_stmt (ffecom_modify (void_type_node,
5804 result,
5805 convert (ltype, integer_one_node)));
5806 expand_start_cond (ffecom_truth_value
5807 (ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
5808 ffecom_truth_value_invert
5809 (basetypeof_l_is_int),
5810 ffecom_2 (LT_EXPR, integer_type_node,
5811 rtmp,
5812 convert (rtype,
5813 integer_zero_node)))),
5814 0);
5815 expand_expr_stmt (ffecom_modify (void_type_node,
5816 ltmp,
5817 ffecom_tree_divide_
5818 (ltype,
5819 convert (ltype, integer_one_node),
5820 ltmp,
5821 NULL_TREE, NULL, NULL,
5822 divide)));
5823 expand_expr_stmt (ffecom_modify (void_type_node,
5824 rtmp,
5825 ffecom_1 (NEGATE_EXPR, rtype,
5826 rtmp)));
5827 expand_start_cond (ffecom_truth_value
5828 (ffecom_2 (LT_EXPR, integer_type_node,
5829 rtmp,
5830 convert (rtype, integer_zero_node))),
5831 0);
5832 expand_expr_stmt (ffecom_modify (void_type_node,
5833 rtmp,
5834 ffecom_1 (NEGATE_EXPR, rtype,
5835 ffecom_2 (RSHIFT_EXPR,
5836 rtype,
5837 rtmp,
5838 integer_one_node))));
5839 expand_expr_stmt (ffecom_modify (void_type_node,
5840 ltmp,
5841 ffecom_2 (MULT_EXPR, ltype,
5842 ltmp,
5843 ltmp)));
5844 expand_end_cond ();
5845 expand_end_cond ();
5846 expand_start_loop (1);
5847 expand_start_cond (ffecom_truth_value
5848 (ffecom_2 (BIT_AND_EXPR, rtype,
5849 rtmp,
5850 convert (rtype, integer_one_node))),
5851 0);
5852 expand_expr_stmt (ffecom_modify (void_type_node,
5853 result,
5854 ffecom_2 (MULT_EXPR, ltype,
5855 result,
5856 ltmp)));
5857 expand_end_cond ();
5858 expand_exit_loop_if_false (NULL,
5859 ffecom_truth_value
5860 (ffecom_modify (rtype,
5861 rtmp,
5862 ffecom_2 (RSHIFT_EXPR,
5863 rtype,
5864 rtmp,
5865 integer_one_node))));
5866 expand_expr_stmt (ffecom_modify (void_type_node,
5867 ltmp,
5868 ffecom_2 (MULT_EXPR, ltype,
5869 ltmp,
5870 ltmp)));
5871 expand_end_loop ();
5872 expand_end_cond ();
5873 if (!integer_zerop (basetypeof_l_is_int))
5874 expand_end_cond ();
5875 expand_expr_stmt (result);
5ff904cd 5876
c7e4ee3a 5877 t = ffecom_end_compstmt ();
5ff904cd 5878
c7e4ee3a 5879 result = expand_end_stmt_expr (se);
5ff904cd 5880
c7e4ee3a 5881 /* This code comes from c-parse.in, after its expand_end_stmt_expr. */
5ff904cd 5882
c7e4ee3a
CB
5883 if (TREE_CODE (t) == BLOCK)
5884 {
5885 /* Make a BIND_EXPR for the BLOCK already made. */
5886 result = build (BIND_EXPR, TREE_TYPE (result),
5887 NULL_TREE, result, t);
5888 /* Remove the block from the tree at this point.
5889 It gets put back at the proper place
5890 when the BIND_EXPR is expanded. */
5891 delete_block (t);
5892 }
5893 else
5894 result = t;
5895 }
5ff904cd 5896
c7e4ee3a
CB
5897 return result;
5898}
5ff904cd 5899
c7e4ee3a
CB
5900#endif
5901/* ffecom_expr_transform_ -- Transform symbols in expr
5ff904cd 5902
c7e4ee3a
CB
5903 ffebld expr; // FFE expression.
5904 ffecom_expr_transform_ (expr);
5ff904cd 5905
c7e4ee3a 5906 Recursive descent on expr while transforming any untransformed SYMTERs. */
5ff904cd 5907
c7e4ee3a
CB
5908#if FFECOM_targetCURRENT == FFECOM_targetGCC
5909static void
5910ffecom_expr_transform_ (ffebld expr)
5911{
5912 tree t;
5913 ffesymbol s;
5ff904cd 5914
c7e4ee3a 5915tail_recurse: /* :::::::::::::::::::: */
5ff904cd 5916
c7e4ee3a
CB
5917 if (expr == NULL)
5918 return;
5ff904cd 5919
c7e4ee3a
CB
5920 switch (ffebld_op (expr))
5921 {
5922 case FFEBLD_opSYMTER:
5923 s = ffebld_symter (expr);
5924 t = ffesymbol_hook (s).decl_tree;
5925 if ((t == NULL_TREE)
5926 && ((ffesymbol_kind (s) != FFEINFO_kindNONE)
5927 || ((ffesymbol_where (s) != FFEINFO_whereNONE)
5928 && (ffesymbol_where (s) != FFEINFO_whereINTRINSIC))))
5929 {
5930 s = ffecom_sym_transform_ (s);
5931 t = ffesymbol_hook (s).decl_tree; /* Sfunc expr non-dummy,
5932 DIMENSION expr? */
5933 }
5934 break; /* Ok if (t == NULL) here. */
5ff904cd 5935
c7e4ee3a
CB
5936 case FFEBLD_opITEM:
5937 ffecom_expr_transform_ (ffebld_head (expr));
5938 expr = ffebld_trail (expr);
5939 goto tail_recurse; /* :::::::::::::::::::: */
5ff904cd 5940
c7e4ee3a
CB
5941 default:
5942 break;
5943 }
5ff904cd 5944
c7e4ee3a
CB
5945 switch (ffebld_arity (expr))
5946 {
5947 case 2:
5948 ffecom_expr_transform_ (ffebld_left (expr));
5949 expr = ffebld_right (expr);
5950 goto tail_recurse; /* :::::::::::::::::::: */
5ff904cd 5951
c7e4ee3a
CB
5952 case 1:
5953 expr = ffebld_left (expr);
5954 goto tail_recurse; /* :::::::::::::::::::: */
5ff904cd 5955
c7e4ee3a
CB
5956 default:
5957 break;
5958 }
5ff904cd 5959
c7e4ee3a
CB
5960 return;
5961}
5ff904cd 5962
c7e4ee3a
CB
5963#endif
5964/* Make a type based on info in live f2c.h file. */
5ff904cd 5965
c7e4ee3a
CB
5966#if FFECOM_targetCURRENT == FFECOM_targetGCC
5967static void
5968ffecom_f2c_make_type_ (tree *type, int tcode, const char *name)
5969{
5970 switch (tcode)
5971 {
5972 case FFECOM_f2ccodeCHAR:
5973 *type = make_signed_type (CHAR_TYPE_SIZE);
5974 break;
5ff904cd 5975
c7e4ee3a
CB
5976 case FFECOM_f2ccodeSHORT:
5977 *type = make_signed_type (SHORT_TYPE_SIZE);
5978 break;
5ff904cd 5979
c7e4ee3a
CB
5980 case FFECOM_f2ccodeINT:
5981 *type = make_signed_type (INT_TYPE_SIZE);
5982 break;
5ff904cd 5983
c7e4ee3a
CB
5984 case FFECOM_f2ccodeLONG:
5985 *type = make_signed_type (LONG_TYPE_SIZE);
5986 break;
5ff904cd 5987
c7e4ee3a
CB
5988 case FFECOM_f2ccodeLONGLONG:
5989 *type = make_signed_type (LONG_LONG_TYPE_SIZE);
5990 break;
5ff904cd 5991
c7e4ee3a
CB
5992 case FFECOM_f2ccodeCHARPTR:
5993 *type = build_pointer_type (DEFAULT_SIGNED_CHAR
5994 ? signed_char_type_node
5995 : unsigned_char_type_node);
5996 break;
5ff904cd 5997
c7e4ee3a
CB
5998 case FFECOM_f2ccodeFLOAT:
5999 *type = make_node (REAL_TYPE);
6000 TYPE_PRECISION (*type) = FLOAT_TYPE_SIZE;
6001 layout_type (*type);
6002 break;
6003
6004 case FFECOM_f2ccodeDOUBLE:
6005 *type = make_node (REAL_TYPE);
6006 TYPE_PRECISION (*type) = DOUBLE_TYPE_SIZE;
6007 layout_type (*type);
6008 break;
6009
6010 case FFECOM_f2ccodeLONGDOUBLE:
6011 *type = make_node (REAL_TYPE);
6012 TYPE_PRECISION (*type) = LONG_DOUBLE_TYPE_SIZE;
6013 layout_type (*type);
6014 break;
5ff904cd 6015
c7e4ee3a
CB
6016 case FFECOM_f2ccodeTWOREALS:
6017 *type = ffecom_make_complex_type_ (ffecom_f2c_real_type_node);
6018 break;
5ff904cd 6019
c7e4ee3a
CB
6020 case FFECOM_f2ccodeTWODOUBLEREALS:
6021 *type = ffecom_make_complex_type_ (ffecom_f2c_doublereal_type_node);
6022 break;
5ff904cd 6023
c7e4ee3a
CB
6024 default:
6025 assert ("unexpected FFECOM_f2ccodeXYZZY!" == NULL);
6026 *type = error_mark_node;
6027 return;
6028 }
5ff904cd 6029
c7e4ee3a 6030 pushdecl (build_decl (TYPE_DECL,
14657de8 6031 ffecom_get_invented_identifier ("__g77_f2c_%s", name),
c7e4ee3a
CB
6032 *type));
6033}
5ff904cd 6034
c7e4ee3a
CB
6035#endif
6036#if FFECOM_targetCURRENT == FFECOM_targetGCC
6037/* Set the f2c list-directed-I/O code for whatever (integral) type has the
6038 given size. */
5ff904cd 6039
c7e4ee3a
CB
6040static void
6041ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size,
6042 int code)
6043{
6044 int j;
6045 tree t;
5ff904cd 6046
c7e4ee3a 6047 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
05bccae2
RK
6048 if ((t = ffecom_tree_type[bt][j]) != NULL_TREE
6049 && compare_tree_int (TYPE_SIZE (t), size) == 0)
c7e4ee3a
CB
6050 {
6051 assert (code != -1);
6052 ffecom_f2c_typecode_[bt][j] = code;
6053 code = -1;
6054 }
6055}
5ff904cd 6056
c7e4ee3a
CB
6057#endif
6058/* Finish up globals after doing all program units in file
5ff904cd 6059
c7e4ee3a 6060 Need to handle only uninitialized COMMON areas. */
5ff904cd 6061
c7e4ee3a
CB
6062#if FFECOM_targetCURRENT == FFECOM_targetGCC
6063static ffeglobal
6064ffecom_finish_global_ (ffeglobal global)
6065{
6066 tree cbtype;
6067 tree cbt;
6068 tree size;
5ff904cd 6069
c7e4ee3a
CB
6070 if (ffeglobal_type (global) != FFEGLOBAL_typeCOMMON)
6071 return global;
5ff904cd 6072
c7e4ee3a
CB
6073 if (ffeglobal_common_init (global))
6074 return global;
5ff904cd 6075
c7e4ee3a
CB
6076 cbt = ffeglobal_hook (global);
6077 if ((cbt == NULL_TREE)
6078 || !ffeglobal_common_have_size (global))
6079 return global; /* No need to make common, never ref'd. */
5ff904cd 6080
c7e4ee3a 6081 suspend_momentary ();
5ff904cd 6082
c7e4ee3a 6083 DECL_EXTERNAL (cbt) = 0;
5ff904cd 6084
c7e4ee3a 6085 /* Give the array a size now. */
5ff904cd 6086
c7e4ee3a
CB
6087 size = build_int_2 ((ffeglobal_common_size (global)
6088 + ffeglobal_common_pad (global)) - 1,
6089 0);
5ff904cd 6090
c7e4ee3a
CB
6091 cbtype = TREE_TYPE (cbt);
6092 TYPE_DOMAIN (cbtype) = build_range_type (integer_type_node,
6093 integer_zero_node,
6094 size);
6095 if (!TREE_TYPE (size))
6096 TREE_TYPE (size) = TYPE_DOMAIN (cbtype);
6097 layout_type (cbtype);
5ff904cd 6098
c7e4ee3a
CB
6099 cbt = start_decl (cbt, FALSE);
6100 assert (cbt == ffeglobal_hook (global));
5ff904cd 6101
c7e4ee3a 6102 finish_decl (cbt, NULL_TREE, FALSE);
5ff904cd 6103
c7e4ee3a
CB
6104 return global;
6105}
5ff904cd 6106
c7e4ee3a
CB
6107#endif
6108/* Finish up any untransformed symbols. */
5ff904cd 6109
c7e4ee3a
CB
6110#if FFECOM_targetCURRENT == FFECOM_targetGCC
6111static ffesymbol
6112ffecom_finish_symbol_transform_ (ffesymbol s)
5ff904cd 6113{
c7e4ee3a
CB
6114 if ((s == NULL) || (TREE_CODE (current_function_decl) == ERROR_MARK))
6115 return s;
5ff904cd 6116
c7e4ee3a
CB
6117 /* It's easy to know to transform an untransformed symbol, to make sure
6118 we put out debugging info for it. But COMMON variables, unlike
6119 EQUIVALENCE ones, aren't given declarations in addition to the
6120 tree expressions that specify offsets, because COMMON variables
6121 can be referenced in the outer scope where only dummy arguments
6122 (PARM_DECLs) should really be seen. To be safe, just don't do any
6123 VAR_DECLs for COMMON variables when we transform them for real
6124 use, and therefore we do all the VAR_DECL creating here. */
5ff904cd 6125
c7e4ee3a
CB
6126 if (ffesymbol_hook (s).decl_tree == NULL_TREE)
6127 {
6128 if (ffesymbol_kind (s) != FFEINFO_kindNONE
6129 || (ffesymbol_where (s) != FFEINFO_whereNONE
6130 && ffesymbol_where (s) != FFEINFO_whereINTRINSIC
6131 && ffesymbol_where (s) != FFEINFO_whereDUMMY))
6132 /* Not transformed, and not CHARACTER*(*), and not a dummy
6133 argument, which can happen only if the entry point names
6134 it "rides in on" are all invalidated for other reasons. */
6135 s = ffecom_sym_transform_ (s);
6136 }
5ff904cd 6137
c7e4ee3a
CB
6138 if ((ffesymbol_where (s) == FFEINFO_whereCOMMON)
6139 && (ffesymbol_hook (s).decl_tree != error_mark_node))
6140 {
c7e4ee3a 6141 int yes = suspend_momentary ();
5ff904cd 6142
c7e4ee3a
CB
6143 /* This isn't working, at least for dbxout. The .s file looks
6144 okay to me (burley), but in gdb 4.9 at least, the variables
6145 appear to reside somewhere outside of the common area, so
6146 it doesn't make sense to mislead anyone by generating the info
6147 on those variables until this is fixed. NOTE: Same problem
6148 with EQUIVALENCE, sadly...see similar #if later. */
6149 ffecom_member_phase2_ (ffesymbol_storage (ffesymbol_common (s)),
6150 ffesymbol_storage (s));
5ff904cd 6151
c7e4ee3a 6152 resume_momentary (yes);
5ff904cd
JL
6153 }
6154
c7e4ee3a
CB
6155 return s;
6156}
5ff904cd 6157
c7e4ee3a
CB
6158#endif
6159/* Append underscore(s) to name before calling get_identifier. "us"
6160 is nonzero if the name already contains an underscore and thus
6161 needs two underscores appended. */
5ff904cd 6162
c7e4ee3a
CB
6163#if FFECOM_targetCURRENT == FFECOM_targetGCC
6164static tree
6165ffecom_get_appended_identifier_ (char us, const char *name)
6166{
6167 int i;
6168 char *newname;
6169 tree id;
5ff904cd 6170
c7e4ee3a
CB
6171 newname = xmalloc ((i = strlen (name)) + 1
6172 + ffe_is_underscoring ()
6173 + us);
6174 memcpy (newname, name, i);
6175 newname[i] = '_';
6176 newname[i + us] = '_';
6177 newname[i + 1 + us] = '\0';
6178 id = get_identifier (newname);
5ff904cd 6179
c7e4ee3a 6180 free (newname);
5ff904cd 6181
c7e4ee3a
CB
6182 return id;
6183}
5ff904cd 6184
c7e4ee3a
CB
6185#endif
6186/* Decide whether to append underscore to name before calling
6187 get_identifier. */
5ff904cd 6188
c7e4ee3a
CB
6189#if FFECOM_targetCURRENT == FFECOM_targetGCC
6190static tree
6191ffecom_get_external_identifier_ (ffesymbol s)
6192{
6193 char us;
6194 const char *name = ffesymbol_text (s);
5ff904cd 6195
c7e4ee3a 6196 /* If name is a built-in name, just return it as is. */
5ff904cd 6197
c7e4ee3a
CB
6198 if (!ffe_is_underscoring ()
6199 || (strcmp (name, FFETARGET_nameBLANK_COMMON) == 0)
6200#if FFETARGET_isENFORCED_MAIN_NAME
6201 || (strcmp (name, FFETARGET_nameENFORCED_NAME) == 0)
6202#else
6203 || (strcmp (name, FFETARGET_nameUNNAMED_MAIN) == 0)
6204#endif
6205 || (strcmp (name, FFETARGET_nameUNNAMED_BLOCK_DATA) == 0))
6206 return get_identifier (name);
5ff904cd 6207
c7e4ee3a
CB
6208 us = ffe_is_second_underscore ()
6209 ? (strchr (name, '_') != NULL)
6210 : 0;
5ff904cd 6211
c7e4ee3a
CB
6212 return ffecom_get_appended_identifier_ (us, name);
6213}
5ff904cd 6214
c7e4ee3a
CB
6215#endif
6216/* Decide whether to append underscore to internal name before calling
6217 get_identifier.
6218
6219 This is for non-external, top-function-context names only. Transform
6220 identifier so it doesn't conflict with the transformed result
6221 of using a _different_ external name. E.g. if "CALL FOO" is
6222 transformed into "FOO_();", then the variable in "FOO_ = 3"
6223 must be transformed into something that does not conflict, since
6224 these two things should be independent.
5ff904cd 6225
c7e4ee3a
CB
6226 The transformation is as follows. If the name does not contain
6227 an underscore, there is no possible conflict, so just return.
6228 If the name does contain an underscore, then transform it just
6229 like we transform an external identifier. */
5ff904cd 6230
c7e4ee3a
CB
6231#if FFECOM_targetCURRENT == FFECOM_targetGCC
6232static tree
6233ffecom_get_identifier_ (const char *name)
6234{
6235 /* If name does not contain an underscore, just return it as is. */
6236
6237 if (!ffe_is_underscoring ()
6238 || (strchr (name, '_') == NULL))
6239 return get_identifier (name);
6240
6241 return ffecom_get_appended_identifier_ (ffe_is_second_underscore (),
6242 name);
5ff904cd
JL
6243}
6244
6245#endif
c7e4ee3a 6246/* ffecom_gen_sfuncdef_ -- Generate definition of statement function
5ff904cd 6247
c7e4ee3a
CB
6248 tree t;
6249 ffesymbol s; // kindFUNCTION, whereIMMEDIATE.
6250 t = ffecom_gen_sfuncdef_(s,ffesymbol_basictype(s),
6251 ffesymbol_kindtype(s));
5ff904cd 6252
c7e4ee3a
CB
6253 Call after setting up containing function and getting trees for all
6254 other symbols. */
5ff904cd
JL
6255
6256#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
6257static tree
6258ffecom_gen_sfuncdef_ (ffesymbol s, ffeinfoBasictype bt, ffeinfoKindtype kt)
5ff904cd 6259{
c7e4ee3a
CB
6260 ffebld expr = ffesymbol_sfexpr (s);
6261 tree type;
6262 tree func;
6263 tree result;
6264 bool charfunc = (bt == FFEINFO_basictypeCHARACTER);
6265 static bool recurse = FALSE;
6266 int yes;
6267 int old_lineno = lineno;
3b304f5b 6268 const char *old_input_filename = input_filename;
5ff904cd 6269
c7e4ee3a 6270 ffecom_nested_entry_ = s;
5ff904cd 6271
c7e4ee3a
CB
6272 /* For now, we don't have a handy pointer to where the sfunc is actually
6273 defined, though that should be easy to add to an ffesymbol. (The
6274 token/where info available might well point to the place where the type
6275 of the sfunc is declared, especially if that precedes the place where
6276 the sfunc itself is defined, which is typically the case.) We should
6277 put out a null pointer rather than point somewhere wrong, but I want to
6278 see how it works at this point. */
5ff904cd 6279
c7e4ee3a
CB
6280 input_filename = ffesymbol_where_filename (s);
6281 lineno = ffesymbol_where_filelinenum (s);
5ff904cd 6282
c7e4ee3a
CB
6283 /* Pretransform the expression so any newly discovered things belong to the
6284 outer program unit, not to the statement function. */
5ff904cd 6285
c7e4ee3a 6286 ffecom_expr_transform_ (expr);
5ff904cd 6287
c7e4ee3a
CB
6288 /* Make sure no recursive invocation of this fn (a specific case of failing
6289 to pretransform an sfunc's expression, i.e. where its expression
6290 references another untransformed sfunc) happens. */
6291
6292 assert (!recurse);
6293 recurse = TRUE;
6294
6295 yes = suspend_momentary ();
6296
6297 push_f_function_context ();
6298
6299 if (charfunc)
6300 type = void_type_node;
6301 else
5ff904cd 6302 {
c7e4ee3a
CB
6303 type = ffecom_tree_type[bt][kt];
6304 if (type == NULL_TREE)
6305 type = integer_type_node; /* _sym_exec_transition reports
6306 error. */
6307 }
5ff904cd 6308
c7e4ee3a
CB
6309 start_function (ffecom_get_identifier_ (ffesymbol_text (s)),
6310 build_function_type (type, NULL_TREE),
6311 1, /* nested/inline */
6312 0); /* TREE_PUBLIC */
5ff904cd 6313
c7e4ee3a
CB
6314 /* We don't worry about COMPLEX return values here, because this is
6315 entirely internal to our code, and gcc has the ability to return COMPLEX
6316 directly as a value. */
6317
6318 yes = suspend_momentary ();
6319
6320 if (charfunc)
6321 { /* Prepend arg for where result goes. */
6322 tree type;
6323
6324 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
6325
14657de8 6326 result = ffecom_get_invented_identifier ("__g77_%s", "result");
c7e4ee3a
CB
6327
6328 ffecom_char_enhance_arg_ (&type, s); /* Ignore returned length. */
6329
6330 type = build_pointer_type (type);
6331 result = build_decl (PARM_DECL, result, type);
6332
6333 push_parm_decl (result);
5ff904cd 6334 }
c7e4ee3a
CB
6335 else
6336 result = NULL_TREE; /* Not ref'd if !charfunc. */
5ff904cd 6337
c7e4ee3a 6338 ffecom_push_dummy_decls_ (ffesymbol_dummyargs (s), TRUE);
5ff904cd 6339
c7e4ee3a 6340 resume_momentary (yes);
5ff904cd 6341
c7e4ee3a
CB
6342 store_parm_decls (0);
6343
6344 ffecom_start_compstmt ();
6345
6346 if (expr != NULL)
5ff904cd 6347 {
c7e4ee3a
CB
6348 if (charfunc)
6349 {
6350 ffetargetCharacterSize sz = ffesymbol_size (s);
6351 tree result_length;
5ff904cd 6352
c7e4ee3a
CB
6353 result_length = build_int_2 (sz, 0);
6354 TREE_TYPE (result_length) = ffecom_f2c_ftnlen_type_node;
5ff904cd 6355
c7e4ee3a 6356 ffecom_prepare_let_char_ (sz, expr);
5ff904cd 6357
c7e4ee3a 6358 ffecom_prepare_end ();
5ff904cd 6359
c7e4ee3a
CB
6360 ffecom_let_char_ (result, result_length, sz, expr);
6361 expand_null_return ();
6362 }
6363 else
6364 {
6365 ffecom_prepare_expr (expr);
5ff904cd 6366
c7e4ee3a 6367 ffecom_prepare_end ();
5ff904cd 6368
c7e4ee3a
CB
6369 expand_return (ffecom_modify (NULL_TREE,
6370 DECL_RESULT (current_function_decl),
6371 ffecom_expr (expr)));
6372 }
5ff904cd 6373
c7e4ee3a
CB
6374 clear_momentary ();
6375 }
5ff904cd 6376
c7e4ee3a 6377 ffecom_end_compstmt ();
5ff904cd 6378
c7e4ee3a
CB
6379 func = current_function_decl;
6380 finish_function (1);
5ff904cd 6381
c7e4ee3a 6382 pop_f_function_context ();
5ff904cd 6383
c7e4ee3a 6384 resume_momentary (yes);
5ff904cd 6385
c7e4ee3a
CB
6386 recurse = FALSE;
6387
6388 lineno = old_lineno;
6389 input_filename = old_input_filename;
6390
6391 ffecom_nested_entry_ = NULL;
6392
6393 return func;
5ff904cd
JL
6394}
6395
6396#endif
5ff904cd 6397
c7e4ee3a
CB
6398#if FFECOM_targetCURRENT == FFECOM_targetGCC
6399static const char *
6400ffecom_gfrt_args_ (ffecomGfrt ix)
5ff904cd 6401{
c7e4ee3a
CB
6402 return ffecom_gfrt_argstring_[ix];
6403}
5ff904cd 6404
c7e4ee3a
CB
6405#endif
6406#if FFECOM_targetCURRENT == FFECOM_targetGCC
6407static tree
6408ffecom_gfrt_tree_ (ffecomGfrt ix)
6409{
6410 if (ffecom_gfrt_[ix] == NULL_TREE)
6411 ffecom_make_gfrt_ (ix);
6412
6413 return ffecom_1 (ADDR_EXPR,
6414 build_pointer_type (TREE_TYPE (ffecom_gfrt_[ix])),
6415 ffecom_gfrt_[ix]);
5ff904cd
JL
6416}
6417
6418#endif
c7e4ee3a 6419/* Return initialize-to-zero expression for this VAR_DECL. */
5ff904cd
JL
6420
6421#if FFECOM_targetCURRENT == FFECOM_targetGCC
7189a4b0
GK
6422/* A somewhat evil way to prevent the garbage collector
6423 from collecting 'tree' structures. */
6424#define NUM_TRACKED_CHUNK 63
6425static struct tree_ggc_tracker
6426{
6427 struct tree_ggc_tracker *next;
6428 tree trees[NUM_TRACKED_CHUNK];
6429} *tracker_head = NULL;
6430
6431static void
54551044 6432mark_tracker_head (void *arg)
7189a4b0
GK
6433{
6434 struct tree_ggc_tracker *head;
6435 int i;
6436
6437 for (head = * (struct tree_ggc_tracker **) arg;
6438 head != NULL;
6439 head = head->next)
6440 {
6441 ggc_mark (head);
6442 for (i = 0; i < NUM_TRACKED_CHUNK; i++)
6443 ggc_mark_tree (head->trees[i]);
6444 }
6445}
6446
6447void
6448ffecom_save_tree_forever (tree t)
6449{
6450 int i;
6451 if (tracker_head != NULL)
6452 for (i = 0; i < NUM_TRACKED_CHUNK; i++)
6453 if (tracker_head->trees[i] == NULL)
6454 {
6455 tracker_head->trees[i] = t;
6456 return;
6457 }
6458
6459 {
6460 /* Need to allocate a new block. */
6461 struct tree_ggc_tracker *old_head = tracker_head;
6462
6463 tracker_head = ggc_alloc (sizeof (*tracker_head));
6464 tracker_head->next = old_head;
6465 tracker_head->trees[0] = t;
6466 for (i = 1; i < NUM_TRACKED_CHUNK; i++)
6467 tracker_head->trees[i] = NULL;
6468 }
6469}
6470
c7e4ee3a
CB
6471static tree
6472ffecom_init_zero_ (tree decl)
5ff904cd 6473{
c7e4ee3a
CB
6474 tree init;
6475 int incremental = TREE_STATIC (decl);
6476 tree type = TREE_TYPE (decl);
5ff904cd 6477
c7e4ee3a
CB
6478 if (incremental)
6479 {
c7e4ee3a
CB
6480 make_decl_rtl (decl, NULL, TREE_PUBLIC (decl) ? 1 : 0);
6481 assemble_variable (decl, TREE_PUBLIC (decl) ? 1 : 0, 0, 1);
c7e4ee3a 6482 }
5ff904cd 6483
c7e4ee3a 6484 push_momentary ();
5ff904cd 6485
c7e4ee3a
CB
6486 if ((TREE_CODE (type) != ARRAY_TYPE)
6487 && (TREE_CODE (type) != RECORD_TYPE)
6488 && (TREE_CODE (type) != UNION_TYPE)
6489 && !incremental)
6490 init = convert (type, integer_zero_node);
6491 else if (!incremental)
6492 {
6493 int momentary = suspend_momentary ();
5ff904cd 6494
c7e4ee3a
CB
6495 init = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
6496 TREE_CONSTANT (init) = 1;
6497 TREE_STATIC (init) = 1;
5ff904cd 6498
c7e4ee3a
CB
6499 resume_momentary (momentary);
6500 }
6501 else
6502 {
6503 int momentary = suspend_momentary ();
5ff904cd 6504
c7e4ee3a
CB
6505 assemble_zeros (int_size_in_bytes (type));
6506 init = error_mark_node;
5ff904cd 6507
c7e4ee3a
CB
6508 resume_momentary (momentary);
6509 }
5ff904cd 6510
c7e4ee3a 6511 pop_momentary_nofree ();
5ff904cd 6512
c7e4ee3a 6513 return init;
5ff904cd
JL
6514}
6515
6516#endif
5ff904cd 6517#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
6518static tree
6519ffecom_intrinsic_ichar_ (tree tree_type, ffebld arg,
6520 tree *maybe_tree)
5ff904cd 6521{
c7e4ee3a
CB
6522 tree expr_tree;
6523 tree length_tree;
5ff904cd 6524
c7e4ee3a 6525 switch (ffebld_op (arg))
6829256f 6526 {
c7e4ee3a
CB
6527 case FFEBLD_opCONTER: /* For F90, check 0-length. */
6528 if (ffetarget_length_character1
6529 (ffebld_constant_character1
6530 (ffebld_conter (arg))) == 0)
6531 {
6532 *maybe_tree = integer_zero_node;
6533 return convert (tree_type, integer_zero_node);
6534 }
5ff904cd 6535
c7e4ee3a
CB
6536 *maybe_tree = integer_one_node;
6537 expr_tree = build_int_2 (*ffetarget_text_character1
6538 (ffebld_constant_character1
6539 (ffebld_conter (arg))),
6540 0);
6541 TREE_TYPE (expr_tree) = tree_type;
6542 return expr_tree;
5ff904cd 6543
c7e4ee3a
CB
6544 case FFEBLD_opSYMTER:
6545 case FFEBLD_opARRAYREF:
6546 case FFEBLD_opFUNCREF:
6547 case FFEBLD_opSUBSTR:
6548 ffecom_char_args_ (&expr_tree, &length_tree, arg);
5ff904cd 6549
c7e4ee3a
CB
6550 if ((expr_tree == error_mark_node)
6551 || (length_tree == error_mark_node))
6552 {
6553 *maybe_tree = error_mark_node;
6554 return error_mark_node;
6555 }
5ff904cd 6556
c7e4ee3a
CB
6557 if (integer_zerop (length_tree))
6558 {
6559 *maybe_tree = integer_zero_node;
6560 return convert (tree_type, integer_zero_node);
6561 }
6562
6563 expr_tree
6564 = ffecom_1 (INDIRECT_REF,
6565 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
6566 expr_tree);
6567 expr_tree
6568 = ffecom_2 (ARRAY_REF,
6569 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
6570 expr_tree,
6571 integer_one_node);
6572 expr_tree = convert (tree_type, expr_tree);
6573
6574 if (TREE_CODE (length_tree) == INTEGER_CST)
6575 *maybe_tree = integer_one_node;
6576 else /* Must check length at run time. */
6577 *maybe_tree
6578 = ffecom_truth_value
6579 (ffecom_2 (GT_EXPR, integer_type_node,
6580 length_tree,
6581 ffecom_f2c_ftnlen_zero_node));
6582 return expr_tree;
6583
6584 case FFEBLD_opPAREN:
6585 case FFEBLD_opCONVERT:
6586 if (ffeinfo_size (ffebld_info (arg)) == 0)
6587 {
6588 *maybe_tree = integer_zero_node;
6589 return convert (tree_type, integer_zero_node);
6590 }
6591 return ffecom_intrinsic_ichar_ (tree_type, ffebld_left (arg),
6592 maybe_tree);
6593
6594 case FFEBLD_opCONCATENATE:
6595 {
6596 tree maybe_left;
6597 tree maybe_right;
6598 tree expr_left;
6599 tree expr_right;
6600
6601 expr_left = ffecom_intrinsic_ichar_ (tree_type, ffebld_left (arg),
6602 &maybe_left);
6603 expr_right = ffecom_intrinsic_ichar_ (tree_type, ffebld_right (arg),
6604 &maybe_right);
6605 *maybe_tree = ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
6606 maybe_left,
6607 maybe_right);
6608 expr_tree = ffecom_3 (COND_EXPR, tree_type,
6609 maybe_left,
6610 expr_left,
6611 expr_right);
6612 return expr_tree;
6613 }
6614
6615 default:
6616 assert ("bad op in ICHAR" == NULL);
6617 return error_mark_node;
6618 }
5ff904cd
JL
6619}
6620
6621#endif
c7e4ee3a
CB
6622/* ffecom_intrinsic_len_ -- Return length info for char arg (LEN())
6623
6624 tree length_arg;
6625 ffebld expr;
6626 length_arg = ffecom_intrinsic_len_ (expr);
6627
6628 Handles CHARACTER-type CONTER, SYMTER, SUBSTR, ARRAYREF, and FUNCREF
6629 subexpressions by constructing the appropriate tree for the
6630 length-of-character-text argument in a calling sequence. */
5ff904cd
JL
6631
6632#if FFECOM_targetCURRENT == FFECOM_targetGCC
6633static tree
c7e4ee3a 6634ffecom_intrinsic_len_ (ffebld expr)
5ff904cd 6635{
c7e4ee3a
CB
6636 ffetargetCharacter1 val;
6637 tree length;
6638
6639 switch (ffebld_op (expr))
6640 {
6641 case FFEBLD_opCONTER:
6642 val = ffebld_constant_character1 (ffebld_conter (expr));
6643 length = build_int_2 (ffetarget_length_character1 (val), 0);
6644 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6645 break;
6646
6647 case FFEBLD_opSYMTER:
6648 {
6649 ffesymbol s = ffebld_symter (expr);
6650 tree item;
6651
6652 item = ffesymbol_hook (s).decl_tree;
6653 if (item == NULL_TREE)
6654 {
6655 s = ffecom_sym_transform_ (s);
6656 item = ffesymbol_hook (s).decl_tree;
6657 }
6658 if (ffesymbol_kind (s) == FFEINFO_kindENTITY)
6659 {
6660 if (ffesymbol_size (s) == FFETARGET_charactersizeNONE)
6661 length = ffesymbol_hook (s).length_tree;
6662 else
6663 {
6664 length = build_int_2 (ffesymbol_size (s), 0);
6665 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6666 }
6667 }
6668 else if (item == error_mark_node)
6669 length = error_mark_node;
6670 else /* FFEINFO_kindFUNCTION: */
6671 length = NULL_TREE;
6672 }
6673 break;
5ff904cd 6674
c7e4ee3a
CB
6675 case FFEBLD_opARRAYREF:
6676 length = ffecom_intrinsic_len_ (ffebld_left (expr));
6677 break;
5ff904cd 6678
c7e4ee3a
CB
6679 case FFEBLD_opSUBSTR:
6680 {
6681 ffebld start;
6682 ffebld end;
6683 ffebld thing = ffebld_right (expr);
6684 tree start_tree;
6685 tree end_tree;
5ff904cd 6686
c7e4ee3a
CB
6687 assert (ffebld_op (thing) == FFEBLD_opITEM);
6688 start = ffebld_head (thing);
6689 thing = ffebld_trail (thing);
6690 assert (ffebld_trail (thing) == NULL);
6691 end = ffebld_head (thing);
5ff904cd 6692
c7e4ee3a 6693 length = ffecom_intrinsic_len_ (ffebld_left (expr));
5ff904cd 6694
c7e4ee3a
CB
6695 if (length == error_mark_node)
6696 break;
5ff904cd 6697
c7e4ee3a
CB
6698 if (start == NULL)
6699 {
6700 if (end == NULL)
6701 ;
6702 else
6703 {
6704 length = convert (ffecom_f2c_ftnlen_type_node,
6705 ffecom_expr (end));
6706 }
6707 }
6708 else
6709 {
6710 start_tree = convert (ffecom_f2c_ftnlen_type_node,
6711 ffecom_expr (start));
5ff904cd 6712
c7e4ee3a
CB
6713 if (start_tree == error_mark_node)
6714 {
6715 length = error_mark_node;
6716 break;
6717 }
5ff904cd 6718
c7e4ee3a
CB
6719 if (end == NULL)
6720 {
6721 length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6722 ffecom_f2c_ftnlen_one_node,
6723 ffecom_2 (MINUS_EXPR,
6724 ffecom_f2c_ftnlen_type_node,
6725 length,
6726 start_tree));
6727 }
6728 else
6729 {
6730 end_tree = convert (ffecom_f2c_ftnlen_type_node,
6731 ffecom_expr (end));
5ff904cd 6732
c7e4ee3a
CB
6733 if (end_tree == error_mark_node)
6734 {
6735 length = error_mark_node;
6736 break;
6737 }
5ff904cd 6738
c7e4ee3a
CB
6739 length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6740 ffecom_f2c_ftnlen_one_node,
6741 ffecom_2 (MINUS_EXPR,
6742 ffecom_f2c_ftnlen_type_node,
6743 end_tree, start_tree));
6744 }
6745 }
6746 }
6747 break;
5ff904cd 6748
c7e4ee3a
CB
6749 case FFEBLD_opCONCATENATE:
6750 length
6751 = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6752 ffecom_intrinsic_len_ (ffebld_left (expr)),
6753 ffecom_intrinsic_len_ (ffebld_right (expr)));
6754 break;
5ff904cd 6755
c7e4ee3a
CB
6756 case FFEBLD_opFUNCREF:
6757 case FFEBLD_opCONVERT:
6758 length = build_int_2 (ffebld_size (expr), 0);
6759 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6760 break;
5ff904cd 6761
c7e4ee3a
CB
6762 default:
6763 assert ("bad op for single char arg expr" == NULL);
6764 length = ffecom_f2c_ftnlen_zero_node;
6765 break;
6766 }
5ff904cd 6767
c7e4ee3a 6768 assert (length != NULL_TREE);
5ff904cd 6769
c7e4ee3a 6770 return length;
5ff904cd
JL
6771}
6772
6773#endif
c7e4ee3a 6774/* Handle CHARACTER assignments.
5ff904cd 6775
c7e4ee3a
CB
6776 Generates code to do the assignment. Used by ordinary assignment
6777 statement handler ffecom_let_stmt and by statement-function
6778 handler to generate code for a statement function. */
5ff904cd
JL
6779
6780#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
6781static void
6782ffecom_let_char_ (tree dest_tree, tree dest_length,
6783 ffetargetCharacterSize dest_size, ffebld source)
5ff904cd 6784{
c7e4ee3a
CB
6785 ffecomConcatList_ catlist;
6786 tree source_length;
6787 tree source_tree;
6788 tree expr_tree;
5ff904cd 6789
c7e4ee3a
CB
6790 if ((dest_tree == error_mark_node)
6791 || (dest_length == error_mark_node))
6792 return;
5ff904cd 6793
c7e4ee3a
CB
6794 assert (dest_tree != NULL_TREE);
6795 assert (dest_length != NULL_TREE);
5ff904cd 6796
c7e4ee3a
CB
6797 /* Source might be an opCONVERT, which just means it is a different size
6798 than the destination. Since the underlying implementation here handles
6799 that (directly or via the s_copy or s_cat run-time-library functions),
6800 we don't need the "convenience" of an opCONVERT that tells us to
6801 truncate or blank-pad, particularly since the resulting implementation
6802 would probably be slower than otherwise. */
5ff904cd 6803
c7e4ee3a
CB
6804 while (ffebld_op (source) == FFEBLD_opCONVERT)
6805 source = ffebld_left (source);
5ff904cd 6806
c7e4ee3a
CB
6807 catlist = ffecom_concat_list_new_ (source, dest_size);
6808 switch (ffecom_concat_list_count_ (catlist))
6809 {
6810 case 0: /* Shouldn't happen, but in case it does... */
6811 ffecom_concat_list_kill_ (catlist);
6812 source_tree = null_pointer_node;
6813 source_length = ffecom_f2c_ftnlen_zero_node;
6814 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6815 TREE_CHAIN (expr_tree) = build_tree_list (NULL_TREE, source_tree);
6816 TREE_CHAIN (TREE_CHAIN (expr_tree))
6817 = build_tree_list (NULL_TREE, dest_length);
6818 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6819 = build_tree_list (NULL_TREE, source_length);
5ff904cd 6820
c7e4ee3a
CB
6821 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCOPY, expr_tree, NULL_TREE);
6822 TREE_SIDE_EFFECTS (expr_tree) = 1;
5ff904cd 6823
c7e4ee3a 6824 expand_expr_stmt (expr_tree);
5ff904cd 6825
c7e4ee3a 6826 return;
5ff904cd 6827
c7e4ee3a
CB
6828 case 1: /* The (fairly) easy case. */
6829 ffecom_char_args_ (&source_tree, &source_length,
6830 ffecom_concat_list_expr_ (catlist, 0));
6831 ffecom_concat_list_kill_ (catlist);
6832 assert (source_tree != NULL_TREE);
6833 assert (source_length != NULL_TREE);
6834
6835 if ((source_tree == error_mark_node)
6836 || (source_length == error_mark_node))
6837 return;
6838
6839 if (dest_size == 1)
6840 {
6841 dest_tree
6842 = ffecom_1 (INDIRECT_REF,
6843 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6844 (dest_tree))),
6845 dest_tree);
6846 dest_tree
6847 = ffecom_2 (ARRAY_REF,
6848 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6849 (dest_tree))),
6850 dest_tree,
6851 integer_one_node);
6852 source_tree
6853 = ffecom_1 (INDIRECT_REF,
6854 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6855 (source_tree))),
6856 source_tree);
6857 source_tree
6858 = ffecom_2 (ARRAY_REF,
6859 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6860 (source_tree))),
6861 source_tree,
6862 integer_one_node);
5ff904cd 6863
c7e4ee3a 6864 expr_tree = ffecom_modify (void_type_node, dest_tree, source_tree);
5ff904cd 6865
c7e4ee3a 6866 expand_expr_stmt (expr_tree);
5ff904cd 6867
c7e4ee3a
CB
6868 return;
6869 }
5ff904cd 6870
c7e4ee3a
CB
6871 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6872 TREE_CHAIN (expr_tree) = build_tree_list (NULL_TREE, source_tree);
6873 TREE_CHAIN (TREE_CHAIN (expr_tree))
6874 = build_tree_list (NULL_TREE, dest_length);
6875 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6876 = build_tree_list (NULL_TREE, source_length);
5ff904cd 6877
c7e4ee3a
CB
6878 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCOPY, expr_tree, NULL_TREE);
6879 TREE_SIDE_EFFECTS (expr_tree) = 1;
5ff904cd 6880
c7e4ee3a 6881 expand_expr_stmt (expr_tree);
5ff904cd 6882
c7e4ee3a 6883 return;
5ff904cd 6884
c7e4ee3a
CB
6885 default: /* Must actually concatenate things. */
6886 break;
6887 }
5ff904cd 6888
c7e4ee3a 6889 /* Heavy-duty concatenation. */
5ff904cd 6890
c7e4ee3a
CB
6891 {
6892 int count = ffecom_concat_list_count_ (catlist);
6893 int i;
6894 tree lengths;
6895 tree items;
6896 tree length_array;
6897 tree item_array;
6898 tree citem;
6899 tree clength;
5ff904cd 6900
c7e4ee3a
CB
6901#ifdef HOHO
6902 length_array
6903 = lengths
6904 = ffecom_push_tempvar (ffecom_f2c_ftnlen_type_node,
6905 FFETARGET_charactersizeNONE, count, TRUE);
6906 item_array = items = ffecom_push_tempvar (ffecom_f2c_address_type_node,
6907 FFETARGET_charactersizeNONE,
6908 count, TRUE);
6909#else
6910 {
6911 tree hook;
6912
6913 hook = ffebld_nonter_hook (source);
6914 assert (hook);
6915 assert (TREE_CODE (hook) == TREE_VEC);
6916 assert (TREE_VEC_LENGTH (hook) == 2);
6917 length_array = lengths = TREE_VEC_ELT (hook, 0);
6918 item_array = items = TREE_VEC_ELT (hook, 1);
5ff904cd 6919 }
c7e4ee3a 6920#endif
5ff904cd 6921
c7e4ee3a
CB
6922 for (i = 0; i < count; ++i)
6923 {
6924 ffecom_char_args_ (&citem, &clength,
6925 ffecom_concat_list_expr_ (catlist, i));
6926 if ((citem == error_mark_node)
6927 || (clength == error_mark_node))
6928 {
6929 ffecom_concat_list_kill_ (catlist);
6930 return;
6931 }
5ff904cd 6932
c7e4ee3a
CB
6933 items
6934 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (items),
6935 ffecom_modify (void_type_node,
6936 ffecom_2 (ARRAY_REF,
6937 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array))),
6938 item_array,
6939 build_int_2 (i, 0)),
6940 citem),
6941 items);
6942 lengths
6943 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (lengths),
6944 ffecom_modify (void_type_node,
6945 ffecom_2 (ARRAY_REF,
6946 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array))),
6947 length_array,
6948 build_int_2 (i, 0)),
6949 clength),
6950 lengths);
6951 }
5ff904cd 6952
c7e4ee3a
CB
6953 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6954 TREE_CHAIN (expr_tree)
6955 = build_tree_list (NULL_TREE,
6956 ffecom_1 (ADDR_EXPR,
6957 build_pointer_type (TREE_TYPE (items)),
6958 items));
6959 TREE_CHAIN (TREE_CHAIN (expr_tree))
6960 = build_tree_list (NULL_TREE,
6961 ffecom_1 (ADDR_EXPR,
6962 build_pointer_type (TREE_TYPE (lengths)),
6963 lengths));
6964 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6965 = build_tree_list
6966 (NULL_TREE,
6967 ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
6968 convert (ffecom_f2c_ftnlen_type_node,
6969 build_int_2 (count, 0))));
6970 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree))))
6971 = build_tree_list (NULL_TREE, dest_length);
5ff904cd 6972
c7e4ee3a
CB
6973 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCAT, expr_tree, NULL_TREE);
6974 TREE_SIDE_EFFECTS (expr_tree) = 1;
5ff904cd 6975
c7e4ee3a
CB
6976 expand_expr_stmt (expr_tree);
6977 }
5ff904cd 6978
c7e4ee3a
CB
6979 ffecom_concat_list_kill_ (catlist);
6980}
5ff904cd 6981
c7e4ee3a
CB
6982#endif
6983/* ffecom_make_gfrt_ -- Make initial info for run-time routine
5ff904cd 6984
c7e4ee3a
CB
6985 ffecomGfrt ix;
6986 ffecom_make_gfrt_(ix);
5ff904cd 6987
c7e4ee3a
CB
6988 Assumes gfrt_[ix] is NULL_TREE, and replaces it with the FUNCTION_DECL
6989 for the indicated run-time routine (ix). */
5ff904cd 6990
c7e4ee3a
CB
6991#if FFECOM_targetCURRENT == FFECOM_targetGCC
6992static void
6993ffecom_make_gfrt_ (ffecomGfrt ix)
6994{
6995 tree t;
6996 tree ttype;
5ff904cd 6997
c7e4ee3a
CB
6998 switch (ffecom_gfrt_type_[ix])
6999 {
7000 case FFECOM_rttypeVOID_:
7001 ttype = void_type_node;
7002 break;
5ff904cd 7003
c7e4ee3a
CB
7004 case FFECOM_rttypeVOIDSTAR_:
7005 ttype = TREE_TYPE (null_pointer_node); /* `void *'. */
7006 break;
5ff904cd 7007
c7e4ee3a
CB
7008 case FFECOM_rttypeFTNINT_:
7009 ttype = ffecom_f2c_ftnint_type_node;
7010 break;
5ff904cd 7011
c7e4ee3a
CB
7012 case FFECOM_rttypeINTEGER_:
7013 ttype = ffecom_f2c_integer_type_node;
7014 break;
5ff904cd 7015
c7e4ee3a
CB
7016 case FFECOM_rttypeLONGINT_:
7017 ttype = ffecom_f2c_longint_type_node;
7018 break;
5ff904cd 7019
c7e4ee3a
CB
7020 case FFECOM_rttypeLOGICAL_:
7021 ttype = ffecom_f2c_logical_type_node;
7022 break;
5ff904cd 7023
c7e4ee3a
CB
7024 case FFECOM_rttypeREAL_F2C_:
7025 ttype = double_type_node;
7026 break;
5ff904cd 7027
c7e4ee3a
CB
7028 case FFECOM_rttypeREAL_GNU_:
7029 ttype = float_type_node;
7030 break;
5ff904cd 7031
c7e4ee3a
CB
7032 case FFECOM_rttypeCOMPLEX_F2C_:
7033 ttype = void_type_node;
7034 break;
5ff904cd 7035
c7e4ee3a
CB
7036 case FFECOM_rttypeCOMPLEX_GNU_:
7037 ttype = ffecom_f2c_complex_type_node;
7038 break;
5ff904cd 7039
c7e4ee3a
CB
7040 case FFECOM_rttypeDOUBLE_:
7041 ttype = double_type_node;
7042 break;
5ff904cd 7043
c7e4ee3a
CB
7044 case FFECOM_rttypeDOUBLEREAL_:
7045 ttype = ffecom_f2c_doublereal_type_node;
7046 break;
5ff904cd 7047
c7e4ee3a
CB
7048 case FFECOM_rttypeDBLCMPLX_F2C_:
7049 ttype = void_type_node;
7050 break;
5ff904cd 7051
c7e4ee3a
CB
7052 case FFECOM_rttypeDBLCMPLX_GNU_:
7053 ttype = ffecom_f2c_doublecomplex_type_node;
7054 break;
5ff904cd 7055
c7e4ee3a
CB
7056 case FFECOM_rttypeCHARACTER_:
7057 ttype = void_type_node;
7058 break;
7059
7060 default:
7061 ttype = NULL;
7062 assert ("bad rttype" == NULL);
7063 break;
5ff904cd 7064 }
5ff904cd 7065
c7e4ee3a
CB
7066 ttype = build_function_type (ttype, NULL_TREE);
7067 t = build_decl (FUNCTION_DECL,
7068 get_identifier (ffecom_gfrt_name_[ix]),
7069 ttype);
7070 DECL_EXTERNAL (t) = 1;
7071 TREE_PUBLIC (t) = 1;
7072 TREE_THIS_VOLATILE (t) = ffecom_gfrt_volatile_[ix] ? 1 : 0;
5ff904cd 7073
c7e4ee3a 7074 t = start_decl (t, TRUE);
5ff904cd 7075
c7e4ee3a 7076 finish_decl (t, NULL_TREE, TRUE);
5ff904cd 7077
c7e4ee3a 7078 ffecom_gfrt_[ix] = t;
5ff904cd
JL
7079}
7080
7081#endif
c7e4ee3a
CB
7082/* Phase 1 pass over each member of a COMMON/EQUIVALENCE group. */
7083
5ff904cd 7084#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
7085static void
7086ffecom_member_phase1_ (ffestorag mst UNUSED, ffestorag st)
5ff904cd 7087{
c7e4ee3a 7088 ffesymbol s = ffestorag_symbol (st);
5ff904cd 7089
c7e4ee3a
CB
7090 if (ffesymbol_namelisted (s))
7091 ffecom_member_namelisted_ = TRUE;
7092}
5ff904cd 7093
c7e4ee3a
CB
7094#endif
7095/* Phase 2 pass over each member of a COMMON/EQUIVALENCE group. Declare
7096 the member so debugger will see it. Otherwise nobody should be
7097 referencing the member. */
5ff904cd 7098
c7e4ee3a 7099#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
7100static void
7101ffecom_member_phase2_ (ffestorag mst, ffestorag st)
7102{
7103 ffesymbol s;
7104 tree t;
7105 tree mt;
7106 tree type;
5ff904cd 7107
c7e4ee3a
CB
7108 if ((mst == NULL)
7109 || ((mt = ffestorag_hook (mst)) == NULL)
7110 || (mt == error_mark_node))
7111 return;
5ff904cd 7112
c7e4ee3a
CB
7113 if ((st == NULL)
7114 || ((s = ffestorag_symbol (st)) == NULL))
7115 return;
5ff904cd 7116
c7e4ee3a
CB
7117 type = ffecom_type_localvar_ (s,
7118 ffesymbol_basictype (s),
7119 ffesymbol_kindtype (s));
7120 if (type == error_mark_node)
7121 return;
5ff904cd 7122
c7e4ee3a
CB
7123 t = build_decl (VAR_DECL,
7124 ffecom_get_identifier_ (ffesymbol_text (s)),
7125 type);
5ff904cd 7126
c7e4ee3a
CB
7127 TREE_STATIC (t) = TREE_STATIC (mt);
7128 DECL_INITIAL (t) = NULL_TREE;
7129 TREE_ASM_WRITTEN (t) = 1;
5ff904cd 7130
c7e4ee3a
CB
7131 DECL_RTL (t)
7132 = gen_rtx (MEM, TYPE_MODE (type),
7133 plus_constant (XEXP (DECL_RTL (mt), 0),
7134 ffestorag_modulo (mst)
7135 + ffestorag_offset (st)
7136 - ffestorag_offset (mst)));
5ff904cd 7137
c7e4ee3a 7138 t = start_decl (t, FALSE);
5ff904cd 7139
c7e4ee3a 7140 finish_decl (t, NULL_TREE, FALSE);
5ff904cd
JL
7141}
7142
c7e4ee3a
CB
7143#endif
7144/* Prepare source expression for assignment into a destination perhaps known
7145 to be of a specific size. */
5ff904cd 7146
c7e4ee3a
CB
7147static void
7148ffecom_prepare_let_char_ (ffetargetCharacterSize dest_size, ffebld source)
5ff904cd 7149{
c7e4ee3a
CB
7150 ffecomConcatList_ catlist;
7151 int count;
7152 int i;
7153 tree ltmp;
7154 tree itmp;
7155 tree tempvar = NULL_TREE;
5ff904cd 7156
c7e4ee3a
CB
7157 while (ffebld_op (source) == FFEBLD_opCONVERT)
7158 source = ffebld_left (source);
5ff904cd 7159
c7e4ee3a
CB
7160 catlist = ffecom_concat_list_new_ (source, dest_size);
7161 count = ffecom_concat_list_count_ (catlist);
5ff904cd 7162
c7e4ee3a
CB
7163 if (count >= 2)
7164 {
7165 ltmp
7166 = ffecom_make_tempvar ("let_char_len", ffecom_f2c_ftnlen_type_node,
7167 FFETARGET_charactersizeNONE, count);
7168 itmp
7169 = ffecom_make_tempvar ("let_char_item", ffecom_f2c_address_type_node,
7170 FFETARGET_charactersizeNONE, count);
7171
7172 tempvar = make_tree_vec (2);
7173 TREE_VEC_ELT (tempvar, 0) = ltmp;
7174 TREE_VEC_ELT (tempvar, 1) = itmp;
7175 }
5ff904cd 7176
c7e4ee3a
CB
7177 for (i = 0; i < count; ++i)
7178 ffecom_prepare_arg_ptr_to_expr (ffecom_concat_list_expr_ (catlist, i));
5ff904cd 7179
c7e4ee3a 7180 ffecom_concat_list_kill_ (catlist);
5ff904cd 7181
c7e4ee3a
CB
7182 if (tempvar)
7183 {
7184 ffebld_nonter_set_hook (source, tempvar);
7185 current_binding_level->prep_state = 1;
7186 }
7187}
5ff904cd 7188
c7e4ee3a 7189/* ffecom_push_dummy_decls_ -- Transform dummy args, push parm decls in order
5ff904cd 7190
c7e4ee3a
CB
7191 Ignores STAR (alternate-return) dummies. All other get exec-transitioned
7192 (which generates their trees) and then their trees get push_parm_decl'd.
5ff904cd 7193
c7e4ee3a
CB
7194 The second arg is TRUE if the dummies are for a statement function, in
7195 which case lengths are not pushed for character arguments (since they are
7196 always known by both the caller and the callee, though the code allows
7197 for someday permitting CHAR*(*) stmtfunc dummies). */
5ff904cd 7198
c7e4ee3a
CB
7199#if FFECOM_targetCURRENT == FFECOM_targetGCC
7200static void
7201ffecom_push_dummy_decls_ (ffebld dummy_list, bool stmtfunc)
7202{
7203 ffebld dummy;
7204 ffebld dumlist;
7205 ffesymbol s;
7206 tree parm;
5ff904cd 7207
c7e4ee3a 7208 ffecom_transform_only_dummies_ = TRUE;
5ff904cd 7209
c7e4ee3a 7210 /* First push the parms corresponding to actual dummy "contents". */
5ff904cd 7211
c7e4ee3a
CB
7212 for (dumlist = dummy_list; dumlist != NULL; dumlist = ffebld_trail (dumlist))
7213 {
7214 dummy = ffebld_head (dumlist);
7215 switch (ffebld_op (dummy))
7216 {
7217 case FFEBLD_opSTAR:
7218 case FFEBLD_opANY:
7219 continue; /* Forget alternate returns. */
5ff904cd 7220
c7e4ee3a
CB
7221 default:
7222 break;
7223 }
7224 assert (ffebld_op (dummy) == FFEBLD_opSYMTER);
7225 s = ffebld_symter (dummy);
7226 parm = ffesymbol_hook (s).decl_tree;
7227 if (parm == NULL_TREE)
7228 {
7229 s = ffecom_sym_transform_ (s);
7230 parm = ffesymbol_hook (s).decl_tree;
7231 assert (parm != NULL_TREE);
7232 }
7233 if (parm != error_mark_node)
7234 push_parm_decl (parm);
5ff904cd
JL
7235 }
7236
c7e4ee3a 7237 /* Then, for CHARACTER dummies, push the parms giving their lengths. */
5ff904cd 7238
c7e4ee3a
CB
7239 for (dumlist = dummy_list; dumlist != NULL; dumlist = ffebld_trail (dumlist))
7240 {
7241 dummy = ffebld_head (dumlist);
7242 switch (ffebld_op (dummy))
7243 {
7244 case FFEBLD_opSTAR:
7245 case FFEBLD_opANY:
7246 continue; /* Forget alternate returns, they mean
7247 NOTHING! */
7248
7249 default:
7250 break;
7251 }
7252 s = ffebld_symter (dummy);
7253 if (ffesymbol_basictype (s) != FFEINFO_basictypeCHARACTER)
7254 continue; /* Only looking for CHARACTER arguments. */
7255 if (stmtfunc && (ffesymbol_size (s) != FFETARGET_charactersizeNONE))
7256 continue; /* Stmtfunc arg with known size needs no
7257 length param. */
7258 if (ffesymbol_kind (s) != FFEINFO_kindENTITY)
7259 continue; /* Only looking for variables and arrays. */
7260 parm = ffesymbol_hook (s).length_tree;
7261 assert (parm != NULL_TREE);
7262 if (parm != error_mark_node)
7263 push_parm_decl (parm);
7264 }
7265
7266 ffecom_transform_only_dummies_ = FALSE;
5ff904cd
JL
7267}
7268
7269#endif
c7e4ee3a 7270/* ffecom_start_progunit_ -- Beginning of program unit
5ff904cd 7271
c7e4ee3a
CB
7272 Does GNU back end stuff necessary to teach it about the start of its
7273 equivalent of a Fortran program unit. */
5ff904cd
JL
7274
7275#if FFECOM_targetCURRENT == FFECOM_targetGCC
7276static void
c7e4ee3a 7277ffecom_start_progunit_ ()
5ff904cd 7278{
c7e4ee3a
CB
7279 ffesymbol fn = ffecom_primary_entry_;
7280 ffebld arglist;
7281 tree id; /* Identifier (name) of function. */
7282 tree type; /* Type of function. */
7283 tree result; /* Result of function. */
7284 ffeinfoBasictype bt;
7285 ffeinfoKindtype kt;
7286 ffeglobal g;
7287 ffeglobalType gt;
7288 ffeglobalType egt = FFEGLOBAL_type;
7289 bool charfunc;
7290 bool cmplxfunc;
7291 bool altentries = (ffecom_num_entrypoints_ != 0);
7292 bool multi
7293 = altentries
7294 && (ffecom_primary_entry_kind_ == FFEINFO_kindFUNCTION)
7295 && (ffecom_master_bt_ == FFEINFO_basictypeNONE);
7296 bool main_program = FALSE;
7297 int old_lineno = lineno;
3b304f5b 7298 const char *old_input_filename = input_filename;
c7e4ee3a 7299 int yes;
5ff904cd 7300
c7e4ee3a
CB
7301 assert (fn != NULL);
7302 assert (ffesymbol_hook (fn).decl_tree == NULL_TREE);
5ff904cd 7303
c7e4ee3a
CB
7304 input_filename = ffesymbol_where_filename (fn);
7305 lineno = ffesymbol_where_filelinenum (fn);
5ff904cd 7306
c7e4ee3a
CB
7307 /* c-parse.y indeed does call suspend_momentary and not only ignores the
7308 return value, but also never calls resume_momentary, when starting an
7309 outer function (see "fndef:", "setspecs:", and so on). So g77 does the
7310 same thing. It shouldn't be a problem since start_function calls
7311 temporary_allocation, but it might be necessary. If it causes a problem
7312 here, then maybe there's a bug lurking in gcc. NOTE: This identical
7313 comment appears twice in thist file. */
7314
7315 suspend_momentary ();
7316
7317 switch (ffecom_primary_entry_kind_)
7318 {
7319 case FFEINFO_kindPROGRAM:
7320 main_program = TRUE;
7321 gt = FFEGLOBAL_typeMAIN;
7322 bt = FFEINFO_basictypeNONE;
7323 kt = FFEINFO_kindtypeNONE;
7324 type = ffecom_tree_fun_type_void;
7325 charfunc = FALSE;
7326 cmplxfunc = FALSE;
7327 break;
7328
7329 case FFEINFO_kindBLOCKDATA:
7330 gt = FFEGLOBAL_typeBDATA;
7331 bt = FFEINFO_basictypeNONE;
7332 kt = FFEINFO_kindtypeNONE;
7333 type = ffecom_tree_fun_type_void;
7334 charfunc = FALSE;
7335 cmplxfunc = FALSE;
7336 break;
7337
7338 case FFEINFO_kindFUNCTION:
7339 gt = FFEGLOBAL_typeFUNC;
7340 egt = FFEGLOBAL_typeEXT;
7341 bt = ffesymbol_basictype (fn);
7342 kt = ffesymbol_kindtype (fn);
7343 if (bt == FFEINFO_basictypeNONE)
7344 {
7345 ffeimplic_establish_symbol (fn);
7346 if (ffesymbol_funcresult (fn) != NULL)
7347 ffeimplic_establish_symbol (ffesymbol_funcresult (fn));
7348 bt = ffesymbol_basictype (fn);
7349 kt = ffesymbol_kindtype (fn);
7350 }
7351
7352 if (multi)
7353 charfunc = cmplxfunc = FALSE;
7354 else if (bt == FFEINFO_basictypeCHARACTER)
7355 charfunc = TRUE, cmplxfunc = FALSE;
7356 else if ((bt == FFEINFO_basictypeCOMPLEX)
7357 && ffesymbol_is_f2c (fn)
7358 && !altentries)
7359 charfunc = FALSE, cmplxfunc = TRUE;
7360 else
7361 charfunc = cmplxfunc = FALSE;
7362
7363 if (multi || charfunc)
7364 type = ffecom_tree_fun_type_void;
7365 else if (ffesymbol_is_f2c (fn) && !altentries)
7366 type = ffecom_tree_fun_type[bt][kt];
7367 else
7368 type = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
7369
7370 if ((type == NULL_TREE)
7371 || (TREE_TYPE (type) == NULL_TREE))
7372 type = ffecom_tree_fun_type_void; /* _sym_exec_transition. */
7373 break;
7374
7375 case FFEINFO_kindSUBROUTINE:
7376 gt = FFEGLOBAL_typeSUBR;
7377 egt = FFEGLOBAL_typeEXT;
7378 bt = FFEINFO_basictypeNONE;
7379 kt = FFEINFO_kindtypeNONE;
7380 if (ffecom_is_altreturning_)
7381 type = ffecom_tree_subr_type;
7382 else
7383 type = ffecom_tree_fun_type_void;
7384 charfunc = FALSE;
7385 cmplxfunc = FALSE;
7386 break;
5ff904cd 7387
c7e4ee3a
CB
7388 default:
7389 assert ("say what??" == NULL);
7390 /* Fall through. */
7391 case FFEINFO_kindANY:
7392 gt = FFEGLOBAL_typeANY;
7393 bt = FFEINFO_basictypeNONE;
7394 kt = FFEINFO_kindtypeNONE;
7395 type = error_mark_node;
7396 charfunc = FALSE;
7397 cmplxfunc = FALSE;
7398 break;
7399 }
5ff904cd 7400
c7e4ee3a 7401 if (altentries)
5ff904cd 7402 {
c7e4ee3a 7403 id = ffecom_get_invented_identifier ("__g77_masterfun_%s",
14657de8 7404 ffesymbol_text (fn));
c7e4ee3a
CB
7405 }
7406#if FFETARGET_isENFORCED_MAIN
7407 else if (main_program)
7408 id = get_identifier (FFETARGET_nameENFORCED_MAIN_NAME);
7409#endif
7410 else
7411 id = ffecom_get_external_identifier_ (fn);
5ff904cd 7412
c7e4ee3a
CB
7413 start_function (id,
7414 type,
7415 0, /* nested/inline */
7416 !altentries); /* TREE_PUBLIC */
5ff904cd 7417
c7e4ee3a 7418 TREE_USED (current_function_decl) = 1; /* Avoid spurious warning if altentries. */
5ff904cd 7419
c7e4ee3a
CB
7420 if (!altentries
7421 && ((g = ffesymbol_global (fn)) != NULL)
7422 && ((ffeglobal_type (g) == gt)
7423 || (ffeglobal_type (g) == egt)))
7424 {
7425 ffeglobal_set_hook (g, current_function_decl);
7426 }
5ff904cd 7427
c7e4ee3a 7428 yes = suspend_momentary ();
5ff904cd 7429
c7e4ee3a
CB
7430 /* Arg handling needs exec-transitioned ffesymbols to work with. But
7431 exec-transitioning needs current_function_decl to be filled in. So we
7432 do these things in two phases. */
5ff904cd 7433
c7e4ee3a
CB
7434 if (altentries)
7435 { /* 1st arg identifies which entrypoint. */
7436 ffecom_which_entrypoint_decl_
7437 = build_decl (PARM_DECL,
7438 ffecom_get_invented_identifier ("__g77_%s",
14657de8 7439 "which_entrypoint"),
c7e4ee3a
CB
7440 integer_type_node);
7441 push_parm_decl (ffecom_which_entrypoint_decl_);
7442 }
5ff904cd 7443
c7e4ee3a
CB
7444 if (charfunc
7445 || cmplxfunc
7446 || multi)
7447 { /* Arg for result (return value). */
7448 tree type;
7449 tree length;
5ff904cd 7450
c7e4ee3a
CB
7451 if (charfunc)
7452 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
7453 else if (cmplxfunc)
7454 type = ffecom_tree_type[FFEINFO_basictypeCOMPLEX][kt];
7455 else
7456 type = ffecom_multi_type_node_;
5ff904cd 7457
14657de8 7458 result = ffecom_get_invented_identifier ("__g77_%s", "result");
5ff904cd 7459
c7e4ee3a 7460 /* Make length arg _and_ enhance type info for CHAR arg itself. */
5ff904cd 7461
c7e4ee3a
CB
7462 if (charfunc)
7463 length = ffecom_char_enhance_arg_ (&type, fn);
7464 else
7465 length = NULL_TREE; /* Not ref'd if !charfunc. */
5ff904cd 7466
c7e4ee3a
CB
7467 type = build_pointer_type (type);
7468 result = build_decl (PARM_DECL, result, type);
5ff904cd 7469
c7e4ee3a
CB
7470 push_parm_decl (result);
7471 if (multi)
7472 ffecom_multi_retval_ = result;
7473 else
7474 ffecom_func_result_ = result;
5ff904cd 7475
c7e4ee3a
CB
7476 if (charfunc)
7477 {
7478 push_parm_decl (length);
7479 ffecom_func_length_ = length;
7480 }
5ff904cd
JL
7481 }
7482
c7e4ee3a
CB
7483 if (ffecom_primary_entry_is_proc_)
7484 {
7485 if (altentries)
7486 arglist = ffecom_master_arglist_;
7487 else
7488 arglist = ffesymbol_dummyargs (fn);
7489 ffecom_push_dummy_decls_ (arglist, FALSE);
7490 }
5ff904cd 7491
c7e4ee3a 7492 resume_momentary (yes);
5ff904cd 7493
c7e4ee3a
CB
7494 if (TREE_CODE (current_function_decl) != ERROR_MARK)
7495 store_parm_decls (main_program ? 1 : 0);
5ff904cd 7496
c7e4ee3a
CB
7497 ffecom_start_compstmt ();
7498 /* Disallow temp vars at this level. */
7499 current_binding_level->prep_state = 2;
5ff904cd 7500
c7e4ee3a
CB
7501 lineno = old_lineno;
7502 input_filename = old_input_filename;
5ff904cd 7503
c7e4ee3a
CB
7504 /* This handles any symbols still untransformed, in case -g specified.
7505 This used to be done in ffecom_finish_progunit, but it turns out to
7506 be necessary to do it here so that statement functions are
7507 expanded before code. But don't bother for BLOCK DATA. */
5ff904cd 7508
c7e4ee3a
CB
7509 if (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA)
7510 ffesymbol_drive (ffecom_finish_symbol_transform_);
5ff904cd
JL
7511}
7512
7513#endif
c7e4ee3a 7514/* ffecom_sym_transform_ -- Transform FFE sym into backend sym
5ff904cd 7515
c7e4ee3a
CB
7516 ffesymbol s;
7517 ffecom_sym_transform_(s);
7518
7519 The ffesymbol_hook info for s is updated with appropriate backend info
7520 on the symbol. */
7521
7522#if FFECOM_targetCURRENT == FFECOM_targetGCC
7523static ffesymbol
7524ffecom_sym_transform_ (ffesymbol s)
7525{
7526 tree t; /* Transformed thingy. */
7527 tree tlen; /* Length if CHAR*(*). */
7528 bool addr; /* Is t the address of the thingy? */
7529 ffeinfoBasictype bt;
7530 ffeinfoKindtype kt;
7531 ffeglobal g;
7532 int yes;
7533 int old_lineno = lineno;
3b304f5b 7534 const char *old_input_filename = input_filename;
5ff904cd 7535
c7e4ee3a
CB
7536 /* Must ensure special ASSIGN variables are declared at top of outermost
7537 block, else they'll end up in the innermost block when their first
7538 ASSIGN is seen, which leaves them out of scope when they're the
7539 subject of a GOTO or I/O statement.
5ff904cd 7540
c7e4ee3a
CB
7541 We make this variable even if -fugly-assign. Just let it go unused,
7542 in case it turns out there are cases where we really want to use this
7543 variable anyway (e.g. ASSIGN to INTEGER*2 variable). */
5ff904cd 7544
c7e4ee3a
CB
7545 if (! ffecom_transform_only_dummies_
7546 && ffesymbol_assigned (s)
7547 && ! ffesymbol_hook (s).assign_tree)
7548 s = ffecom_sym_transform_assign_ (s);
5ff904cd 7549
c7e4ee3a 7550 if (ffesymbol_sfdummyparent (s) == NULL)
5ff904cd 7551 {
c7e4ee3a
CB
7552 input_filename = ffesymbol_where_filename (s);
7553 lineno = ffesymbol_where_filelinenum (s);
7554 }
7555 else
7556 {
7557 ffesymbol sf = ffesymbol_sfdummyparent (s);
5ff904cd 7558
c7e4ee3a
CB
7559 input_filename = ffesymbol_where_filename (sf);
7560 lineno = ffesymbol_where_filelinenum (sf);
7561 }
6d433196 7562
c7e4ee3a
CB
7563 bt = ffeinfo_basictype (ffebld_info (s));
7564 kt = ffeinfo_kindtype (ffebld_info (s));
5ff904cd 7565
c7e4ee3a
CB
7566 t = NULL_TREE;
7567 tlen = NULL_TREE;
7568 addr = FALSE;
5ff904cd 7569
c7e4ee3a
CB
7570 switch (ffesymbol_kind (s))
7571 {
7572 case FFEINFO_kindNONE:
7573 switch (ffesymbol_where (s))
7574 {
7575 case FFEINFO_whereDUMMY: /* Subroutine or function. */
7576 assert (ffecom_transform_only_dummies_);
5ff904cd 7577
c7e4ee3a
CB
7578 /* Before 0.4, this could be ENTITY/DUMMY, but see
7579 ffestu_sym_end_transition -- no longer true (in particular, if
7580 it could be an ENTITY, it _will_ be made one, so that
7581 possibility won't come through here). So we never make length
7582 arg for CHARACTER type. */
5ff904cd 7583
c7e4ee3a
CB
7584 t = build_decl (PARM_DECL,
7585 ffecom_get_identifier_ (ffesymbol_text (s)),
7586 ffecom_tree_ptr_to_subr_type);
7587#if BUILT_FOR_270
7588 DECL_ARTIFICIAL (t) = 1;
7589#endif
7590 addr = TRUE;
7591 break;
5ff904cd 7592
c7e4ee3a
CB
7593 case FFEINFO_whereGLOBAL: /* Subroutine or function. */
7594 assert (!ffecom_transform_only_dummies_);
5ff904cd 7595
c7e4ee3a
CB
7596 if (((g = ffesymbol_global (s)) != NULL)
7597 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
7598 || (ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
7599 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
7600 && (ffeglobal_hook (g) != NULL_TREE)
7601 && ffe_is_globals ())
7602 {
7603 t = ffeglobal_hook (g);
7604 break;
7605 }
5ff904cd 7606
c7e4ee3a
CB
7607 t = build_decl (FUNCTION_DECL,
7608 ffecom_get_external_identifier_ (s),
7609 ffecom_tree_subr_type); /* Assume subr. */
7610 DECL_EXTERNAL (t) = 1;
7611 TREE_PUBLIC (t) = 1;
5ff904cd 7612
c7e4ee3a
CB
7613 t = start_decl (t, FALSE);
7614 finish_decl (t, NULL_TREE, FALSE);
795232f7 7615
c7e4ee3a
CB
7616 if ((g != NULL)
7617 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
7618 || (ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
7619 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
7620 ffeglobal_set_hook (g, t);
5ff904cd 7621
7189a4b0 7622 ffecom_save_tree_forever (t);
5ff904cd 7623
c7e4ee3a 7624 break;
5ff904cd 7625
c7e4ee3a
CB
7626 default:
7627 assert ("NONE where unexpected" == NULL);
7628 /* Fall through. */
7629 case FFEINFO_whereANY:
7630 break;
7631 }
5ff904cd 7632 break;
5ff904cd 7633
c7e4ee3a
CB
7634 case FFEINFO_kindENTITY:
7635 switch (ffeinfo_where (ffesymbol_info (s)))
7636 {
5ff904cd 7637
c7e4ee3a
CB
7638 case FFEINFO_whereCONSTANT:
7639 /* ~~Debugging info needed? */
7640 assert (!ffecom_transform_only_dummies_);
7641 t = error_mark_node; /* Shouldn't ever see this in expr. */
7642 break;
5ff904cd 7643
c7e4ee3a
CB
7644 case FFEINFO_whereLOCAL:
7645 assert (!ffecom_transform_only_dummies_);
5ff904cd 7646
c7e4ee3a
CB
7647 {
7648 ffestorag st = ffesymbol_storage (s);
7649 tree type;
5ff904cd 7650
c7e4ee3a
CB
7651 if ((st != NULL)
7652 && (ffestorag_size (st) == 0))
7653 {
7654 t = error_mark_node;
7655 break;
7656 }
5ff904cd 7657
c7e4ee3a
CB
7658 yes = suspend_momentary ();
7659 type = ffecom_type_localvar_ (s, bt, kt);
7660 resume_momentary (yes);
5ff904cd 7661
c7e4ee3a
CB
7662 if (type == error_mark_node)
7663 {
7664 t = error_mark_node;
7665 break;
7666 }
5ff904cd 7667
c7e4ee3a
CB
7668 if ((st != NULL)
7669 && (ffestorag_parent (st) != NULL))
7670 { /* Child of EQUIVALENCE parent. */
7671 ffestorag est;
7672 tree et;
7673 int yes;
7674 ffetargetOffset offset;
5ff904cd 7675
c7e4ee3a
CB
7676 est = ffestorag_parent (st);
7677 ffecom_transform_equiv_ (est);
5ff904cd 7678
c7e4ee3a
CB
7679 et = ffestorag_hook (est);
7680 assert (et != NULL_TREE);
5ff904cd 7681
c7e4ee3a
CB
7682 if (! TREE_STATIC (et))
7683 put_var_into_stack (et);
5ff904cd 7684
c7e4ee3a 7685 yes = suspend_momentary ();
5ff904cd 7686
c7e4ee3a
CB
7687 offset = ffestorag_modulo (est)
7688 + ffestorag_offset (ffesymbol_storage (s))
7689 - ffestorag_offset (est);
5ff904cd 7690
c7e4ee3a 7691 ffecom_debug_kludge_ (et, "EQUIVALENCE", s, type, offset);
5ff904cd 7692
c7e4ee3a 7693 /* (t_type *) (((char *) &et) + offset) */
5ff904cd 7694
c7e4ee3a
CB
7695 t = convert (string_type_node, /* (char *) */
7696 ffecom_1 (ADDR_EXPR,
7697 build_pointer_type (TREE_TYPE (et)),
7698 et));
7699 t = ffecom_2 (PLUS_EXPR, TREE_TYPE (t),
7700 t,
7701 build_int_2 (offset, 0));
7702 t = convert (build_pointer_type (type),
7703 t);
d50108c7 7704 TREE_CONSTANT (t) = staticp (et);
5ff904cd 7705
c7e4ee3a 7706 addr = TRUE;
5ff904cd 7707
c7e4ee3a
CB
7708 resume_momentary (yes);
7709 }
7710 else
7711 {
7712 tree initexpr;
7713 bool init = ffesymbol_is_init (s);
5ff904cd 7714
c7e4ee3a 7715 yes = suspend_momentary ();
5ff904cd 7716
c7e4ee3a
CB
7717 t = build_decl (VAR_DECL,
7718 ffecom_get_identifier_ (ffesymbol_text (s)),
7719 type);
5ff904cd 7720
c7e4ee3a
CB
7721 if (init
7722 || ffesymbol_namelisted (s)
7723#ifdef FFECOM_sizeMAXSTACKITEM
7724 || ((st != NULL)
7725 && (ffestorag_size (st) > FFECOM_sizeMAXSTACKITEM))
7726#endif
7727 || ((ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
7728 && (ffecom_primary_entry_kind_
7729 != FFEINFO_kindBLOCKDATA)
7730 && (ffesymbol_is_save (s) || ffe_is_saveall ())))
7731 TREE_STATIC (t) = !ffesymbol_attr (s, FFESYMBOL_attrADJUSTABLE);
7732 else
7733 TREE_STATIC (t) = 0; /* No need to make static. */
5ff904cd 7734
c7e4ee3a
CB
7735 if (init || ffe_is_init_local_zero ())
7736 DECL_INITIAL (t) = error_mark_node;
5ff904cd 7737
c7e4ee3a
CB
7738 /* Keep -Wunused from complaining about var if it
7739 is used as sfunc arg or DATA implied-DO. */
7740 if (ffesymbol_attrs (s) & FFESYMBOL_attrsSFARG)
7741 DECL_IN_SYSTEM_HEADER (t) = 1;
5ff904cd 7742
c7e4ee3a 7743 t = start_decl (t, FALSE);
5ff904cd 7744
c7e4ee3a
CB
7745 if (init)
7746 {
7747 if (ffesymbol_init (s) != NULL)
7748 initexpr = ffecom_expr (ffesymbol_init (s));
7749 else
7750 initexpr = ffecom_init_zero_ (t);
7751 }
7752 else if (ffe_is_init_local_zero ())
7753 initexpr = ffecom_init_zero_ (t);
7754 else
7755 initexpr = NULL_TREE; /* Not ref'd if !init. */
5ff904cd 7756
c7e4ee3a 7757 finish_decl (t, initexpr, FALSE);
5ff904cd 7758
06ceef4e 7759 if (st != NULL && DECL_SIZE (t) != error_mark_node)
c7e4ee3a 7760 {
06ceef4e 7761 assert (TREE_CODE (DECL_SIZE_UNIT (t)) == INTEGER_CST);
05bccae2
RK
7762 assert (0 == compare_tree_int (DECL_SIZE_UNIT (t),
7763 ffestorag_size (st)));
c7e4ee3a 7764 }
5ff904cd 7765
c7e4ee3a
CB
7766 resume_momentary (yes);
7767 }
7768 }
5ff904cd 7769 break;
5ff904cd 7770
c7e4ee3a
CB
7771 case FFEINFO_whereRESULT:
7772 assert (!ffecom_transform_only_dummies_);
5ff904cd 7773
c7e4ee3a
CB
7774 if (bt == FFEINFO_basictypeCHARACTER)
7775 { /* Result is already in list of dummies, use
7776 it (& length). */
7777 t = ffecom_func_result_;
7778 tlen = ffecom_func_length_;
7779 addr = TRUE;
7780 break;
7781 }
7782 if ((ffecom_num_entrypoints_ == 0)
7783 && (bt == FFEINFO_basictypeCOMPLEX)
7784 && (ffesymbol_is_f2c (ffecom_primary_entry_)))
7785 { /* Result is already in list of dummies, use
7786 it. */
7787 t = ffecom_func_result_;
7788 addr = TRUE;
7789 break;
7790 }
7791 if (ffecom_func_result_ != NULL_TREE)
7792 {
7793 t = ffecom_func_result_;
7794 break;
7795 }
7796 if ((ffecom_num_entrypoints_ != 0)
7797 && (ffecom_master_bt_ == FFEINFO_basictypeNONE))
7798 {
7799 yes = suspend_momentary ();
5ff904cd 7800
c7e4ee3a
CB
7801 assert (ffecom_multi_retval_ != NULL_TREE);
7802 t = ffecom_1 (INDIRECT_REF, ffecom_multi_type_node_,
7803 ffecom_multi_retval_);
7804 t = ffecom_2 (COMPONENT_REF, ffecom_tree_type[bt][kt],
7805 t, ffecom_multi_fields_[bt][kt]);
5ff904cd 7806
c7e4ee3a
CB
7807 resume_momentary (yes);
7808 break;
7809 }
5ff904cd 7810
c7e4ee3a 7811 yes = suspend_momentary ();
5ff904cd 7812
c7e4ee3a
CB
7813 t = build_decl (VAR_DECL,
7814 ffecom_get_identifier_ (ffesymbol_text (s)),
7815 ffecom_tree_type[bt][kt]);
7816 TREE_STATIC (t) = 0; /* Put result on stack. */
7817 t = start_decl (t, FALSE);
7818 finish_decl (t, NULL_TREE, FALSE);
5ff904cd 7819
c7e4ee3a 7820 ffecom_func_result_ = t;
5ff904cd 7821
c7e4ee3a
CB
7822 resume_momentary (yes);
7823 break;
5ff904cd 7824
c7e4ee3a
CB
7825 case FFEINFO_whereDUMMY:
7826 {
7827 tree type;
7828 ffebld dl;
7829 ffebld dim;
7830 tree low;
7831 tree high;
7832 tree old_sizes;
7833 bool adjustable = FALSE; /* Conditionally adjustable? */
5ff904cd 7834
c7e4ee3a
CB
7835 type = ffecom_tree_type[bt][kt];
7836 if (ffesymbol_sfdummyparent (s) != NULL)
7837 {
7838 if (current_function_decl == ffecom_outer_function_decl_)
7839 { /* Exec transition before sfunc
7840 context; get it later. */
7841 break;
7842 }
7843 t = ffecom_get_identifier_ (ffesymbol_text
7844 (ffesymbol_sfdummyparent (s)));
7845 }
7846 else
7847 t = ffecom_get_identifier_ (ffesymbol_text (s));
5ff904cd 7848
c7e4ee3a 7849 assert (ffecom_transform_only_dummies_);
5ff904cd 7850
c7e4ee3a
CB
7851 old_sizes = get_pending_sizes ();
7852 put_pending_sizes (old_sizes);
5ff904cd 7853
c7e4ee3a
CB
7854 if (bt == FFEINFO_basictypeCHARACTER)
7855 tlen = ffecom_char_enhance_arg_ (&type, s);
7856 type = ffecom_check_size_overflow_ (s, type, TRUE);
5ff904cd 7857
c7e4ee3a
CB
7858 for (dl = ffesymbol_dims (s); dl != NULL; dl = ffebld_trail (dl))
7859 {
7860 if (type == error_mark_node)
7861 break;
5ff904cd 7862
c7e4ee3a
CB
7863 dim = ffebld_head (dl);
7864 assert (ffebld_op (dim) == FFEBLD_opBOUNDS);
7865 if ((ffebld_left (dim) == NULL) || ffecom_doing_entry_)
7866 low = ffecom_integer_one_node;
7867 else
7868 low = ffecom_expr (ffebld_left (dim));
7869 assert (ffebld_right (dim) != NULL);
7870 if ((ffebld_op (ffebld_right (dim)) == FFEBLD_opSTAR)
7871 || ffecom_doing_entry_)
7872 {
7873 /* Used to just do high=low. But for ffecom_tree_
7874 canonize_ref_, it probably is important to correctly
7875 assess the size. E.g. given COMPLEX C(*),CFUNC and
7876 C(2)=CFUNC(C), overlap can happen, while it can't
7877 for, say, C(1)=CFUNC(C(2)). */
7878 /* Even more recently used to set to INT_MAX, but that
7879 broke when some overflow checking went into the back
7880 end. Now we just leave the upper bound unspecified. */
7881 high = NULL;
7882 }
7883 else
7884 high = ffecom_expr (ffebld_right (dim));
5ff904cd 7885
c7e4ee3a
CB
7886 /* Determine whether array is conditionally adjustable,
7887 to decide whether back-end magic is needed.
5ff904cd 7888
c7e4ee3a
CB
7889 Normally the front end uses the back-end function
7890 variable_size to wrap SAVE_EXPR's around expressions
7891 affecting the size/shape of an array so that the
7892 size/shape info doesn't change during execution
7893 of the compiled code even though variables and
7894 functions referenced in those expressions might.
5ff904cd 7895
c7e4ee3a
CB
7896 variable_size also makes sure those saved expressions
7897 get evaluated immediately upon entry to the
7898 compiled procedure -- the front end normally doesn't
7899 have to worry about that.
3cf0cea4 7900
c7e4ee3a
CB
7901 However, there is a problem with this that affects
7902 g77's implementation of entry points, and that is
7903 that it is _not_ true that each invocation of the
7904 compiled procedure is permitted to evaluate
7905 array size/shape info -- because it is possible
7906 that, for some invocations, that info is invalid (in
7907 which case it is "promised" -- i.e. a violation of
7908 the Fortran standard -- that the compiled code
7909 won't reference the array or its size/shape
7910 during that particular invocation).
5ff904cd 7911
c7e4ee3a 7912 To phrase this in C terms, consider this gcc function:
5ff904cd 7913
c7e4ee3a
CB
7914 void foo (int *n, float (*a)[*n])
7915 {
7916 // a is "pointer to array ...", fyi.
7917 }
5ff904cd 7918
c7e4ee3a
CB
7919 Suppose that, for some invocations, it is permitted
7920 for a caller of foo to do this:
5ff904cd 7921
c7e4ee3a 7922 foo (NULL, NULL);
5ff904cd 7923
c7e4ee3a
CB
7924 Now the _written_ code for foo can take such a call
7925 into account by either testing explicitly for whether
7926 (a == NULL) || (n == NULL) -- presumably it is
7927 not permitted to reference *a in various fashions
7928 if (n == NULL) I suppose -- or it can avoid it by
7929 looking at other info (other arguments, static/global
7930 data, etc.).
5ff904cd 7931
c7e4ee3a
CB
7932 However, this won't work in gcc 2.5.8 because it'll
7933 automatically emit the code to save the "*n"
7934 expression, which'll yield a NULL dereference for
7935 the "foo (NULL, NULL)" call, something the code
7936 for foo cannot prevent.
5ff904cd 7937
c7e4ee3a
CB
7938 g77 definitely needs to avoid executing such
7939 code anytime the pointer to the adjustable array
7940 is NULL, because even if its bounds expressions
7941 don't have any references to possible "absent"
7942 variables like "*n" -- say all variable references
7943 are to COMMON variables, i.e. global (though in C,
7944 local static could actually make sense) -- the
7945 expressions could yield other run-time problems
7946 for allowably "dead" values in those variables.
5ff904cd 7947
c7e4ee3a
CB
7948 For example, let's consider a more complicated
7949 version of foo:
5ff904cd 7950
c7e4ee3a
CB
7951 extern int i;
7952 extern int j;
5ff904cd 7953
c7e4ee3a
CB
7954 void foo (float (*a)[i/j])
7955 {
7956 ...
7957 }
5ff904cd 7958
c7e4ee3a
CB
7959 The above is (essentially) quite valid for Fortran
7960 but, again, for a call like "foo (NULL);", it is
7961 permitted for i and j to be undefined when the
7962 call is made. If j happened to be zero, for
7963 example, emitting the code to evaluate "i/j"
7964 could result in a run-time error.
5ff904cd 7965
c7e4ee3a
CB
7966 Offhand, though I don't have my F77 or F90
7967 standards handy, it might even be valid for a
7968 bounds expression to contain a function reference,
7969 in which case I doubt it is permitted for an
7970 implementation to invoke that function in the
7971 Fortran case involved here (invocation of an
7972 alternate ENTRY point that doesn't have the adjustable
7973 array as one of its arguments).
5ff904cd 7974
c7e4ee3a
CB
7975 So, the code that the compiler would normally emit
7976 to preevaluate the size/shape info for an
7977 adjustable array _must not_ be executed at run time
7978 in certain cases. Specifically, for Fortran,
7979 the case is when the pointer to the adjustable
7980 array == NULL. (For gnu-ish C, it might be nice
7981 for the source code itself to specify an expression
7982 that, if TRUE, inhibits execution of the code. Or
7983 reverse the sense for elegance.)
5ff904cd 7984
c7e4ee3a
CB
7985 (Note that g77 could use a different test than NULL,
7986 actually, since it happens to always pass an
7987 integer to the called function that specifies which
7988 entry point is being invoked. Hmm, this might
7989 solve the next problem.)
7990
7991 One way a user could, I suppose, write "foo" so
7992 it works is to insert COND_EXPR's for the
7993 size/shape info so the dangerous stuff isn't
7994 actually done, as in:
7995
7996 void foo (int *n, float (*a)[(a == NULL) ? 0 : *n])
7997 {
7998 ...
7999 }
5ff904cd 8000
c7e4ee3a
CB
8001 The next problem is that the front end needs to
8002 be able to tell the back end about the array's
8003 decl _before_ it tells it about the conditional
8004 expression to inhibit evaluation of size/shape info,
8005 as shown above.
5ff904cd 8006
c7e4ee3a
CB
8007 To solve this, the front end needs to be able
8008 to give the back end the expression to inhibit
8009 generation of the preevaluation code _after_
8010 it makes the decl for the adjustable array.
5ff904cd 8011
c7e4ee3a
CB
8012 Until then, the above example using the COND_EXPR
8013 doesn't pass muster with gcc because the "(a == NULL)"
8014 part has a reference to "a", which is still
8015 undefined at that point.
5ff904cd 8016
c7e4ee3a
CB
8017 g77 will therefore use a different mechanism in the
8018 meantime. */
5ff904cd 8019
c7e4ee3a
CB
8020 if (!adjustable
8021 && ((TREE_CODE (low) != INTEGER_CST)
8022 || (high && TREE_CODE (high) != INTEGER_CST)))
8023 adjustable = TRUE;
5ff904cd 8024
c7e4ee3a
CB
8025#if 0 /* Old approach -- see below. */
8026 if (TREE_CODE (low) != INTEGER_CST)
8027 low = ffecom_3 (COND_EXPR, integer_type_node,
8028 ffecom_adjarray_passed_ (s),
8029 low,
8030 ffecom_integer_zero_node);
5ff904cd 8031
c7e4ee3a
CB
8032 if (high && TREE_CODE (high) != INTEGER_CST)
8033 high = ffecom_3 (COND_EXPR, integer_type_node,
8034 ffecom_adjarray_passed_ (s),
8035 high,
8036 ffecom_integer_zero_node);
8037#endif
5ff904cd 8038
c7e4ee3a
CB
8039 /* ~~~gcc/stor-layout.c (layout_type) should do this,
8040 probably. Fixes 950302-1.f. */
5ff904cd 8041
c7e4ee3a
CB
8042 if (TREE_CODE (low) != INTEGER_CST)
8043 low = variable_size (low);
5ff904cd 8044
c7e4ee3a
CB
8045 /* ~~~Similarly, this fixes dumb0.f. The C front end
8046 does this, which is why dumb0.c would work. */
5ff904cd 8047
c7e4ee3a
CB
8048 if (high && TREE_CODE (high) != INTEGER_CST)
8049 high = variable_size (high);
5ff904cd 8050
c7e4ee3a
CB
8051 type
8052 = build_array_type
8053 (type,
8054 build_range_type (ffecom_integer_type_node,
8055 low, high));
8056 type = ffecom_check_size_overflow_ (s, type, TRUE);
8057 }
5ff904cd 8058
c7e4ee3a
CB
8059 if (type == error_mark_node)
8060 {
8061 t = error_mark_node;
8062 break;
8063 }
5ff904cd 8064
c7e4ee3a
CB
8065 if ((ffesymbol_sfdummyparent (s) == NULL)
8066 || (ffesymbol_basictype (s) == FFEINFO_basictypeCHARACTER))
8067 {
8068 type = build_pointer_type (type);
8069 addr = TRUE;
8070 }
5ff904cd 8071
c7e4ee3a 8072 t = build_decl (PARM_DECL, t, type);
5ff904cd 8073#if BUILT_FOR_270
c7e4ee3a 8074 DECL_ARTIFICIAL (t) = 1;
5ff904cd 8075#endif
5ff904cd 8076
c7e4ee3a
CB
8077 /* If this arg is present in every entry point's list of
8078 dummy args, then we're done. */
5ff904cd 8079
c7e4ee3a
CB
8080 if (ffesymbol_numentries (s)
8081 == (ffecom_num_entrypoints_ + 1))
5ff904cd 8082 break;
5ff904cd 8083
c7e4ee3a 8084#if 1
5ff904cd 8085
c7e4ee3a
CB
8086 /* If variable_size in stor-layout has been called during
8087 the above, then get_pending_sizes should have the
8088 yet-to-be-evaluated saved expressions pending.
8089 Make the whole lot of them get emitted, conditionally
8090 on whether the array decl ("t" above) is not NULL. */
5ff904cd 8091
c7e4ee3a
CB
8092 {
8093 tree sizes = get_pending_sizes ();
8094 tree tem;
5ff904cd 8095
c7e4ee3a
CB
8096 for (tem = sizes;
8097 tem != old_sizes;
8098 tem = TREE_CHAIN (tem))
8099 {
8100 tree temv = TREE_VALUE (tem);
5ff904cd 8101
c7e4ee3a
CB
8102 if (sizes == tem)
8103 sizes = temv;
8104 else
8105 sizes
8106 = ffecom_2 (COMPOUND_EXPR,
8107 TREE_TYPE (sizes),
8108 temv,
8109 sizes);
8110 }
5ff904cd 8111
c7e4ee3a
CB
8112 if (sizes != tem)
8113 {
8114 sizes
8115 = ffecom_3 (COND_EXPR,
8116 TREE_TYPE (sizes),
8117 ffecom_2 (NE_EXPR,
8118 integer_type_node,
8119 t,
8120 null_pointer_node),
8121 sizes,
8122 convert (TREE_TYPE (sizes),
8123 integer_zero_node));
8124 sizes = ffecom_save_tree (sizes);
5ff904cd 8125
c7e4ee3a
CB
8126 sizes
8127 = tree_cons (NULL_TREE, sizes, tem);
8128 }
5ff904cd 8129
c7e4ee3a
CB
8130 if (sizes)
8131 put_pending_sizes (sizes);
8132 }
5ff904cd 8133
c7e4ee3a
CB
8134#else
8135#if 0
8136 if (adjustable
8137 && (ffesymbol_numentries (s)
8138 != ffecom_num_entrypoints_ + 1))
8139 DECL_SOMETHING (t)
8140 = ffecom_2 (NE_EXPR, integer_type_node,
8141 t,
8142 null_pointer_node);
8143#else
8144#if 0
8145 if (adjustable
8146 && (ffesymbol_numentries (s)
8147 != ffecom_num_entrypoints_ + 1))
8148 {
8149 ffebad_start (FFEBAD_MISSING_ADJARRAY_UNSUPPORTED);
8150 ffebad_here (0, ffesymbol_where_line (s),
8151 ffesymbol_where_column (s));
8152 ffebad_string (ffesymbol_text (s));
8153 ffebad_finish ();
8154 }
8155#endif
8156#endif
8157#endif
8158 }
5ff904cd
JL
8159 break;
8160
c7e4ee3a 8161 case FFEINFO_whereCOMMON:
5ff904cd 8162 {
c7e4ee3a
CB
8163 ffesymbol cs;
8164 ffeglobal cg;
8165 tree ct;
5ff904cd
JL
8166 ffestorag st = ffesymbol_storage (s);
8167 tree type;
c7e4ee3a 8168 int yes;
5ff904cd 8169
c7e4ee3a
CB
8170 cs = ffesymbol_common (s); /* The COMMON area itself. */
8171 if (st != NULL) /* Else not laid out. */
5ff904cd 8172 {
c7e4ee3a
CB
8173 ffecom_transform_common_ (cs);
8174 st = ffesymbol_storage (s);
5ff904cd
JL
8175 }
8176
c7e4ee3a 8177 yes = suspend_momentary ();
5ff904cd 8178
c7e4ee3a 8179 type = ffecom_type_localvar_ (s, bt, kt);
5ff904cd 8180
c7e4ee3a
CB
8181 cg = ffesymbol_global (cs); /* The global COMMON info. */
8182 if ((cg == NULL)
8183 || (ffeglobal_type (cg) != FFEGLOBAL_typeCOMMON))
8184 ct = NULL_TREE;
8185 else
8186 ct = ffeglobal_hook (cg); /* The common area's tree. */
5ff904cd 8187
c7e4ee3a
CB
8188 if ((ct == NULL_TREE)
8189 || (st == NULL)
8190 || (type == error_mark_node))
8191 t = error_mark_node;
8192 else
8193 {
8194 ffetargetOffset offset;
8195 ffestorag cst;
5ff904cd 8196
c7e4ee3a
CB
8197 cst = ffestorag_parent (st);
8198 assert (cst == ffesymbol_storage (cs));
5ff904cd 8199
c7e4ee3a
CB
8200 offset = ffestorag_modulo (cst)
8201 + ffestorag_offset (st)
8202 - ffestorag_offset (cst);
5ff904cd 8203
c7e4ee3a 8204 ffecom_debug_kludge_ (ct, "COMMON", s, type, offset);
5ff904cd 8205
c7e4ee3a 8206 /* (t_type *) (((char *) &ct) + offset) */
5ff904cd
JL
8207
8208 t = convert (string_type_node, /* (char *) */
8209 ffecom_1 (ADDR_EXPR,
c7e4ee3a
CB
8210 build_pointer_type (TREE_TYPE (ct)),
8211 ct));
5ff904cd
JL
8212 t = ffecom_2 (PLUS_EXPR, TREE_TYPE (t),
8213 t,
8214 build_int_2 (offset, 0));
8215 t = convert (build_pointer_type (type),
8216 t);
d50108c7 8217 TREE_CONSTANT (t) = 1;
5ff904cd
JL
8218
8219 addr = TRUE;
5ff904cd 8220 }
5ff904cd 8221
c7e4ee3a
CB
8222 resume_momentary (yes);
8223 }
8224 break;
5ff904cd 8225
c7e4ee3a
CB
8226 case FFEINFO_whereIMMEDIATE:
8227 case FFEINFO_whereGLOBAL:
8228 case FFEINFO_whereFLEETING:
8229 case FFEINFO_whereFLEETING_CADDR:
8230 case FFEINFO_whereFLEETING_IADDR:
8231 case FFEINFO_whereINTRINSIC:
8232 case FFEINFO_whereCONSTANT_SUBOBJECT:
8233 default:
8234 assert ("ENTITY where unheard of" == NULL);
8235 /* Fall through. */
8236 case FFEINFO_whereANY:
8237 t = error_mark_node;
8238 break;
8239 }
8240 break;
5ff904cd 8241
c7e4ee3a
CB
8242 case FFEINFO_kindFUNCTION:
8243 switch (ffeinfo_where (ffesymbol_info (s)))
8244 {
8245 case FFEINFO_whereLOCAL: /* Me. */
8246 assert (!ffecom_transform_only_dummies_);
8247 t = current_function_decl;
5ff904cd
JL
8248 break;
8249
c7e4ee3a 8250 case FFEINFO_whereGLOBAL:
5ff904cd
JL
8251 assert (!ffecom_transform_only_dummies_);
8252
c7e4ee3a
CB
8253 if (((g = ffesymbol_global (s)) != NULL)
8254 && ((ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
8255 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
8256 && (ffeglobal_hook (g) != NULL_TREE)
8257 && ffe_is_globals ())
5ff904cd 8258 {
c7e4ee3a 8259 t = ffeglobal_hook (g);
5ff904cd
JL
8260 break;
8261 }
5ff904cd 8262
c7e4ee3a
CB
8263 if (ffesymbol_is_f2c (s)
8264 && (ffesymbol_where (s) != FFEINFO_whereCONSTANT))
8265 t = ffecom_tree_fun_type[bt][kt];
8266 else
8267 t = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
5ff904cd 8268
c7e4ee3a
CB
8269 t = build_decl (FUNCTION_DECL,
8270 ffecom_get_external_identifier_ (s),
8271 t);
8272 DECL_EXTERNAL (t) = 1;
8273 TREE_PUBLIC (t) = 1;
5ff904cd 8274
5ff904cd
JL
8275 t = start_decl (t, FALSE);
8276 finish_decl (t, NULL_TREE, FALSE);
8277
c7e4ee3a
CB
8278 if ((g != NULL)
8279 && ((ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
8280 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
8281 ffeglobal_set_hook (g, t);
8282
7189a4b0 8283 ffecom_save_tree_forever (t);
5ff904cd 8284
5ff904cd
JL
8285 break;
8286
8287 case FFEINFO_whereDUMMY:
c7e4ee3a 8288 assert (ffecom_transform_only_dummies_);
5ff904cd 8289
c7e4ee3a
CB
8290 if (ffesymbol_is_f2c (s)
8291 && (ffesymbol_where (s) != FFEINFO_whereCONSTANT))
8292 t = ffecom_tree_ptr_to_fun_type[bt][kt];
8293 else
8294 t = build_pointer_type
8295 (build_function_type (ffecom_tree_type[bt][kt], NULL_TREE));
8296
8297 t = build_decl (PARM_DECL,
8298 ffecom_get_identifier_ (ffesymbol_text (s)),
8299 t);
8300#if BUILT_FOR_270
8301 DECL_ARTIFICIAL (t) = 1;
8302#endif
8303 addr = TRUE;
8304 break;
8305
8306 case FFEINFO_whereCONSTANT: /* Statement function. */
8307 assert (!ffecom_transform_only_dummies_);
8308 t = ffecom_gen_sfuncdef_ (s, bt, kt);
8309 break;
8310
8311 case FFEINFO_whereINTRINSIC:
8312 assert (!ffecom_transform_only_dummies_);
8313 break; /* Let actual references generate their
8314 decls. */
8315
8316 default:
8317 assert ("FUNCTION where unheard of" == NULL);
8318 /* Fall through. */
8319 case FFEINFO_whereANY:
8320 t = error_mark_node;
8321 break;
8322 }
8323 break;
8324
8325 case FFEINFO_kindSUBROUTINE:
8326 switch (ffeinfo_where (ffesymbol_info (s)))
8327 {
8328 case FFEINFO_whereLOCAL: /* Me. */
8329 assert (!ffecom_transform_only_dummies_);
8330 t = current_function_decl;
8331 break;
5ff904cd 8332
c7e4ee3a
CB
8333 case FFEINFO_whereGLOBAL:
8334 assert (!ffecom_transform_only_dummies_);
5ff904cd 8335
c7e4ee3a
CB
8336 if (((g = ffesymbol_global (s)) != NULL)
8337 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
8338 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
8339 && (ffeglobal_hook (g) != NULL_TREE)
8340 && ffe_is_globals ())
8341 {
8342 t = ffeglobal_hook (g);
8343 break;
8344 }
5ff904cd 8345
c7e4ee3a
CB
8346 t = build_decl (FUNCTION_DECL,
8347 ffecom_get_external_identifier_ (s),
8348 ffecom_tree_subr_type);
8349 DECL_EXTERNAL (t) = 1;
8350 TREE_PUBLIC (t) = 1;
5ff904cd 8351
c7e4ee3a
CB
8352 t = start_decl (t, FALSE);
8353 finish_decl (t, NULL_TREE, FALSE);
5ff904cd 8354
c7e4ee3a
CB
8355 if ((g != NULL)
8356 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
8357 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
8358 ffeglobal_set_hook (g, t);
5ff904cd 8359
7189a4b0 8360 ffecom_save_tree_forever (t);
5ff904cd 8361
c7e4ee3a 8362 break;
5ff904cd 8363
c7e4ee3a
CB
8364 case FFEINFO_whereDUMMY:
8365 assert (ffecom_transform_only_dummies_);
5ff904cd 8366
c7e4ee3a
CB
8367 t = build_decl (PARM_DECL,
8368 ffecom_get_identifier_ (ffesymbol_text (s)),
8369 ffecom_tree_ptr_to_subr_type);
8370#if BUILT_FOR_270
8371 DECL_ARTIFICIAL (t) = 1;
8372#endif
8373 addr = TRUE;
8374 break;
5ff904cd 8375
c7e4ee3a
CB
8376 case FFEINFO_whereINTRINSIC:
8377 assert (!ffecom_transform_only_dummies_);
8378 break; /* Let actual references generate their
8379 decls. */
5ff904cd 8380
c7e4ee3a
CB
8381 default:
8382 assert ("SUBROUTINE where unheard of" == NULL);
8383 /* Fall through. */
8384 case FFEINFO_whereANY:
8385 t = error_mark_node;
8386 break;
8387 }
8388 break;
5ff904cd 8389
c7e4ee3a
CB
8390 case FFEINFO_kindPROGRAM:
8391 switch (ffeinfo_where (ffesymbol_info (s)))
8392 {
8393 case FFEINFO_whereLOCAL: /* Me. */
8394 assert (!ffecom_transform_only_dummies_);
8395 t = current_function_decl;
8396 break;
5ff904cd 8397
c7e4ee3a
CB
8398 case FFEINFO_whereCOMMON:
8399 case FFEINFO_whereDUMMY:
8400 case FFEINFO_whereGLOBAL:
8401 case FFEINFO_whereRESULT:
8402 case FFEINFO_whereFLEETING:
8403 case FFEINFO_whereFLEETING_CADDR:
8404 case FFEINFO_whereFLEETING_IADDR:
8405 case FFEINFO_whereIMMEDIATE:
8406 case FFEINFO_whereINTRINSIC:
8407 case FFEINFO_whereCONSTANT:
8408 case FFEINFO_whereCONSTANT_SUBOBJECT:
8409 default:
8410 assert ("PROGRAM where unheard of" == NULL);
8411 /* Fall through. */
8412 case FFEINFO_whereANY:
8413 t = error_mark_node;
8414 break;
8415 }
8416 break;
5ff904cd 8417
c7e4ee3a
CB
8418 case FFEINFO_kindBLOCKDATA:
8419 switch (ffeinfo_where (ffesymbol_info (s)))
8420 {
8421 case FFEINFO_whereLOCAL: /* Me. */
8422 assert (!ffecom_transform_only_dummies_);
8423 t = current_function_decl;
8424 break;
5ff904cd 8425
c7e4ee3a
CB
8426 case FFEINFO_whereGLOBAL:
8427 assert (!ffecom_transform_only_dummies_);
5ff904cd 8428
c7e4ee3a
CB
8429 t = build_decl (FUNCTION_DECL,
8430 ffecom_get_external_identifier_ (s),
8431 ffecom_tree_blockdata_type);
8432 DECL_EXTERNAL (t) = 1;
8433 TREE_PUBLIC (t) = 1;
5ff904cd 8434
c7e4ee3a
CB
8435 t = start_decl (t, FALSE);
8436 finish_decl (t, NULL_TREE, FALSE);
5ff904cd 8437
7189a4b0 8438 ffecom_save_tree_forever (t);
5ff904cd 8439
c7e4ee3a 8440 break;
5ff904cd 8441
c7e4ee3a
CB
8442 case FFEINFO_whereCOMMON:
8443 case FFEINFO_whereDUMMY:
8444 case FFEINFO_whereRESULT:
8445 case FFEINFO_whereFLEETING:
8446 case FFEINFO_whereFLEETING_CADDR:
8447 case FFEINFO_whereFLEETING_IADDR:
8448 case FFEINFO_whereIMMEDIATE:
8449 case FFEINFO_whereINTRINSIC:
8450 case FFEINFO_whereCONSTANT:
8451 case FFEINFO_whereCONSTANT_SUBOBJECT:
8452 default:
8453 assert ("BLOCKDATA where unheard of" == NULL);
8454 /* Fall through. */
8455 case FFEINFO_whereANY:
8456 t = error_mark_node;
8457 break;
8458 }
8459 break;
5ff904cd 8460
c7e4ee3a
CB
8461 case FFEINFO_kindCOMMON:
8462 switch (ffeinfo_where (ffesymbol_info (s)))
8463 {
8464 case FFEINFO_whereLOCAL:
8465 assert (!ffecom_transform_only_dummies_);
8466 ffecom_transform_common_ (s);
8467 break;
8468
8469 case FFEINFO_whereNONE:
8470 case FFEINFO_whereCOMMON:
8471 case FFEINFO_whereDUMMY:
8472 case FFEINFO_whereGLOBAL:
8473 case FFEINFO_whereRESULT:
8474 case FFEINFO_whereFLEETING:
8475 case FFEINFO_whereFLEETING_CADDR:
8476 case FFEINFO_whereFLEETING_IADDR:
8477 case FFEINFO_whereIMMEDIATE:
8478 case FFEINFO_whereINTRINSIC:
8479 case FFEINFO_whereCONSTANT:
8480 case FFEINFO_whereCONSTANT_SUBOBJECT:
8481 default:
8482 assert ("COMMON where unheard of" == NULL);
8483 /* Fall through. */
8484 case FFEINFO_whereANY:
8485 t = error_mark_node;
8486 break;
8487 }
8488 break;
5ff904cd 8489
c7e4ee3a
CB
8490 case FFEINFO_kindCONSTRUCT:
8491 switch (ffeinfo_where (ffesymbol_info (s)))
8492 {
8493 case FFEINFO_whereLOCAL:
8494 assert (!ffecom_transform_only_dummies_);
8495 break;
5ff904cd 8496
c7e4ee3a
CB
8497 case FFEINFO_whereNONE:
8498 case FFEINFO_whereCOMMON:
8499 case FFEINFO_whereDUMMY:
8500 case FFEINFO_whereGLOBAL:
8501 case FFEINFO_whereRESULT:
8502 case FFEINFO_whereFLEETING:
8503 case FFEINFO_whereFLEETING_CADDR:
8504 case FFEINFO_whereFLEETING_IADDR:
8505 case FFEINFO_whereIMMEDIATE:
8506 case FFEINFO_whereINTRINSIC:
8507 case FFEINFO_whereCONSTANT:
8508 case FFEINFO_whereCONSTANT_SUBOBJECT:
8509 default:
8510 assert ("CONSTRUCT where unheard of" == NULL);
8511 /* Fall through. */
8512 case FFEINFO_whereANY:
8513 t = error_mark_node;
8514 break;
8515 }
8516 break;
5ff904cd 8517
c7e4ee3a
CB
8518 case FFEINFO_kindNAMELIST:
8519 switch (ffeinfo_where (ffesymbol_info (s)))
8520 {
8521 case FFEINFO_whereLOCAL:
8522 assert (!ffecom_transform_only_dummies_);
8523 t = ffecom_transform_namelist_ (s);
8524 break;
5ff904cd 8525
c7e4ee3a
CB
8526 case FFEINFO_whereNONE:
8527 case FFEINFO_whereCOMMON:
8528 case FFEINFO_whereDUMMY:
8529 case FFEINFO_whereGLOBAL:
8530 case FFEINFO_whereRESULT:
8531 case FFEINFO_whereFLEETING:
8532 case FFEINFO_whereFLEETING_CADDR:
8533 case FFEINFO_whereFLEETING_IADDR:
8534 case FFEINFO_whereIMMEDIATE:
8535 case FFEINFO_whereINTRINSIC:
8536 case FFEINFO_whereCONSTANT:
8537 case FFEINFO_whereCONSTANT_SUBOBJECT:
8538 default:
8539 assert ("NAMELIST where unheard of" == NULL);
8540 /* Fall through. */
8541 case FFEINFO_whereANY:
8542 t = error_mark_node;
8543 break;
8544 }
8545 break;
5ff904cd 8546
c7e4ee3a
CB
8547 default:
8548 assert ("kind unheard of" == NULL);
8549 /* Fall through. */
8550 case FFEINFO_kindANY:
8551 t = error_mark_node;
8552 break;
8553 }
5ff904cd 8554
c7e4ee3a
CB
8555 ffesymbol_hook (s).decl_tree = t;
8556 ffesymbol_hook (s).length_tree = tlen;
8557 ffesymbol_hook (s).addr = addr;
5ff904cd 8558
c7e4ee3a
CB
8559 lineno = old_lineno;
8560 input_filename = old_input_filename;
5ff904cd 8561
c7e4ee3a
CB
8562 return s;
8563}
5ff904cd 8564
5ff904cd 8565#endif
c7e4ee3a 8566/* Transform into ASSIGNable symbol.
5ff904cd 8567
c7e4ee3a
CB
8568 Symbol has already been transformed, but for whatever reason, the
8569 resulting decl_tree has been deemed not usable for an ASSIGN target.
8570 (E.g. it isn't wide enough to hold a pointer.) So, here we invent
8571 another local symbol of type void * and stuff that in the assign_tree
8572 argument. The F77/F90 standards allow this implementation. */
5ff904cd 8573
c7e4ee3a
CB
8574#if FFECOM_targetCURRENT == FFECOM_targetGCC
8575static ffesymbol
8576ffecom_sym_transform_assign_ (ffesymbol s)
8577{
8578 tree t; /* Transformed thingy. */
8579 int yes;
8580 int old_lineno = lineno;
3b304f5b 8581 const char *old_input_filename = input_filename;
5ff904cd 8582
c7e4ee3a
CB
8583 if (ffesymbol_sfdummyparent (s) == NULL)
8584 {
8585 input_filename = ffesymbol_where_filename (s);
8586 lineno = ffesymbol_where_filelinenum (s);
8587 }
8588 else
8589 {
8590 ffesymbol sf = ffesymbol_sfdummyparent (s);
5ff904cd 8591
c7e4ee3a
CB
8592 input_filename = ffesymbol_where_filename (sf);
8593 lineno = ffesymbol_where_filelinenum (sf);
8594 }
5ff904cd 8595
c7e4ee3a 8596 assert (!ffecom_transform_only_dummies_);
5ff904cd 8597
c7e4ee3a 8598 yes = suspend_momentary ();
5ff904cd 8599
c7e4ee3a
CB
8600 t = build_decl (VAR_DECL,
8601 ffecom_get_invented_identifier ("__g77_ASSIGN_%s",
14657de8 8602 ffesymbol_text (s)),
c7e4ee3a 8603 TREE_TYPE (null_pointer_node));
5ff904cd 8604
c7e4ee3a
CB
8605 switch (ffesymbol_where (s))
8606 {
8607 case FFEINFO_whereLOCAL:
8608 /* Unlike for regular vars, SAVE status is easy to determine for
8609 ASSIGNed vars, since there's no initialization, there's no
8610 effective storage association (so "SAVE J" does not apply to
8611 K even given "EQUIVALENCE (J,K)"), there's no size issue
8612 to worry about, etc. */
8613 if ((ffesymbol_is_save (s) || ffe_is_saveall ())
8614 && (ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
8615 && (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA))
8616 TREE_STATIC (t) = 1; /* SAVEd in proc, make static. */
8617 else
8618 TREE_STATIC (t) = 0; /* No need to make static. */
8619 break;
5ff904cd 8620
c7e4ee3a
CB
8621 case FFEINFO_whereCOMMON:
8622 TREE_STATIC (t) = 1; /* Assume COMMONs always SAVEd. */
8623 break;
5ff904cd 8624
c7e4ee3a
CB
8625 case FFEINFO_whereDUMMY:
8626 /* Note that twinning a DUMMY means the caller won't see
8627 the ASSIGNed value. But both F77 and F90 allow implementations
8628 to do this, i.e. disallow Fortran code that would try and
8629 take advantage of actually putting a label into a variable
8630 via a dummy argument (or any other storage association, for
8631 that matter). */
8632 TREE_STATIC (t) = 0;
8633 break;
5ff904cd 8634
c7e4ee3a
CB
8635 default:
8636 TREE_STATIC (t) = 0;
8637 break;
8638 }
5ff904cd 8639
c7e4ee3a
CB
8640 t = start_decl (t, FALSE);
8641 finish_decl (t, NULL_TREE, FALSE);
5ff904cd 8642
c7e4ee3a 8643 resume_momentary (yes);
5ff904cd 8644
c7e4ee3a 8645 ffesymbol_hook (s).assign_tree = t;
5ff904cd 8646
c7e4ee3a
CB
8647 lineno = old_lineno;
8648 input_filename = old_input_filename;
5ff904cd 8649
c7e4ee3a
CB
8650 return s;
8651}
5ff904cd 8652
c7e4ee3a
CB
8653#endif
8654/* Implement COMMON area in back end.
5ff904cd 8655
c7e4ee3a
CB
8656 Because COMMON-based variables can be referenced in the dimension
8657 expressions of dummy (adjustable) arrays, and because dummies
8658 (in the gcc back end) need to be put in the outer binding level
8659 of a function (which has two binding levels, the outer holding
8660 the dummies and the inner holding the other vars), special care
8661 must be taken to handle COMMON areas.
5ff904cd 8662
c7e4ee3a
CB
8663 The current strategy is basically to always tell the back end about
8664 the COMMON area as a top-level external reference to just a block
8665 of storage of the master type of that area (e.g. integer, real,
8666 character, whatever -- not a structure). As a distinct action,
8667 if initial values are provided, tell the back end about the area
8668 as a top-level non-external (initialized) area and remember not to
8669 allow further initialization or expansion of the area. Meanwhile,
8670 if no initialization happens at all, tell the back end about
8671 the largest size we've seen declared so the space does get reserved.
8672 (This function doesn't handle all that stuff, but it does some
8673 of the important things.)
5ff904cd 8674
c7e4ee3a
CB
8675 Meanwhile, for COMMON variables themselves, just keep creating
8676 references like *((float *) (&common_area + offset)) each time
8677 we reference the variable. In other words, don't make a VAR_DECL
8678 or any kind of component reference (like we used to do before 0.4),
8679 though we might do that as well just for debugging purposes (and
8680 stuff the rtl with the appropriate offset expression). */
5ff904cd 8681
c7e4ee3a
CB
8682#if FFECOM_targetCURRENT == FFECOM_targetGCC
8683static void
8684ffecom_transform_common_ (ffesymbol s)
8685{
8686 ffestorag st = ffesymbol_storage (s);
8687 ffeglobal g = ffesymbol_global (s);
8688 tree cbt;
8689 tree cbtype;
8690 tree init;
8691 tree high;
8692 bool is_init = ffestorag_is_init (st);
5ff904cd 8693
c7e4ee3a 8694 assert (st != NULL);
5ff904cd 8695
c7e4ee3a
CB
8696 if ((g == NULL)
8697 || (ffeglobal_type (g) != FFEGLOBAL_typeCOMMON))
8698 return;
5ff904cd 8699
c7e4ee3a 8700 /* First update the size of the area in global terms. */
5ff904cd 8701
c7e4ee3a 8702 ffeglobal_size_common (s, ffestorag_size (st));
5ff904cd 8703
c7e4ee3a
CB
8704 if (!ffeglobal_common_init (g))
8705 is_init = FALSE; /* No explicit init, don't let erroneous joins init. */
5ff904cd 8706
c7e4ee3a 8707 cbt = ffeglobal_hook (g);
5ff904cd 8708
c7e4ee3a
CB
8709 /* If we already have declared this common block for a previous program
8710 unit, and either we already initialized it or we don't have new
8711 initialization for it, just return what we have without changing it. */
5ff904cd 8712
c7e4ee3a
CB
8713 if ((cbt != NULL_TREE)
8714 && (!is_init
8715 || !DECL_EXTERNAL (cbt)))
b7a80862
AV
8716 {
8717 if (st->hook == NULL) ffestorag_set_hook (st, cbt);
8718 return;
8719 }
5ff904cd 8720
c7e4ee3a 8721 /* Process inits. */
5ff904cd 8722
c7e4ee3a
CB
8723 if (is_init)
8724 {
8725 if (ffestorag_init (st) != NULL)
5ff904cd 8726 {
c7e4ee3a 8727 ffebld sexp;
5ff904cd 8728
c7e4ee3a
CB
8729 /* Set the padding for the expression, so ffecom_expr
8730 knows to insert that many zeros. */
8731 switch (ffebld_op (sexp = ffestorag_init (st)))
5ff904cd 8732 {
c7e4ee3a
CB
8733 case FFEBLD_opCONTER:
8734 ffebld_conter_set_pad (sexp, ffestorag_modulo (st));
5ff904cd 8735 break;
5ff904cd 8736
c7e4ee3a
CB
8737 case FFEBLD_opARRTER:
8738 ffebld_arrter_set_pad (sexp, ffestorag_modulo (st));
8739 break;
5ff904cd 8740
c7e4ee3a
CB
8741 case FFEBLD_opACCTER:
8742 ffebld_accter_set_pad (sexp, ffestorag_modulo (st));
8743 break;
5ff904cd 8744
c7e4ee3a
CB
8745 default:
8746 assert ("bad op for cmn init (pad)" == NULL);
8747 break;
8748 }
5ff904cd 8749
c7e4ee3a
CB
8750 init = ffecom_expr (sexp);
8751 if (init == error_mark_node)
8752 { /* Hopefully the back end complained! */
8753 init = NULL_TREE;
8754 if (cbt != NULL_TREE)
8755 return;
8756 }
8757 }
8758 else
8759 init = error_mark_node;
8760 }
8761 else
8762 init = NULL_TREE;
5ff904cd 8763
c7e4ee3a 8764 /* cbtype must be permanently allocated! */
5ff904cd 8765
c7e4ee3a
CB
8766 /* Allocate the MAX of the areas so far, seen filewide. */
8767 high = build_int_2 ((ffeglobal_common_size (g)
8768 + ffeglobal_common_pad (g)) - 1, 0);
8769 TREE_TYPE (high) = ffecom_integer_type_node;
5ff904cd 8770
c7e4ee3a
CB
8771 if (init)
8772 cbtype = build_array_type (char_type_node,
8773 build_range_type (integer_type_node,
8774 integer_zero_node,
8775 high));
8776 else
8777 cbtype = build_array_type (char_type_node, NULL_TREE);
5ff904cd 8778
c7e4ee3a
CB
8779 if (cbt == NULL_TREE)
8780 {
8781 cbt
8782 = build_decl (VAR_DECL,
8783 ffecom_get_external_identifier_ (s),
8784 cbtype);
8785 TREE_STATIC (cbt) = 1;
8786 TREE_PUBLIC (cbt) = 1;
8787 }
8788 else
8789 {
8790 assert (is_init);
8791 TREE_TYPE (cbt) = cbtype;
8792 }
8793 DECL_EXTERNAL (cbt) = init ? 0 : 1;
8794 DECL_INITIAL (cbt) = init ? error_mark_node : NULL_TREE;
5ff904cd 8795
c7e4ee3a
CB
8796 cbt = start_decl (cbt, TRUE);
8797 if (ffeglobal_hook (g) != NULL)
8798 assert (cbt == ffeglobal_hook (g));
5ff904cd 8799
c7e4ee3a 8800 assert (!init || !DECL_EXTERNAL (cbt));
5ff904cd 8801
c7e4ee3a
CB
8802 /* Make sure that any type can live in COMMON and be referenced
8803 without getting a bus error. We could pick the most restrictive
8804 alignment of all entities actually placed in the COMMON, but
8805 this seems easy enough. */
5ff904cd 8806
c7e4ee3a 8807 DECL_ALIGN (cbt) = BIGGEST_ALIGNMENT;
11cf4d18 8808 DECL_USER_ALIGN (cbt) = 0;
5ff904cd 8809
c7e4ee3a
CB
8810 if (is_init && (ffestorag_init (st) == NULL))
8811 init = ffecom_init_zero_ (cbt);
5ff904cd 8812
c7e4ee3a 8813 finish_decl (cbt, init, TRUE);
5ff904cd 8814
c7e4ee3a
CB
8815 if (is_init)
8816 ffestorag_set_init (st, ffebld_new_any ());
5ff904cd 8817
c7e4ee3a
CB
8818 if (init)
8819 {
06ceef4e
RK
8820 assert (DECL_SIZE_UNIT (cbt) != NULL_TREE);
8821 assert (TREE_CODE (DECL_SIZE_UNIT (cbt)) == INTEGER_CST);
05bccae2
RK
8822 assert (0 == compare_tree_int (DECL_SIZE_UNIT (cbt),
8823 (ffeglobal_common_size (g)
8824 + ffeglobal_common_pad (g))));
c7e4ee3a 8825 }
5ff904cd 8826
c7e4ee3a 8827 ffeglobal_set_hook (g, cbt);
5ff904cd 8828
c7e4ee3a 8829 ffestorag_set_hook (st, cbt);
5ff904cd 8830
7189a4b0 8831 ffecom_save_tree_forever (cbt);
c7e4ee3a 8832}
5ff904cd 8833
c7e4ee3a
CB
8834#endif
8835/* Make master area for local EQUIVALENCE. */
5ff904cd 8836
c7e4ee3a
CB
8837#if FFECOM_targetCURRENT == FFECOM_targetGCC
8838static void
8839ffecom_transform_equiv_ (ffestorag eqst)
8840{
8841 tree eqt;
8842 tree eqtype;
8843 tree init;
8844 tree high;
8845 bool is_init = ffestorag_is_init (eqst);
8846 int yes;
5ff904cd 8847
c7e4ee3a 8848 assert (eqst != NULL);
5ff904cd 8849
c7e4ee3a 8850 eqt = ffestorag_hook (eqst);
5ff904cd 8851
c7e4ee3a
CB
8852 if (eqt != NULL_TREE)
8853 return;
5ff904cd 8854
c7e4ee3a
CB
8855 /* Process inits. */
8856
8857 if (is_init)
8858 {
8859 if (ffestorag_init (eqst) != NULL)
5ff904cd 8860 {
c7e4ee3a 8861 ffebld sexp;
5ff904cd 8862
c7e4ee3a
CB
8863 /* Set the padding for the expression, so ffecom_expr
8864 knows to insert that many zeros. */
8865 switch (ffebld_op (sexp = ffestorag_init (eqst)))
8866 {
8867 case FFEBLD_opCONTER:
8868 ffebld_conter_set_pad (sexp, ffestorag_modulo (eqst));
8869 break;
5ff904cd 8870
c7e4ee3a
CB
8871 case FFEBLD_opARRTER:
8872 ffebld_arrter_set_pad (sexp, ffestorag_modulo (eqst));
8873 break;
5ff904cd 8874
c7e4ee3a
CB
8875 case FFEBLD_opACCTER:
8876 ffebld_accter_set_pad (sexp, ffestorag_modulo (eqst));
8877 break;
5ff904cd 8878
c7e4ee3a
CB
8879 default:
8880 assert ("bad op for eqv init (pad)" == NULL);
8881 break;
8882 }
5ff904cd 8883
c7e4ee3a
CB
8884 init = ffecom_expr (sexp);
8885 if (init == error_mark_node)
8886 init = NULL_TREE; /* Hopefully the back end complained! */
8887 }
8888 else
8889 init = error_mark_node;
8890 }
8891 else if (ffe_is_init_local_zero ())
8892 init = error_mark_node;
8893 else
8894 init = NULL_TREE;
5ff904cd 8895
c7e4ee3a
CB
8896 ffecom_member_namelisted_ = FALSE;
8897 ffestorag_drive (ffestorag_list_equivs (eqst),
8898 &ffecom_member_phase1_,
8899 eqst);
5ff904cd 8900
c7e4ee3a 8901 yes = suspend_momentary ();
5ff904cd 8902
c7e4ee3a
CB
8903 high = build_int_2 ((ffestorag_size (eqst)
8904 + ffestorag_modulo (eqst)) - 1, 0);
8905 TREE_TYPE (high) = ffecom_integer_type_node;
5ff904cd 8906
c7e4ee3a
CB
8907 eqtype = build_array_type (char_type_node,
8908 build_range_type (ffecom_integer_type_node,
8909 ffecom_integer_zero_node,
8910 high));
8911
8912 eqt = build_decl (VAR_DECL,
8913 ffecom_get_invented_identifier ("__g77_equiv_%s",
8914 ffesymbol_text
14657de8 8915 (ffestorag_symbol (eqst))),
c7e4ee3a
CB
8916 eqtype);
8917 DECL_EXTERNAL (eqt) = 0;
8918 if (is_init
8919 || ffecom_member_namelisted_
8920#ifdef FFECOM_sizeMAXSTACKITEM
8921 || (ffestorag_size (eqst) > FFECOM_sizeMAXSTACKITEM)
8922#endif
8923 || ((ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
8924 && (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA)
8925 && (ffestorag_is_save (eqst) || ffe_is_saveall ())))
8926 TREE_STATIC (eqt) = 1;
8927 else
8928 TREE_STATIC (eqt) = 0;
8929 TREE_PUBLIC (eqt) = 0;
a8e2bb76 8930 TREE_ADDRESSABLE (eqt) = 1; /* Ensure non-register allocation */
c7e4ee3a
CB
8931 DECL_CONTEXT (eqt) = current_function_decl;
8932 if (init)
8933 DECL_INITIAL (eqt) = error_mark_node;
8934 else
8935 DECL_INITIAL (eqt) = NULL_TREE;
5ff904cd 8936
c7e4ee3a 8937 eqt = start_decl (eqt, FALSE);
5ff904cd 8938
c7e4ee3a
CB
8939 /* Make sure that any type can live in EQUIVALENCE and be referenced
8940 without getting a bus error. We could pick the most restrictive
8941 alignment of all entities actually placed in the EQUIVALENCE, but
8942 this seems easy enough. */
5ff904cd 8943
c7e4ee3a 8944 DECL_ALIGN (eqt) = BIGGEST_ALIGNMENT;
11cf4d18 8945 DECL_USER_ALIGN (eqt) = 0;
5ff904cd 8946
c7e4ee3a
CB
8947 if ((!is_init && ffe_is_init_local_zero ())
8948 || (is_init && (ffestorag_init (eqst) == NULL)))
8949 init = ffecom_init_zero_ (eqt);
5ff904cd 8950
c7e4ee3a 8951 finish_decl (eqt, init, FALSE);
5ff904cd 8952
c7e4ee3a
CB
8953 if (is_init)
8954 ffestorag_set_init (eqst, ffebld_new_any ());
5ff904cd 8955
c7e4ee3a 8956 {
06ceef4e 8957 assert (TREE_CODE (DECL_SIZE_UNIT (eqt)) == INTEGER_CST);
05bccae2
RK
8958 assert (0 == compare_tree_int (DECL_SIZE_UNIT (eqt),
8959 (ffestorag_size (eqst)
8960 + ffestorag_modulo (eqst))));
c7e4ee3a 8961 }
5ff904cd 8962
c7e4ee3a 8963 ffestorag_set_hook (eqst, eqt);
5ff904cd 8964
c7e4ee3a
CB
8965 ffestorag_drive (ffestorag_list_equivs (eqst),
8966 &ffecom_member_phase2_,
8967 eqst);
c7e4ee3a
CB
8968
8969 resume_momentary (yes);
5ff904cd
JL
8970}
8971
8972#endif
c7e4ee3a 8973/* Implement NAMELIST in back end. See f2c/format.c for more info. */
5ff904cd
JL
8974
8975#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
8976static tree
8977ffecom_transform_namelist_ (ffesymbol s)
5ff904cd 8978{
c7e4ee3a
CB
8979 tree nmlt;
8980 tree nmltype = ffecom_type_namelist_ ();
8981 tree nmlinits;
8982 tree nameinit;
8983 tree varsinit;
8984 tree nvarsinit;
8985 tree field;
8986 tree high;
5ff904cd 8987 int yes;
c7e4ee3a
CB
8988 int i;
8989 static int mynumber = 0;
5ff904cd 8990
c7e4ee3a 8991 yes = suspend_momentary ();
5ff904cd 8992
c7e4ee3a
CB
8993 nmlt = build_decl (VAR_DECL,
8994 ffecom_get_invented_identifier ("__g77_namelist_%d",
14657de8 8995 mynumber++),
c7e4ee3a
CB
8996 nmltype);
8997 TREE_STATIC (nmlt) = 1;
8998 DECL_INITIAL (nmlt) = error_mark_node;
5ff904cd 8999
c7e4ee3a 9000 nmlt = start_decl (nmlt, FALSE);
5ff904cd 9001
c7e4ee3a 9002 /* Process inits. */
5ff904cd 9003
c7e4ee3a 9004 i = strlen (ffesymbol_text (s));
5ff904cd 9005
c7e4ee3a
CB
9006 high = build_int_2 (i, 0);
9007 TREE_TYPE (high) = ffecom_f2c_ftnlen_type_node;
9008
9009 nameinit = ffecom_build_f2c_string_ (i + 1,
9010 ffesymbol_text (s));
9011 TREE_TYPE (nameinit)
9012 = build_type_variant
9013 (build_array_type
9014 (char_type_node,
9015 build_range_type (ffecom_f2c_ftnlen_type_node,
9016 ffecom_f2c_ftnlen_one_node,
9017 high)),
9018 1, 0);
9019 TREE_CONSTANT (nameinit) = 1;
9020 TREE_STATIC (nameinit) = 1;
9021 nameinit = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (nameinit)),
9022 nameinit);
9023
9024 varsinit = ffecom_vardesc_array_ (s);
9025 varsinit = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (varsinit)),
9026 varsinit);
9027 TREE_CONSTANT (varsinit) = 1;
9028 TREE_STATIC (varsinit) = 1;
9029
9030 {
9031 ffebld b;
9032
9033 for (i = 0, b = ffesymbol_namelist (s); b != NULL; b = ffebld_trail (b))
9034 ++i;
9035 }
9036 nvarsinit = build_int_2 (i, 0);
9037 TREE_TYPE (nvarsinit) = integer_type_node;
9038 TREE_CONSTANT (nvarsinit) = 1;
9039 TREE_STATIC (nvarsinit) = 1;
9040
9041 nmlinits = build_tree_list ((field = TYPE_FIELDS (nmltype)), nameinit);
9042 TREE_CHAIN (nmlinits) = build_tree_list ((field = TREE_CHAIN (field)),
9043 varsinit);
9044 TREE_CHAIN (TREE_CHAIN (nmlinits))
9045 = build_tree_list ((field = TREE_CHAIN (field)), nvarsinit);
9046
9047 nmlinits = build (CONSTRUCTOR, nmltype, NULL_TREE, nmlinits);
9048 TREE_CONSTANT (nmlinits) = 1;
9049 TREE_STATIC (nmlinits) = 1;
9050
9051 finish_decl (nmlt, nmlinits, FALSE);
9052
9053 nmlt = ffecom_1 (ADDR_EXPR, build_pointer_type (nmltype), nmlt);
9054
9055 resume_momentary (yes);
9056
9057 return nmlt;
9058}
9059
9060#endif
9061
9062/* A subroutine of ffecom_tree_canonize_ref_. The incoming tree is
9063 analyzed on the assumption it is calculating a pointer to be
9064 indirected through. It must return the proper decl and offset,
9065 taking into account different units of measurements for offsets. */
9066
9067#if FFECOM_targetCURRENT == FFECOM_targetGCC
9068static void
9069ffecom_tree_canonize_ptr_ (tree *decl, tree *offset,
9070 tree t)
9071{
9072 switch (TREE_CODE (t))
9073 {
9074 case NOP_EXPR:
9075 case CONVERT_EXPR:
9076 case NON_LVALUE_EXPR:
9077 ffecom_tree_canonize_ptr_ (decl, offset, TREE_OPERAND (t, 0));
5ff904cd
JL
9078 break;
9079
c7e4ee3a
CB
9080 case PLUS_EXPR:
9081 ffecom_tree_canonize_ptr_ (decl, offset, TREE_OPERAND (t, 0));
9082 if ((*decl == NULL_TREE)
9083 || (*decl == error_mark_node))
9084 break;
9085
9086 if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST)
9087 {
9088 /* An offset into COMMON. */
fed3cef0
RK
9089 *offset = fold (build (PLUS_EXPR, TREE_TYPE (*offset),
9090 *offset, TREE_OPERAND (t, 1)));
c7e4ee3a
CB
9091 /* Convert offset (presumably in bytes) into canonical units
9092 (presumably bits). */
76fa6b3b
ZW
9093 *offset = size_binop (MULT_EXPR,
9094 convert (bitsizetype, *offset),
9095 TYPE_SIZE (TREE_TYPE (TREE_TYPE (t))));
c7e4ee3a
CB
9096 break;
9097 }
9098 /* Not a COMMON reference, so an unrecognized pattern. */
9099 *decl = error_mark_node;
5ff904cd
JL
9100 break;
9101
c7e4ee3a
CB
9102 case PARM_DECL:
9103 *decl = t;
770ae6cc 9104 *offset = bitsize_zero_node;
5ff904cd
JL
9105 break;
9106
c7e4ee3a
CB
9107 case ADDR_EXPR:
9108 if (TREE_CODE (TREE_OPERAND (t, 0)) == VAR_DECL)
9109 {
9110 /* A reference to COMMON. */
9111 *decl = TREE_OPERAND (t, 0);
770ae6cc 9112 *offset = bitsize_zero_node;
c7e4ee3a
CB
9113 break;
9114 }
9115 /* Fall through. */
5ff904cd 9116 default:
c7e4ee3a
CB
9117 /* Not a COMMON reference, so an unrecognized pattern. */
9118 *decl = error_mark_node;
5ff904cd
JL
9119 break;
9120 }
c7e4ee3a
CB
9121}
9122#endif
5ff904cd 9123
c7e4ee3a
CB
9124/* Given a tree that is possibly intended for use as an lvalue, return
9125 information representing a canonical view of that tree as a decl, an
9126 offset into that decl, and a size for the lvalue.
5ff904cd 9127
c7e4ee3a
CB
9128 If there's no applicable decl, NULL_TREE is returned for the decl,
9129 and the other fields are left undefined.
5ff904cd 9130
c7e4ee3a
CB
9131 If the tree doesn't fit the recognizable forms, an ERROR_MARK node
9132 is returned for the decl, and the other fields are left undefined.
5ff904cd 9133
c7e4ee3a
CB
9134 Otherwise, the decl returned currently is either a VAR_DECL or a
9135 PARM_DECL.
5ff904cd 9136
c7e4ee3a
CB
9137 The offset returned is always valid, but of course not necessarily
9138 a constant, and not necessarily converted into the appropriate
9139 type, leaving that up to the caller (so as to avoid that overhead
9140 if the decls being looked at are different anyway).
5ff904cd 9141
c7e4ee3a
CB
9142 If the size cannot be determined (e.g. an adjustable array),
9143 an ERROR_MARK node is returned for the size. Otherwise, the
9144 size returned is valid, not necessarily a constant, and not
9145 necessarily converted into the appropriate type as with the
9146 offset.
5ff904cd 9147
c7e4ee3a
CB
9148 Note that the offset and size expressions are expressed in the
9149 base storage units (usually bits) rather than in the units of
9150 the type of the decl, because two decls with different types
9151 might overlap but with apparently non-overlapping array offsets,
9152 whereas converting the array offsets to consistant offsets will
9153 reveal the overlap. */
5ff904cd
JL
9154
9155#if FFECOM_targetCURRENT == FFECOM_targetGCC
9156static void
c7e4ee3a
CB
9157ffecom_tree_canonize_ref_ (tree *decl, tree *offset,
9158 tree *size, tree t)
5ff904cd 9159{
c7e4ee3a
CB
9160 /* The default path is to report a nonexistant decl. */
9161 *decl = NULL_TREE;
5ff904cd 9162
c7e4ee3a 9163 if (t == NULL_TREE)
5ff904cd
JL
9164 return;
9165
c7e4ee3a
CB
9166 switch (TREE_CODE (t))
9167 {
9168 case ERROR_MARK:
9169 case IDENTIFIER_NODE:
9170 case INTEGER_CST:
9171 case REAL_CST:
9172 case COMPLEX_CST:
9173 case STRING_CST:
9174 case CONST_DECL:
9175 case PLUS_EXPR:
9176 case MINUS_EXPR:
9177 case MULT_EXPR:
9178 case TRUNC_DIV_EXPR:
9179 case CEIL_DIV_EXPR:
9180 case FLOOR_DIV_EXPR:
9181 case ROUND_DIV_EXPR:
9182 case TRUNC_MOD_EXPR:
9183 case CEIL_MOD_EXPR:
9184 case FLOOR_MOD_EXPR:
9185 case ROUND_MOD_EXPR:
9186 case RDIV_EXPR:
9187 case EXACT_DIV_EXPR:
9188 case FIX_TRUNC_EXPR:
9189 case FIX_CEIL_EXPR:
9190 case FIX_FLOOR_EXPR:
9191 case FIX_ROUND_EXPR:
9192 case FLOAT_EXPR:
9193 case EXPON_EXPR:
9194 case NEGATE_EXPR:
9195 case MIN_EXPR:
9196 case MAX_EXPR:
9197 case ABS_EXPR:
9198 case FFS_EXPR:
9199 case LSHIFT_EXPR:
9200 case RSHIFT_EXPR:
9201 case LROTATE_EXPR:
9202 case RROTATE_EXPR:
9203 case BIT_IOR_EXPR:
9204 case BIT_XOR_EXPR:
9205 case BIT_AND_EXPR:
9206 case BIT_ANDTC_EXPR:
9207 case BIT_NOT_EXPR:
9208 case TRUTH_ANDIF_EXPR:
9209 case TRUTH_ORIF_EXPR:
9210 case TRUTH_AND_EXPR:
9211 case TRUTH_OR_EXPR:
9212 case TRUTH_XOR_EXPR:
9213 case TRUTH_NOT_EXPR:
9214 case LT_EXPR:
9215 case LE_EXPR:
9216 case GT_EXPR:
9217 case GE_EXPR:
9218 case EQ_EXPR:
9219 case NE_EXPR:
9220 case COMPLEX_EXPR:
9221 case CONJ_EXPR:
9222 case REALPART_EXPR:
9223 case IMAGPART_EXPR:
9224 case LABEL_EXPR:
9225 case COMPONENT_REF:
9226 case COMPOUND_EXPR:
9227 case ADDR_EXPR:
9228 return;
5ff904cd 9229
c7e4ee3a
CB
9230 case VAR_DECL:
9231 case PARM_DECL:
9232 *decl = t;
770ae6cc 9233 *offset = bitsize_zero_node;
c7e4ee3a
CB
9234 *size = TYPE_SIZE (TREE_TYPE (t));
9235 return;
5ff904cd 9236
c7e4ee3a
CB
9237 case ARRAY_REF:
9238 {
9239 tree array = TREE_OPERAND (t, 0);
9240 tree element = TREE_OPERAND (t, 1);
9241 tree init_offset;
9242
9243 if ((array == NULL_TREE)
9244 || (element == NULL_TREE))
9245 {
9246 *decl = error_mark_node;
9247 return;
9248 }
9249
9250 ffecom_tree_canonize_ref_ (decl, &init_offset, size,
9251 array);
9252 if ((*decl == NULL_TREE)
9253 || (*decl == error_mark_node))
9254 return;
9255
76fa6b3b
ZW
9256 /* Calculate ((element - base) * NBBY) + init_offset. */
9257 *offset = fold (build (MINUS_EXPR, TREE_TYPE (element),
9258 element,
9259 TYPE_MIN_VALUE (TYPE_DOMAIN
9260 (TREE_TYPE (array)))));
9261
9262 *offset = size_binop (MULT_EXPR,
9263 convert (bitsizetype, *offset),
9264 TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))));
9265
9266 *offset = size_binop (PLUS_EXPR, init_offset, *offset);
c7e4ee3a
CB
9267
9268 *size = TYPE_SIZE (TREE_TYPE (t));
9269 return;
9270 }
9271
9272 case INDIRECT_REF:
9273
9274 /* Most of this code is to handle references to COMMON. And so
9275 far that is useful only for calling library functions, since
9276 external (user) functions might reference common areas. But
9277 even calling an external function, it's worthwhile to decode
9278 COMMON references because if not storing into COMMON, we don't
9279 want COMMON-based arguments to gratuitously force use of a
9280 temporary. */
9281
9282 *size = TYPE_SIZE (TREE_TYPE (t));
5ff904cd 9283
c7e4ee3a
CB
9284 ffecom_tree_canonize_ptr_ (decl, offset,
9285 TREE_OPERAND (t, 0));
5ff904cd 9286
c7e4ee3a 9287 return;
5ff904cd 9288
c7e4ee3a
CB
9289 case CONVERT_EXPR:
9290 case NOP_EXPR:
9291 case MODIFY_EXPR:
9292 case NON_LVALUE_EXPR:
9293 case RESULT_DECL:
9294 case FIELD_DECL:
9295 case COND_EXPR: /* More cases than we can handle. */
9296 case SAVE_EXPR:
9297 case REFERENCE_EXPR:
9298 case PREDECREMENT_EXPR:
9299 case PREINCREMENT_EXPR:
9300 case POSTDECREMENT_EXPR:
9301 case POSTINCREMENT_EXPR:
9302 case CALL_EXPR:
9303 default:
9304 *decl = error_mark_node;
9305 return;
9306 }
9307}
9308#endif
5ff904cd 9309
c7e4ee3a 9310/* Do divide operation appropriate to type of operands. */
5ff904cd 9311
c7e4ee3a
CB
9312#if FFECOM_targetCURRENT == FFECOM_targetGCC
9313static tree
9314ffecom_tree_divide_ (tree tree_type, tree left, tree right,
9315 tree dest_tree, ffebld dest, bool *dest_used,
9316 tree hook)
9317{
9318 if ((left == error_mark_node)
9319 || (right == error_mark_node))
9320 return error_mark_node;
a6fa6420 9321
c7e4ee3a
CB
9322 switch (TREE_CODE (tree_type))
9323 {
9324 case INTEGER_TYPE:
9325 return ffecom_2 (TRUNC_DIV_EXPR, tree_type,
9326 left,
9327 right);
a6fa6420 9328
c7e4ee3a 9329 case COMPLEX_TYPE:
c64f913e
CB
9330 if (! optimize_size)
9331 return ffecom_2 (RDIV_EXPR, tree_type,
9332 left,
9333 right);
c7e4ee3a
CB
9334 {
9335 ffecomGfrt ix;
a6fa6420 9336
c7e4ee3a
CB
9337 if (TREE_TYPE (tree_type)
9338 == ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1])
9339 ix = FFECOM_gfrtDIV_CC; /* Overlapping result okay. */
9340 else
9341 ix = FFECOM_gfrtDIV_ZZ; /* Overlapping result okay. */
a6fa6420 9342
c7e4ee3a
CB
9343 left = ffecom_1 (ADDR_EXPR,
9344 build_pointer_type (TREE_TYPE (left)),
9345 left);
9346 left = build_tree_list (NULL_TREE, left);
9347 right = ffecom_1 (ADDR_EXPR,
9348 build_pointer_type (TREE_TYPE (right)),
9349 right);
9350 right = build_tree_list (NULL_TREE, right);
9351 TREE_CHAIN (left) = right;
a6fa6420 9352
c7e4ee3a
CB
9353 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
9354 ffecom_gfrt_kindtype (ix),
9355 ffe_is_f2c_library (),
9356 tree_type,
9357 left,
9358 dest_tree, dest, dest_used,
9359 NULL_TREE, TRUE, hook);
9360 }
9361 break;
5ff904cd 9362
c7e4ee3a
CB
9363 case RECORD_TYPE:
9364 {
9365 ffecomGfrt ix;
5ff904cd 9366
c7e4ee3a
CB
9367 if (TREE_TYPE (TYPE_FIELDS (tree_type))
9368 == ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1])
9369 ix = FFECOM_gfrtDIV_CC; /* Overlapping result okay. */
9370 else
9371 ix = FFECOM_gfrtDIV_ZZ; /* Overlapping result okay. */
5ff904cd 9372
c7e4ee3a
CB
9373 left = ffecom_1 (ADDR_EXPR,
9374 build_pointer_type (TREE_TYPE (left)),
9375 left);
9376 left = build_tree_list (NULL_TREE, left);
9377 right = ffecom_1 (ADDR_EXPR,
9378 build_pointer_type (TREE_TYPE (right)),
9379 right);
9380 right = build_tree_list (NULL_TREE, right);
9381 TREE_CHAIN (left) = right;
a6fa6420 9382
c7e4ee3a
CB
9383 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
9384 ffecom_gfrt_kindtype (ix),
9385 ffe_is_f2c_library (),
9386 tree_type,
9387 left,
9388 dest_tree, dest, dest_used,
9389 NULL_TREE, TRUE, hook);
9390 }
9391 break;
5ff904cd 9392
c7e4ee3a
CB
9393 default:
9394 return ffecom_2 (RDIV_EXPR, tree_type,
9395 left,
9396 right);
5ff904cd 9397 }
c7e4ee3a 9398}
5ff904cd 9399
c7e4ee3a
CB
9400#endif
9401/* Build type info for non-dummy variable. */
5ff904cd 9402
c7e4ee3a
CB
9403#if FFECOM_targetCURRENT == FFECOM_targetGCC
9404static tree
9405ffecom_type_localvar_ (ffesymbol s, ffeinfoBasictype bt,
9406 ffeinfoKindtype kt)
9407{
9408 tree type;
9409 ffebld dl;
9410 ffebld dim;
9411 tree lowt;
9412 tree hight;
5ff904cd 9413
c7e4ee3a
CB
9414 type = ffecom_tree_type[bt][kt];
9415 if (bt == FFEINFO_basictypeCHARACTER)
9416 {
9417 hight = build_int_2 (ffesymbol_size (s), 0);
9418 TREE_TYPE (hight) = ffecom_f2c_ftnlen_type_node;
5ff904cd 9419
c7e4ee3a
CB
9420 type
9421 = build_array_type
9422 (type,
9423 build_range_type (ffecom_f2c_ftnlen_type_node,
9424 ffecom_f2c_ftnlen_one_node,
9425 hight));
9426 type = ffecom_check_size_overflow_ (s, type, FALSE);
9427 }
5ff904cd 9428
c7e4ee3a
CB
9429 for (dl = ffesymbol_dims (s); dl != NULL; dl = ffebld_trail (dl))
9430 {
9431 if (type == error_mark_node)
9432 break;
5ff904cd 9433
c7e4ee3a
CB
9434 dim = ffebld_head (dl);
9435 assert (ffebld_op (dim) == FFEBLD_opBOUNDS);
5ff904cd 9436
c7e4ee3a
CB
9437 if (ffebld_left (dim) == NULL)
9438 lowt = integer_one_node;
9439 else
9440 lowt = ffecom_expr (ffebld_left (dim));
5ff904cd 9441
c7e4ee3a
CB
9442 if (TREE_CODE (lowt) != INTEGER_CST)
9443 lowt = variable_size (lowt);
5ff904cd 9444
c7e4ee3a
CB
9445 assert (ffebld_right (dim) != NULL);
9446 hight = ffecom_expr (ffebld_right (dim));
5ff904cd 9447
c7e4ee3a
CB
9448 if (TREE_CODE (hight) != INTEGER_CST)
9449 hight = variable_size (hight);
5ff904cd 9450
c7e4ee3a
CB
9451 type = build_array_type (type,
9452 build_range_type (ffecom_integer_type_node,
9453 lowt, hight));
9454 type = ffecom_check_size_overflow_ (s, type, FALSE);
9455 }
5ff904cd 9456
c7e4ee3a 9457 return type;
5ff904cd
JL
9458}
9459
9460#endif
c7e4ee3a 9461/* Build Namelist type. */
5ff904cd 9462
c7e4ee3a
CB
9463#if FFECOM_targetCURRENT == FFECOM_targetGCC
9464static tree
9465ffecom_type_namelist_ ()
9466{
9467 static tree type = NULL_TREE;
5ff904cd 9468
c7e4ee3a
CB
9469 if (type == NULL_TREE)
9470 {
9471 static tree namefield, varsfield, nvarsfield;
9472 tree vardesctype;
5ff904cd 9473
c7e4ee3a 9474 vardesctype = ffecom_type_vardesc_ ();
5ff904cd 9475
c7e4ee3a 9476 type = make_node (RECORD_TYPE);
a6fa6420 9477
c7e4ee3a 9478 vardesctype = build_pointer_type (build_pointer_type (vardesctype));
a6fa6420 9479
c7e4ee3a
CB
9480 namefield = ffecom_decl_field (type, NULL_TREE, "name",
9481 string_type_node);
9482 varsfield = ffecom_decl_field (type, namefield, "vars", vardesctype);
9483 nvarsfield = ffecom_decl_field (type, varsfield, "nvars",
9484 integer_type_node);
a6fa6420 9485
c7e4ee3a
CB
9486 TYPE_FIELDS (type) = namefield;
9487 layout_type (type);
a6fa6420 9488
7189a4b0 9489 ggc_add_tree_root (&type, 1);
5ff904cd 9490 }
5ff904cd 9491
c7e4ee3a
CB
9492 return type;
9493}
5ff904cd 9494
c7e4ee3a 9495#endif
5ff904cd 9496
c7e4ee3a 9497/* Build Vardesc type. */
5ff904cd 9498
c7e4ee3a
CB
9499#if FFECOM_targetCURRENT == FFECOM_targetGCC
9500static tree
9501ffecom_type_vardesc_ ()
9502{
9503 static tree type = NULL_TREE;
9504 static tree namefield, addrfield, dimsfield, typefield;
5ff904cd 9505
c7e4ee3a
CB
9506 if (type == NULL_TREE)
9507 {
c7e4ee3a 9508 type = make_node (RECORD_TYPE);
5ff904cd 9509
c7e4ee3a
CB
9510 namefield = ffecom_decl_field (type, NULL_TREE, "name",
9511 string_type_node);
9512 addrfield = ffecom_decl_field (type, namefield, "addr",
9513 string_type_node);
9514 dimsfield = ffecom_decl_field (type, addrfield, "dims",
9515 ffecom_f2c_ptr_to_ftnlen_type_node);
9516 typefield = ffecom_decl_field (type, dimsfield, "type",
9517 integer_type_node);
5ff904cd 9518
c7e4ee3a
CB
9519 TYPE_FIELDS (type) = namefield;
9520 layout_type (type);
9521
7189a4b0 9522 ggc_add_tree_root (&type, 1);
c7e4ee3a
CB
9523 }
9524
9525 return type;
5ff904cd
JL
9526}
9527
9528#endif
5ff904cd
JL
9529
9530#if FFECOM_targetCURRENT == FFECOM_targetGCC
9531static tree
c7e4ee3a 9532ffecom_vardesc_ (ffebld expr)
5ff904cd 9533{
c7e4ee3a 9534 ffesymbol s;
5ff904cd 9535
c7e4ee3a
CB
9536 assert (ffebld_op (expr) == FFEBLD_opSYMTER);
9537 s = ffebld_symter (expr);
5ff904cd 9538
c7e4ee3a
CB
9539 if (ffesymbol_hook (s).vardesc_tree == NULL_TREE)
9540 {
9541 int i;
9542 tree vardesctype = ffecom_type_vardesc_ ();
9543 tree var;
9544 tree nameinit;
9545 tree dimsinit;
9546 tree addrinit;
9547 tree typeinit;
9548 tree field;
9549 tree varinits;
9550 int yes;
9551 static int mynumber = 0;
5ff904cd 9552
c7e4ee3a 9553 yes = suspend_momentary ();
5ff904cd 9554
c7e4ee3a
CB
9555 var = build_decl (VAR_DECL,
9556 ffecom_get_invented_identifier ("__g77_vardesc_%d",
14657de8 9557 mynumber++),
c7e4ee3a
CB
9558 vardesctype);
9559 TREE_STATIC (var) = 1;
9560 DECL_INITIAL (var) = error_mark_node;
5ff904cd 9561
c7e4ee3a 9562 var = start_decl (var, FALSE);
5ff904cd 9563
c7e4ee3a 9564 /* Process inits. */
5ff904cd 9565
c7e4ee3a
CB
9566 nameinit = ffecom_build_f2c_string_ ((i = strlen (ffesymbol_text (s)))
9567 + 1,
9568 ffesymbol_text (s));
9569 TREE_TYPE (nameinit)
9570 = build_type_variant
9571 (build_array_type
9572 (char_type_node,
9573 build_range_type (integer_type_node,
9574 integer_one_node,
9575 build_int_2 (i, 0))),
9576 1, 0);
9577 TREE_CONSTANT (nameinit) = 1;
9578 TREE_STATIC (nameinit) = 1;
9579 nameinit = ffecom_1 (ADDR_EXPR,
9580 build_pointer_type (TREE_TYPE (nameinit)),
9581 nameinit);
5ff904cd 9582
c7e4ee3a 9583 addrinit = ffecom_arg_ptr_to_expr (expr, &typeinit);
5ff904cd 9584
c7e4ee3a 9585 dimsinit = ffecom_vardesc_dims_ (s);
5ff904cd 9586
c7e4ee3a
CB
9587 if (typeinit == NULL_TREE)
9588 {
9589 ffeinfoBasictype bt = ffesymbol_basictype (s);
9590 ffeinfoKindtype kt = ffesymbol_kindtype (s);
9591 int tc = ffecom_f2c_typecode (bt, kt);
5ff904cd 9592
c7e4ee3a
CB
9593 assert (tc != -1);
9594 typeinit = build_int_2 (tc, (tc < 0) ? -1 : 0);
9595 }
9596 else
9597 typeinit = ffecom_1 (NEGATE_EXPR, TREE_TYPE (typeinit), typeinit);
5ff904cd 9598
c7e4ee3a
CB
9599 varinits = build_tree_list ((field = TYPE_FIELDS (vardesctype)),
9600 nameinit);
9601 TREE_CHAIN (varinits) = build_tree_list ((field = TREE_CHAIN (field)),
9602 addrinit);
9603 TREE_CHAIN (TREE_CHAIN (varinits))
9604 = build_tree_list ((field = TREE_CHAIN (field)), dimsinit);
9605 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (varinits)))
9606 = build_tree_list ((field = TREE_CHAIN (field)), typeinit);
5ff904cd 9607
c7e4ee3a
CB
9608 varinits = build (CONSTRUCTOR, vardesctype, NULL_TREE, varinits);
9609 TREE_CONSTANT (varinits) = 1;
9610 TREE_STATIC (varinits) = 1;
5ff904cd 9611
c7e4ee3a 9612 finish_decl (var, varinits, FALSE);
5ff904cd 9613
c7e4ee3a 9614 var = ffecom_1 (ADDR_EXPR, build_pointer_type (vardesctype), var);
5ff904cd 9615
c7e4ee3a 9616 resume_momentary (yes);
5ff904cd 9617
c7e4ee3a
CB
9618 ffesymbol_hook (s).vardesc_tree = var;
9619 }
5ff904cd 9620
c7e4ee3a
CB
9621 return ffesymbol_hook (s).vardesc_tree;
9622}
5ff904cd 9623
c7e4ee3a 9624#endif
5ff904cd 9625#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
9626static tree
9627ffecom_vardesc_array_ (ffesymbol s)
5ff904cd 9628{
c7e4ee3a
CB
9629 ffebld b;
9630 tree list;
9631 tree item = NULL_TREE;
9632 tree var;
9633 int i;
9634 int yes;
9635 static int mynumber = 0;
5ff904cd 9636
c7e4ee3a
CB
9637 for (i = 0, list = NULL_TREE, b = ffesymbol_namelist (s);
9638 b != NULL;
9639 b = ffebld_trail (b), ++i)
9640 {
9641 tree t;
5ff904cd 9642
c7e4ee3a 9643 t = ffecom_vardesc_ (ffebld_head (b));
5ff904cd 9644
c7e4ee3a
CB
9645 if (list == NULL_TREE)
9646 list = item = build_tree_list (NULL_TREE, t);
9647 else
5ff904cd 9648 {
c7e4ee3a
CB
9649 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
9650 item = TREE_CHAIN (item);
5ff904cd 9651 }
5ff904cd 9652 }
5ff904cd 9653
c7e4ee3a 9654 yes = suspend_momentary ();
5ff904cd 9655
c7e4ee3a
CB
9656 item = build_array_type (build_pointer_type (ffecom_type_vardesc_ ()),
9657 build_range_type (integer_type_node,
9658 integer_one_node,
9659 build_int_2 (i, 0)));
9660 list = build (CONSTRUCTOR, item, NULL_TREE, list);
9661 TREE_CONSTANT (list) = 1;
9662 TREE_STATIC (list) = 1;
5ff904cd 9663
14657de8 9664 var = ffecom_get_invented_identifier ("__g77_vardesc_array_%d", mynumber++);
c7e4ee3a
CB
9665 var = build_decl (VAR_DECL, var, item);
9666 TREE_STATIC (var) = 1;
9667 DECL_INITIAL (var) = error_mark_node;
9668 var = start_decl (var, FALSE);
9669 finish_decl (var, list, FALSE);
5ff904cd 9670
c7e4ee3a 9671 resume_momentary (yes);
5ff904cd 9672
c7e4ee3a
CB
9673 return var;
9674}
5ff904cd 9675
c7e4ee3a
CB
9676#endif
9677#if FFECOM_targetCURRENT == FFECOM_targetGCC
9678static tree
9679ffecom_vardesc_dims_ (ffesymbol s)
9680{
9681 if (ffesymbol_dims (s) == NULL)
9682 return convert (ffecom_f2c_ptr_to_ftnlen_type_node,
9683 integer_zero_node);
5ff904cd 9684
c7e4ee3a
CB
9685 {
9686 ffebld b;
9687 ffebld e;
9688 tree list;
9689 tree backlist;
9690 tree item = NULL_TREE;
9691 tree var;
9692 int yes;
9693 tree numdim;
9694 tree numelem;
9695 tree baseoff = NULL_TREE;
9696 static int mynumber = 0;
9697
9698 numdim = build_int_2 ((int) ffesymbol_rank (s), 0);
9699 TREE_TYPE (numdim) = ffecom_f2c_ftnlen_type_node;
9700
9701 numelem = ffecom_expr (ffesymbol_arraysize (s));
9702 TREE_TYPE (numelem) = ffecom_f2c_ftnlen_type_node;
9703
9704 list = NULL_TREE;
9705 backlist = NULL_TREE;
9706 for (b = ffesymbol_dims (s), e = ffesymbol_extents (s);
9707 b != NULL;
9708 b = ffebld_trail (b), e = ffebld_trail (e))
5ff904cd 9709 {
c7e4ee3a
CB
9710 tree t;
9711 tree low;
9712 tree back;
5ff904cd 9713
c7e4ee3a
CB
9714 if (ffebld_trail (b) == NULL)
9715 t = NULL_TREE;
9716 else
5ff904cd 9717 {
c7e4ee3a
CB
9718 t = convert (ffecom_f2c_ftnlen_type_node,
9719 ffecom_expr (ffebld_head (e)));
5ff904cd 9720
c7e4ee3a
CB
9721 if (list == NULL_TREE)
9722 list = item = build_tree_list (NULL_TREE, t);
9723 else
9724 {
9725 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
9726 item = TREE_CHAIN (item);
9727 }
9728 }
5ff904cd 9729
c7e4ee3a
CB
9730 if (ffebld_left (ffebld_head (b)) == NULL)
9731 low = ffecom_integer_one_node;
9732 else
9733 low = ffecom_expr (ffebld_left (ffebld_head (b)));
9734 low = convert (ffecom_f2c_ftnlen_type_node, low);
5ff904cd 9735
c7e4ee3a
CB
9736 back = build_tree_list (low, t);
9737 TREE_CHAIN (back) = backlist;
9738 backlist = back;
9739 }
5ff904cd 9740
c7e4ee3a
CB
9741 for (item = backlist; item != NULL_TREE; item = TREE_CHAIN (item))
9742 {
9743 if (TREE_VALUE (item) == NULL_TREE)
9744 baseoff = TREE_PURPOSE (item);
9745 else
9746 baseoff = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
9747 TREE_PURPOSE (item),
9748 ffecom_2 (MULT_EXPR,
9749 ffecom_f2c_ftnlen_type_node,
9750 TREE_VALUE (item),
9751 baseoff));
5ff904cd
JL
9752 }
9753
c7e4ee3a 9754 /* backlist now dead, along with all TREE_PURPOSEs on it. */
5ff904cd 9755
c7e4ee3a
CB
9756 baseoff = build_tree_list (NULL_TREE, baseoff);
9757 TREE_CHAIN (baseoff) = list;
5ff904cd 9758
c7e4ee3a
CB
9759 numelem = build_tree_list (NULL_TREE, numelem);
9760 TREE_CHAIN (numelem) = baseoff;
5ff904cd 9761
c7e4ee3a
CB
9762 numdim = build_tree_list (NULL_TREE, numdim);
9763 TREE_CHAIN (numdim) = numelem;
5ff904cd 9764
c7e4ee3a 9765 yes = suspend_momentary ();
5ff904cd 9766
c7e4ee3a
CB
9767 item = build_array_type (ffecom_f2c_ftnlen_type_node,
9768 build_range_type (integer_type_node,
9769 integer_zero_node,
9770 build_int_2
9771 ((int) ffesymbol_rank (s)
9772 + 2, 0)));
9773 list = build (CONSTRUCTOR, item, NULL_TREE, numdim);
9774 TREE_CONSTANT (list) = 1;
9775 TREE_STATIC (list) = 1;
9776
14657de8 9777 var = ffecom_get_invented_identifier ("__g77_dims_%d", mynumber++);
c7e4ee3a
CB
9778 var = build_decl (VAR_DECL, var, item);
9779 TREE_STATIC (var) = 1;
9780 DECL_INITIAL (var) = error_mark_node;
9781 var = start_decl (var, FALSE);
9782 finish_decl (var, list, FALSE);
9783
9784 var = ffecom_1 (ADDR_EXPR, build_pointer_type (item), var);
9785
9786 resume_momentary (yes);
9787
9788 return var;
9789 }
5ff904cd 9790}
c7e4ee3a 9791
5ff904cd 9792#endif
c7e4ee3a
CB
9793/* Essentially does a "fold (build1 (code, type, node))" while checking
9794 for certain housekeeping things.
5ff904cd 9795
c7e4ee3a
CB
9796 NOTE: for building an ADDR_EXPR around a FUNCTION_DECL, use
9797 ffecom_1_fn instead. */
5ff904cd
JL
9798
9799#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
9800tree
9801ffecom_1 (enum tree_code code, tree type, tree node)
5ff904cd 9802{
c7e4ee3a
CB
9803 tree item;
9804
9805 if ((node == error_mark_node)
9806 || (type == error_mark_node))
5ff904cd
JL
9807 return error_mark_node;
9808
c7e4ee3a 9809 if (code == ADDR_EXPR)
5ff904cd 9810 {
c7e4ee3a
CB
9811 if (!mark_addressable (node))
9812 assert ("can't mark_addressable this node!" == NULL);
9813 }
5ff904cd 9814
c7e4ee3a
CB
9815 switch (ffe_is_emulate_complex () ? code : NOP_EXPR)
9816 {
9817 tree realtype;
5ff904cd 9818
c7e4ee3a
CB
9819 case REALPART_EXPR:
9820 item = build (COMPONENT_REF, type, node, TYPE_FIELDS (TREE_TYPE (node)));
5ff904cd
JL
9821 break;
9822
c7e4ee3a
CB
9823 case IMAGPART_EXPR:
9824 item = build (COMPONENT_REF, type, node, TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (node))));
9825 break;
5ff904cd 9826
5ff904cd 9827
c7e4ee3a
CB
9828 case NEGATE_EXPR:
9829 if (TREE_CODE (type) != RECORD_TYPE)
9830 {
9831 item = build1 (code, type, node);
9832 break;
9833 }
9834 node = ffecom_stabilize_aggregate_ (node);
9835 realtype = TREE_TYPE (TYPE_FIELDS (type));
9836 item =
9837 ffecom_2 (COMPLEX_EXPR, type,
9838 ffecom_1 (NEGATE_EXPR, realtype,
9839 ffecom_1 (REALPART_EXPR, realtype,
9840 node)),
9841 ffecom_1 (NEGATE_EXPR, realtype,
9842 ffecom_1 (IMAGPART_EXPR, realtype,
9843 node)));
5ff904cd
JL
9844 break;
9845
9846 default:
c7e4ee3a
CB
9847 item = build1 (code, type, node);
9848 break;
5ff904cd 9849 }
5ff904cd 9850
c7e4ee3a
CB
9851 if (TREE_SIDE_EFFECTS (node))
9852 TREE_SIDE_EFFECTS (item) = 1;
9853 if ((code == ADDR_EXPR) && staticp (node))
9854 TREE_CONSTANT (item) = 1;
9855 return fold (item);
9856}
5ff904cd 9857#endif
5ff904cd 9858
c7e4ee3a
CB
9859/* Like ffecom_1 (ADDR_EXPR, TREE_TYPE (node), node), except
9860 handles TREE_CODE (node) == FUNCTION_DECL. In particular,
9861 does not set TREE_ADDRESSABLE (because calling an inline
9862 function does not mean the function needs to be separately
9863 compiled). */
5ff904cd
JL
9864
9865#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
9866tree
9867ffecom_1_fn (tree node)
5ff904cd 9868{
c7e4ee3a 9869 tree item;
5ff904cd 9870 tree type;
5ff904cd 9871
c7e4ee3a
CB
9872 if (node == error_mark_node)
9873 return error_mark_node;
5ff904cd 9874
c7e4ee3a
CB
9875 type = build_type_variant (TREE_TYPE (node),
9876 TREE_READONLY (node),
9877 TREE_THIS_VOLATILE (node));
9878 item = build1 (ADDR_EXPR,
9879 build_pointer_type (type), node);
9880 if (TREE_SIDE_EFFECTS (node))
9881 TREE_SIDE_EFFECTS (item) = 1;
9882 if (staticp (node))
9883 TREE_CONSTANT (item) = 1;
9884 return fold (item);
5ff904cd 9885}
5ff904cd 9886#endif
c7e4ee3a
CB
9887
9888/* Essentially does a "fold (build (code, type, node1, node2))" while
9889 checking for certain housekeeping things. */
5ff904cd
JL
9890
9891#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
9892tree
9893ffecom_2 (enum tree_code code, tree type, tree node1,
9894 tree node2)
5ff904cd 9895{
c7e4ee3a 9896 tree item;
5ff904cd 9897
c7e4ee3a
CB
9898 if ((node1 == error_mark_node)
9899 || (node2 == error_mark_node)
9900 || (type == error_mark_node))
9901 return error_mark_node;
9902
9903 switch (ffe_is_emulate_complex () ? code : NOP_EXPR)
5ff904cd 9904 {
c7e4ee3a 9905 tree a, b, c, d, realtype;
5ff904cd 9906
c7e4ee3a
CB
9907 case CONJ_EXPR:
9908 assert ("no CONJ_EXPR support yet" == NULL);
9909 return error_mark_node;
5ff904cd 9910
c7e4ee3a
CB
9911 case COMPLEX_EXPR:
9912 item = build_tree_list (TYPE_FIELDS (type), node1);
9913 TREE_CHAIN (item) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), node2);
9914 item = build (CONSTRUCTOR, type, NULL_TREE, item);
9915 break;
5ff904cd 9916
c7e4ee3a
CB
9917 case PLUS_EXPR:
9918 if (TREE_CODE (type) != RECORD_TYPE)
9919 {
9920 item = build (code, type, node1, node2);
9921 break;
9922 }
9923 node1 = ffecom_stabilize_aggregate_ (node1);
9924 node2 = ffecom_stabilize_aggregate_ (node2);
9925 realtype = TREE_TYPE (TYPE_FIELDS (type));
9926 item =
9927 ffecom_2 (COMPLEX_EXPR, type,
9928 ffecom_2 (PLUS_EXPR, realtype,
9929 ffecom_1 (REALPART_EXPR, realtype,
9930 node1),
9931 ffecom_1 (REALPART_EXPR, realtype,
9932 node2)),
9933 ffecom_2 (PLUS_EXPR, realtype,
9934 ffecom_1 (IMAGPART_EXPR, realtype,
9935 node1),
9936 ffecom_1 (IMAGPART_EXPR, realtype,
9937 node2)));
9938 break;
5ff904cd 9939
c7e4ee3a
CB
9940 case MINUS_EXPR:
9941 if (TREE_CODE (type) != RECORD_TYPE)
9942 {
9943 item = build (code, type, node1, node2);
9944 break;
9945 }
9946 node1 = ffecom_stabilize_aggregate_ (node1);
9947 node2 = ffecom_stabilize_aggregate_ (node2);
9948 realtype = TREE_TYPE (TYPE_FIELDS (type));
9949 item =
9950 ffecom_2 (COMPLEX_EXPR, type,
9951 ffecom_2 (MINUS_EXPR, realtype,
9952 ffecom_1 (REALPART_EXPR, realtype,
9953 node1),
9954 ffecom_1 (REALPART_EXPR, realtype,
9955 node2)),
9956 ffecom_2 (MINUS_EXPR, realtype,
9957 ffecom_1 (IMAGPART_EXPR, realtype,
9958 node1),
9959 ffecom_1 (IMAGPART_EXPR, realtype,
9960 node2)));
9961 break;
5ff904cd 9962
c7e4ee3a
CB
9963 case MULT_EXPR:
9964 if (TREE_CODE (type) != RECORD_TYPE)
9965 {
9966 item = build (code, type, node1, node2);
9967 break;
9968 }
9969 node1 = ffecom_stabilize_aggregate_ (node1);
9970 node2 = ffecom_stabilize_aggregate_ (node2);
9971 realtype = TREE_TYPE (TYPE_FIELDS (type));
9972 a = save_expr (ffecom_1 (REALPART_EXPR, realtype,
9973 node1));
9974 b = save_expr (ffecom_1 (IMAGPART_EXPR, realtype,
9975 node1));
9976 c = save_expr (ffecom_1 (REALPART_EXPR, realtype,
9977 node2));
9978 d = save_expr (ffecom_1 (IMAGPART_EXPR, realtype,
9979 node2));
9980 item =
9981 ffecom_2 (COMPLEX_EXPR, type,
9982 ffecom_2 (MINUS_EXPR, realtype,
9983 ffecom_2 (MULT_EXPR, realtype,
9984 a,
9985 c),
9986 ffecom_2 (MULT_EXPR, realtype,
9987 b,
9988 d)),
9989 ffecom_2 (PLUS_EXPR, realtype,
9990 ffecom_2 (MULT_EXPR, realtype,
9991 a,
9992 d),
9993 ffecom_2 (MULT_EXPR, realtype,
9994 c,
9995 b)));
9996 break;
5ff904cd 9997
c7e4ee3a
CB
9998 case EQ_EXPR:
9999 if ((TREE_CODE (node1) != RECORD_TYPE)
10000 && (TREE_CODE (node2) != RECORD_TYPE))
10001 {
10002 item = build (code, type, node1, node2);
10003 break;
10004 }
10005 assert (TREE_CODE (node1) == RECORD_TYPE);
10006 assert (TREE_CODE (node2) == RECORD_TYPE);
10007 node1 = ffecom_stabilize_aggregate_ (node1);
10008 node2 = ffecom_stabilize_aggregate_ (node2);
10009 realtype = TREE_TYPE (TYPE_FIELDS (type));
10010 item =
10011 ffecom_2 (TRUTH_ANDIF_EXPR, type,
10012 ffecom_2 (code, type,
10013 ffecom_1 (REALPART_EXPR, realtype,
10014 node1),
10015 ffecom_1 (REALPART_EXPR, realtype,
10016 node2)),
10017 ffecom_2 (code, type,
10018 ffecom_1 (IMAGPART_EXPR, realtype,
10019 node1),
10020 ffecom_1 (IMAGPART_EXPR, realtype,
10021 node2)));
10022 break;
10023
10024 case NE_EXPR:
10025 if ((TREE_CODE (node1) != RECORD_TYPE)
10026 && (TREE_CODE (node2) != RECORD_TYPE))
10027 {
10028 item = build (code, type, node1, node2);
10029 break;
10030 }
10031 assert (TREE_CODE (node1) == RECORD_TYPE);
10032 assert (TREE_CODE (node2) == RECORD_TYPE);
10033 node1 = ffecom_stabilize_aggregate_ (node1);
10034 node2 = ffecom_stabilize_aggregate_ (node2);
10035 realtype = TREE_TYPE (TYPE_FIELDS (type));
10036 item =
10037 ffecom_2 (TRUTH_ORIF_EXPR, type,
10038 ffecom_2 (code, type,
10039 ffecom_1 (REALPART_EXPR, realtype,
10040 node1),
10041 ffecom_1 (REALPART_EXPR, realtype,
10042 node2)),
10043 ffecom_2 (code, type,
10044 ffecom_1 (IMAGPART_EXPR, realtype,
10045 node1),
10046 ffecom_1 (IMAGPART_EXPR, realtype,
10047 node2)));
10048 break;
5ff904cd 10049
c7e4ee3a
CB
10050 default:
10051 item = build (code, type, node1, node2);
10052 break;
5ff904cd
JL
10053 }
10054
c7e4ee3a
CB
10055 if (TREE_SIDE_EFFECTS (node1) || TREE_SIDE_EFFECTS (node2))
10056 TREE_SIDE_EFFECTS (item) = 1;
10057 return fold (item);
5ff904cd
JL
10058}
10059
10060#endif
c7e4ee3a 10061/* ffecom_2pass_advise_entrypoint -- Advise that there's this entrypoint
5ff904cd 10062
c7e4ee3a
CB
10063 ffesymbol s; // the ENTRY point itself
10064 if (ffecom_2pass_advise_entrypoint(s))
10065 // the ENTRY point has been accepted
5ff904cd 10066
c7e4ee3a
CB
10067 Does whatever compiler needs to do when it learns about the entrypoint,
10068 like determine the return type of the master function, count the
10069 number of entrypoints, etc. Returns FALSE if the return type is
10070 not compatible with the return type(s) of other entrypoint(s).
5ff904cd 10071
c7e4ee3a
CB
10072 NOTE: for every call to this fn that returns TRUE, _do_entrypoint must
10073 later (after _finish_progunit) be called with the same entrypoint(s)
10074 as passed to this fn for which TRUE was returned.
5ff904cd 10075
c7e4ee3a
CB
10076 03-Jan-92 JCB 2.0
10077 Return FALSE if the return type conflicts with previous entrypoints. */
5ff904cd
JL
10078
10079#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
10080bool
10081ffecom_2pass_advise_entrypoint (ffesymbol entry)
5ff904cd 10082{
c7e4ee3a
CB
10083 ffebld list; /* opITEM. */
10084 ffebld mlist; /* opITEM. */
10085 ffebld plist; /* opITEM. */
10086 ffebld arg; /* ffebld_head(opITEM). */
10087 ffebld item; /* opITEM. */
10088 ffesymbol s; /* ffebld_symter(arg). */
10089 ffeinfoBasictype bt = ffesymbol_basictype (entry);
10090 ffeinfoKindtype kt = ffesymbol_kindtype (entry);
10091 ffetargetCharacterSize size = ffesymbol_size (entry);
10092 bool ok;
5ff904cd 10093
c7e4ee3a
CB
10094 if (ffecom_num_entrypoints_ == 0)
10095 { /* First entrypoint, make list of main
10096 arglist's dummies. */
10097 assert (ffecom_primary_entry_ != NULL);
5ff904cd 10098
c7e4ee3a
CB
10099 ffecom_master_bt_ = ffesymbol_basictype (ffecom_primary_entry_);
10100 ffecom_master_kt_ = ffesymbol_kindtype (ffecom_primary_entry_);
10101 ffecom_master_size_ = ffesymbol_size (ffecom_primary_entry_);
5ff904cd 10102
c7e4ee3a
CB
10103 for (plist = NULL, list = ffesymbol_dummyargs (ffecom_primary_entry_);
10104 list != NULL;
10105 list = ffebld_trail (list))
10106 {
10107 arg = ffebld_head (list);
10108 if (ffebld_op (arg) != FFEBLD_opSYMTER)
10109 continue; /* Alternate return or some such thing. */
10110 item = ffebld_new_item (arg, NULL);
10111 if (plist == NULL)
10112 ffecom_master_arglist_ = item;
10113 else
10114 ffebld_set_trail (plist, item);
10115 plist = item;
10116 }
5ff904cd
JL
10117 }
10118
c7e4ee3a
CB
10119 /* If necessary, scan entry arglist for alternate returns. Do this scan
10120 apparently redundantly (it's done below to UNIONize the arglists) so
10121 that we don't complain about RETURN 1 if an offending ENTRY is the only
10122 one with an alternate return. */
5ff904cd 10123
c7e4ee3a 10124 if (!ffecom_is_altreturning_)
5ff904cd 10125 {
c7e4ee3a
CB
10126 for (list = ffesymbol_dummyargs (entry);
10127 list != NULL;
10128 list = ffebld_trail (list))
10129 {
10130 arg = ffebld_head (list);
10131 if (ffebld_op (arg) == FFEBLD_opSTAR)
10132 {
10133 ffecom_is_altreturning_ = TRUE;
10134 break;
10135 }
10136 }
10137 }
5ff904cd 10138
c7e4ee3a 10139 /* Now check type compatibility. */
5ff904cd 10140
c7e4ee3a
CB
10141 switch (ffecom_master_bt_)
10142 {
10143 case FFEINFO_basictypeNONE:
10144 ok = (bt != FFEINFO_basictypeCHARACTER);
10145 break;
5ff904cd 10146
c7e4ee3a
CB
10147 case FFEINFO_basictypeCHARACTER:
10148 ok
10149 = (bt == FFEINFO_basictypeCHARACTER)
10150 && (kt == ffecom_master_kt_)
10151 && (size == ffecom_master_size_);
10152 break;
5ff904cd 10153
c7e4ee3a
CB
10154 case FFEINFO_basictypeANY:
10155 return FALSE; /* Just don't bother. */
5ff904cd 10156
c7e4ee3a
CB
10157 default:
10158 if (bt == FFEINFO_basictypeCHARACTER)
5ff904cd 10159 {
c7e4ee3a
CB
10160 ok = FALSE;
10161 break;
5ff904cd 10162 }
c7e4ee3a
CB
10163 ok = TRUE;
10164 if ((bt != ffecom_master_bt_) || (kt != ffecom_master_kt_))
10165 {
10166 ffecom_master_bt_ = FFEINFO_basictypeNONE;
10167 ffecom_master_kt_ = FFEINFO_kindtypeNONE;
10168 }
10169 break;
10170 }
5ff904cd 10171
c7e4ee3a
CB
10172 if (!ok)
10173 {
10174 ffebad_start (FFEBAD_ENTRY_CONFLICTS);
10175 ffest_ffebad_here_current_stmt (0);
10176 ffebad_finish ();
10177 return FALSE; /* Can't handle entrypoint. */
10178 }
5ff904cd 10179
c7e4ee3a 10180 /* Entrypoint type compatible with previous types. */
5ff904cd 10181
c7e4ee3a 10182 ++ffecom_num_entrypoints_;
5ff904cd 10183
c7e4ee3a
CB
10184 /* Master-arg-list = UNION(Master-arg-list,entry-arg-list). */
10185
10186 for (list = ffesymbol_dummyargs (entry);
10187 list != NULL;
10188 list = ffebld_trail (list))
10189 {
10190 arg = ffebld_head (list);
10191 if (ffebld_op (arg) != FFEBLD_opSYMTER)
10192 continue; /* Alternate return or some such thing. */
10193 s = ffebld_symter (arg);
10194 for (plist = NULL, mlist = ffecom_master_arglist_;
10195 mlist != NULL;
10196 plist = mlist, mlist = ffebld_trail (mlist))
10197 { /* plist points to previous item for easy
10198 appending of arg. */
10199 if (ffebld_symter (ffebld_head (mlist)) == s)
10200 break; /* Already have this arg in the master list. */
10201 }
10202 if (mlist != NULL)
10203 continue; /* Already have this arg in the master list. */
5ff904cd 10204
c7e4ee3a 10205 /* Append this arg to the master list. */
5ff904cd 10206
c7e4ee3a
CB
10207 item = ffebld_new_item (arg, NULL);
10208 if (plist == NULL)
10209 ffecom_master_arglist_ = item;
10210 else
10211 ffebld_set_trail (plist, item);
5ff904cd
JL
10212 }
10213
c7e4ee3a 10214 return TRUE;
5ff904cd
JL
10215}
10216
10217#endif
c7e4ee3a
CB
10218/* ffecom_2pass_do_entrypoint -- Do compilation of entrypoint
10219
10220 ffesymbol s; // the ENTRY point itself
10221 ffecom_2pass_do_entrypoint(s);
10222
10223 Does whatever compiler needs to do to make the entrypoint actually
10224 happen. Must be called for each entrypoint after
10225 ffecom_finish_progunit is called. */
10226
5ff904cd 10227#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
10228void
10229ffecom_2pass_do_entrypoint (ffesymbol entry)
5ff904cd 10230{
c7e4ee3a
CB
10231 static int mfn_num = 0;
10232 static int ent_num;
5ff904cd 10233
c7e4ee3a
CB
10234 if (mfn_num != ffecom_num_fns_)
10235 { /* First entrypoint for this program unit. */
10236 ent_num = 1;
10237 mfn_num = ffecom_num_fns_;
10238 ffecom_do_entry_ (ffecom_primary_entry_, 0);
10239 }
10240 else
10241 ++ent_num;
5ff904cd 10242
c7e4ee3a 10243 --ffecom_num_entrypoints_;
5ff904cd 10244
c7e4ee3a
CB
10245 ffecom_do_entry_ (entry, ent_num);
10246}
5ff904cd 10247
c7e4ee3a 10248#endif
5ff904cd 10249
c7e4ee3a
CB
10250/* Essentially does a "fold (build (code, type, node1, node2))" while
10251 checking for certain housekeeping things. Always sets
10252 TREE_SIDE_EFFECTS. */
5ff904cd 10253
c7e4ee3a
CB
10254#if FFECOM_targetCURRENT == FFECOM_targetGCC
10255tree
10256ffecom_2s (enum tree_code code, tree type, tree node1,
10257 tree node2)
10258{
10259 tree item;
5ff904cd 10260
c7e4ee3a
CB
10261 if ((node1 == error_mark_node)
10262 || (node2 == error_mark_node)
10263 || (type == error_mark_node))
10264 return error_mark_node;
5ff904cd 10265
c7e4ee3a
CB
10266 item = build (code, type, node1, node2);
10267 TREE_SIDE_EFFECTS (item) = 1;
10268 return fold (item);
5ff904cd
JL
10269}
10270
10271#endif
c7e4ee3a
CB
10272/* Essentially does a "fold (build (code, type, node1, node2, node3))" while
10273 checking for certain housekeeping things. */
10274
5ff904cd 10275#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
10276tree
10277ffecom_3 (enum tree_code code, tree type, tree node1,
10278 tree node2, tree node3)
5ff904cd 10279{
c7e4ee3a 10280 tree item;
5ff904cd 10281
c7e4ee3a
CB
10282 if ((node1 == error_mark_node)
10283 || (node2 == error_mark_node)
10284 || (node3 == error_mark_node)
10285 || (type == error_mark_node))
10286 return error_mark_node;
5ff904cd 10287
c7e4ee3a
CB
10288 item = build (code, type, node1, node2, node3);
10289 if (TREE_SIDE_EFFECTS (node1) || TREE_SIDE_EFFECTS (node2)
10290 || (node3 != NULL_TREE && TREE_SIDE_EFFECTS (node3)))
10291 TREE_SIDE_EFFECTS (item) = 1;
10292 return fold (item);
10293}
5ff904cd 10294
c7e4ee3a
CB
10295#endif
10296/* Essentially does a "fold (build (code, type, node1, node2, node3))" while
10297 checking for certain housekeeping things. Always sets
10298 TREE_SIDE_EFFECTS. */
5ff904cd 10299
c7e4ee3a
CB
10300#if FFECOM_targetCURRENT == FFECOM_targetGCC
10301tree
10302ffecom_3s (enum tree_code code, tree type, tree node1,
10303 tree node2, tree node3)
10304{
10305 tree item;
5ff904cd 10306
c7e4ee3a
CB
10307 if ((node1 == error_mark_node)
10308 || (node2 == error_mark_node)
10309 || (node3 == error_mark_node)
10310 || (type == error_mark_node))
10311 return error_mark_node;
5ff904cd 10312
c7e4ee3a
CB
10313 item = build (code, type, node1, node2, node3);
10314 TREE_SIDE_EFFECTS (item) = 1;
10315 return fold (item);
10316}
5ff904cd 10317
c7e4ee3a 10318#endif
5ff904cd 10319
c7e4ee3a 10320/* ffecom_arg_expr -- Transform argument expr into gcc tree
5ff904cd 10321
c7e4ee3a 10322 See use by ffecom_list_expr.
5ff904cd 10323
c7e4ee3a
CB
10324 If expression is NULL, returns an integer zero tree. If it is not
10325 a CHARACTER expression, returns whatever ffecom_expr
10326 returns and sets the length return value to NULL_TREE. Otherwise
10327 generates code to evaluate the character expression, returns the proper
10328 pointer to the result, but does NOT set the length return value to a tree
10329 that specifies the length of the result. (In other words, the length
10330 variable is always set to NULL_TREE, because a length is never passed.)
5ff904cd 10331
c7e4ee3a
CB
10332 21-Dec-91 JCB 1.1
10333 Don't set returned length, since nobody needs it (yet; someday if
10334 we allow CHARACTER*(*) dummies to statement functions, we'll need
10335 it). */
5ff904cd 10336
c7e4ee3a
CB
10337#if FFECOM_targetCURRENT == FFECOM_targetGCC
10338tree
10339ffecom_arg_expr (ffebld expr, tree *length)
10340{
10341 tree ign;
5ff904cd 10342
c7e4ee3a 10343 *length = NULL_TREE;
5ff904cd 10344
c7e4ee3a
CB
10345 if (expr == NULL)
10346 return integer_zero_node;
5ff904cd 10347
c7e4ee3a
CB
10348 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10349 return ffecom_expr (expr);
5ff904cd 10350
c7e4ee3a
CB
10351 return ffecom_arg_ptr_to_expr (expr, &ign);
10352}
10353
10354#endif
10355/* Transform expression into constant argument-pointer-to-expression tree.
10356
10357 If the expression can be transformed into a argument-pointer-to-expression
10358 tree that is constant, that is done, and the tree returned. Else
10359 NULL_TREE is returned.
5ff904cd 10360
c7e4ee3a
CB
10361 That way, a caller can attempt to provide compile-time initialization
10362 of a variable and, if that fails, *then* choose to start a new block
10363 and resort to using temporaries, as appropriate. */
5ff904cd 10364
c7e4ee3a
CB
10365tree
10366ffecom_arg_ptr_to_const_expr (ffebld expr, tree *length)
10367{
10368 if (! expr)
10369 return integer_zero_node;
5ff904cd 10370
c7e4ee3a
CB
10371 if (ffebld_op (expr) == FFEBLD_opANY)
10372 {
10373 if (length)
10374 *length = error_mark_node;
10375 return error_mark_node;
10376 }
10377
10378 if (ffebld_arity (expr) == 0
10379 && (ffebld_op (expr) != FFEBLD_opSYMTER
10380 || ffebld_where (expr) == FFEINFO_whereCOMMON
10381 || ffebld_where (expr) == FFEINFO_whereGLOBAL
10382 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
10383 {
10384 tree t;
10385
10386 t = ffecom_arg_ptr_to_expr (expr, length);
10387 assert (TREE_CONSTANT (t));
10388 assert (! length || TREE_CONSTANT (*length));
10389 return t;
10390 }
10391
10392 if (length
10393 && ffebld_size (expr) != FFETARGET_charactersizeNONE)
10394 *length = build_int_2 (ffebld_size (expr), 0);
10395 else if (length)
10396 *length = NULL_TREE;
10397 return NULL_TREE;
5ff904cd
JL
10398}
10399
c7e4ee3a 10400/* ffecom_arg_ptr_to_expr -- Transform argument expr into gcc tree
5ff904cd 10401
c7e4ee3a
CB
10402 See use by ffecom_list_ptr_to_expr.
10403
10404 If expression is NULL, returns an integer zero tree. If it is not
10405 a CHARACTER expression, returns whatever ffecom_ptr_to_expr
10406 returns and sets the length return value to NULL_TREE. Otherwise
10407 generates code to evaluate the character expression, returns the proper
10408 pointer to the result, AND sets the length return value to a tree that
10409 specifies the length of the result.
10410
10411 If the length argument is NULL, this is a slightly special
10412 case of building a FORMAT expression, that is, an expression that
10413 will be used at run time without regard to length. For the current
10414 implementation, which uses the libf2c library, this means it is nice
10415 to append a null byte to the end of the expression, where feasible,
10416 to make sure any diagnostic about the FORMAT string terminates at
10417 some useful point.
10418
10419 For now, treat %REF(char-expr) as the same as char-expr with a NULL
10420 length argument. This might even be seen as a feature, if a null
10421 byte can always be appended. */
5ff904cd
JL
10422
10423#if FFECOM_targetCURRENT == FFECOM_targetGCC
10424tree
c7e4ee3a 10425ffecom_arg_ptr_to_expr (ffebld expr, tree *length)
5ff904cd
JL
10426{
10427 tree item;
c7e4ee3a
CB
10428 tree ign_length;
10429 ffecomConcatList_ catlist;
5ff904cd 10430
c7e4ee3a
CB
10431 if (length != NULL)
10432 *length = NULL_TREE;
5ff904cd 10433
c7e4ee3a
CB
10434 if (expr == NULL)
10435 return integer_zero_node;
5ff904cd 10436
c7e4ee3a 10437 switch (ffebld_op (expr))
5ff904cd 10438 {
c7e4ee3a
CB
10439 case FFEBLD_opPERCENT_VAL:
10440 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10441 return ffecom_expr (ffebld_left (expr));
10442 {
10443 tree temp_exp;
10444 tree temp_length;
5ff904cd 10445
c7e4ee3a
CB
10446 temp_exp = ffecom_arg_ptr_to_expr (ffebld_left (expr), &temp_length);
10447 if (temp_exp == error_mark_node)
10448 return error_mark_node;
5ff904cd 10449
c7e4ee3a
CB
10450 return ffecom_1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (temp_exp)),
10451 temp_exp);
10452 }
5ff904cd 10453
c7e4ee3a
CB
10454 case FFEBLD_opPERCENT_REF:
10455 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10456 return ffecom_ptr_to_expr (ffebld_left (expr));
10457 if (length != NULL)
10458 {
10459 ign_length = NULL_TREE;
10460 length = &ign_length;
10461 }
10462 expr = ffebld_left (expr);
10463 break;
5ff904cd 10464
c7e4ee3a
CB
10465 case FFEBLD_opPERCENT_DESCR:
10466 switch (ffeinfo_basictype (ffebld_info (expr)))
5ff904cd 10467 {
c7e4ee3a
CB
10468#ifdef PASS_HOLLERITH_BY_DESCRIPTOR
10469 case FFEINFO_basictypeHOLLERITH:
10470#endif
10471 case FFEINFO_basictypeCHARACTER:
10472 break; /* Passed by descriptor anyway. */
10473
10474 default:
10475 item = ffecom_ptr_to_expr (expr);
10476 if (item != error_mark_node)
10477 *length = TYPE_SIZE (TREE_TYPE (TREE_TYPE (item)));
5ff904cd
JL
10478 break;
10479 }
5ff904cd
JL
10480 break;
10481
10482 default:
5ff904cd
JL
10483 break;
10484 }
10485
c7e4ee3a
CB
10486#ifdef PASS_HOLLERITH_BY_DESCRIPTOR
10487 if ((ffeinfo_basictype (ffebld_info (expr)) == FFEINFO_basictypeHOLLERITH)
10488 && (length != NULL))
10489 { /* Pass Hollerith by descriptor. */
10490 ffetargetHollerith h;
10491
10492 assert (ffebld_op (expr) == FFEBLD_opCONTER);
10493 h = ffebld_cu_val_hollerith (ffebld_constant_union
10494 (ffebld_conter (expr)));
10495 *length
10496 = build_int_2 (h.length, 0);
10497 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
10498 }
10499#endif
10500
10501 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10502 return ffecom_ptr_to_expr (expr);
10503
10504 assert (ffeinfo_kindtype (ffebld_info (expr))
10505 == FFEINFO_kindtypeCHARACTER1);
10506
47d98fa2
CB
10507 while (ffebld_op (expr) == FFEBLD_opPAREN)
10508 expr = ffebld_left (expr);
10509
c7e4ee3a
CB
10510 catlist = ffecom_concat_list_new_ (expr, FFETARGET_charactersizeNONE);
10511 switch (ffecom_concat_list_count_ (catlist))
10512 {
10513 case 0: /* Shouldn't happen, but in case it does... */
10514 if (length != NULL)
10515 {
10516 *length = ffecom_f2c_ftnlen_zero_node;
10517 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
10518 }
10519 ffecom_concat_list_kill_ (catlist);
10520 return null_pointer_node;
10521
10522 case 1: /* The (fairly) easy case. */
10523 if (length == NULL)
10524 ffecom_char_args_with_null_ (&item, &ign_length,
10525 ffecom_concat_list_expr_ (catlist, 0));
10526 else
10527 ffecom_char_args_ (&item, length,
10528 ffecom_concat_list_expr_ (catlist, 0));
10529 ffecom_concat_list_kill_ (catlist);
10530 assert (item != NULL_TREE);
10531 return item;
10532
10533 default: /* Must actually concatenate things. */
10534 break;
10535 }
10536
10537 {
10538 int count = ffecom_concat_list_count_ (catlist);
10539 int i;
10540 tree lengths;
10541 tree items;
10542 tree length_array;
10543 tree item_array;
10544 tree citem;
10545 tree clength;
10546 tree temporary;
10547 tree num;
10548 tree known_length;
10549 ffetargetCharacterSize sz;
10550
10551 sz = ffecom_concat_list_maxlen_ (catlist);
10552 /* ~~Kludge! */
10553 assert (sz != FFETARGET_charactersizeNONE);
10554
10555#ifdef HOHO
10556 length_array
10557 = lengths
10558 = ffecom_push_tempvar (ffecom_f2c_ftnlen_type_node,
10559 FFETARGET_charactersizeNONE, count, TRUE);
10560 item_array
10561 = items
10562 = ffecom_push_tempvar (ffecom_f2c_address_type_node,
10563 FFETARGET_charactersizeNONE, count, TRUE);
10564 temporary = ffecom_push_tempvar (char_type_node,
10565 sz, -1, TRUE);
10566#else
10567 {
10568 tree hook;
10569
10570 hook = ffebld_nonter_hook (expr);
10571 assert (hook);
10572 assert (TREE_CODE (hook) == TREE_VEC);
10573 assert (TREE_VEC_LENGTH (hook) == 3);
10574 length_array = lengths = TREE_VEC_ELT (hook, 0);
10575 item_array = items = TREE_VEC_ELT (hook, 1);
10576 temporary = TREE_VEC_ELT (hook, 2);
10577 }
10578#endif
10579
10580 known_length = ffecom_f2c_ftnlen_zero_node;
10581
10582 for (i = 0; i < count; ++i)
10583 {
10584 if ((i == count)
10585 && (length == NULL))
10586 ffecom_char_args_with_null_ (&citem, &clength,
10587 ffecom_concat_list_expr_ (catlist, i));
10588 else
10589 ffecom_char_args_ (&citem, &clength,
10590 ffecom_concat_list_expr_ (catlist, i));
10591 if ((citem == error_mark_node)
10592 || (clength == error_mark_node))
10593 {
10594 ffecom_concat_list_kill_ (catlist);
10595 *length = error_mark_node;
10596 return error_mark_node;
10597 }
10598
10599 items
10600 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (items),
10601 ffecom_modify (void_type_node,
10602 ffecom_2 (ARRAY_REF,
10603 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array))),
10604 item_array,
10605 build_int_2 (i, 0)),
10606 citem),
10607 items);
10608 clength = ffecom_save_tree (clength);
10609 if (length != NULL)
10610 known_length
10611 = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
10612 known_length,
10613 clength);
10614 lengths
10615 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (lengths),
10616 ffecom_modify (void_type_node,
10617 ffecom_2 (ARRAY_REF,
10618 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array))),
10619 length_array,
10620 build_int_2 (i, 0)),
10621 clength),
10622 lengths);
10623 }
10624
10625 temporary = ffecom_1 (ADDR_EXPR,
10626 build_pointer_type (TREE_TYPE (temporary)),
10627 temporary);
10628
10629 item = build_tree_list (NULL_TREE, temporary);
10630 TREE_CHAIN (item)
10631 = build_tree_list (NULL_TREE,
10632 ffecom_1 (ADDR_EXPR,
10633 build_pointer_type (TREE_TYPE (items)),
10634 items));
10635 TREE_CHAIN (TREE_CHAIN (item))
10636 = build_tree_list (NULL_TREE,
10637 ffecom_1 (ADDR_EXPR,
10638 build_pointer_type (TREE_TYPE (lengths)),
10639 lengths));
10640 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item)))
10641 = build_tree_list
10642 (NULL_TREE,
10643 ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
10644 convert (ffecom_f2c_ftnlen_type_node,
10645 build_int_2 (count, 0))));
10646 num = build_int_2 (sz, 0);
10647 TREE_TYPE (num) = ffecom_f2c_ftnlen_type_node;
10648 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item))))
10649 = build_tree_list (NULL_TREE, num);
10650
10651 item = ffecom_call_gfrt (FFECOM_gfrtCAT, item, NULL_TREE);
5ff904cd 10652 TREE_SIDE_EFFECTS (item) = 1;
c7e4ee3a
CB
10653 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (temporary),
10654 item,
10655 temporary);
10656
10657 if (length != NULL)
10658 *length = known_length;
10659 }
10660
10661 ffecom_concat_list_kill_ (catlist);
10662 assert (item != NULL_TREE);
10663 return item;
5ff904cd 10664}
c7e4ee3a 10665
5ff904cd 10666#endif
c7e4ee3a 10667/* Generate call to run-time function.
5ff904cd 10668
c7e4ee3a
CB
10669 The first arg is the GNU Fortran Run-Time function index, the second
10670 arg is the list of arguments to pass to it. Returned is the expression
10671 (WITHOUT TREE_SIDE_EFFECTS set!) that makes the call and returns the
10672 result (which may be void). */
5ff904cd
JL
10673
10674#if FFECOM_targetCURRENT == FFECOM_targetGCC
10675tree
c7e4ee3a 10676ffecom_call_gfrt (ffecomGfrt ix, tree args, tree hook)
5ff904cd 10677{
c7e4ee3a
CB
10678 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
10679 ffecom_gfrt_kindtype (ix),
10680 ffe_is_f2c_library () && ffecom_gfrt_complex_[ix],
10681 NULL_TREE, args, NULL_TREE, NULL,
10682 NULL, NULL_TREE, TRUE, hook);
5ff904cd
JL
10683}
10684#endif
10685
c7e4ee3a 10686/* Transform constant-union to tree. */
5ff904cd
JL
10687
10688#if FFECOM_targetCURRENT == FFECOM_targetGCC
10689tree
c7e4ee3a
CB
10690ffecom_constantunion (ffebldConstantUnion *cu, ffeinfoBasictype bt,
10691 ffeinfoKindtype kt, tree tree_type)
5ff904cd
JL
10692{
10693 tree item;
10694
c7e4ee3a 10695 switch (bt)
5ff904cd 10696 {
c7e4ee3a
CB
10697 case FFEINFO_basictypeINTEGER:
10698 {
10699 int val;
5ff904cd 10700
c7e4ee3a
CB
10701 switch (kt)
10702 {
10703#if FFETARGET_okINTEGER1
10704 case FFEINFO_kindtypeINTEGER1:
10705 val = ffebld_cu_val_integer1 (*cu);
10706 break;
10707#endif
5ff904cd 10708
c7e4ee3a
CB
10709#if FFETARGET_okINTEGER2
10710 case FFEINFO_kindtypeINTEGER2:
10711 val = ffebld_cu_val_integer2 (*cu);
10712 break;
10713#endif
5ff904cd 10714
c7e4ee3a
CB
10715#if FFETARGET_okINTEGER3
10716 case FFEINFO_kindtypeINTEGER3:
10717 val = ffebld_cu_val_integer3 (*cu);
10718 break;
10719#endif
5ff904cd 10720
c7e4ee3a
CB
10721#if FFETARGET_okINTEGER4
10722 case FFEINFO_kindtypeINTEGER4:
10723 val = ffebld_cu_val_integer4 (*cu);
10724 break;
10725#endif
5ff904cd 10726
c7e4ee3a
CB
10727 default:
10728 assert ("bad INTEGER constant kind type" == NULL);
10729 /* Fall through. */
10730 case FFEINFO_kindtypeANY:
10731 return error_mark_node;
10732 }
10733 item = build_int_2 (val, (val < 0) ? -1 : 0);
10734 TREE_TYPE (item) = tree_type;
10735 }
5ff904cd 10736 break;
5ff904cd 10737
c7e4ee3a
CB
10738 case FFEINFO_basictypeLOGICAL:
10739 {
10740 int val;
5ff904cd 10741
c7e4ee3a
CB
10742 switch (kt)
10743 {
10744#if FFETARGET_okLOGICAL1
10745 case FFEINFO_kindtypeLOGICAL1:
10746 val = ffebld_cu_val_logical1 (*cu);
10747 break;
5ff904cd 10748#endif
5ff904cd 10749
c7e4ee3a
CB
10750#if FFETARGET_okLOGICAL2
10751 case FFEINFO_kindtypeLOGICAL2:
10752 val = ffebld_cu_val_logical2 (*cu);
10753 break;
10754#endif
5ff904cd 10755
c7e4ee3a
CB
10756#if FFETARGET_okLOGICAL3
10757 case FFEINFO_kindtypeLOGICAL3:
10758 val = ffebld_cu_val_logical3 (*cu);
10759 break;
10760#endif
5ff904cd 10761
c7e4ee3a
CB
10762#if FFETARGET_okLOGICAL4
10763 case FFEINFO_kindtypeLOGICAL4:
10764 val = ffebld_cu_val_logical4 (*cu);
10765 break;
10766#endif
5ff904cd 10767
c7e4ee3a
CB
10768 default:
10769 assert ("bad LOGICAL constant kind type" == NULL);
10770 /* Fall through. */
10771 case FFEINFO_kindtypeANY:
10772 return error_mark_node;
10773 }
10774 item = build_int_2 (val, (val < 0) ? -1 : 0);
10775 TREE_TYPE (item) = tree_type;
10776 }
10777 break;
5ff904cd 10778
c7e4ee3a
CB
10779 case FFEINFO_basictypeREAL:
10780 {
10781 REAL_VALUE_TYPE val;
5ff904cd 10782
c7e4ee3a
CB
10783 switch (kt)
10784 {
10785#if FFETARGET_okREAL1
10786 case FFEINFO_kindtypeREAL1:
10787 val = ffetarget_value_real1 (ffebld_cu_val_real1 (*cu));
10788 break;
10789#endif
5ff904cd 10790
c7e4ee3a
CB
10791#if FFETARGET_okREAL2
10792 case FFEINFO_kindtypeREAL2:
10793 val = ffetarget_value_real2 (ffebld_cu_val_real2 (*cu));
10794 break;
10795#endif
5ff904cd 10796
c7e4ee3a
CB
10797#if FFETARGET_okREAL3
10798 case FFEINFO_kindtypeREAL3:
10799 val = ffetarget_value_real3 (ffebld_cu_val_real3 (*cu));
10800 break;
10801#endif
5ff904cd 10802
c7e4ee3a
CB
10803#if FFETARGET_okREAL4
10804 case FFEINFO_kindtypeREAL4:
10805 val = ffetarget_value_real4 (ffebld_cu_val_real4 (*cu));
10806 break;
10807#endif
5ff904cd 10808
c7e4ee3a
CB
10809 default:
10810 assert ("bad REAL constant kind type" == NULL);
10811 /* Fall through. */
10812 case FFEINFO_kindtypeANY:
10813 return error_mark_node;
10814 }
10815 item = build_real (tree_type, val);
10816 }
5ff904cd
JL
10817 break;
10818
c7e4ee3a
CB
10819 case FFEINFO_basictypeCOMPLEX:
10820 {
10821 REAL_VALUE_TYPE real;
10822 REAL_VALUE_TYPE imag;
10823 tree el_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
5ff904cd 10824
c7e4ee3a
CB
10825 switch (kt)
10826 {
10827#if FFETARGET_okCOMPLEX1
10828 case FFEINFO_kindtypeREAL1:
10829 real = ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu).real);
10830 imag = ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu).imaginary);
10831 break;
10832#endif
5ff904cd 10833
c7e4ee3a
CB
10834#if FFETARGET_okCOMPLEX2
10835 case FFEINFO_kindtypeREAL2:
10836 real = ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu).real);
10837 imag = ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu).imaginary);
10838 break;
10839#endif
5ff904cd 10840
c7e4ee3a
CB
10841#if FFETARGET_okCOMPLEX3
10842 case FFEINFO_kindtypeREAL3:
10843 real = ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu).real);
10844 imag = ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu).imaginary);
10845 break;
10846#endif
5ff904cd 10847
c7e4ee3a
CB
10848#if FFETARGET_okCOMPLEX4
10849 case FFEINFO_kindtypeREAL4:
10850 real = ffetarget_value_real4 (ffebld_cu_val_complex4 (*cu).real);
10851 imag = ffetarget_value_real4 (ffebld_cu_val_complex4 (*cu).imaginary);
10852 break;
10853#endif
5ff904cd 10854
c7e4ee3a
CB
10855 default:
10856 assert ("bad REAL constant kind type" == NULL);
10857 /* Fall through. */
10858 case FFEINFO_kindtypeANY:
10859 return error_mark_node;
10860 }
10861 item = ffecom_build_complex_constant_ (tree_type,
10862 build_real (el_type, real),
10863 build_real (el_type, imag));
10864 }
10865 break;
5ff904cd 10866
c7e4ee3a
CB
10867 case FFEINFO_basictypeCHARACTER:
10868 { /* Happens only in DATA and similar contexts. */
10869 ffetargetCharacter1 val;
5ff904cd 10870
c7e4ee3a
CB
10871 switch (kt)
10872 {
10873#if FFETARGET_okCHARACTER1
10874 case FFEINFO_kindtypeLOGICAL1:
10875 val = ffebld_cu_val_character1 (*cu);
10876 break;
10877#endif
10878
10879 default:
10880 assert ("bad CHARACTER constant kind type" == NULL);
10881 /* Fall through. */
10882 case FFEINFO_kindtypeANY:
10883 return error_mark_node;
10884 }
10885 item = build_string (ffetarget_length_character1 (val),
10886 ffetarget_text_character1 (val));
10887 TREE_TYPE (item)
10888 = build_type_variant (build_array_type (char_type_node,
10889 build_range_type
10890 (integer_type_node,
10891 integer_one_node,
10892 build_int_2
10893 (ffetarget_length_character1
10894 (val), 0))),
10895 1, 0);
10896 }
10897 break;
5ff904cd 10898
c7e4ee3a
CB
10899 case FFEINFO_basictypeHOLLERITH:
10900 {
10901 ffetargetHollerith h;
5ff904cd 10902
c7e4ee3a 10903 h = ffebld_cu_val_hollerith (*cu);
5ff904cd 10904
c7e4ee3a
CB
10905 /* If not at least as wide as default INTEGER, widen it. */
10906 if (h.length >= FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE)
10907 item = build_string (h.length, h.text);
10908 else
10909 {
10910 char str[FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE];
5ff904cd 10911
c7e4ee3a
CB
10912 memcpy (str, h.text, h.length);
10913 memset (&str[h.length], ' ',
10914 FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE
10915 - h.length);
10916 item = build_string (FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE,
10917 str);
10918 }
10919 TREE_TYPE (item)
10920 = build_type_variant (build_array_type (char_type_node,
10921 build_range_type
10922 (integer_type_node,
10923 integer_one_node,
10924 build_int_2
10925 (h.length, 0))),
10926 1, 0);
10927 }
10928 break;
5ff904cd 10929
c7e4ee3a
CB
10930 case FFEINFO_basictypeTYPELESS:
10931 {
10932 ffetargetInteger1 ival;
10933 ffetargetTypeless tless;
10934 ffebad error;
5ff904cd 10935
c7e4ee3a
CB
10936 tless = ffebld_cu_val_typeless (*cu);
10937 error = ffetarget_convert_integer1_typeless (&ival, tless);
10938 assert (error == FFEBAD);
5ff904cd 10939
c7e4ee3a
CB
10940 item = build_int_2 ((int) ival, 0);
10941 }
10942 break;
5ff904cd 10943
c7e4ee3a
CB
10944 default:
10945 assert ("not yet on constant type" == NULL);
10946 /* Fall through. */
10947 case FFEINFO_basictypeANY:
10948 return error_mark_node;
5ff904cd 10949 }
5ff904cd 10950
c7e4ee3a 10951 TREE_CONSTANT (item) = 1;
5ff904cd 10952
c7e4ee3a 10953 return item;
5ff904cd
JL
10954}
10955
10956#endif
10957
c7e4ee3a
CB
10958/* Transform expression into constant tree.
10959
10960 If the expression can be transformed into a tree that is constant,
10961 that is done, and the tree returned. Else NULL_TREE is returned.
10962
10963 That way, a caller can attempt to provide compile-time initialization
10964 of a variable and, if that fails, *then* choose to start a new block
10965 and resort to using temporaries, as appropriate. */
5ff904cd 10966
5ff904cd 10967tree
c7e4ee3a 10968ffecom_const_expr (ffebld expr)
5ff904cd 10969{
c7e4ee3a
CB
10970 if (! expr)
10971 return integer_zero_node;
5ff904cd 10972
c7e4ee3a 10973 if (ffebld_op (expr) == FFEBLD_opANY)
5ff904cd
JL
10974 return error_mark_node;
10975
c7e4ee3a
CB
10976 if (ffebld_arity (expr) == 0
10977 && (ffebld_op (expr) != FFEBLD_opSYMTER
10978#if NEWCOMMON
10979 /* ~~Enable once common/equivalence is handled properly? */
10980 || ffebld_where (expr) == FFEINFO_whereCOMMON
5ff904cd 10981#endif
c7e4ee3a
CB
10982 || ffebld_where (expr) == FFEINFO_whereGLOBAL
10983 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
10984 {
10985 tree t;
5ff904cd 10986
c7e4ee3a
CB
10987 t = ffecom_expr (expr);
10988 assert (TREE_CONSTANT (t));
10989 return t;
10990 }
5ff904cd 10991
c7e4ee3a 10992 return NULL_TREE;
5ff904cd
JL
10993}
10994
c7e4ee3a 10995/* Handy way to make a field in a struct/union. */
5ff904cd
JL
10996
10997#if FFECOM_targetCURRENT == FFECOM_targetGCC
10998tree
c7e4ee3a
CB
10999ffecom_decl_field (tree context, tree prevfield,
11000 const char *name, tree type)
5ff904cd 11001{
c7e4ee3a 11002 tree field;
5ff904cd 11003
c7e4ee3a
CB
11004 field = build_decl (FIELD_DECL, get_identifier (name), type);
11005 DECL_CONTEXT (field) = context;
8ba77681 11006 DECL_ALIGN (field) = 0;
11cf4d18 11007 DECL_USER_ALIGN (field) = 0;
c7e4ee3a
CB
11008 if (prevfield != NULL_TREE)
11009 TREE_CHAIN (prevfield) = field;
5ff904cd 11010
c7e4ee3a 11011 return field;
5ff904cd
JL
11012}
11013
11014#endif
5ff904cd 11015
c7e4ee3a
CB
11016void
11017ffecom_close_include (FILE *f)
11018{
11019#if FFECOM_GCC_INCLUDE
11020 ffecom_close_include_ (f);
11021#endif
11022}
5ff904cd 11023
c7e4ee3a
CB
11024int
11025ffecom_decode_include_option (char *spec)
11026{
11027#if FFECOM_GCC_INCLUDE
11028 return ffecom_decode_include_option_ (spec);
11029#else
11030 return 1;
11031#endif
11032}
5ff904cd 11033
c7e4ee3a 11034/* End a compound statement (block). */
5ff904cd
JL
11035
11036#if FFECOM_targetCURRENT == FFECOM_targetGCC
11037tree
c7e4ee3a 11038ffecom_end_compstmt (void)
5ff904cd 11039{
c7e4ee3a
CB
11040 return bison_rule_compstmt_ ();
11041}
11042#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
5ff904cd 11043
c7e4ee3a 11044/* ffecom_end_transition -- Perform end transition on all symbols
5ff904cd 11045
c7e4ee3a 11046 ffecom_end_transition();
5ff904cd 11047
c7e4ee3a 11048 Calls ffecom_sym_end_transition for each global and local symbol. */
5ff904cd 11049
c7e4ee3a
CB
11050void
11051ffecom_end_transition ()
11052{
11053#if FFECOM_targetCURRENT == FFECOM_targetGCC
11054 ffebld item;
5ff904cd 11055#endif
5ff904cd 11056
c7e4ee3a
CB
11057 if (ffe_is_ffedebug ())
11058 fprintf (dmpout, "; end_stmt_transition\n");
86fc7a6c 11059
c7e4ee3a
CB
11060#if FFECOM_targetCURRENT == FFECOM_targetGCC
11061 ffecom_list_blockdata_ = NULL;
11062 ffecom_list_common_ = NULL;
11063#endif
86fc7a6c 11064
c7e4ee3a
CB
11065 ffesymbol_drive (ffecom_sym_end_transition);
11066 if (ffe_is_ffedebug ())
11067 {
11068 ffestorag_report ();
11069#if FFECOM_targetCURRENT == FFECOM_targetFFE
11070 ffesymbol_report_all ();
11071#endif
11072 }
5ff904cd
JL
11073
11074#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
11075 ffecom_start_progunit_ ();
11076
11077 for (item = ffecom_list_blockdata_;
11078 item != NULL;
11079 item = ffebld_trail (item))
11080 {
11081 ffebld callee;
11082 ffesymbol s;
11083 tree dt;
11084 tree t;
11085 tree var;
11086 int yes;
11087 static int number = 0;
11088
11089 callee = ffebld_head (item);
11090 s = ffebld_symter (callee);
11091 t = ffesymbol_hook (s).decl_tree;
11092 if (t == NULL_TREE)
11093 {
11094 s = ffecom_sym_transform_ (s);
11095 t = ffesymbol_hook (s).decl_tree;
11096 }
5ff904cd 11097
c7e4ee3a 11098 yes = suspend_momentary ();
5ff904cd 11099
c7e4ee3a 11100 dt = build_pointer_type (TREE_TYPE (t));
5ff904cd 11101
c7e4ee3a
CB
11102 var = build_decl (VAR_DECL,
11103 ffecom_get_invented_identifier ("__g77_forceload_%d",
14657de8 11104 number++),
c7e4ee3a
CB
11105 dt);
11106 DECL_EXTERNAL (var) = 0;
11107 TREE_STATIC (var) = 1;
11108 TREE_PUBLIC (var) = 0;
11109 DECL_INITIAL (var) = error_mark_node;
11110 TREE_USED (var) = 1;
5ff904cd 11111
c7e4ee3a 11112 var = start_decl (var, FALSE);
702edf1d 11113
c7e4ee3a 11114 t = ffecom_1 (ADDR_EXPR, dt, t);
5ff904cd 11115
c7e4ee3a 11116 finish_decl (var, t, FALSE);
5ff904cd 11117
c7e4ee3a
CB
11118 resume_momentary (yes);
11119 }
11120
11121 /* This handles any COMMON areas that weren't referenced but have, for
11122 example, important initial data. */
11123
11124 for (item = ffecom_list_common_;
11125 item != NULL;
11126 item = ffebld_trail (item))
11127 ffecom_transform_common_ (ffebld_symter (ffebld_head (item)));
11128
11129 ffecom_list_common_ = NULL;
5ff904cd 11130#endif
c7e4ee3a 11131}
5ff904cd 11132
c7e4ee3a 11133/* ffecom_exec_transition -- Perform exec transition on all symbols
5ff904cd 11134
c7e4ee3a 11135 ffecom_exec_transition();
5ff904cd 11136
c7e4ee3a
CB
11137 Calls ffecom_sym_exec_transition for each global and local symbol.
11138 Make sure error updating not inhibited. */
5ff904cd 11139
c7e4ee3a
CB
11140void
11141ffecom_exec_transition ()
11142{
11143 bool inhibited;
5ff904cd 11144
c7e4ee3a
CB
11145 if (ffe_is_ffedebug ())
11146 fprintf (dmpout, "; exec_stmt_transition\n");
5ff904cd 11147
c7e4ee3a
CB
11148 inhibited = ffebad_inhibit ();
11149 ffebad_set_inhibit (FALSE);
5ff904cd 11150
c7e4ee3a
CB
11151 ffesymbol_drive (ffecom_sym_exec_transition); /* Don't retract! */
11152 ffeequiv_exec_transition (); /* Handle all pending EQUIVALENCEs. */
11153 if (ffe_is_ffedebug ())
5ff904cd 11154 {
c7e4ee3a
CB
11155 ffestorag_report ();
11156#if FFECOM_targetCURRENT == FFECOM_targetFFE
11157 ffesymbol_report_all ();
11158#endif
11159 }
5ff904cd 11160
c7e4ee3a
CB
11161 if (inhibited)
11162 ffebad_set_inhibit (TRUE);
11163}
5ff904cd 11164
c7e4ee3a 11165/* Handle assignment statement.
5ff904cd 11166
c7e4ee3a
CB
11167 Convert dest and source using ffecom_expr, then join them
11168 with an ASSIGN op and pass the whole thing to expand_expr_stmt. */
5ff904cd 11169
c7e4ee3a
CB
11170#if FFECOM_targetCURRENT == FFECOM_targetGCC
11171void
11172ffecom_expand_let_stmt (ffebld dest, ffebld source)
11173{
11174 tree dest_tree;
11175 tree dest_length;
11176 tree source_tree;
11177 tree expr_tree;
5ff904cd 11178
c7e4ee3a
CB
11179 if (ffeinfo_basictype (ffebld_info (dest)) != FFEINFO_basictypeCHARACTER)
11180 {
11181 bool dest_used;
d6cd84e0 11182 tree assign_temp;
5ff904cd 11183
c7e4ee3a
CB
11184 /* This attempts to replicate the test below, but must not be
11185 true when the test below is false. (Always err on the side
11186 of creating unused temporaries, to avoid ICEs.) */
11187 if (ffebld_op (dest) != FFEBLD_opSYMTER
11188 || ((dest_tree = ffesymbol_hook (ffebld_symter (dest)).decl_tree)
11189 && (TREE_CODE (dest_tree) != VAR_DECL
11190 || TREE_ADDRESSABLE (dest_tree))))
11191 {
11192 ffecom_prepare_expr_ (source, dest);
11193 dest_used = TRUE;
11194 }
11195 else
11196 {
11197 ffecom_prepare_expr_ (source, NULL);
11198 dest_used = FALSE;
11199 }
5ff904cd 11200
c7e4ee3a 11201 ffecom_prepare_expr_w (NULL_TREE, dest);
5ff904cd 11202
d6cd84e0
CB
11203 /* For COMPLEX assignment like C1=C2, if partial overlap is possible,
11204 create a temporary through which the assignment is to take place,
11205 since MODIFY_EXPR doesn't handle partial overlap properly. */
11206 if (ffebld_basictype (dest) == FFEINFO_basictypeCOMPLEX
11207 && ffecom_possible_partial_overlap_ (dest, source))
11208 {
11209 assign_temp = ffecom_make_tempvar ("complex_let",
11210 ffecom_tree_type
11211 [ffebld_basictype (dest)]
11212 [ffebld_kindtype (dest)],
11213 FFETARGET_charactersizeNONE,
11214 -1);
11215 }
11216 else
11217 assign_temp = NULL_TREE;
11218
c7e4ee3a 11219 ffecom_prepare_end ();
5ff904cd 11220
c7e4ee3a
CB
11221 dest_tree = ffecom_expr_w (NULL_TREE, dest);
11222 if (dest_tree == error_mark_node)
11223 return;
5ff904cd 11224
c7e4ee3a
CB
11225 if ((TREE_CODE (dest_tree) != VAR_DECL)
11226 || TREE_ADDRESSABLE (dest_tree))
11227 source_tree = ffecom_expr_ (source, dest_tree, dest, &dest_used,
11228 FALSE, FALSE);
11229 else
11230 {
11231 assert (! dest_used);
11232 dest_used = FALSE;
11233 source_tree = ffecom_expr (source);
11234 }
11235 if (source_tree == error_mark_node)
11236 return;
5ff904cd 11237
c7e4ee3a
CB
11238 if (dest_used)
11239 expr_tree = source_tree;
d6cd84e0
CB
11240 else if (assign_temp)
11241 {
11242#ifdef MOVE_EXPR
11243 /* The back end understands a conceptual move (evaluate source;
11244 store into dest), so use that, in case it can determine
11245 that it is going to use, say, two registers as temporaries
11246 anyway. So don't use the temp (and someday avoid generating
11247 it, once this code starts triggering regularly). */
11248 expr_tree = ffecom_2s (MOVE_EXPR, void_type_node,
11249 dest_tree,
11250 source_tree);
11251#else
11252 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
11253 assign_temp,
11254 source_tree);
11255 expand_expr_stmt (expr_tree);
11256 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
11257 dest_tree,
11258 assign_temp);
11259#endif
11260 }
c7e4ee3a
CB
11261 else
11262 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
11263 dest_tree,
11264 source_tree);
5ff904cd 11265
c7e4ee3a
CB
11266 expand_expr_stmt (expr_tree);
11267 return;
11268 }
5ff904cd 11269
c7e4ee3a
CB
11270 ffecom_prepare_let_char_ (ffebld_size_known (dest), source);
11271 ffecom_prepare_expr_w (NULL_TREE, dest);
11272
11273 ffecom_prepare_end ();
11274
11275 ffecom_char_args_ (&dest_tree, &dest_length, dest);
11276 ffecom_let_char_ (dest_tree, dest_length, ffebld_size_known (dest),
11277 source);
5ff904cd
JL
11278}
11279
11280#endif
c7e4ee3a 11281/* ffecom_expr -- Transform expr into gcc tree
5ff904cd 11282
c7e4ee3a
CB
11283 tree t;
11284 ffebld expr; // FFE expression.
11285 tree = ffecom_expr(expr);
5ff904cd 11286
c7e4ee3a
CB
11287 Recursive descent on expr while making corresponding tree nodes and
11288 attaching type info and such. */
5ff904cd
JL
11289
11290#if FFECOM_targetCURRENT == FFECOM_targetGCC
11291tree
c7e4ee3a 11292ffecom_expr (ffebld expr)
5ff904cd 11293{
c7e4ee3a 11294 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, FALSE, FALSE);
5ff904cd 11295}
c7e4ee3a 11296
5ff904cd 11297#endif
c7e4ee3a 11298/* Like ffecom_expr, but return tree usable for assigned GOTO or FORMAT. */
5ff904cd 11299
c7e4ee3a
CB
11300#if FFECOM_targetCURRENT == FFECOM_targetGCC
11301tree
11302ffecom_expr_assign (ffebld expr)
11303{
11304 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, TRUE, FALSE);
11305}
5ff904cd 11306
c7e4ee3a
CB
11307#endif
11308/* Like ffecom_expr_rw, but return tree usable for ASSIGN. */
5ff904cd
JL
11309
11310#if FFECOM_targetCURRENT == FFECOM_targetGCC
11311tree
c7e4ee3a 11312ffecom_expr_assign_w (ffebld expr)
5ff904cd 11313{
c7e4ee3a
CB
11314 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, TRUE, FALSE);
11315}
5ff904cd 11316
5ff904cd 11317#endif
c7e4ee3a
CB
11318/* Transform expr for use as into read/write tree and stabilize the
11319 reference. Not for use on CHARACTER expressions.
5ff904cd 11320
c7e4ee3a
CB
11321 Recursive descent on expr while making corresponding tree nodes and
11322 attaching type info and such. */
5ff904cd 11323
c7e4ee3a
CB
11324#if FFECOM_targetCURRENT == FFECOM_targetGCC
11325tree
11326ffecom_expr_rw (tree type, ffebld expr)
11327{
11328 assert (expr != NULL);
11329 /* Different target types not yet supported. */
11330 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
11331
11332 return stabilize_reference (ffecom_expr (expr));
11333}
5ff904cd 11334
5ff904cd 11335#endif
c7e4ee3a
CB
11336/* Transform expr for use as into write tree and stabilize the
11337 reference. Not for use on CHARACTER expressions.
5ff904cd 11338
c7e4ee3a
CB
11339 Recursive descent on expr while making corresponding tree nodes and
11340 attaching type info and such. */
5ff904cd 11341
c7e4ee3a
CB
11342#if FFECOM_targetCURRENT == FFECOM_targetGCC
11343tree
11344ffecom_expr_w (tree type, ffebld expr)
11345{
11346 assert (expr != NULL);
11347 /* Different target types not yet supported. */
11348 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
11349
11350 return stabilize_reference (ffecom_expr (expr));
11351}
5ff904cd 11352
5ff904cd 11353#endif
c7e4ee3a
CB
11354/* Do global stuff. */
11355
11356#if FFECOM_targetCURRENT == FFECOM_targetGCC
11357void
11358ffecom_finish_compile ()
11359{
11360 assert (ffecom_outer_function_decl_ == NULL_TREE);
11361 assert (current_function_decl == NULL_TREE);
11362
11363 ffeglobal_drive (ffecom_finish_global_);
11364}
5ff904cd 11365
5ff904cd 11366#endif
c7e4ee3a
CB
11367/* Public entry point for front end to access finish_decl. */
11368
11369#if FFECOM_targetCURRENT == FFECOM_targetGCC
11370void
11371ffecom_finish_decl (tree decl, tree init, bool is_top_level)
11372{
11373 assert (!is_top_level);
11374 finish_decl (decl, init, FALSE);
11375}
5ff904cd 11376
5ff904cd 11377#endif
c7e4ee3a
CB
11378/* Finish a program unit. */
11379
11380#if FFECOM_targetCURRENT == FFECOM_targetGCC
11381void
11382ffecom_finish_progunit ()
11383{
11384 ffecom_end_compstmt ();
11385
11386 ffecom_previous_function_decl_ = current_function_decl;
11387 ffecom_which_entrypoint_decl_ = NULL_TREE;
11388
11389 finish_function (0);
11390}
5ff904cd 11391
5ff904cd 11392#endif
14657de8
KG
11393
11394/* Wrapper for get_identifier. pattern is sprintf-like. */
c7e4ee3a
CB
11395
11396#if FFECOM_targetCURRENT == FFECOM_targetGCC
11397tree
14657de8 11398ffecom_get_invented_identifier (const char *pattern, ...)
c7e4ee3a
CB
11399{
11400 tree decl;
11401 char *nam;
14657de8 11402 va_list ap;
c7e4ee3a 11403
14657de8
KG
11404 va_start (ap, pattern);
11405 if (vasprintf (&nam, pattern, ap) == 0)
11406 abort ();
11407 va_end (ap);
c7e4ee3a 11408 decl = get_identifier (nam);
14657de8 11409 free (nam);
c7e4ee3a 11410 IDENTIFIER_INVENTED (decl) = 1;
c7e4ee3a
CB
11411 return decl;
11412}
11413
11414ffeinfoBasictype
11415ffecom_gfrt_basictype (ffecomGfrt gfrt)
11416{
11417 assert (gfrt < FFECOM_gfrt);
11418
11419 switch (ffecom_gfrt_type_[gfrt])
11420 {
11421 case FFECOM_rttypeVOID_:
11422 case FFECOM_rttypeVOIDSTAR_:
11423 return FFEINFO_basictypeNONE;
11424
11425 case FFECOM_rttypeFTNINT_:
11426 return FFEINFO_basictypeINTEGER;
11427
11428 case FFECOM_rttypeINTEGER_:
11429 return FFEINFO_basictypeINTEGER;
11430
11431 case FFECOM_rttypeLONGINT_:
11432 return FFEINFO_basictypeINTEGER;
11433
11434 case FFECOM_rttypeLOGICAL_:
11435 return FFEINFO_basictypeLOGICAL;
11436
11437 case FFECOM_rttypeREAL_F2C_:
11438 case FFECOM_rttypeREAL_GNU_:
11439 return FFEINFO_basictypeREAL;
11440
11441 case FFECOM_rttypeCOMPLEX_F2C_:
11442 case FFECOM_rttypeCOMPLEX_GNU_:
11443 return FFEINFO_basictypeCOMPLEX;
11444
11445 case FFECOM_rttypeDOUBLE_:
11446 case FFECOM_rttypeDOUBLEREAL_:
11447 return FFEINFO_basictypeREAL;
11448
11449 case FFECOM_rttypeDBLCMPLX_F2C_:
11450 case FFECOM_rttypeDBLCMPLX_GNU_:
11451 return FFEINFO_basictypeCOMPLEX;
11452
11453 case FFECOM_rttypeCHARACTER_:
11454 return FFEINFO_basictypeCHARACTER;
11455
11456 default:
11457 return FFEINFO_basictypeANY;
11458 }
11459}
11460
11461ffeinfoKindtype
11462ffecom_gfrt_kindtype (ffecomGfrt gfrt)
11463{
11464 assert (gfrt < FFECOM_gfrt);
11465
11466 switch (ffecom_gfrt_type_[gfrt])
11467 {
11468 case FFECOM_rttypeVOID_:
11469 case FFECOM_rttypeVOIDSTAR_:
11470 return FFEINFO_kindtypeNONE;
5ff904cd 11471
c7e4ee3a
CB
11472 case FFECOM_rttypeFTNINT_:
11473 return FFEINFO_kindtypeINTEGER1;
5ff904cd 11474
c7e4ee3a
CB
11475 case FFECOM_rttypeINTEGER_:
11476 return FFEINFO_kindtypeINTEGER1;
5ff904cd 11477
c7e4ee3a
CB
11478 case FFECOM_rttypeLONGINT_:
11479 return FFEINFO_kindtypeINTEGER4;
5ff904cd 11480
c7e4ee3a
CB
11481 case FFECOM_rttypeLOGICAL_:
11482 return FFEINFO_kindtypeLOGICAL1;
5ff904cd 11483
c7e4ee3a
CB
11484 case FFECOM_rttypeREAL_F2C_:
11485 case FFECOM_rttypeREAL_GNU_:
11486 return FFEINFO_kindtypeREAL1;
5ff904cd 11487
c7e4ee3a
CB
11488 case FFECOM_rttypeCOMPLEX_F2C_:
11489 case FFECOM_rttypeCOMPLEX_GNU_:
11490 return FFEINFO_kindtypeREAL1;
5ff904cd 11491
c7e4ee3a
CB
11492 case FFECOM_rttypeDOUBLE_:
11493 case FFECOM_rttypeDOUBLEREAL_:
11494 return FFEINFO_kindtypeREAL2;
5ff904cd 11495
c7e4ee3a
CB
11496 case FFECOM_rttypeDBLCMPLX_F2C_:
11497 case FFECOM_rttypeDBLCMPLX_GNU_:
11498 return FFEINFO_kindtypeREAL2;
5ff904cd 11499
c7e4ee3a
CB
11500 case FFECOM_rttypeCHARACTER_:
11501 return FFEINFO_kindtypeCHARACTER1;
5ff904cd 11502
c7e4ee3a
CB
11503 default:
11504 return FFEINFO_kindtypeANY;
11505 }
11506}
5ff904cd 11507
c7e4ee3a
CB
11508void
11509ffecom_init_0 ()
11510{
11511 tree endlink;
11512 int i;
11513 int j;
11514 tree t;
11515 tree field;
11516 ffetype type;
11517 ffetype base_type;
7189a4b0
GK
11518 tree double_ftype_double;
11519 tree float_ftype_float;
11520 tree ldouble_ftype_ldouble;
11521 tree ffecom_tree_ptr_to_fun_type_void;
5ff904cd 11522
c7e4ee3a
CB
11523 /* This block of code comes from the now-obsolete cktyps.c. It checks
11524 whether the compiler environment is buggy in known ways, some of which
11525 would, if not explicitly checked here, result in subtle bugs in g77. */
5ff904cd 11526
c7e4ee3a
CB
11527 if (ffe_is_do_internal_checks ())
11528 {
11529 static char names[][12]
11530 =
11531 {"bar", "bletch", "foo", "foobar"};
11532 char *name;
11533 unsigned long ul;
11534 double fl;
5ff904cd 11535
c7e4ee3a 11536 name = bsearch ("foo", &names[0], ARRAY_SIZE (names), sizeof (names[0]),
b0791fa9 11537 (int (*)(const void *, const void *)) strcmp);
c7e4ee3a
CB
11538 if (name != (char *) &names[2])
11539 {
11540 assert ("bsearch doesn't work, #define FFEPROJ_BSEARCH 0 in proj.h"
11541 == NULL);
11542 abort ();
11543 }
5ff904cd 11544
c7e4ee3a
CB
11545 ul = strtoul ("123456789", NULL, 10);
11546 if (ul != 123456789L)
11547 {
11548 assert ("strtoul doesn't have enough range, #define FFEPROJ_STRTOUL 0\
11549 in proj.h" == NULL);
11550 abort ();
11551 }
5ff904cd 11552
c7e4ee3a
CB
11553 fl = atof ("56.789");
11554 if ((fl < 56.788) || (fl > 56.79))
11555 {
11556 assert ("atof not type double, fix your #include <stdio.h>"
11557 == NULL);
11558 abort ();
11559 }
11560 }
5ff904cd 11561
c7e4ee3a
CB
11562#if FFECOM_GCC_INCLUDE
11563 ffecom_initialize_char_syntax_ ();
11564#endif
5ff904cd 11565
c7e4ee3a
CB
11566 ffecom_outer_function_decl_ = NULL_TREE;
11567 current_function_decl = NULL_TREE;
11568 named_labels = NULL_TREE;
11569 current_binding_level = NULL_BINDING_LEVEL;
11570 free_binding_level = NULL_BINDING_LEVEL;
11571 /* Make the binding_level structure for global names. */
11572 pushlevel (0);
11573 global_binding_level = current_binding_level;
11574 current_binding_level->prep_state = 2;
5ff904cd 11575
81b3411c 11576 build_common_tree_nodes (1);
5ff904cd 11577
81b3411c 11578 /* Define `int' and `char' first so that dbx will output them first. */
c7e4ee3a
CB
11579 pushdecl (build_decl (TYPE_DECL, get_identifier ("int"),
11580 integer_type_node));
c7e4ee3a
CB
11581 pushdecl (build_decl (TYPE_DECL, get_identifier ("char"),
11582 char_type_node));
c7e4ee3a
CB
11583 pushdecl (build_decl (TYPE_DECL, get_identifier ("long int"),
11584 long_integer_type_node));
c7e4ee3a
CB
11585 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned int"),
11586 unsigned_type_node));
c7e4ee3a
CB
11587 pushdecl (build_decl (TYPE_DECL, get_identifier ("long unsigned int"),
11588 long_unsigned_type_node));
c7e4ee3a
CB
11589 pushdecl (build_decl (TYPE_DECL, get_identifier ("long long int"),
11590 long_long_integer_type_node));
c7e4ee3a
CB
11591 pushdecl (build_decl (TYPE_DECL, get_identifier ("long long unsigned int"),
11592 long_long_unsigned_type_node));
c7e4ee3a
CB
11593 pushdecl (build_decl (TYPE_DECL, get_identifier ("short int"),
11594 short_integer_type_node));
c7e4ee3a
CB
11595 pushdecl (build_decl (TYPE_DECL, get_identifier ("short unsigned int"),
11596 short_unsigned_type_node));
5ff904cd 11597
ff852b44
CB
11598 /* Set the sizetype before we make other types. This *should* be the
11599 first type we create. */
11600
11601 set_sizetype
11602 (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE))));
11603 ffecom_typesize_pointer_
11604 = TREE_INT_CST_LOW (TYPE_SIZE (sizetype)) / BITS_PER_UNIT;
11605
81b3411c 11606 build_common_tree_nodes_2 (0);
ff852b44 11607
c7e4ee3a 11608 /* Define both `signed char' and `unsigned char'. */
c7e4ee3a
CB
11609 pushdecl (build_decl (TYPE_DECL, get_identifier ("signed char"),
11610 signed_char_type_node));
5ff904cd 11611
c7e4ee3a
CB
11612 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned char"),
11613 unsigned_char_type_node));
5ff904cd 11614
c7e4ee3a
CB
11615 pushdecl (build_decl (TYPE_DECL, get_identifier ("float"),
11616 float_type_node));
c7e4ee3a
CB
11617 pushdecl (build_decl (TYPE_DECL, get_identifier ("double"),
11618 double_type_node));
c7e4ee3a
CB
11619 pushdecl (build_decl (TYPE_DECL, get_identifier ("long double"),
11620 long_double_type_node));
5ff904cd 11621
81b3411c 11622 /* For now, override what build_common_tree_nodes has done. */
c7e4ee3a 11623 complex_integer_type_node = ffecom_make_complex_type_ (integer_type_node);
81b3411c
BS
11624 complex_float_type_node = ffecom_make_complex_type_ (float_type_node);
11625 complex_double_type_node = ffecom_make_complex_type_ (double_type_node);
11626 complex_long_double_type_node
11627 = ffecom_make_complex_type_ (long_double_type_node);
11628
c7e4ee3a
CB
11629 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex int"),
11630 complex_integer_type_node));
c7e4ee3a
CB
11631 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex float"),
11632 complex_float_type_node));
c7e4ee3a
CB
11633 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex double"),
11634 complex_double_type_node));
c7e4ee3a
CB
11635 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex long double"),
11636 complex_long_double_type_node));
5ff904cd 11637
c7e4ee3a
CB
11638 pushdecl (build_decl (TYPE_DECL, get_identifier ("void"),
11639 void_type_node));
c7e4ee3a
CB
11640 /* We are not going to have real types in C with less than byte alignment,
11641 so we might as well not have any types that claim to have it. */
11642 TYPE_ALIGN (void_type_node) = BITS_PER_UNIT;
11cf4d18 11643 TYPE_USER_ALIGN (void_type_node) = 0;
5ff904cd 11644
c7e4ee3a 11645 string_type_node = build_pointer_type (char_type_node);
5ff904cd 11646
c7e4ee3a
CB
11647 ffecom_tree_fun_type_void
11648 = build_function_type (void_type_node, NULL_TREE);
5ff904cd 11649
c7e4ee3a
CB
11650 ffecom_tree_ptr_to_fun_type_void
11651 = build_pointer_type (ffecom_tree_fun_type_void);
5ff904cd 11652
c7e4ee3a 11653 endlink = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
5ff904cd 11654
c7e4ee3a
CB
11655 float_ftype_float
11656 = build_function_type (float_type_node,
11657 tree_cons (NULL_TREE, float_type_node, endlink));
5ff904cd 11658
c7e4ee3a
CB
11659 double_ftype_double
11660 = build_function_type (double_type_node,
11661 tree_cons (NULL_TREE, double_type_node, endlink));
5ff904cd 11662
c7e4ee3a
CB
11663 ldouble_ftype_ldouble
11664 = build_function_type (long_double_type_node,
11665 tree_cons (NULL_TREE, long_double_type_node,
11666 endlink));
5ff904cd 11667
c7e4ee3a
CB
11668 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11669 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11670 {
11671 ffecom_tree_type[i][j] = NULL_TREE;
11672 ffecom_tree_fun_type[i][j] = NULL_TREE;
11673 ffecom_tree_ptr_to_fun_type[i][j] = NULL_TREE;
11674 ffecom_f2c_typecode_[i][j] = -1;
11675 }
5ff904cd 11676
c7e4ee3a
CB
11677 /* Set up standard g77 types. Note that INTEGER and LOGICAL are set
11678 to size FLOAT_TYPE_SIZE because they have to be the same size as
11679 REAL, which also is FLOAT_TYPE_SIZE, according to the standard.
11680 Compiler options and other such stuff that change the ways these
11681 types are set should not affect this particular setup. */
5ff904cd 11682
c7e4ee3a
CB
11683 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER1]
11684 = t = make_signed_type (FLOAT_TYPE_SIZE);
11685 pushdecl (build_decl (TYPE_DECL, get_identifier ("integer"),
11686 t));
11687 type = ffetype_new ();
11688 base_type = type;
11689 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER1,
11690 type);
11691 ffetype_set_ams (type,
11692 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11693 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11694 ffetype_set_star (base_type,
11695 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11696 type);
11697 ffetype_set_kind (base_type, 1, type);
ff852b44 11698 ffecom_typesize_integer1_ = ffetype_size (type);
c7e4ee3a 11699 assert (ffetype_size (type) == sizeof (ffetargetInteger1));
5ff904cd 11700
c7e4ee3a
CB
11701 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER1]
11702 = t = make_unsigned_type (FLOAT_TYPE_SIZE); /* HOLLERITH means unsigned. */
11703 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned"),
11704 t));
5ff904cd 11705
c7e4ee3a
CB
11706 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER2]
11707 = t = make_signed_type (CHAR_TYPE_SIZE);
11708 pushdecl (build_decl (TYPE_DECL, get_identifier ("byte"),
11709 t));
11710 type = ffetype_new ();
11711 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER2,
11712 type);
11713 ffetype_set_ams (type,
11714 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11715 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11716 ffetype_set_star (base_type,
11717 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11718 type);
11719 ffetype_set_kind (base_type, 3, type);
11720 assert (ffetype_size (type) == sizeof (ffetargetInteger2));
5ff904cd 11721
c7e4ee3a
CB
11722 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER2]
11723 = t = make_unsigned_type (CHAR_TYPE_SIZE);
11724 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned byte"),
11725 t));
11726
11727 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER3]
11728 = t = make_signed_type (CHAR_TYPE_SIZE * 2);
11729 pushdecl (build_decl (TYPE_DECL, get_identifier ("word"),
11730 t));
11731 type = ffetype_new ();
11732 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER3,
11733 type);
11734 ffetype_set_ams (type,
11735 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11736 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11737 ffetype_set_star (base_type,
11738 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11739 type);
11740 ffetype_set_kind (base_type, 6, type);
11741 assert (ffetype_size (type) == sizeof (ffetargetInteger3));
5ff904cd 11742
c7e4ee3a
CB
11743 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER3]
11744 = t = make_unsigned_type (CHAR_TYPE_SIZE * 2);
11745 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned word"),
11746 t));
5ff904cd 11747
c7e4ee3a
CB
11748 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER4]
11749 = t = make_signed_type (FLOAT_TYPE_SIZE * 2);
11750 pushdecl (build_decl (TYPE_DECL, get_identifier ("integer4"),
11751 t));
11752 type = ffetype_new ();
11753 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER4,
11754 type);
11755 ffetype_set_ams (type,
11756 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11757 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11758 ffetype_set_star (base_type,
11759 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11760 type);
11761 ffetype_set_kind (base_type, 2, type);
11762 assert (ffetype_size (type) == sizeof (ffetargetInteger4));
5ff904cd 11763
c7e4ee3a
CB
11764 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER4]
11765 = t = make_unsigned_type (FLOAT_TYPE_SIZE * 2);
11766 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned4"),
11767 t));
5ff904cd 11768
c7e4ee3a
CB
11769#if 0
11770 if (ffe_is_do_internal_checks ()
11771 && LONG_TYPE_SIZE != FLOAT_TYPE_SIZE
11772 && LONG_TYPE_SIZE != CHAR_TYPE_SIZE
11773 && LONG_TYPE_SIZE != SHORT_TYPE_SIZE
11774 && LONG_TYPE_SIZE != LONG_LONG_TYPE_SIZE)
5ff904cd 11775 {
c7e4ee3a
CB
11776 fprintf (stderr, "Sorry, no g77 support for LONG_TYPE_SIZE (%d bits) yet.\n",
11777 LONG_TYPE_SIZE);
5ff904cd 11778 }
c7e4ee3a 11779#endif
5ff904cd 11780
c7e4ee3a
CB
11781 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL1]
11782 = t = make_signed_type (FLOAT_TYPE_SIZE);
11783 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical"),
11784 t));
11785 type = ffetype_new ();
11786 base_type = type;
11787 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL1,
11788 type);
11789 ffetype_set_ams (type,
11790 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11791 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11792 ffetype_set_star (base_type,
11793 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11794 type);
11795 ffetype_set_kind (base_type, 1, type);
11796 assert (ffetype_size (type) == sizeof (ffetargetLogical1));
5ff904cd 11797
c7e4ee3a
CB
11798 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL2]
11799 = t = make_signed_type (CHAR_TYPE_SIZE);
11800 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical2"),
11801 t));
11802 type = ffetype_new ();
11803 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL2,
11804 type);
11805 ffetype_set_ams (type,
11806 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11807 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11808 ffetype_set_star (base_type,
11809 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11810 type);
11811 ffetype_set_kind (base_type, 3, type);
11812 assert (ffetype_size (type) == sizeof (ffetargetLogical2));
5ff904cd 11813
c7e4ee3a
CB
11814 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL3]
11815 = t = make_signed_type (CHAR_TYPE_SIZE * 2);
11816 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical3"),
11817 t));
11818 type = ffetype_new ();
11819 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL3,
11820 type);
11821 ffetype_set_ams (type,
11822 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11823 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11824 ffetype_set_star (base_type,
11825 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11826 type);
11827 ffetype_set_kind (base_type, 6, type);
11828 assert (ffetype_size (type) == sizeof (ffetargetLogical3));
5ff904cd 11829
c7e4ee3a
CB
11830 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL4]
11831 = t = make_signed_type (FLOAT_TYPE_SIZE * 2);
11832 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical4"),
11833 t));
11834 type = ffetype_new ();
11835 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL4,
11836 type);
11837 ffetype_set_ams (type,
11838 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11839 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11840 ffetype_set_star (base_type,
11841 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11842 type);
11843 ffetype_set_kind (base_type, 2, type);
11844 assert (ffetype_size (type) == sizeof (ffetargetLogical4));
5ff904cd 11845
c7e4ee3a
CB
11846 ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]
11847 = t = make_node (REAL_TYPE);
11848 TYPE_PRECISION (t) = FLOAT_TYPE_SIZE;
11849 pushdecl (build_decl (TYPE_DECL, get_identifier ("real"),
11850 t));
11851 layout_type (t);
11852 type = ffetype_new ();
11853 base_type = type;
11854 ffeinfo_set_type (FFEINFO_basictypeREAL, FFEINFO_kindtypeREAL1,
11855 type);
11856 ffetype_set_ams (type,
11857 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11858 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11859 ffetype_set_star (base_type,
11860 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11861 type);
11862 ffetype_set_kind (base_type, 1, type);
11863 ffecom_f2c_typecode_[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]
11864 = FFETARGET_f2cTYREAL;
11865 assert (ffetype_size (type) == sizeof (ffetargetReal1));
5ff904cd 11866
c7e4ee3a
CB
11867 ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREALDOUBLE]
11868 = t = make_node (REAL_TYPE);
11869 TYPE_PRECISION (t) = FLOAT_TYPE_SIZE * 2; /* Always twice REAL. */
11870 pushdecl (build_decl (TYPE_DECL, get_identifier ("double precision"),
11871 t));
11872 layout_type (t);
11873 type = ffetype_new ();
11874 ffeinfo_set_type (FFEINFO_basictypeREAL, FFEINFO_kindtypeREALDOUBLE,
11875 type);
11876 ffetype_set_ams (type,
11877 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11878 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11879 ffetype_set_star (base_type,
11880 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11881 type);
11882 ffetype_set_kind (base_type, 2, type);
11883 ffecom_f2c_typecode_[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2]
11884 = FFETARGET_f2cTYDREAL;
11885 assert (ffetype_size (type) == sizeof (ffetargetReal2));
5ff904cd 11886
c7e4ee3a
CB
11887 ffecom_tree_type[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL1]
11888 = t = ffecom_make_complex_type_ (ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]);
11889 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex"),
11890 t));
11891 type = ffetype_new ();
11892 base_type = type;
11893 ffeinfo_set_type (FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREAL1,
11894 type);
11895 ffetype_set_ams (type,
11896 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11897 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11898 ffetype_set_star (base_type,
11899 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11900 type);
11901 ffetype_set_kind (base_type, 1, type);
11902 ffecom_f2c_typecode_[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL1]
11903 = FFETARGET_f2cTYCOMPLEX;
11904 assert (ffetype_size (type) == sizeof (ffetargetComplex1));
5ff904cd 11905
c7e4ee3a
CB
11906 ffecom_tree_type[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREALDOUBLE]
11907 = t = ffecom_make_complex_type_ (ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2]);
11908 pushdecl (build_decl (TYPE_DECL, get_identifier ("double complex"),
11909 t));
11910 type = ffetype_new ();
11911 ffeinfo_set_type (FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREALDOUBLE,
11912 type);
11913 ffetype_set_ams (type,
11914 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11915 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11916 ffetype_set_star (base_type,
11917 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11918 type);
11919 ffetype_set_kind (base_type, 2,
11920 type);
11921 ffecom_f2c_typecode_[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL2]
11922 = FFETARGET_f2cTYDCOMPLEX;
11923 assert (ffetype_size (type) == sizeof (ffetargetComplex2));
5ff904cd 11924
c7e4ee3a 11925 /* Make function and ptr-to-function types for non-CHARACTER types. */
5ff904cd 11926
c7e4ee3a
CB
11927 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11928 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11929 {
11930 if ((t = ffecom_tree_type[i][j]) != NULL_TREE)
11931 {
11932 if (i == FFEINFO_basictypeINTEGER)
11933 {
11934 /* Figure out the smallest INTEGER type that can hold
11935 a pointer on this machine. */
11936 if (GET_MODE_SIZE (TYPE_MODE (t))
11937 >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
11938 {
11939 if ((ffecom_pointer_kind_ == FFEINFO_kindtypeNONE)
11940 || (GET_MODE_SIZE (TYPE_MODE (ffecom_tree_type[i][ffecom_pointer_kind_]))
11941 > GET_MODE_SIZE (TYPE_MODE (t))))
11942 ffecom_pointer_kind_ = j;
11943 }
11944 }
11945 else if (i == FFEINFO_basictypeCOMPLEX)
11946 t = void_type_node;
11947 /* For f2c compatibility, REAL functions are really
11948 implemented as DOUBLE PRECISION. */
11949 else if ((i == FFEINFO_basictypeREAL)
11950 && (j == FFEINFO_kindtypeREAL1))
11951 t = ffecom_tree_type
11952 [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2];
5ff904cd 11953
c7e4ee3a
CB
11954 t = ffecom_tree_fun_type[i][j] = build_function_type (t,
11955 NULL_TREE);
11956 ffecom_tree_ptr_to_fun_type[i][j] = build_pointer_type (t);
11957 }
11958 }
5ff904cd 11959
c7e4ee3a 11960 /* Set up pointer types. */
5ff904cd 11961
c7e4ee3a
CB
11962 if (ffecom_pointer_kind_ == FFEINFO_basictypeNONE)
11963 fatal ("no INTEGER type can hold a pointer on this configuration");
11964 else if (0 && ffe_is_do_internal_checks ())
11965 fprintf (stderr, "Pointer type kt=%d\n", ffecom_pointer_kind_);
11966 ffetype_set_kind (ffeinfo_type (FFEINFO_basictypeINTEGER,
11967 FFEINFO_kindtypeINTEGERDEFAULT),
11968 7,
11969 ffeinfo_type (FFEINFO_basictypeINTEGER,
11970 ffecom_pointer_kind_));
5ff904cd 11971
c7e4ee3a
CB
11972 if (ffe_is_ugly_assign ())
11973 ffecom_label_kind_ = ffecom_pointer_kind_; /* Require ASSIGN etc to this. */
11974 else
11975 ffecom_label_kind_ = FFEINFO_kindtypeINTEGERDEFAULT;
11976 if (0 && ffe_is_do_internal_checks ())
11977 fprintf (stderr, "Label type kt=%d\n", ffecom_label_kind_);
5ff904cd 11978
c7e4ee3a
CB
11979 ffecom_integer_type_node
11980 = ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER1];
11981 ffecom_integer_zero_node = convert (ffecom_integer_type_node,
11982 integer_zero_node);
11983 ffecom_integer_one_node = convert (ffecom_integer_type_node,
11984 integer_one_node);
5ff904cd 11985
c7e4ee3a
CB
11986 /* Yes, the "FLOAT_TYPE_SIZE" references below are intentional.
11987 Turns out that by TYLONG, runtime/libI77/lio.h really means
11988 "whatever size an ftnint is". For consistency and sanity,
11989 com.h and runtime/f2c.h.in agree that flag, ftnint, and ftlen
11990 all are INTEGER, which we also make out of whatever back-end
11991 integer type is FLOAT_TYPE_SIZE bits wide. This change, from
11992 LONG_TYPE_SIZE, for TYLONG and TYLOGICAL, was necessary to
11993 accommodate machines like the Alpha. Note that this suggests
11994 f2c and libf2c are missing a distinction perhaps needed on
11995 some machines between "int" and "long int". -- burley 0.5.5 950215 */
5ff904cd 11996
c7e4ee3a
CB
11997 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, FLOAT_TYPE_SIZE,
11998 FFETARGET_f2cTYLONG);
11999 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, SHORT_TYPE_SIZE,
12000 FFETARGET_f2cTYSHORT);
12001 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, CHAR_TYPE_SIZE,
12002 FFETARGET_f2cTYINT1);
12003 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, LONG_LONG_TYPE_SIZE,
12004 FFETARGET_f2cTYQUAD);
12005 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, FLOAT_TYPE_SIZE,
12006 FFETARGET_f2cTYLOGICAL);
12007 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, SHORT_TYPE_SIZE,
12008 FFETARGET_f2cTYLOGICAL2);
12009 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, CHAR_TYPE_SIZE,
12010 FFETARGET_f2cTYLOGICAL1);
12011 /* ~~~Not really such a type in libf2c, e.g. I/O support? */
12012 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, LONG_LONG_TYPE_SIZE,
12013 FFETARGET_f2cTYQUAD);
5ff904cd 12014
c7e4ee3a
CB
12015 /* CHARACTER stuff is all special-cased, so it is not handled in the above
12016 loop. CHARACTER items are built as arrays of unsigned char. */
5ff904cd 12017
c7e4ee3a
CB
12018 ffecom_tree_type[FFEINFO_basictypeCHARACTER]
12019 [FFEINFO_kindtypeCHARACTER1] = t = char_type_node;
12020 type = ffetype_new ();
12021 base_type = type;
12022 ffeinfo_set_type (FFEINFO_basictypeCHARACTER,
12023 FFEINFO_kindtypeCHARACTER1,
12024 type);
12025 ffetype_set_ams (type,
12026 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
12027 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
12028 ffetype_set_kind (base_type, 1, type);
12029 assert (ffetype_size (type)
12030 == sizeof (((ffetargetCharacter1) { 0, NULL }).text[0]));
5ff904cd 12031
c7e4ee3a
CB
12032 ffecom_tree_fun_type[FFEINFO_basictypeCHARACTER]
12033 [FFEINFO_kindtypeCHARACTER1] = ffecom_tree_fun_type_void;
12034 ffecom_tree_ptr_to_fun_type[FFEINFO_basictypeCHARACTER]
12035 [FFEINFO_kindtypeCHARACTER1]
12036 = ffecom_tree_ptr_to_fun_type_void;
12037 ffecom_f2c_typecode_[FFEINFO_basictypeCHARACTER][FFEINFO_kindtypeCHARACTER1]
12038 = FFETARGET_f2cTYCHAR;
5ff904cd 12039
c7e4ee3a
CB
12040 ffecom_f2c_typecode_[FFEINFO_basictypeANY][FFEINFO_kindtypeANY]
12041 = 0;
5ff904cd 12042
c7e4ee3a 12043 /* Make multi-return-value type and fields. */
5ff904cd 12044
c7e4ee3a 12045 ffecom_multi_type_node_ = make_node (UNION_TYPE);
5ff904cd 12046
c7e4ee3a 12047 field = NULL_TREE;
5ff904cd 12048
c7e4ee3a
CB
12049 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
12050 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
12051 {
12052 char name[30];
5ff904cd 12053
c7e4ee3a
CB
12054 if (ffecom_tree_type[i][j] == NULL_TREE)
12055 continue; /* Not supported. */
12056 sprintf (&name[0], "bt_%s_kt_%s",
12057 ffeinfo_basictype_string ((ffeinfoBasictype) i),
12058 ffeinfo_kindtype_string ((ffeinfoKindtype) j));
12059 ffecom_multi_fields_[i][j] = build_decl (FIELD_DECL,
12060 get_identifier (name),
12061 ffecom_tree_type[i][j]);
12062 DECL_CONTEXT (ffecom_multi_fields_[i][j])
12063 = ffecom_multi_type_node_;
8ba77681 12064 DECL_ALIGN (ffecom_multi_fields_[i][j]) = 0;
11cf4d18 12065 DECL_USER_ALIGN (ffecom_multi_fields_[i][j]) = 0;
c7e4ee3a
CB
12066 TREE_CHAIN (ffecom_multi_fields_[i][j]) = field;
12067 field = ffecom_multi_fields_[i][j];
12068 }
5ff904cd 12069
c7e4ee3a
CB
12070 TYPE_FIELDS (ffecom_multi_type_node_) = field;
12071 layout_type (ffecom_multi_type_node_);
5ff904cd 12072
c7e4ee3a
CB
12073 /* Subroutines usually return integer because they might have alternate
12074 returns. */
5ff904cd 12075
c7e4ee3a
CB
12076 ffecom_tree_subr_type
12077 = build_function_type (integer_type_node, NULL_TREE);
12078 ffecom_tree_ptr_to_subr_type
12079 = build_pointer_type (ffecom_tree_subr_type);
12080 ffecom_tree_blockdata_type
12081 = build_function_type (void_type_node, NULL_TREE);
5ff904cd 12082
c7e4ee3a 12083 builtin_function ("__builtin_sqrtf", float_ftype_float,
26db82d8 12084 BUILT_IN_FSQRT, BUILT_IN_NORMAL, "sqrtf");
c7e4ee3a 12085 builtin_function ("__builtin_fsqrt", double_ftype_double,
26db82d8 12086 BUILT_IN_FSQRT, BUILT_IN_NORMAL, "sqrt");
c7e4ee3a 12087 builtin_function ("__builtin_sqrtl", ldouble_ftype_ldouble,
26db82d8 12088 BUILT_IN_FSQRT, BUILT_IN_NORMAL, "sqrtl");
c7e4ee3a 12089 builtin_function ("__builtin_sinf", float_ftype_float,
26db82d8 12090 BUILT_IN_SIN, BUILT_IN_NORMAL, "sinf");
c7e4ee3a 12091 builtin_function ("__builtin_sin", double_ftype_double,
26db82d8 12092 BUILT_IN_SIN, BUILT_IN_NORMAL, "sin");
c7e4ee3a 12093 builtin_function ("__builtin_sinl", ldouble_ftype_ldouble,
26db82d8 12094 BUILT_IN_SIN, BUILT_IN_NORMAL, "sinl");
c7e4ee3a 12095 builtin_function ("__builtin_cosf", float_ftype_float,
26db82d8 12096 BUILT_IN_COS, BUILT_IN_NORMAL, "cosf");
c7e4ee3a 12097 builtin_function ("__builtin_cos", double_ftype_double,
26db82d8 12098 BUILT_IN_COS, BUILT_IN_NORMAL, "cos");
c7e4ee3a 12099 builtin_function ("__builtin_cosl", ldouble_ftype_ldouble,
26db82d8 12100 BUILT_IN_COS, BUILT_IN_NORMAL, "cosl");
5ff904cd 12101
c7e4ee3a
CB
12102#if BUILT_FOR_270
12103 pedantic_lvalues = FALSE;
5ff904cd 12104#endif
5ff904cd 12105
c7e4ee3a
CB
12106 ffecom_f2c_make_type_ (&ffecom_f2c_integer_type_node,
12107 FFECOM_f2cINTEGER,
12108 "integer");
12109 ffecom_f2c_make_type_ (&ffecom_f2c_address_type_node,
12110 FFECOM_f2cADDRESS,
12111 "address");
12112 ffecom_f2c_make_type_ (&ffecom_f2c_real_type_node,
12113 FFECOM_f2cREAL,
12114 "real");
12115 ffecom_f2c_make_type_ (&ffecom_f2c_doublereal_type_node,
12116 FFECOM_f2cDOUBLEREAL,
12117 "doublereal");
12118 ffecom_f2c_make_type_ (&ffecom_f2c_complex_type_node,
12119 FFECOM_f2cCOMPLEX,
12120 "complex");
12121 ffecom_f2c_make_type_ (&ffecom_f2c_doublecomplex_type_node,
12122 FFECOM_f2cDOUBLECOMPLEX,
12123 "doublecomplex");
12124 ffecom_f2c_make_type_ (&ffecom_f2c_longint_type_node,
12125 FFECOM_f2cLONGINT,
12126 "longint");
12127 ffecom_f2c_make_type_ (&ffecom_f2c_logical_type_node,
12128 FFECOM_f2cLOGICAL,
12129 "logical");
12130 ffecom_f2c_make_type_ (&ffecom_f2c_flag_type_node,
12131 FFECOM_f2cFLAG,
12132 "flag");
12133 ffecom_f2c_make_type_ (&ffecom_f2c_ftnlen_type_node,
12134 FFECOM_f2cFTNLEN,
12135 "ftnlen");
12136 ffecom_f2c_make_type_ (&ffecom_f2c_ftnint_type_node,
12137 FFECOM_f2cFTNINT,
12138 "ftnint");
5ff904cd 12139
c7e4ee3a
CB
12140 ffecom_f2c_ftnlen_zero_node
12141 = convert (ffecom_f2c_ftnlen_type_node, integer_zero_node);
5ff904cd 12142
c7e4ee3a
CB
12143 ffecom_f2c_ftnlen_one_node
12144 = convert (ffecom_f2c_ftnlen_type_node, integer_one_node);
5ff904cd 12145
c7e4ee3a
CB
12146 ffecom_f2c_ftnlen_two_node = build_int_2 (2, 0);
12147 TREE_TYPE (ffecom_f2c_ftnlen_two_node) = ffecom_integer_type_node;
5ff904cd 12148
c7e4ee3a
CB
12149 ffecom_f2c_ptr_to_ftnlen_type_node
12150 = build_pointer_type (ffecom_f2c_ftnlen_type_node);
5ff904cd 12151
c7e4ee3a
CB
12152 ffecom_f2c_ptr_to_ftnint_type_node
12153 = build_pointer_type (ffecom_f2c_ftnint_type_node);
5ff904cd 12154
c7e4ee3a
CB
12155 ffecom_f2c_ptr_to_integer_type_node
12156 = build_pointer_type (ffecom_f2c_integer_type_node);
5ff904cd 12157
c7e4ee3a
CB
12158 ffecom_f2c_ptr_to_real_type_node
12159 = build_pointer_type (ffecom_f2c_real_type_node);
5ff904cd 12160
c7e4ee3a
CB
12161 ffecom_float_zero_ = build_real (float_type_node, dconst0);
12162 ffecom_double_zero_ = build_real (double_type_node, dconst0);
12163 {
12164 REAL_VALUE_TYPE point_5;
5ff904cd 12165
c7e4ee3a
CB
12166#ifdef REAL_ARITHMETIC
12167 REAL_ARITHMETIC (point_5, RDIV_EXPR, dconst1, dconst2);
12168#else
12169 point_5 = .5;
12170#endif
12171 ffecom_float_half_ = build_real (float_type_node, point_5);
12172 ffecom_double_half_ = build_real (double_type_node, point_5);
12173 }
5ff904cd 12174
c7e4ee3a 12175 /* Do "extern int xargc;". */
5ff904cd 12176
c7e4ee3a
CB
12177 ffecom_tree_xargc_ = build_decl (VAR_DECL,
12178 get_identifier ("f__xargc"),
12179 integer_type_node);
12180 DECL_EXTERNAL (ffecom_tree_xargc_) = 1;
12181 TREE_STATIC (ffecom_tree_xargc_) = 1;
12182 TREE_PUBLIC (ffecom_tree_xargc_) = 1;
12183 ffecom_tree_xargc_ = start_decl (ffecom_tree_xargc_, FALSE);
12184 finish_decl (ffecom_tree_xargc_, NULL_TREE, FALSE);
5ff904cd 12185
c7e4ee3a
CB
12186#if 0 /* This is being fixed, and seems to be working now. */
12187 if ((FLOAT_TYPE_SIZE != 32)
12188 || (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node))) != 32))
5ff904cd 12189 {
c7e4ee3a
CB
12190 warning ("configuration: REAL, INTEGER, and LOGICAL are %d bits wide,",
12191 (int) FLOAT_TYPE_SIZE);
12192 warning ("and pointers are %d bits wide, but g77 doesn't yet work",
12193 (int) TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node))));
12194 warning ("properly unless they all are 32 bits wide.");
12195 warning ("Please keep this in mind before you report bugs. g77 should");
12196 warning ("support non-32-bit machines better as of version 0.6.");
12197 }
12198#endif
5ff904cd 12199
c7e4ee3a
CB
12200#if 0 /* Code in ste.c that would crash has been commented out. */
12201 if (TYPE_PRECISION (ffecom_f2c_ftnlen_type_node)
12202 < TYPE_PRECISION (string_type_node))
12203 /* I/O will probably crash. */
12204 warning ("configuration: char * holds %d bits, but ftnlen only %d",
12205 TYPE_PRECISION (string_type_node),
12206 TYPE_PRECISION (ffecom_f2c_ftnlen_type_node));
12207#endif
5ff904cd 12208
c7e4ee3a
CB
12209#if 0 /* ASSIGN-related stuff has been changed to accommodate this. */
12210 if (TYPE_PRECISION (ffecom_integer_type_node)
12211 < TYPE_PRECISION (string_type_node))
12212 /* ASSIGN 10 TO I will crash. */
12213 warning ("configuration: char * holds %d bits, but INTEGER only %d --\n\
12214 ASSIGN statement might fail",
12215 TYPE_PRECISION (string_type_node),
12216 TYPE_PRECISION (ffecom_integer_type_node));
12217#endif
12218}
5ff904cd 12219
c7e4ee3a
CB
12220#endif
12221/* ffecom_init_2 -- Initialize
5ff904cd 12222
c7e4ee3a 12223 ffecom_init_2(); */
5ff904cd 12224
c7e4ee3a
CB
12225#if FFECOM_targetCURRENT == FFECOM_targetGCC
12226void
12227ffecom_init_2 ()
12228{
12229 assert (ffecom_outer_function_decl_ == NULL_TREE);
12230 assert (current_function_decl == NULL_TREE);
12231 assert (ffecom_which_entrypoint_decl_ == NULL_TREE);
5ff904cd 12232
c7e4ee3a
CB
12233 ffecom_master_arglist_ = NULL;
12234 ++ffecom_num_fns_;
12235 ffecom_primary_entry_ = NULL;
12236 ffecom_is_altreturning_ = FALSE;
12237 ffecom_func_result_ = NULL_TREE;
12238 ffecom_multi_retval_ = NULL_TREE;
12239}
5ff904cd 12240
c7e4ee3a
CB
12241#endif
12242/* ffecom_list_expr -- Transform list of exprs into gcc tree
5ff904cd 12243
c7e4ee3a
CB
12244 tree t;
12245 ffebld expr; // FFE opITEM list.
12246 tree = ffecom_list_expr(expr);
5ff904cd 12247
c7e4ee3a 12248 List of actual args is transformed into corresponding gcc backend list. */
5ff904cd 12249
c7e4ee3a
CB
12250#if FFECOM_targetCURRENT == FFECOM_targetGCC
12251tree
12252ffecom_list_expr (ffebld expr)
5ff904cd 12253{
c7e4ee3a
CB
12254 tree list;
12255 tree *plist = &list;
12256 tree trail = NULL_TREE; /* Append char length args here. */
12257 tree *ptrail = &trail;
12258 tree length;
5ff904cd 12259
c7e4ee3a 12260 while (expr != NULL)
5ff904cd 12261 {
c7e4ee3a 12262 tree texpr = ffecom_arg_expr (ffebld_head (expr), &length);
5ff904cd 12263
c7e4ee3a
CB
12264 if (texpr == error_mark_node)
12265 return error_mark_node;
5ff904cd 12266
c7e4ee3a
CB
12267 *plist = build_tree_list (NULL_TREE, texpr);
12268 plist = &TREE_CHAIN (*plist);
12269 expr = ffebld_trail (expr);
12270 if (length != NULL_TREE)
5ff904cd 12271 {
c7e4ee3a
CB
12272 *ptrail = build_tree_list (NULL_TREE, length);
12273 ptrail = &TREE_CHAIN (*ptrail);
5ff904cd
JL
12274 }
12275 }
12276
c7e4ee3a 12277 *plist = trail;
5ff904cd 12278
c7e4ee3a
CB
12279 return list;
12280}
5ff904cd 12281
c7e4ee3a
CB
12282#endif
12283/* ffecom_list_ptr_to_expr -- Transform list of exprs into gcc tree
5ff904cd 12284
c7e4ee3a
CB
12285 tree t;
12286 ffebld expr; // FFE opITEM list.
12287 tree = ffecom_list_ptr_to_expr(expr);
5ff904cd 12288
c7e4ee3a
CB
12289 List of actual args is transformed into corresponding gcc backend list for
12290 use in calling an external procedure (vs. a statement function). */
5ff904cd 12291
c7e4ee3a
CB
12292#if FFECOM_targetCURRENT == FFECOM_targetGCC
12293tree
12294ffecom_list_ptr_to_expr (ffebld expr)
12295{
12296 tree list;
12297 tree *plist = &list;
12298 tree trail = NULL_TREE; /* Append char length args here. */
12299 tree *ptrail = &trail;
12300 tree length;
5ff904cd 12301
c7e4ee3a
CB
12302 while (expr != NULL)
12303 {
12304 tree texpr = ffecom_arg_ptr_to_expr (ffebld_head (expr), &length);
5ff904cd 12305
c7e4ee3a
CB
12306 if (texpr == error_mark_node)
12307 return error_mark_node;
5ff904cd 12308
c7e4ee3a
CB
12309 *plist = build_tree_list (NULL_TREE, texpr);
12310 plist = &TREE_CHAIN (*plist);
12311 expr = ffebld_trail (expr);
12312 if (length != NULL_TREE)
12313 {
12314 *ptrail = build_tree_list (NULL_TREE, length);
12315 ptrail = &TREE_CHAIN (*ptrail);
12316 }
12317 }
5ff904cd 12318
c7e4ee3a 12319 *plist = trail;
5ff904cd 12320
c7e4ee3a
CB
12321 return list;
12322}
5ff904cd 12323
c7e4ee3a
CB
12324#endif
12325/* Obtain gcc's LABEL_DECL tree for label. */
5ff904cd 12326
c7e4ee3a
CB
12327#if FFECOM_targetCURRENT == FFECOM_targetGCC
12328tree
12329ffecom_lookup_label (ffelab label)
12330{
12331 tree glabel;
5ff904cd 12332
c7e4ee3a
CB
12333 if (ffelab_hook (label) == NULL_TREE)
12334 {
12335 char labelname[16];
5ff904cd 12336
c7e4ee3a
CB
12337 switch (ffelab_type (label))
12338 {
12339 case FFELAB_typeLOOPEND:
12340 case FFELAB_typeNOTLOOP:
12341 case FFELAB_typeENDIF:
12342 sprintf (labelname, "%" ffelabValue_f "u", ffelab_value (label));
12343 glabel = build_decl (LABEL_DECL, get_identifier (labelname),
12344 void_type_node);
12345 DECL_CONTEXT (glabel) = current_function_decl;
12346 DECL_MODE (glabel) = VOIDmode;
12347 break;
5ff904cd 12348
c7e4ee3a 12349 case FFELAB_typeFORMAT:
c7e4ee3a
CB
12350 glabel = build_decl (VAR_DECL,
12351 ffecom_get_invented_identifier
14657de8 12352 ("__g77_format_%d", (int) ffelab_value (label)),
c7e4ee3a
CB
12353 build_type_variant (build_array_type
12354 (char_type_node,
12355 NULL_TREE),
12356 1, 0));
12357 TREE_CONSTANT (glabel) = 1;
12358 TREE_STATIC (glabel) = 1;
12359 DECL_CONTEXT (glabel) = 0;
12360 DECL_INITIAL (glabel) = NULL;
12361 make_decl_rtl (glabel, NULL, 0);
12362 expand_decl (glabel);
5ff904cd 12363
7189a4b0 12364 ffecom_save_tree_forever (glabel);
5ff904cd 12365
c7e4ee3a 12366 break;
5ff904cd 12367
c7e4ee3a
CB
12368 case FFELAB_typeANY:
12369 glabel = error_mark_node;
12370 break;
5ff904cd 12371
c7e4ee3a
CB
12372 default:
12373 assert ("bad label type" == NULL);
12374 glabel = NULL;
12375 break;
12376 }
12377 ffelab_set_hook (label, glabel);
12378 }
12379 else
12380 {
12381 glabel = ffelab_hook (label);
12382 }
5ff904cd 12383
c7e4ee3a
CB
12384 return glabel;
12385}
5ff904cd 12386
c7e4ee3a
CB
12387#endif
12388/* Stabilizes the arguments. Don't use this if the lhs and rhs come from
12389 a single source specification (as in the fourth argument of MVBITS).
12390 If the type is NULL_TREE, the type of lhs is used to make the type of
12391 the MODIFY_EXPR. */
5ff904cd 12392
c7e4ee3a
CB
12393#if FFECOM_targetCURRENT == FFECOM_targetGCC
12394tree
12395ffecom_modify (tree newtype, tree lhs,
12396 tree rhs)
12397{
12398 if (lhs == error_mark_node || rhs == error_mark_node)
12399 return error_mark_node;
5ff904cd 12400
c7e4ee3a
CB
12401 if (newtype == NULL_TREE)
12402 newtype = TREE_TYPE (lhs);
5ff904cd 12403
c7e4ee3a
CB
12404 if (TREE_SIDE_EFFECTS (lhs))
12405 lhs = stabilize_reference (lhs);
5ff904cd 12406
c7e4ee3a
CB
12407 return ffecom_2s (MODIFY_EXPR, newtype, lhs, rhs);
12408}
5ff904cd 12409
c7e4ee3a 12410#endif
5ff904cd 12411
c7e4ee3a 12412/* Register source file name. */
5ff904cd 12413
c7e4ee3a 12414void
b0791fa9 12415ffecom_file (const char *name)
c7e4ee3a
CB
12416{
12417#if FFECOM_GCC_INCLUDE
12418 ffecom_file_ (name);
12419#endif
12420}
5ff904cd 12421
c7e4ee3a 12422/* ffecom_notify_init_storage -- An aggregate storage is now fully init'ed
5ff904cd 12423
c7e4ee3a
CB
12424 ffestorag st;
12425 ffecom_notify_init_storage(st);
5ff904cd 12426
c7e4ee3a
CB
12427 Gets called when all possible units in an aggregate storage area (a LOCAL
12428 with equivalences or a COMMON) have been initialized. The initialization
12429 info either is in ffestorag_init or, if that is NULL,
12430 ffestorag_accretion:
5ff904cd 12431
c7e4ee3a
CB
12432 ffestorag_init may contain an opCONTER or opARRTER. opCONTER may occur
12433 even for an array if the array is one element in length!
5ff904cd 12434
c7e4ee3a
CB
12435 ffestorag_accretion will contain an opACCTER. It is much like an
12436 opARRTER except it has an ffebit object in it instead of just a size.
12437 The back end can use the info in the ffebit object, if it wants, to
12438 reduce the amount of actual initialization, but in any case it should
12439 kill the ffebit object when done. Also, set accretion to NULL but
12440 init to a non-NULL value.
5ff904cd 12441
c7e4ee3a
CB
12442 After performing initialization, DO NOT set init to NULL, because that'll
12443 tell the front end it is ok for more initialization to happen. Instead,
12444 set init to an opANY expression or some such thing that you can use to
12445 tell that you've already initialized the object.
5ff904cd 12446
c7e4ee3a
CB
12447 27-Oct-91 JCB 1.1
12448 Support two-pass FFE. */
5ff904cd 12449
c7e4ee3a
CB
12450void
12451ffecom_notify_init_storage (ffestorag st)
12452{
12453 ffebld init; /* The initialization expression. */
12454#if 0 && FFECOM_targetCURRENT == FFECOM_targetGCC
12455 ffetargetOffset size; /* The size of the entity. */
12456 ffetargetAlign pad; /* Its initial padding. */
12457#endif
12458
12459 if (ffestorag_init (st) == NULL)
5ff904cd 12460 {
c7e4ee3a
CB
12461 init = ffestorag_accretion (st);
12462 assert (init != NULL);
12463 ffestorag_set_accretion (st, NULL);
12464 ffestorag_set_accretes (st, 0);
12465
12466#if 0 && FFECOM_targetCURRENT == FFECOM_targetGCC
12467 /* For GNU backend, just turn ACCTER into ARRTER and proceed. */
12468 size = ffebld_accter_size (init);
12469 pad = ffebld_accter_pad (init);
12470 ffebit_kill (ffebld_accter_bits (init));
12471 ffebld_set_op (init, FFEBLD_opARRTER);
12472 ffebld_set_arrter (init, ffebld_accter (init));
12473 ffebld_arrter_set_size (init, size);
12474 ffebld_arrter_set_pad (init, size);
12475#endif
12476
12477#if FFECOM_TWOPASS
12478 ffestorag_set_init (st, init);
12479#endif
5ff904cd 12480 }
c7e4ee3a
CB
12481#if FFECOM_ONEPASS
12482 else
12483 init = ffestorag_init (st);
5ff904cd
JL
12484#endif
12485
c7e4ee3a
CB
12486#if FFECOM_ONEPASS /* Process the inits, wipe 'em out. */
12487 ffestorag_set_init (st, ffebld_new_any ());
5ff904cd 12488
c7e4ee3a
CB
12489 if (ffebld_op (init) == FFEBLD_opANY)
12490 return; /* Oh, we already did this! */
5ff904cd 12491
c7e4ee3a
CB
12492#if FFECOM_targetCURRENT == FFECOM_targetFFE
12493 {
12494 ffesymbol s;
5ff904cd 12495
c7e4ee3a
CB
12496 if (ffestorag_symbol (st) != NULL)
12497 s = ffestorag_symbol (st);
12498 else
12499 s = ffestorag_typesymbol (st);
5ff904cd 12500
c7e4ee3a
CB
12501 fprintf (dmpout, "= initialize_storage \"%s\" ",
12502 (s != NULL) ? ffesymbol_text (s) : "(unnamed)");
12503 ffebld_dump (init);
12504 fputc ('\n', dmpout);
12505 }
12506#endif
5ff904cd 12507
c7e4ee3a
CB
12508#endif /* if FFECOM_ONEPASS */
12509}
5ff904cd 12510
c7e4ee3a 12511/* ffecom_notify_init_symbol -- A symbol is now fully init'ed
5ff904cd 12512
c7e4ee3a
CB
12513 ffesymbol s;
12514 ffecom_notify_init_symbol(s);
5ff904cd 12515
c7e4ee3a
CB
12516 Gets called when all possible units in a symbol (not placed in COMMON
12517 or involved in EQUIVALENCE, unless it as yet has no ffestorag object)
12518 have been initialized. The initialization info either is in
12519 ffesymbol_init or, if that is NULL, ffesymbol_accretion:
5ff904cd 12520
c7e4ee3a
CB
12521 ffesymbol_init may contain an opCONTER or opARRTER. opCONTER may occur
12522 even for an array if the array is one element in length!
5ff904cd 12523
c7e4ee3a
CB
12524 ffesymbol_accretion will contain an opACCTER. It is much like an
12525 opARRTER except it has an ffebit object in it instead of just a size.
12526 The back end can use the info in the ffebit object, if it wants, to
12527 reduce the amount of actual initialization, but in any case it should
12528 kill the ffebit object when done. Also, set accretion to NULL but
12529 init to a non-NULL value.
5ff904cd 12530
c7e4ee3a
CB
12531 After performing initialization, DO NOT set init to NULL, because that'll
12532 tell the front end it is ok for more initialization to happen. Instead,
12533 set init to an opANY expression or some such thing that you can use to
12534 tell that you've already initialized the object.
5ff904cd 12535
c7e4ee3a
CB
12536 27-Oct-91 JCB 1.1
12537 Support two-pass FFE. */
5ff904cd 12538
c7e4ee3a
CB
12539void
12540ffecom_notify_init_symbol (ffesymbol s)
12541{
12542 ffebld init; /* The initialization expression. */
12543#if 0 && FFECOM_targetCURRENT == FFECOM_targetGCC
12544 ffetargetOffset size; /* The size of the entity. */
12545 ffetargetAlign pad; /* Its initial padding. */
12546#endif
5ff904cd 12547
c7e4ee3a
CB
12548 if (ffesymbol_storage (s) == NULL)
12549 return; /* Do nothing until COMMON/EQUIVALENCE
12550 possibilities checked. */
5ff904cd 12551
c7e4ee3a
CB
12552 if ((ffesymbol_init (s) == NULL)
12553 && ((init = ffesymbol_accretion (s)) != NULL))
12554 {
12555 ffesymbol_set_accretion (s, NULL);
12556 ffesymbol_set_accretes (s, 0);
5ff904cd 12557
c7e4ee3a
CB
12558#if 0 && FFECOM_targetCURRENT == FFECOM_targetGCC
12559 /* For GNU backend, just turn ACCTER into ARRTER and proceed. */
12560 size = ffebld_accter_size (init);
12561 pad = ffebld_accter_pad (init);
12562 ffebit_kill (ffebld_accter_bits (init));
12563 ffebld_set_op (init, FFEBLD_opARRTER);
12564 ffebld_set_arrter (init, ffebld_accter (init));
12565 ffebld_arrter_set_size (init, size);
12566 ffebld_arrter_set_pad (init, size);
12567#endif
5ff904cd 12568
c7e4ee3a
CB
12569#if FFECOM_TWOPASS
12570 ffesymbol_set_init (s, init);
12571#endif
12572 }
12573#if FFECOM_ONEPASS
12574 else
12575 init = ffesymbol_init (s);
12576#endif
5ff904cd 12577
c7e4ee3a
CB
12578#if FFECOM_ONEPASS
12579 ffesymbol_set_init (s, ffebld_new_any ());
5ff904cd 12580
c7e4ee3a
CB
12581 if (ffebld_op (init) == FFEBLD_opANY)
12582 return; /* Oh, we already did this! */
5ff904cd 12583
c7e4ee3a
CB
12584#if FFECOM_targetCURRENT == FFECOM_targetFFE
12585 fprintf (dmpout, "= initialize_symbol \"%s\" ", ffesymbol_text (s));
12586 ffebld_dump (init);
12587 fputc ('\n', dmpout);
12588#endif
5ff904cd 12589
c7e4ee3a
CB
12590#endif /* if FFECOM_ONEPASS */
12591}
5ff904cd 12592
c7e4ee3a 12593/* ffecom_notify_primary_entry -- Learn which is the primary entry point
5ff904cd 12594
c7e4ee3a
CB
12595 ffesymbol s;
12596 ffecom_notify_primary_entry(s);
5ff904cd 12597
c7e4ee3a
CB
12598 Gets called when implicit or explicit PROGRAM statement seen or when
12599 FUNCTION, SUBROUTINE, or BLOCK DATA statement seen, with the primary
12600 global symbol that serves as the entry point. */
5ff904cd 12601
c7e4ee3a
CB
12602void
12603ffecom_notify_primary_entry (ffesymbol s)
12604{
12605 ffecom_primary_entry_ = s;
12606 ffecom_primary_entry_kind_ = ffesymbol_kind (s);
5ff904cd 12607
c7e4ee3a
CB
12608 if ((ffecom_primary_entry_kind_ == FFEINFO_kindFUNCTION)
12609 || (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE))
12610 ffecom_primary_entry_is_proc_ = TRUE;
12611 else
12612 ffecom_primary_entry_is_proc_ = FALSE;
5ff904cd 12613
c7e4ee3a
CB
12614 if (!ffe_is_silent ())
12615 {
12616 if (ffecom_primary_entry_kind_ == FFEINFO_kindPROGRAM)
12617 fprintf (stderr, "%s:\n", ffesymbol_text (s));
12618 else
12619 fprintf (stderr, " %s:\n", ffesymbol_text (s));
12620 }
5ff904cd 12621
c7e4ee3a
CB
12622#if FFECOM_targetCURRENT == FFECOM_targetGCC
12623 if (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE)
12624 {
12625 ffebld list;
12626 ffebld arg;
5ff904cd 12627
c7e4ee3a
CB
12628 for (list = ffesymbol_dummyargs (s);
12629 list != NULL;
12630 list = ffebld_trail (list))
12631 {
12632 arg = ffebld_head (list);
12633 if (ffebld_op (arg) == FFEBLD_opSTAR)
12634 {
12635 ffecom_is_altreturning_ = TRUE;
12636 break;
12637 }
12638 }
12639 }
12640#endif
12641}
5ff904cd 12642
c7e4ee3a
CB
12643FILE *
12644ffecom_open_include (char *name, ffewhereLine l, ffewhereColumn c)
12645{
12646#if FFECOM_GCC_INCLUDE
12647 return ffecom_open_include_ (name, l, c);
12648#else
12649 return fopen (name, "r");
5ff904cd 12650#endif
c7e4ee3a 12651}
5ff904cd 12652
c7e4ee3a 12653/* ffecom_ptr_to_expr -- Transform expr into gcc tree with & in front
5ff904cd 12654
c7e4ee3a
CB
12655 tree t;
12656 ffebld expr; // FFE expression.
12657 tree = ffecom_ptr_to_expr(expr);
5ff904cd 12658
c7e4ee3a 12659 Like ffecom_expr, but sticks address-of in front of most things. */
5ff904cd 12660
c7e4ee3a
CB
12661#if FFECOM_targetCURRENT == FFECOM_targetGCC
12662tree
12663ffecom_ptr_to_expr (ffebld expr)
12664{
12665 tree item;
12666 ffeinfoBasictype bt;
12667 ffeinfoKindtype kt;
12668 ffesymbol s;
5ff904cd 12669
c7e4ee3a 12670 assert (expr != NULL);
5ff904cd 12671
c7e4ee3a
CB
12672 switch (ffebld_op (expr))
12673 {
12674 case FFEBLD_opSYMTER:
12675 s = ffebld_symter (expr);
12676 if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC)
12677 {
12678 ffecomGfrt ix;
5ff904cd 12679
c7e4ee3a
CB
12680 ix = ffeintrin_gfrt_indirect (ffebld_symter_implementation (expr));
12681 assert (ix != FFECOM_gfrt);
12682 if ((item = ffecom_gfrt_[ix]) == NULL_TREE)
12683 {
12684 ffecom_make_gfrt_ (ix);
12685 item = ffecom_gfrt_[ix];
12686 }
12687 }
12688 else
12689 {
12690 item = ffesymbol_hook (s).decl_tree;
12691 if (item == NULL_TREE)
12692 {
12693 s = ffecom_sym_transform_ (s);
12694 item = ffesymbol_hook (s).decl_tree;
12695 }
12696 }
12697 assert (item != NULL);
12698 if (item == error_mark_node)
12699 return item;
12700 if (!ffesymbol_hook (s).addr)
12701 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12702 item);
12703 return item;
5ff904cd 12704
c7e4ee3a 12705 case FFEBLD_opARRAYREF:
ff852b44 12706 return ffecom_arrayref_ (NULL_TREE, expr, 1);
5ff904cd 12707
c7e4ee3a 12708 case FFEBLD_opCONTER:
5ff904cd 12709
c7e4ee3a
CB
12710 bt = ffeinfo_basictype (ffebld_info (expr));
12711 kt = ffeinfo_kindtype (ffebld_info (expr));
5ff904cd 12712
c7e4ee3a
CB
12713 item = ffecom_constantunion (&ffebld_constant_union
12714 (ffebld_conter (expr)), bt, kt,
12715 ffecom_tree_type[bt][kt]);
12716 if (item == error_mark_node)
12717 return error_mark_node;
12718 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12719 item);
12720 return item;
5ff904cd 12721
c7e4ee3a
CB
12722 case FFEBLD_opANY:
12723 return error_mark_node;
5ff904cd 12724
c7e4ee3a
CB
12725 default:
12726 bt = ffeinfo_basictype (ffebld_info (expr));
12727 kt = ffeinfo_kindtype (ffebld_info (expr));
12728
12729 item = ffecom_expr (expr);
12730 if (item == error_mark_node)
12731 return error_mark_node;
12732
12733 /* The back end currently optimizes a bit too zealously for us, in that
12734 we fail JCB001 if the following block of code is omitted. It checks
12735 to see if the transformed expression is a symbol or array reference,
12736 and encloses it in a SAVE_EXPR if that is the case. */
12737
12738 STRIP_NOPS (item);
12739 if ((TREE_CODE (item) == VAR_DECL)
12740 || (TREE_CODE (item) == PARM_DECL)
12741 || (TREE_CODE (item) == RESULT_DECL)
12742 || (TREE_CODE (item) == INDIRECT_REF)
12743 || (TREE_CODE (item) == ARRAY_REF)
12744 || (TREE_CODE (item) == COMPONENT_REF)
12745#ifdef OFFSET_REF
12746 || (TREE_CODE (item) == OFFSET_REF)
12747#endif
12748 || (TREE_CODE (item) == BUFFER_REF)
12749 || (TREE_CODE (item) == REALPART_EXPR)
12750 || (TREE_CODE (item) == IMAGPART_EXPR))
12751 {
12752 item = ffecom_save_tree (item);
12753 }
12754
12755 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12756 item);
12757 return item;
12758 }
12759
12760 assert ("fall-through error" == NULL);
12761 return error_mark_node;
5ff904cd
JL
12762}
12763
12764#endif
c7e4ee3a 12765/* Obtain a temp var with given data type.
5ff904cd 12766
c7e4ee3a
CB
12767 size is FFETARGET_charactersizeNONE for a non-CHARACTER type
12768 or >= 0 for a CHARACTER type.
5ff904cd 12769
c7e4ee3a 12770 elements is -1 for a scalar or > 0 for an array of type. */
5ff904cd
JL
12771
12772#if FFECOM_targetCURRENT == FFECOM_targetGCC
12773tree
c7e4ee3a
CB
12774ffecom_make_tempvar (const char *commentary, tree type,
12775 ffetargetCharacterSize size, int elements)
5ff904cd 12776{
c7e4ee3a
CB
12777 int yes;
12778 tree t;
12779 static int mynumber;
5ff904cd 12780
c7e4ee3a 12781 assert (current_binding_level->prep_state < 2);
702edf1d 12782
c7e4ee3a
CB
12783 if (type == error_mark_node)
12784 return error_mark_node;
702edf1d 12785
c7e4ee3a 12786 yes = suspend_momentary ();
5ff904cd 12787
c7e4ee3a
CB
12788 if (size != FFETARGET_charactersizeNONE)
12789 type = build_array_type (type,
12790 build_range_type (ffecom_f2c_ftnlen_type_node,
12791 ffecom_f2c_ftnlen_one_node,
12792 build_int_2 (size, 0)));
12793 if (elements != -1)
12794 type = build_array_type (type,
12795 build_range_type (integer_type_node,
12796 integer_zero_node,
12797 build_int_2 (elements - 1,
12798 0)));
12799 t = build_decl (VAR_DECL,
12800 ffecom_get_invented_identifier ("__g77_%s_%d",
12801 commentary,
12802 mynumber++),
12803 type);
5ff904cd 12804
c7e4ee3a
CB
12805 t = start_decl (t, FALSE);
12806 finish_decl (t, NULL_TREE, FALSE);
12807
12808 resume_momentary (yes);
5ff904cd 12809
c7e4ee3a
CB
12810 return t;
12811}
5ff904cd 12812#endif
5ff904cd 12813
c7e4ee3a 12814/* Prepare argument pointer to expression.
5ff904cd 12815
c7e4ee3a
CB
12816 Like ffecom_prepare_expr, except for expressions to be evaluated
12817 via ffecom_arg_ptr_to_expr. */
5ff904cd 12818
c7e4ee3a
CB
12819void
12820ffecom_prepare_arg_ptr_to_expr (ffebld expr)
5ff904cd 12821{
c7e4ee3a
CB
12822 /* ~~For now, it seems to be the same thing. */
12823 ffecom_prepare_expr (expr);
12824 return;
12825}
702edf1d 12826
c7e4ee3a 12827/* End of preparations. */
702edf1d 12828
c7e4ee3a
CB
12829bool
12830ffecom_prepare_end (void)
12831{
12832 int prep_state = current_binding_level->prep_state;
5ff904cd 12833
c7e4ee3a
CB
12834 assert (prep_state < 2);
12835 current_binding_level->prep_state = 2;
5ff904cd 12836
c7e4ee3a 12837 return (prep_state == 1) ? TRUE : FALSE;
5ff904cd
JL
12838}
12839
c7e4ee3a 12840/* Prepare expression.
5ff904cd 12841
c7e4ee3a
CB
12842 This is called before any code is generated for the current block.
12843 It scans the expression, declares any temporaries that might be needed
12844 during evaluation of the expression, and stores those temporaries in
12845 the appropriate "hook" fields of the expression. `dest', if not NULL,
12846 specifies the destination that ffecom_expr_ will see, in case that
12847 helps avoid generating unused temporaries.
12848
12849 ~~Improve to avoid allocating unused temporaries by taking `dest'
12850 into account vis-a-vis aliasing requirements of complex/character
12851 functions. */
12852
12853void
12854ffecom_prepare_expr_ (ffebld expr, ffebld dest UNUSED)
5ff904cd 12855{
c7e4ee3a
CB
12856 ffeinfoBasictype bt;
12857 ffeinfoKindtype kt;
12858 ffetargetCharacterSize sz;
12859 tree tempvar = NULL_TREE;
5ff904cd 12860
c7e4ee3a
CB
12861 assert (current_binding_level->prep_state < 2);
12862
12863 if (! expr)
12864 return;
12865
12866 bt = ffeinfo_basictype (ffebld_info (expr));
12867 kt = ffeinfo_kindtype (ffebld_info (expr));
12868 sz = ffeinfo_size (ffebld_info (expr));
12869
12870 /* Generate whatever temporaries are needed to represent the result
12871 of the expression. */
12872
47d98fa2
CB
12873 if (bt == FFEINFO_basictypeCHARACTER)
12874 {
12875 while (ffebld_op (expr) == FFEBLD_opPAREN)
12876 expr = ffebld_left (expr);
12877 }
12878
c7e4ee3a 12879 switch (ffebld_op (expr))
5ff904cd 12880 {
c7e4ee3a
CB
12881 default:
12882 /* Don't make temps for SYMTER, CONTER, etc. */
12883 if (ffebld_arity (expr) == 0)
12884 break;
5ff904cd 12885
c7e4ee3a 12886 switch (bt)
5ff904cd 12887 {
c7e4ee3a
CB
12888 case FFEINFO_basictypeCOMPLEX:
12889 if (ffebld_op (expr) == FFEBLD_opFUNCREF)
12890 {
12891 ffesymbol s;
5ff904cd 12892
c7e4ee3a
CB
12893 if (ffebld_op (ffebld_left (expr)) != FFEBLD_opSYMTER)
12894 break;
5ff904cd 12895
c7e4ee3a
CB
12896 s = ffebld_symter (ffebld_left (expr));
12897 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT
68779408
CB
12898 || (ffesymbol_where (s) != FFEINFO_whereINTRINSIC
12899 && ! ffesymbol_is_f2c (s))
12900 || (ffesymbol_where (s) == FFEINFO_whereINTRINSIC
12901 && ! ffe_is_f2c_library ()))
c7e4ee3a
CB
12902 break;
12903 }
12904 else if (ffebld_op (expr) == FFEBLD_opPOWER)
12905 {
12906 /* Requires special treatment. There's no POW_CC function
12907 in libg2c, so POW_ZZ is used, which means we always
12908 need a double-complex temp, not a single-complex. */
12909 kt = FFEINFO_kindtypeREAL2;
12910 }
12911 else if (ffebld_op (expr) != FFEBLD_opDIVIDE)
12912 /* The other ops don't need temps for complex operands. */
12913 break;
5ff904cd 12914
c7e4ee3a
CB
12915 /* ~~~Avoid making temps for some intrinsics, such as AIMAG(C),
12916 REAL(C). See 19990325-0.f, routine `check', for cases. */
12917 tempvar = ffecom_make_tempvar ("complex",
12918 ffecom_tree_type
12919 [FFEINFO_basictypeCOMPLEX][kt],
12920 FFETARGET_charactersizeNONE,
12921 -1);
5ff904cd
JL
12922 break;
12923
c7e4ee3a
CB
12924 case FFEINFO_basictypeCHARACTER:
12925 if (ffebld_op (expr) != FFEBLD_opFUNCREF)
12926 break;
12927
12928 if (sz == FFETARGET_charactersizeNONE)
12929 /* ~~Kludge alert! This should someday be fixed. */
12930 sz = 24;
12931
12932 tempvar = ffecom_make_tempvar ("char", char_type_node, sz, -1);
5ff904cd
JL
12933 break;
12934
12935 default:
5ff904cd
JL
12936 break;
12937 }
c7e4ee3a 12938 break;
5ff904cd 12939
c7e4ee3a
CB
12940#ifdef HAHA
12941 case FFEBLD_opPOWER:
12942 {
12943 tree rtype, ltype;
12944 tree rtmp, ltmp, result;
5ff904cd 12945
c7e4ee3a
CB
12946 ltype = ffecom_type_expr (ffebld_left (expr));
12947 rtype = ffecom_type_expr (ffebld_right (expr));
5ff904cd 12948
c7e4ee3a
CB
12949 rtmp = ffecom_make_tempvar (rtype, FFETARGET_charactersizeNONE, -1);
12950 ltmp = ffecom_make_tempvar (ltype, FFETARGET_charactersizeNONE, -1);
12951 result = ffecom_make_tempvar (ltype, FFETARGET_charactersizeNONE, -1);
5ff904cd 12952
c7e4ee3a
CB
12953 tempvar = make_tree_vec (3);
12954 TREE_VEC_ELT (tempvar, 0) = rtmp;
12955 TREE_VEC_ELT (tempvar, 1) = ltmp;
12956 TREE_VEC_ELT (tempvar, 2) = result;
12957 }
12958 break;
12959#endif /* HAHA */
5ff904cd 12960
c7e4ee3a
CB
12961 case FFEBLD_opCONCATENATE:
12962 {
12963 /* This gets special handling, because only one set of temps
12964 is needed for a tree of these -- the tree is treated as
12965 a flattened list of concatenations when generating code. */
5ff904cd 12966
c7e4ee3a
CB
12967 ffecomConcatList_ catlist;
12968 tree ltmp, itmp, result;
12969 int count;
12970 int i;
5ff904cd 12971
c7e4ee3a
CB
12972 catlist = ffecom_concat_list_new_ (expr, FFETARGET_charactersizeNONE);
12973 count = ffecom_concat_list_count_ (catlist);
5ff904cd 12974
c7e4ee3a
CB
12975 if (count >= 2)
12976 {
12977 ltmp
12978 = ffecom_make_tempvar ("concat_len",
12979 ffecom_f2c_ftnlen_type_node,
12980 FFETARGET_charactersizeNONE, count);
12981 itmp
12982 = ffecom_make_tempvar ("concat_item",
12983 ffecom_f2c_address_type_node,
12984 FFETARGET_charactersizeNONE, count);
12985 result
12986 = ffecom_make_tempvar ("concat_res",
12987 char_type_node,
12988 ffecom_concat_list_maxlen_ (catlist),
12989 -1);
12990
12991 tempvar = make_tree_vec (3);
12992 TREE_VEC_ELT (tempvar, 0) = ltmp;
12993 TREE_VEC_ELT (tempvar, 1) = itmp;
12994 TREE_VEC_ELT (tempvar, 2) = result;
12995 }
5ff904cd 12996
c7e4ee3a
CB
12997 for (i = 0; i < count; ++i)
12998 ffecom_prepare_arg_ptr_to_expr (ffecom_concat_list_expr_ (catlist,
12999 i));
5ff904cd 13000
c7e4ee3a 13001 ffecom_concat_list_kill_ (catlist);
5ff904cd 13002
c7e4ee3a
CB
13003 if (tempvar)
13004 {
13005 ffebld_nonter_set_hook (expr, tempvar);
13006 current_binding_level->prep_state = 1;
13007 }
13008 }
13009 return;
5ff904cd 13010
c7e4ee3a
CB
13011 case FFEBLD_opCONVERT:
13012 if (bt == FFEINFO_basictypeCHARACTER
13013 && ((ffebld_size_known (ffebld_left (expr))
13014 == FFETARGET_charactersizeNONE)
13015 || (ffebld_size_known (ffebld_left (expr)) >= sz)))
13016 tempvar = ffecom_make_tempvar ("convert", char_type_node, sz, -1);
13017 break;
13018 }
5ff904cd 13019
c7e4ee3a
CB
13020 if (tempvar)
13021 {
13022 ffebld_nonter_set_hook (expr, tempvar);
13023 current_binding_level->prep_state = 1;
13024 }
5ff904cd 13025
c7e4ee3a 13026 /* Prepare subexpressions for this expr. */
5ff904cd 13027
c7e4ee3a 13028 switch (ffebld_op (expr))
5ff904cd 13029 {
c7e4ee3a
CB
13030 case FFEBLD_opPERCENT_LOC:
13031 ffecom_prepare_ptr_to_expr (ffebld_left (expr));
13032 break;
5ff904cd 13033
c7e4ee3a
CB
13034 case FFEBLD_opPERCENT_VAL:
13035 case FFEBLD_opPERCENT_REF:
13036 ffecom_prepare_expr (ffebld_left (expr));
13037 break;
5ff904cd 13038
c7e4ee3a
CB
13039 case FFEBLD_opPERCENT_DESCR:
13040 ffecom_prepare_arg_ptr_to_expr (ffebld_left (expr));
13041 break;
5ff904cd 13042
c7e4ee3a
CB
13043 case FFEBLD_opITEM:
13044 {
13045 ffebld item;
5ff904cd 13046
c7e4ee3a
CB
13047 for (item = expr;
13048 item != NULL;
13049 item = ffebld_trail (item))
13050 if (ffebld_head (item) != NULL)
13051 ffecom_prepare_expr (ffebld_head (item));
13052 }
13053 break;
5ff904cd 13054
c7e4ee3a
CB
13055 default:
13056 /* Need to handle character conversion specially. */
13057 switch (ffebld_arity (expr))
13058 {
13059 case 2:
13060 ffecom_prepare_expr (ffebld_left (expr));
13061 ffecom_prepare_expr (ffebld_right (expr));
13062 break;
5ff904cd 13063
c7e4ee3a
CB
13064 case 1:
13065 ffecom_prepare_expr (ffebld_left (expr));
13066 break;
5ff904cd 13067
c7e4ee3a
CB
13068 default:
13069 break;
13070 }
13071 }
5ff904cd 13072
c7e4ee3a 13073 return;
5ff904cd
JL
13074}
13075
c7e4ee3a 13076/* Prepare expression for reading and writing.
5ff904cd 13077
c7e4ee3a
CB
13078 Like ffecom_prepare_expr, except for expressions to be evaluated
13079 via ffecom_expr_rw. */
5ff904cd 13080
c7e4ee3a
CB
13081void
13082ffecom_prepare_expr_rw (tree type, ffebld expr)
13083{
13084 /* This is all we support for now. */
13085 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
5ff904cd 13086
c7e4ee3a
CB
13087 /* ~~For now, it seems to be the same thing. */
13088 ffecom_prepare_expr (expr);
13089 return;
13090}
5ff904cd 13091
c7e4ee3a 13092/* Prepare expression for writing.
5ff904cd 13093
c7e4ee3a
CB
13094 Like ffecom_prepare_expr, except for expressions to be evaluated
13095 via ffecom_expr_w. */
5ff904cd
JL
13096
13097void
c7e4ee3a 13098ffecom_prepare_expr_w (tree type, ffebld expr)
5ff904cd 13099{
c7e4ee3a
CB
13100 /* This is all we support for now. */
13101 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
5ff904cd 13102
c7e4ee3a
CB
13103 /* ~~For now, it seems to be the same thing. */
13104 ffecom_prepare_expr (expr);
13105 return;
13106}
5ff904cd 13107
c7e4ee3a 13108/* Prepare expression for returning.
5ff904cd 13109
c7e4ee3a
CB
13110 Like ffecom_prepare_expr, except for expressions to be evaluated
13111 via ffecom_return_expr. */
5ff904cd 13112
c7e4ee3a
CB
13113void
13114ffecom_prepare_return_expr (ffebld expr)
13115{
13116 assert (current_binding_level->prep_state < 2);
5ff904cd 13117
c7e4ee3a
CB
13118 if (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE
13119 && ffecom_is_altreturning_
13120 && expr != NULL)
13121 ffecom_prepare_expr (expr);
13122}
5ff904cd 13123
c7e4ee3a 13124/* Prepare pointer to expression.
5ff904cd 13125
c7e4ee3a
CB
13126 Like ffecom_prepare_expr, except for expressions to be evaluated
13127 via ffecom_ptr_to_expr. */
5ff904cd 13128
c7e4ee3a
CB
13129void
13130ffecom_prepare_ptr_to_expr (ffebld expr)
13131{
13132 /* ~~For now, it seems to be the same thing. */
13133 ffecom_prepare_expr (expr);
13134 return;
5ff904cd
JL
13135}
13136
c7e4ee3a 13137/* Transform expression into constant pointer-to-expression tree.
5ff904cd 13138
c7e4ee3a
CB
13139 If the expression can be transformed into a pointer-to-expression tree
13140 that is constant, that is done, and the tree returned. Else NULL_TREE
13141 is returned.
5ff904cd 13142
c7e4ee3a
CB
13143 That way, a caller can attempt to provide compile-time initialization
13144 of a variable and, if that fails, *then* choose to start a new block
13145 and resort to using temporaries, as appropriate. */
5ff904cd 13146
c7e4ee3a
CB
13147tree
13148ffecom_ptr_to_const_expr (ffebld expr)
5ff904cd 13149{
c7e4ee3a
CB
13150 if (! expr)
13151 return integer_zero_node;
5ff904cd 13152
c7e4ee3a
CB
13153 if (ffebld_op (expr) == FFEBLD_opANY)
13154 return error_mark_node;
5ff904cd 13155
c7e4ee3a
CB
13156 if (ffebld_arity (expr) == 0
13157 && (ffebld_op (expr) != FFEBLD_opSYMTER
13158 || ffebld_where (expr) == FFEINFO_whereCOMMON
13159 || ffebld_where (expr) == FFEINFO_whereGLOBAL
13160 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
5ff904cd 13161 {
c7e4ee3a
CB
13162 tree t;
13163
13164 t = ffecom_ptr_to_expr (expr);
13165 assert (TREE_CONSTANT (t));
13166 return t;
5ff904cd
JL
13167 }
13168
c7e4ee3a
CB
13169 return NULL_TREE;
13170}
13171
13172/* ffecom_return_expr -- Returns return-value expr given alt return expr
13173
13174 tree rtn; // NULL_TREE means use expand_null_return()
13175 ffebld expr; // NULL if no alt return expr to RETURN stmt
13176 rtn = ffecom_return_expr(expr);
13177
13178 Based on the program unit type and other info (like return function
13179 type, return master function type when alternate ENTRY points,
13180 whether subroutine has any alternate RETURN points, etc), returns the
13181 appropriate expression to be returned to the caller, or NULL_TREE
13182 meaning no return value or the caller expects it to be returned somewhere
13183 else (which is handled by other parts of this module). */
13184
5ff904cd 13185#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
13186tree
13187ffecom_return_expr (ffebld expr)
13188{
13189 tree rtn;
13190
13191 switch (ffecom_primary_entry_kind_)
5ff904cd 13192 {
c7e4ee3a
CB
13193 case FFEINFO_kindPROGRAM:
13194 case FFEINFO_kindBLOCKDATA:
13195 rtn = NULL_TREE;
13196 break;
5ff904cd 13197
c7e4ee3a
CB
13198 case FFEINFO_kindSUBROUTINE:
13199 if (!ffecom_is_altreturning_)
13200 rtn = NULL_TREE; /* No alt returns, never an expr. */
13201 else if (expr == NULL)
13202 rtn = integer_zero_node;
13203 else
13204 rtn = ffecom_expr (expr);
13205 break;
13206
13207 case FFEINFO_kindFUNCTION:
13208 if ((ffecom_multi_retval_ != NULL_TREE)
13209 || (ffesymbol_basictype (ffecom_primary_entry_)
13210 == FFEINFO_basictypeCHARACTER)
13211 || ((ffesymbol_basictype (ffecom_primary_entry_)
13212 == FFEINFO_basictypeCOMPLEX)
13213 && (ffecom_num_entrypoints_ == 0)
13214 && ffesymbol_is_f2c (ffecom_primary_entry_)))
13215 { /* Value is returned by direct assignment
13216 into (implicit) dummy. */
13217 rtn = NULL_TREE;
13218 break;
5ff904cd 13219 }
c7e4ee3a
CB
13220 rtn = ffecom_func_result_;
13221#if 0
13222 /* Spurious error if RETURN happens before first reference! So elide
13223 this code. In particular, for debugging registry, rtn should always
13224 be non-null after all, but TREE_USED won't be set until we encounter
13225 a reference in the code. Perfectly okay (but weird) code that,
13226 e.g., has "GOTO 20;10 RETURN;20 RTN=0;GOTO 10", would result in
13227 this diagnostic for no reason. Have people use -O -Wuninitialized
13228 and leave it to the back end to find obviously weird cases. */
5ff904cd 13229
c7e4ee3a
CB
13230 /* Used to "assert(rtn != NULL_TREE);" here, but it's kind of a valid
13231 situation; if the return value has never been referenced, it won't
13232 have a tree under 2pass mode. */
13233 if ((rtn == NULL_TREE)
13234 || !TREE_USED (rtn))
13235 {
13236 ffebad_start (FFEBAD_RETURN_VALUE_UNSET);
13237 ffebad_here (0, ffesymbol_where_line (ffecom_primary_entry_),
13238 ffesymbol_where_column (ffecom_primary_entry_));
13239 ffebad_string (ffesymbol_text (ffesymbol_funcresult
13240 (ffecom_primary_entry_)));
13241 ffebad_finish ();
13242 }
5ff904cd 13243#endif
c7e4ee3a 13244 break;
5ff904cd 13245
c7e4ee3a
CB
13246 default:
13247 assert ("bad unit kind" == NULL);
13248 case FFEINFO_kindANY:
13249 rtn = error_mark_node;
13250 break;
13251 }
5ff904cd 13252
c7e4ee3a
CB
13253 return rtn;
13254}
5ff904cd 13255
c7e4ee3a
CB
13256#endif
13257/* Do save_expr only if tree is not error_mark_node. */
5ff904cd
JL
13258
13259#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
13260tree
13261ffecom_save_tree (tree t)
5ff904cd 13262{
c7e4ee3a 13263 return save_expr (t);
5ff904cd 13264}
5ff904cd 13265#endif
c7e4ee3a
CB
13266
13267/* Start a compound statement (block). */
5ff904cd
JL
13268
13269#if FFECOM_targetCURRENT == FFECOM_targetGCC
13270void
c7e4ee3a 13271ffecom_start_compstmt (void)
5ff904cd 13272{
c7e4ee3a 13273 bison_rule_pushlevel_ ();
5ff904cd 13274}
c7e4ee3a 13275#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
5ff904cd 13276
c7e4ee3a 13277/* Public entry point for front end to access start_decl. */
5ff904cd
JL
13278
13279#if FFECOM_targetCURRENT == FFECOM_targetGCC
13280tree
c7e4ee3a 13281ffecom_start_decl (tree decl, bool is_initialized)
5ff904cd 13282{
c7e4ee3a
CB
13283 DECL_INITIAL (decl) = is_initialized ? error_mark_node : NULL_TREE;
13284 return start_decl (decl, FALSE);
13285}
5ff904cd 13286
c7e4ee3a
CB
13287#endif
13288/* ffecom_sym_commit -- Symbol's state being committed to reality
5ff904cd 13289
c7e4ee3a
CB
13290 ffesymbol s;
13291 ffecom_sym_commit(s);
5ff904cd 13292
c7e4ee3a
CB
13293 Does whatever the backend needs when a symbol is committed after having
13294 been backtrackable for a period of time. */
5ff904cd 13295
c7e4ee3a
CB
13296#if FFECOM_targetCURRENT == FFECOM_targetGCC
13297void
13298ffecom_sym_commit (ffesymbol s UNUSED)
13299{
13300 assert (!ffesymbol_retractable ());
13301}
5ff904cd 13302
c7e4ee3a
CB
13303#endif
13304/* ffecom_sym_end_transition -- Perform end transition on all symbols
5ff904cd 13305
c7e4ee3a 13306 ffecom_sym_end_transition();
5ff904cd 13307
c7e4ee3a
CB
13308 Does backend-specific stuff and also calls ffest_sym_end_transition
13309 to do the necessary FFE stuff.
5ff904cd 13310
c7e4ee3a
CB
13311 Backtracking is never enabled when this fn is called, so don't worry
13312 about it. */
5ff904cd 13313
c7e4ee3a
CB
13314ffesymbol
13315ffecom_sym_end_transition (ffesymbol s)
13316{
13317 ffestorag st;
5ff904cd 13318
c7e4ee3a 13319 assert (!ffesymbol_retractable ());
5ff904cd 13320
c7e4ee3a 13321 s = ffest_sym_end_transition (s);
5ff904cd 13322
c7e4ee3a
CB
13323#if FFECOM_targetCURRENT == FFECOM_targetGCC
13324 if ((ffesymbol_kind (s) == FFEINFO_kindBLOCKDATA)
13325 && (ffesymbol_where (s) == FFEINFO_whereGLOBAL))
13326 {
13327 ffecom_list_blockdata_
13328 = ffebld_new_item (ffebld_new_symter (s, FFEINTRIN_genNONE,
13329 FFEINTRIN_specNONE,
13330 FFEINTRIN_impNONE),
13331 ffecom_list_blockdata_);
5ff904cd 13332 }
5ff904cd 13333#endif
5ff904cd 13334
c7e4ee3a
CB
13335 /* This is where we finally notice that a symbol has partial initialization
13336 and finalize it. */
5ff904cd 13337
c7e4ee3a
CB
13338 if (ffesymbol_accretion (s) != NULL)
13339 {
13340 assert (ffesymbol_init (s) == NULL);
13341 ffecom_notify_init_symbol (s);
13342 }
13343 else if (((st = ffesymbol_storage (s)) != NULL)
13344 && ((st = ffestorag_parent (st)) != NULL)
13345 && (ffestorag_accretion (st) != NULL))
13346 {
13347 assert (ffestorag_init (st) == NULL);
13348 ffecom_notify_init_storage (st);
13349 }
5ff904cd
JL
13350
13351#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
13352 if ((ffesymbol_kind (s) == FFEINFO_kindCOMMON)
13353 && (ffesymbol_where (s) == FFEINFO_whereLOCAL)
13354 && (ffesymbol_storage (s) != NULL))
13355 {
13356 ffecom_list_common_
13357 = ffebld_new_item (ffebld_new_symter (s, FFEINTRIN_genNONE,
13358 FFEINTRIN_specNONE,
13359 FFEINTRIN_impNONE),
13360 ffecom_list_common_);
13361 }
13362#endif
5ff904cd 13363
c7e4ee3a
CB
13364 return s;
13365}
5ff904cd 13366
c7e4ee3a 13367/* ffecom_sym_exec_transition -- Perform exec transition on all symbols
5ff904cd 13368
c7e4ee3a 13369 ffecom_sym_exec_transition();
5ff904cd 13370
c7e4ee3a
CB
13371 Does backend-specific stuff and also calls ffest_sym_exec_transition
13372 to do the necessary FFE stuff.
5ff904cd 13373
c7e4ee3a
CB
13374 See the long-winded description in ffecom_sym_learned for info
13375 on handling the situation where backtracking is inhibited. */
5ff904cd 13376
c7e4ee3a
CB
13377ffesymbol
13378ffecom_sym_exec_transition (ffesymbol s)
13379{
13380 s = ffest_sym_exec_transition (s);
5ff904cd 13381
c7e4ee3a
CB
13382 return s;
13383}
5ff904cd 13384
c7e4ee3a 13385/* ffecom_sym_learned -- Initial or more info gained on symbol after exec
5ff904cd 13386
c7e4ee3a
CB
13387 ffesymbol s;
13388 s = ffecom_sym_learned(s);
5ff904cd 13389
c7e4ee3a
CB
13390 Called when a new symbol is seen after the exec transition or when more
13391 info (perhaps) is gained for an UNCERTAIN symbol. The symbol state when
13392 it arrives here is that all its latest info is updated already, so its
13393 state may be UNCERTAIN or UNDERSTOOD, it might already have the hook
13394 field filled in if its gone through here or exec_transition first, and
13395 so on.
5ff904cd 13396
c7e4ee3a
CB
13397 The backend probably wants to check ffesymbol_retractable() to see if
13398 backtracking is in effect. If so, the FFE's changes to the symbol may
13399 be retracted (undone) or committed (ratified), at which time the
13400 appropriate ffecom_sym_retract or _commit function will be called
13401 for that function.
5ff904cd 13402
c7e4ee3a
CB
13403 If the backend has its own backtracking mechanism, great, use it so that
13404 committal is a simple operation. Though it doesn't make much difference,
13405 I suppose: the reason for tentative symbol evolution in the FFE is to
13406 enable error detection in weird incorrect statements early and to disable
13407 incorrect error detection on a correct statement. The backend is not
13408 likely to introduce any information that'll get involved in these
13409 considerations, so it is probably just fine that the implementation
13410 model for this fn and for _exec_transition is to not do anything
13411 (besides the required FFE stuff) if ffesymbol_retractable() returns TRUE
13412 and instead wait until ffecom_sym_commit is called (which it never
13413 will be as long as we're using ambiguity-detecting statement analysis in
13414 the FFE, which we are initially to shake out the code, but don't depend
13415 on this), otherwise go ahead and do whatever is needed.
5ff904cd 13416
c7e4ee3a
CB
13417 In essence, then, when this fn and _exec_transition get called while
13418 backtracking is enabled, a general mechanism would be to flag which (or
13419 both) of these were called (and in what order? neat question as to what
13420 might happen that I'm too lame to think through right now) and then when
13421 _commit is called reproduce the original calling sequence, if any, for
13422 the two fns (at which point backtracking will, of course, be disabled). */
5ff904cd 13423
c7e4ee3a
CB
13424ffesymbol
13425ffecom_sym_learned (ffesymbol s)
13426{
13427 ffestorag_exec_layout (s);
5ff904cd 13428
c7e4ee3a 13429 return s;
5ff904cd
JL
13430}
13431
c7e4ee3a 13432/* ffecom_sym_retract -- Symbol's state being retracted from reality
5ff904cd 13433
c7e4ee3a
CB
13434 ffesymbol s;
13435 ffecom_sym_retract(s);
5ff904cd 13436
c7e4ee3a
CB
13437 Does whatever the backend needs when a symbol is retracted after having
13438 been backtrackable for a period of time. */
5ff904cd
JL
13439
13440#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
13441void
13442ffecom_sym_retract (ffesymbol s UNUSED)
5ff904cd 13443{
c7e4ee3a 13444 assert (!ffesymbol_retractable ());
5ff904cd 13445
c7e4ee3a
CB
13446#if 0 /* GCC doesn't commit any backtrackable sins,
13447 so nothing needed here. */
13448 switch (ffesymbol_hook (s).state)
5ff904cd 13449 {
c7e4ee3a 13450 case 0: /* nothing happened yet. */
5ff904cd
JL
13451 break;
13452
c7e4ee3a 13453 case 1: /* exec transition happened. */
5ff904cd
JL
13454 break;
13455
c7e4ee3a
CB
13456 case 2: /* learned happened. */
13457 break;
5ff904cd 13458
c7e4ee3a
CB
13459 case 3: /* learned then exec. */
13460 break;
13461
13462 case 4: /* exec then learned. */
5ff904cd
JL
13463 break;
13464
13465 default:
c7e4ee3a 13466 assert ("bad hook state" == NULL);
5ff904cd
JL
13467 break;
13468 }
c7e4ee3a
CB
13469#endif
13470}
5ff904cd 13471
c7e4ee3a
CB
13472#endif
13473/* Create temporary gcc label. */
13474
13475#if FFECOM_targetCURRENT == FFECOM_targetGCC
13476tree
13477ffecom_temp_label ()
13478{
13479 tree glabel;
13480 static int mynumber = 0;
13481
13482 glabel = build_decl (LABEL_DECL,
13483 ffecom_get_invented_identifier ("__g77_label_%d",
c7e4ee3a
CB
13484 mynumber++),
13485 void_type_node);
13486 DECL_CONTEXT (glabel) = current_function_decl;
13487 DECL_MODE (glabel) = VOIDmode;
13488
13489 return glabel;
5ff904cd
JL
13490}
13491
13492#endif
c7e4ee3a
CB
13493/* Return an expression that is usable as an arg in a conditional context
13494 (IF, DO WHILE, .NOT., and so on).
13495
13496 Use the one provided for the back end as of >2.6.0. */
5ff904cd
JL
13497
13498#if FFECOM_targetCURRENT == FFECOM_targetGCC
a2977d2d 13499tree
c7e4ee3a 13500ffecom_truth_value (tree expr)
5ff904cd 13501{
c7e4ee3a 13502 return truthvalue_conversion (expr);
5ff904cd 13503}
c7e4ee3a 13504
5ff904cd 13505#endif
c7e4ee3a
CB
13506/* Return the inversion of a truth value (the inversion of what
13507 ffecom_truth_value builds).
5ff904cd 13508
c7e4ee3a
CB
13509 Apparently invert_truthvalue, which is properly in the back end, is
13510 enough for now, so just use it. */
5ff904cd
JL
13511
13512#if FFECOM_targetCURRENT == FFECOM_targetGCC
13513tree
c7e4ee3a 13514ffecom_truth_value_invert (tree expr)
5ff904cd 13515{
c7e4ee3a 13516 return invert_truthvalue (ffecom_truth_value (expr));
5ff904cd
JL
13517}
13518
13519#endif
5ff904cd 13520
c7e4ee3a
CB
13521/* Return the tree that is the type of the expression, as would be
13522 returned in TREE_TYPE(ffecom_expr(expr)), without otherwise
13523 transforming the expression, generating temporaries, etc. */
5ff904cd 13524
c7e4ee3a
CB
13525tree
13526ffecom_type_expr (ffebld expr)
13527{
13528 ffeinfoBasictype bt;
13529 ffeinfoKindtype kt;
13530 tree tree_type;
13531
13532 assert (expr != NULL);
13533
13534 bt = ffeinfo_basictype (ffebld_info (expr));
13535 kt = ffeinfo_kindtype (ffebld_info (expr));
13536 tree_type = ffecom_tree_type[bt][kt];
13537
13538 switch (ffebld_op (expr))
13539 {
13540 case FFEBLD_opCONTER:
13541 case FFEBLD_opSYMTER:
13542 case FFEBLD_opARRAYREF:
13543 case FFEBLD_opUPLUS:
13544 case FFEBLD_opPAREN:
13545 case FFEBLD_opUMINUS:
13546 case FFEBLD_opADD:
13547 case FFEBLD_opSUBTRACT:
13548 case FFEBLD_opMULTIPLY:
13549 case FFEBLD_opDIVIDE:
13550 case FFEBLD_opPOWER:
13551 case FFEBLD_opNOT:
13552 case FFEBLD_opFUNCREF:
13553 case FFEBLD_opSUBRREF:
13554 case FFEBLD_opAND:
13555 case FFEBLD_opOR:
13556 case FFEBLD_opXOR:
13557 case FFEBLD_opNEQV:
13558 case FFEBLD_opEQV:
13559 case FFEBLD_opCONVERT:
13560 case FFEBLD_opLT:
13561 case FFEBLD_opLE:
13562 case FFEBLD_opEQ:
13563 case FFEBLD_opNE:
13564 case FFEBLD_opGT:
13565 case FFEBLD_opGE:
13566 case FFEBLD_opPERCENT_LOC:
13567 return tree_type;
13568
13569 case FFEBLD_opACCTER:
13570 case FFEBLD_opARRTER:
13571 case FFEBLD_opITEM:
13572 case FFEBLD_opSTAR:
13573 case FFEBLD_opBOUNDS:
13574 case FFEBLD_opREPEAT:
13575 case FFEBLD_opLABTER:
13576 case FFEBLD_opLABTOK:
13577 case FFEBLD_opIMPDO:
13578 case FFEBLD_opCONCATENATE:
13579 case FFEBLD_opSUBSTR:
13580 default:
13581 assert ("bad op for ffecom_type_expr" == NULL);
13582 /* Fall through. */
13583 case FFEBLD_opANY:
13584 return error_mark_node;
13585 }
13586}
13587
13588/* Return PARM_DECL for arg#1 of master fn containing alternate ENTRY points
13589
13590 If the PARM_DECL already exists, return it, else create it. It's an
13591 integer_type_node argument for the master function that implements a
13592 subroutine or function with more than one entrypoint and is bound at
13593 run time with the entrypoint number (0 for SUBROUTINE/FUNCTION, 1 for
13594 first ENTRY statement, and so on). */
5ff904cd
JL
13595
13596#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
13597tree
13598ffecom_which_entrypoint_decl ()
5ff904cd 13599{
c7e4ee3a
CB
13600 assert (ffecom_which_entrypoint_decl_ != NULL_TREE);
13601
13602 return ffecom_which_entrypoint_decl_;
5ff904cd
JL
13603}
13604
13605#endif
c7e4ee3a
CB
13606\f
13607/* The following sections consists of private and public functions
13608 that have the same names and perform roughly the same functions
13609 as counterparts in the C front end. Changes in the C front end
13610 might affect how things should be done here. Only functions
13611 needed by the back end should be public here; the rest should
13612 be private (static in the C sense). Functions needed by other
13613 g77 front-end modules should be accessed by them via public
13614 ffecom_* names, which should themselves call private versions
13615 in this section so the private versions are easy to recognize
13616 when upgrading to a new gcc and finding interesting changes
13617 in the front end.
5ff904cd 13618
c7e4ee3a
CB
13619 Functions named after rule "foo:" in c-parse.y are named
13620 "bison_rule_foo_" so they are easy to find. */
5ff904cd 13621
c7e4ee3a 13622#if FFECOM_targetCURRENT == FFECOM_targetGCC
5ff904cd 13623
c7e4ee3a
CB
13624static void
13625bison_rule_pushlevel_ ()
13626{
13627 emit_line_note (input_filename, lineno);
13628 pushlevel (0);
13629 clear_last_expr ();
13630 push_momentary ();
13631 expand_start_bindings (0);
13632}
5ff904cd 13633
c7e4ee3a
CB
13634static tree
13635bison_rule_compstmt_ ()
5ff904cd 13636{
c7e4ee3a
CB
13637 tree t;
13638 int keep = kept_level_p ();
5ff904cd 13639
c7e4ee3a
CB
13640 /* Make the temps go away. */
13641 if (! keep)
13642 current_binding_level->names = NULL_TREE;
5ff904cd 13643
c7e4ee3a
CB
13644 emit_line_note (input_filename, lineno);
13645 expand_end_bindings (getdecls (), keep, 0);
13646 t = poplevel (keep, 1, 0);
13647 pop_momentary ();
5ff904cd 13648
c7e4ee3a
CB
13649 return t;
13650}
5ff904cd 13651
c7e4ee3a
CB
13652/* Return a definition for a builtin function named NAME and whose data type
13653 is TYPE. TYPE should be a function type with argument types.
13654 FUNCTION_CODE tells later passes how to compile calls to this function.
13655 See tree.h for its possible values.
5ff904cd 13656
c7e4ee3a
CB
13657 If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME,
13658 the name to be called if we can't opencode the function. */
5ff904cd 13659
26db82d8
BS
13660tree
13661builtin_function (const char *name, tree type, int function_code,
13662 enum built_in_class class,
c7e4ee3a
CB
13663 const char *library_name)
13664{
13665 tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
13666 DECL_EXTERNAL (decl) = 1;
13667 TREE_PUBLIC (decl) = 1;
13668 if (library_name)
13669 DECL_ASSEMBLER_NAME (decl) = get_identifier (library_name);
13670 make_decl_rtl (decl, NULL_PTR, 1);
13671 pushdecl (decl);
26db82d8
BS
13672 DECL_BUILT_IN_CLASS (decl) = class;
13673 DECL_FUNCTION_CODE (decl) = function_code;
5ff904cd 13674
c7e4ee3a 13675 return decl;
5ff904cd
JL
13676}
13677
c7e4ee3a
CB
13678/* Handle when a new declaration NEWDECL
13679 has the same name as an old one OLDDECL
13680 in the same binding contour.
13681 Prints an error message if appropriate.
5ff904cd 13682
c7e4ee3a
CB
13683 If safely possible, alter OLDDECL to look like NEWDECL, and return 1.
13684 Otherwise, return 0. */
5ff904cd 13685
c7e4ee3a
CB
13686static int
13687duplicate_decls (tree newdecl, tree olddecl)
5ff904cd 13688{
c7e4ee3a
CB
13689 int types_match = 1;
13690 int new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL
13691 && DECL_INITIAL (newdecl) != 0);
13692 tree oldtype = TREE_TYPE (olddecl);
13693 tree newtype = TREE_TYPE (newdecl);
5ff904cd 13694
c7e4ee3a
CB
13695 if (olddecl == newdecl)
13696 return 1;
5ff904cd 13697
c7e4ee3a
CB
13698 if (TREE_CODE (newtype) == ERROR_MARK
13699 || TREE_CODE (oldtype) == ERROR_MARK)
13700 types_match = 0;
5ff904cd 13701
c7e4ee3a
CB
13702 /* New decl is completely inconsistent with the old one =>
13703 tell caller to replace the old one.
13704 This is always an error except in the case of shadowing a builtin. */
13705 if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
13706 return 0;
5ff904cd 13707
c7e4ee3a
CB
13708 /* For real parm decl following a forward decl,
13709 return 1 so old decl will be reused. */
13710 if (types_match && TREE_CODE (newdecl) == PARM_DECL
13711 && TREE_ASM_WRITTEN (olddecl) && ! TREE_ASM_WRITTEN (newdecl))
13712 return 1;
5ff904cd 13713
c7e4ee3a
CB
13714 /* The new declaration is the same kind of object as the old one.
13715 The declarations may partially match. Print warnings if they don't
13716 match enough. Ultimately, copy most of the information from the new
13717 decl to the old one, and keep using the old one. */
5ff904cd 13718
c7e4ee3a
CB
13719 if (TREE_CODE (olddecl) == FUNCTION_DECL
13720 && DECL_BUILT_IN (olddecl))
13721 {
13722 /* A function declaration for a built-in function. */
13723 if (!TREE_PUBLIC (newdecl))
13724 return 0;
13725 else if (!types_match)
13726 {
13727 /* Accept the return type of the new declaration if same modes. */
13728 tree oldreturntype = TREE_TYPE (TREE_TYPE (olddecl));
13729 tree newreturntype = TREE_TYPE (TREE_TYPE (newdecl));
5ff904cd 13730
c7e4ee3a
CB
13731 if (TYPE_MODE (oldreturntype) == TYPE_MODE (newreturntype))
13732 {
13733 /* Function types may be shared, so we can't just modify
13734 the return type of olddecl's function type. */
13735 tree newtype
13736 = build_function_type (newreturntype,
13737 TYPE_ARG_TYPES (TREE_TYPE (olddecl)));
5ff904cd 13738
c7e4ee3a
CB
13739 types_match = 1;
13740 if (types_match)
13741 TREE_TYPE (olddecl) = newtype;
13742 }
c7e4ee3a
CB
13743 }
13744 if (!types_match)
13745 return 0;
13746 }
13747 else if (TREE_CODE (olddecl) == FUNCTION_DECL
13748 && DECL_SOURCE_LINE (olddecl) == 0)
5ff904cd 13749 {
c7e4ee3a
CB
13750 /* A function declaration for a predeclared function
13751 that isn't actually built in. */
13752 if (!TREE_PUBLIC (newdecl))
13753 return 0;
13754 else if (!types_match)
13755 {
13756 /* If the types don't match, preserve volatility indication.
13757 Later on, we will discard everything else about the
13758 default declaration. */
13759 TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
13760 }
13761 }
5ff904cd 13762
c7e4ee3a
CB
13763 /* Copy all the DECL_... slots specified in the new decl
13764 except for any that we copy here from the old type.
5ff904cd 13765
c7e4ee3a
CB
13766 Past this point, we don't change OLDTYPE and NEWTYPE
13767 even if we change the types of NEWDECL and OLDDECL. */
5ff904cd 13768
c7e4ee3a
CB
13769 if (types_match)
13770 {
c7e4ee3a
CB
13771 /* Merge the data types specified in the two decls. */
13772 if (TREE_CODE (newdecl) != FUNCTION_DECL || !DECL_BUILT_IN (olddecl))
13773 TREE_TYPE (newdecl)
13774 = TREE_TYPE (olddecl)
13775 = TREE_TYPE (newdecl);
5ff904cd 13776
c7e4ee3a
CB
13777 /* Lay the type out, unless already done. */
13778 if (oldtype != TREE_TYPE (newdecl))
13779 {
13780 if (TREE_TYPE (newdecl) != error_mark_node)
13781 layout_type (TREE_TYPE (newdecl));
13782 if (TREE_CODE (newdecl) != FUNCTION_DECL
13783 && TREE_CODE (newdecl) != TYPE_DECL
13784 && TREE_CODE (newdecl) != CONST_DECL)
13785 layout_decl (newdecl, 0);
13786 }
13787 else
13788 {
13789 /* Since the type is OLDDECL's, make OLDDECL's size go with. */
13790 DECL_SIZE (newdecl) = DECL_SIZE (olddecl);
06ceef4e 13791 DECL_SIZE_UNIT (newdecl) = DECL_SIZE_UNIT (olddecl);
c7e4ee3a
CB
13792 if (TREE_CODE (olddecl) != FUNCTION_DECL)
13793 if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl))
11cf4d18
JJ
13794 {
13795 DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl);
13796 DECL_USER_ALIGN (newdecl) |= DECL_USER_ALIGN (olddecl);
13797 }
c7e4ee3a 13798 }
5ff904cd 13799
c7e4ee3a
CB
13800 /* Keep the old rtl since we can safely use it. */
13801 DECL_RTL (newdecl) = DECL_RTL (olddecl);
5ff904cd 13802
c7e4ee3a
CB
13803 /* Merge the type qualifiers. */
13804 if (DECL_BUILT_IN_NONANSI (olddecl) && TREE_THIS_VOLATILE (olddecl)
13805 && !TREE_THIS_VOLATILE (newdecl))
13806 TREE_THIS_VOLATILE (olddecl) = 0;
13807 if (TREE_READONLY (newdecl))
13808 TREE_READONLY (olddecl) = 1;
13809 if (TREE_THIS_VOLATILE (newdecl))
13810 {
13811 TREE_THIS_VOLATILE (olddecl) = 1;
13812 if (TREE_CODE (newdecl) == VAR_DECL)
13813 make_var_volatile (newdecl);
13814 }
5ff904cd 13815
c7e4ee3a
CB
13816 /* Keep source location of definition rather than declaration.
13817 Likewise, keep decl at outer scope. */
13818 if ((DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0)
13819 || (DECL_CONTEXT (newdecl) != 0 && DECL_CONTEXT (olddecl) == 0))
13820 {
13821 DECL_SOURCE_LINE (newdecl) = DECL_SOURCE_LINE (olddecl);
13822 DECL_SOURCE_FILE (newdecl) = DECL_SOURCE_FILE (olddecl);
5ff904cd 13823
c7e4ee3a
CB
13824 if (DECL_CONTEXT (olddecl) == 0
13825 && TREE_CODE (newdecl) != FUNCTION_DECL)
13826 DECL_CONTEXT (newdecl) = 0;
13827 }
5ff904cd 13828
c7e4ee3a
CB
13829 /* Merge the unused-warning information. */
13830 if (DECL_IN_SYSTEM_HEADER (olddecl))
13831 DECL_IN_SYSTEM_HEADER (newdecl) = 1;
13832 else if (DECL_IN_SYSTEM_HEADER (newdecl))
13833 DECL_IN_SYSTEM_HEADER (olddecl) = 1;
5ff904cd 13834
c7e4ee3a
CB
13835 /* Merge the initialization information. */
13836 if (DECL_INITIAL (newdecl) == 0)
13837 DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
5ff904cd 13838
c7e4ee3a
CB
13839 /* Merge the section attribute.
13840 We want to issue an error if the sections conflict but that must be
13841 done later in decl_attributes since we are called before attributes
13842 are assigned. */
13843 if (DECL_SECTION_NAME (newdecl) == NULL_TREE)
13844 DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl);
5ff904cd 13845
c7e4ee3a
CB
13846#if BUILT_FOR_270
13847 if (TREE_CODE (newdecl) == FUNCTION_DECL)
13848 {
13849 DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl);
13850 DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
13851 }
5ff904cd 13852#endif
c7e4ee3a
CB
13853 }
13854 /* If cannot merge, then use the new type and qualifiers,
13855 and don't preserve the old rtl. */
13856 else
13857 {
13858 TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
13859 TREE_READONLY (olddecl) = TREE_READONLY (newdecl);
13860 TREE_THIS_VOLATILE (olddecl) = TREE_THIS_VOLATILE (newdecl);
13861 TREE_SIDE_EFFECTS (olddecl) = TREE_SIDE_EFFECTS (newdecl);
13862 }
5ff904cd 13863
c7e4ee3a
CB
13864 /* Merge the storage class information. */
13865 /* For functions, static overrides non-static. */
13866 if (TREE_CODE (newdecl) == FUNCTION_DECL)
13867 {
13868 TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl);
13869 /* This is since we don't automatically
13870 copy the attributes of NEWDECL into OLDDECL. */
13871 TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
13872 /* If this clears `static', clear it in the identifier too. */
13873 if (! TREE_PUBLIC (olddecl))
13874 TREE_PUBLIC (DECL_NAME (olddecl)) = 0;
13875 }
13876 if (DECL_EXTERNAL (newdecl))
13877 {
13878 TREE_STATIC (newdecl) = TREE_STATIC (olddecl);
13879 DECL_EXTERNAL (newdecl) = DECL_EXTERNAL (olddecl);
13880 /* An extern decl does not override previous storage class. */
13881 TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
13882 }
13883 else
13884 {
13885 TREE_STATIC (olddecl) = TREE_STATIC (newdecl);
13886 TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
13887 }
5ff904cd 13888
c7e4ee3a
CB
13889 /* If either decl says `inline', this fn is inline,
13890 unless its definition was passed already. */
13891 if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == 0)
13892 DECL_INLINE (olddecl) = 1;
13893 DECL_INLINE (newdecl) = DECL_INLINE (olddecl);
5ff904cd 13894
c7e4ee3a
CB
13895 /* Get rid of any built-in function if new arg types don't match it
13896 or if we have a function definition. */
13897 if (TREE_CODE (newdecl) == FUNCTION_DECL
13898 && DECL_BUILT_IN (olddecl)
13899 && (!types_match || new_is_definition))
13900 {
13901 TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
26db82d8 13902 DECL_BUILT_IN_CLASS (olddecl) = NOT_BUILT_IN;
c7e4ee3a 13903 }
5ff904cd 13904
c7e4ee3a
CB
13905 /* If redeclaring a builtin function, and not a definition,
13906 it stays built in.
13907 Also preserve various other info from the definition. */
13908 if (TREE_CODE (newdecl) == FUNCTION_DECL && !new_is_definition)
13909 {
13910 if (DECL_BUILT_IN (olddecl))
13911 {
26db82d8 13912 DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl);
c7e4ee3a
CB
13913 DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
13914 }
13915 else
13916 DECL_FRAME_SIZE (newdecl) = DECL_FRAME_SIZE (olddecl);
5ff904cd 13917
c7e4ee3a
CB
13918 DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
13919 DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
13920 DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl);
13921 DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
13922 }
5ff904cd 13923
c7e4ee3a
CB
13924 /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
13925 But preserve olddecl's DECL_UID. */
13926 {
13927 register unsigned olddecl_uid = DECL_UID (olddecl);
5ff904cd 13928
c7e4ee3a
CB
13929 memcpy ((char *) olddecl + sizeof (struct tree_common),
13930 (char *) newdecl + sizeof (struct tree_common),
13931 sizeof (struct tree_decl) - sizeof (struct tree_common));
13932 DECL_UID (olddecl) = olddecl_uid;
13933 }
5ff904cd 13934
c7e4ee3a 13935 return 1;
5ff904cd
JL
13936}
13937
c7e4ee3a
CB
13938/* Finish processing of a declaration;
13939 install its initial value.
13940 If the length of an array type is not known before,
13941 it must be determined now, from the initial value, or it is an error. */
13942
5ff904cd 13943static void
c7e4ee3a 13944finish_decl (tree decl, tree init, bool is_top_level)
5ff904cd 13945{
c7e4ee3a
CB
13946 register tree type = TREE_TYPE (decl);
13947 int was_incomplete = (DECL_SIZE (decl) == 0);
13948 int temporary = allocation_temporary_p ();
13949 bool at_top_level = (current_binding_level == global_binding_level);
13950 bool top_level = is_top_level || at_top_level;
5ff904cd 13951
c7e4ee3a
CB
13952 /* Caller should pass TRUE for is_top_level only if we wouldn't be at top
13953 level anyway. */
13954 assert (!is_top_level || !at_top_level);
5ff904cd 13955
c7e4ee3a
CB
13956 if (TREE_CODE (decl) == PARM_DECL)
13957 assert (init == NULL_TREE);
13958 /* Remember that PARM_DECL doesn't have a DECL_INITIAL field per se -- it
13959 overlaps DECL_ARG_TYPE. */
13960 else if (init == NULL_TREE)
13961 assert (DECL_INITIAL (decl) == NULL_TREE);
13962 else
13963 assert (DECL_INITIAL (decl) == error_mark_node);
5ff904cd 13964
c7e4ee3a 13965 if (init != NULL_TREE)
5ff904cd 13966 {
c7e4ee3a
CB
13967 if (TREE_CODE (decl) != TYPE_DECL)
13968 DECL_INITIAL (decl) = init;
13969 else
13970 {
13971 /* typedef foo = bar; store the type of bar as the type of foo. */
13972 TREE_TYPE (decl) = TREE_TYPE (init);
13973 DECL_INITIAL (decl) = init = 0;
13974 }
5ff904cd
JL
13975 }
13976
c7e4ee3a
CB
13977 /* Pop back to the obstack that is current for this binding level. This is
13978 because MAXINDEX, rtl, etc. to be made below must go in the permanent
13979 obstack. But don't discard the temporary data yet. */
13980 pop_obstacks ();
5ff904cd 13981
c7e4ee3a 13982 /* Deduce size of array from initialization, if not already known */
5ff904cd 13983
c7e4ee3a
CB
13984 if (TREE_CODE (type) == ARRAY_TYPE
13985 && TYPE_DOMAIN (type) == 0
13986 && TREE_CODE (decl) != TYPE_DECL)
13987 {
13988 assert (top_level);
13989 assert (was_incomplete);
5ff904cd 13990
c7e4ee3a
CB
13991 layout_decl (decl, 0);
13992 }
5ff904cd 13993
c7e4ee3a
CB
13994 if (TREE_CODE (decl) == VAR_DECL)
13995 {
13996 if (DECL_SIZE (decl) == NULL_TREE
13997 && TYPE_SIZE (TREE_TYPE (decl)) != NULL_TREE)
13998 layout_decl (decl, 0);
5ff904cd 13999
c7e4ee3a
CB
14000 if (DECL_SIZE (decl) == NULL_TREE
14001 && (TREE_STATIC (decl)
14002 ?
14003 /* A static variable with an incomplete type is an error if it is
14004 initialized. Also if it is not file scope. Otherwise, let it
14005 through, but if it is not `extern' then it may cause an error
14006 message later. */
14007 (DECL_INITIAL (decl) != 0 || DECL_CONTEXT (decl) != 0)
14008 :
14009 /* An automatic variable with an incomplete type is an error. */
14010 !DECL_EXTERNAL (decl)))
14011 {
14012 assert ("storage size not known" == NULL);
14013 abort ();
14014 }
5ff904cd 14015
c7e4ee3a
CB
14016 if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl))
14017 && (DECL_SIZE (decl) != 0)
14018 && (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST))
14019 {
14020 assert ("storage size not constant" == NULL);
14021 abort ();
14022 }
14023 }
5ff904cd 14024
c7e4ee3a
CB
14025 /* Output the assembler code and/or RTL code for variables and functions,
14026 unless the type is an undefined structure or union. If not, it will get
14027 done when the type is completed. */
5ff904cd 14028
c7e4ee3a 14029 if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)
5ff904cd 14030 {
c7e4ee3a
CB
14031 rest_of_decl_compilation (decl, NULL,
14032 DECL_CONTEXT (decl) == 0,
14033 0);
5ff904cd 14034
c7e4ee3a
CB
14035 if (DECL_CONTEXT (decl) != 0)
14036 {
14037 /* Recompute the RTL of a local array now if it used to be an
14038 incomplete type. */
14039 if (was_incomplete
14040 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
5ff904cd 14041 {
c7e4ee3a
CB
14042 /* If we used it already as memory, it must stay in memory. */
14043 TREE_ADDRESSABLE (decl) = TREE_USED (decl);
14044 /* If it's still incomplete now, no init will save it. */
14045 if (DECL_SIZE (decl) == 0)
14046 DECL_INITIAL (decl) = 0;
14047 expand_decl (decl);
5ff904cd 14048 }
c7e4ee3a
CB
14049 /* Compute and store the initial value. */
14050 if (TREE_CODE (decl) != FUNCTION_DECL)
14051 expand_decl_init (decl);
14052 }
14053 }
14054 else if (TREE_CODE (decl) == TYPE_DECL)
14055 {
14056 rest_of_decl_compilation (decl, NULL_PTR,
14057 DECL_CONTEXT (decl) == 0,
14058 0);
14059 }
5ff904cd 14060
c7e4ee3a
CB
14061 if (!(TREE_CODE (decl) == FUNCTION_DECL && DECL_INLINE (decl))
14062 && temporary
14063 /* DECL_INITIAL is not defined in PARM_DECLs, since it shares space with
14064 DECL_ARG_TYPE. */
14065 && TREE_CODE (decl) != PARM_DECL)
14066 {
14067 /* We need to remember that this array HAD an initialization, but
14068 discard the actual temporary nodes, since we can't have a permanent
14069 node keep pointing to them. */
14070 /* We make an exception for inline functions, since it's normal for a
14071 local extern redeclaration of an inline function to have a copy of
14072 the top-level decl's DECL_INLINE. */
14073 if ((DECL_INITIAL (decl) != 0)
14074 && (DECL_INITIAL (decl) != error_mark_node))
14075 {
14076 /* If this is a const variable, then preserve the
14077 initializer instead of discarding it so that we can optimize
14078 references to it. */
14079 /* This test used to include TREE_STATIC, but this won't be set
14080 for function level initializers. */
14081 if (TREE_READONLY (decl))
5ff904cd 14082 {
c7e4ee3a 14083 preserve_initializer ();
5ff904cd 14084
c7e4ee3a
CB
14085 /* The initializer and DECL must have the same (or equivalent
14086 types), but if the initializer is a STRING_CST, its type
14087 might not be on the right obstack, so copy the type
14088 of DECL. */
14089 TREE_TYPE (DECL_INITIAL (decl)) = type;
5ff904cd 14090 }
c7e4ee3a
CB
14091 else
14092 DECL_INITIAL (decl) = error_mark_node;
5ff904cd 14093 }
5ff904cd 14094 }
c7e4ee3a 14095
c7e4ee3a
CB
14096 /* If we have gone back from temporary to permanent allocation, actually
14097 free the temporary space that we no longer need. */
14098 if (temporary && !allocation_temporary_p ())
14099 permanent_allocation (0);
5ff904cd 14100
c7e4ee3a
CB
14101 /* At the end of a declaration, throw away any variable type sizes of types
14102 defined inside that declaration. There is no use computing them in the
14103 following function definition. */
14104 if (current_binding_level == global_binding_level)
14105 get_pending_sizes ();
14106}
5ff904cd 14107
c7e4ee3a
CB
14108/* Finish up a function declaration and compile that function
14109 all the way to assembler language output. The free the storage
14110 for the function definition.
5ff904cd 14111
c7e4ee3a 14112 This is called after parsing the body of the function definition.
5ff904cd 14113
c7e4ee3a
CB
14114 NESTED is nonzero if the function being finished is nested in another. */
14115
14116static void
14117finish_function (int nested)
14118{
14119 register tree fndecl = current_function_decl;
14120
14121 assert (fndecl != NULL_TREE);
14122 if (TREE_CODE (fndecl) != ERROR_MARK)
14123 {
14124 if (nested)
14125 assert (DECL_CONTEXT (fndecl) != NULL_TREE);
5ff904cd 14126 else
c7e4ee3a
CB
14127 assert (DECL_CONTEXT (fndecl) == NULL_TREE);
14128 }
5ff904cd 14129
c7e4ee3a
CB
14130/* TREE_READONLY (fndecl) = 1;
14131 This caused &foo to be of type ptr-to-const-function
14132 which then got a warning when stored in a ptr-to-function variable. */
5ff904cd 14133
c7e4ee3a 14134 poplevel (1, 0, 1);
5ff904cd 14135
c7e4ee3a
CB
14136 if (TREE_CODE (fndecl) != ERROR_MARK)
14137 {
14138 BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
5ff904cd 14139
c7e4ee3a 14140 /* Must mark the RESULT_DECL as being in this function. */
5ff904cd 14141
c7e4ee3a 14142 DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;
5ff904cd 14143
c7e4ee3a
CB
14144 /* Obey `register' declarations if `setjmp' is called in this fn. */
14145 /* Generate rtl for function exit. */
14146 expand_function_end (input_filename, lineno, 0);
5ff904cd 14147
c7e4ee3a
CB
14148 /* So we can tell if jump_optimize sets it to 1. */
14149 can_reach_end = 0;
5ff904cd 14150
7189a4b0
GK
14151 /* If this is a nested function, protect the local variables in the stack
14152 above us from being collected while we're compiling this function. */
14153 if (ggc_p && nested)
14154 ggc_push_context ();
14155
c7e4ee3a
CB
14156 /* Run the optimizers and output the assembler code for this function. */
14157 rest_of_compilation (fndecl);
7189a4b0
GK
14158
14159 /* Undo the GC context switch. */
14160 if (ggc_p && nested)
14161 ggc_pop_context ();
c7e4ee3a 14162 }
5ff904cd 14163
c7e4ee3a
CB
14164 /* Free all the tree nodes making up this function. */
14165 /* Switch back to allocating nodes permanently until we start another
14166 function. */
14167 if (!nested)
14168 permanent_allocation (1);
14169
14170 if (TREE_CODE (fndecl) != ERROR_MARK
14171 && !nested
14172 && DECL_SAVED_INSNS (fndecl) == 0)
14173 {
14174 /* Stop pointing to the local nodes about to be freed. */
14175 /* But DECL_INITIAL must remain nonzero so we know this was an actual
14176 function definition. */
14177 /* For a nested function, this is done in pop_f_function_context. */
14178 /* If rest_of_compilation set this to 0, leave it 0. */
14179 if (DECL_INITIAL (fndecl) != 0)
14180 DECL_INITIAL (fndecl) = error_mark_node;
14181 DECL_ARGUMENTS (fndecl) = 0;
5ff904cd 14182 }
c7e4ee3a
CB
14183
14184 if (!nested)
5ff904cd 14185 {
c7e4ee3a
CB
14186 /* Let the error reporting routines know that we're outside a function.
14187 For a nested function, this value is used in pop_c_function_context
14188 and then reset via pop_function_context. */
14189 ffecom_outer_function_decl_ = current_function_decl = NULL;
5ff904cd 14190 }
c7e4ee3a 14191}
5ff904cd 14192
c7e4ee3a
CB
14193/* Plug-in replacement for identifying the name of a decl and, for a
14194 function, what we call it in diagnostics. For now, "program unit"
14195 should suffice, since it's a bit of a hassle to figure out which
14196 of several kinds of things it is. Note that it could conceivably
14197 be a statement function, which probably isn't really a program unit
14198 per se, but if that comes up, it should be easy to check (being a
14199 nested function and all). */
14200
4b731ffa 14201static const char *
c7e4ee3a
CB
14202lang_printable_name (tree decl, int v)
14203{
14204 /* Just to keep GCC quiet about the unused variable.
14205 In theory, differing values of V should produce different
14206 output. */
14207 switch (v)
5ff904cd 14208 {
c7e4ee3a
CB
14209 default:
14210 if (TREE_CODE (decl) == ERROR_MARK)
14211 return "erroneous code";
14212 return IDENTIFIER_POINTER (DECL_NAME (decl));
5ff904cd 14213 }
c7e4ee3a
CB
14214}
14215
14216/* g77's function to print out name of current function that caused
14217 an error. */
14218
14219#if BUILT_FOR_270
b0791fa9
KG
14220static void
14221lang_print_error_function (const char *file)
c7e4ee3a
CB
14222{
14223 static ffeglobal last_g = NULL;
14224 static ffesymbol last_s = NULL;
14225 ffeglobal g;
14226 ffesymbol s;
14227 const char *kind;
14228
14229 if ((ffecom_primary_entry_ == NULL)
14230 || (ffesymbol_global (ffecom_primary_entry_) == NULL))
5ff904cd 14231 {
c7e4ee3a
CB
14232 g = NULL;
14233 s = NULL;
14234 kind = NULL;
5ff904cd
JL
14235 }
14236 else
14237 {
c7e4ee3a
CB
14238 g = ffesymbol_global (ffecom_primary_entry_);
14239 if (ffecom_nested_entry_ == NULL)
14240 {
14241 s = ffecom_primary_entry_;
14242 switch (ffesymbol_kind (s))
14243 {
14244 case FFEINFO_kindFUNCTION:
14245 kind = "function";
14246 break;
5ff904cd 14247
c7e4ee3a
CB
14248 case FFEINFO_kindSUBROUTINE:
14249 kind = "subroutine";
14250 break;
5ff904cd 14251
c7e4ee3a
CB
14252 case FFEINFO_kindPROGRAM:
14253 kind = "program";
14254 break;
14255
14256 case FFEINFO_kindBLOCKDATA:
14257 kind = "block-data";
14258 break;
14259
14260 default:
14261 kind = ffeinfo_kind_message (ffesymbol_kind (s));
14262 break;
14263 }
14264 }
14265 else
14266 {
14267 s = ffecom_nested_entry_;
14268 kind = "statement function";
14269 }
5ff904cd
JL
14270 }
14271
c7e4ee3a 14272 if ((last_g != g) || (last_s != s))
5ff904cd 14273 {
c7e4ee3a
CB
14274 if (file)
14275 fprintf (stderr, "%s: ", file);
14276
14277 if (s == NULL)
14278 fprintf (stderr, "Outside of any program unit:\n");
14279 else
5ff904cd 14280 {
c7e4ee3a
CB
14281 const char *name = ffesymbol_text (s);
14282
14283 fprintf (stderr, "In %s `%s':\n", kind, name);
5ff904cd 14284 }
5ff904cd 14285
c7e4ee3a
CB
14286 last_g = g;
14287 last_s = s;
5ff904cd 14288 }
c7e4ee3a
CB
14289}
14290#endif
5ff904cd 14291
c7e4ee3a 14292/* Similar to `lookup_name' but look only at current binding level. */
5ff904cd 14293
c7e4ee3a
CB
14294static tree
14295lookup_name_current_level (tree name)
14296{
14297 register tree t;
5ff904cd 14298
c7e4ee3a
CB
14299 if (current_binding_level == global_binding_level)
14300 return IDENTIFIER_GLOBAL_VALUE (name);
14301
14302 if (IDENTIFIER_LOCAL_VALUE (name) == 0)
14303 return 0;
14304
14305 for (t = current_binding_level->names; t; t = TREE_CHAIN (t))
14306 if (DECL_NAME (t) == name)
14307 break;
14308
14309 return t;
5ff904cd
JL
14310}
14311
c7e4ee3a 14312/* Create a new `struct binding_level'. */
5ff904cd 14313
c7e4ee3a
CB
14314static struct binding_level *
14315make_binding_level ()
5ff904cd 14316{
c7e4ee3a
CB
14317 /* NOSTRICT */
14318 return (struct binding_level *) xmalloc (sizeof (struct binding_level));
14319}
5ff904cd 14320
c7e4ee3a
CB
14321/* Save and restore the variables in this file and elsewhere
14322 that keep track of the progress of compilation of the current function.
14323 Used for nested functions. */
5ff904cd 14324
c7e4ee3a
CB
14325struct f_function
14326{
14327 struct f_function *next;
14328 tree named_labels;
14329 tree shadowed_labels;
14330 struct binding_level *binding_level;
14331};
5ff904cd 14332
c7e4ee3a 14333struct f_function *f_function_chain;
5ff904cd 14334
c7e4ee3a 14335/* Restore the variables used during compilation of a C function. */
5ff904cd 14336
c7e4ee3a
CB
14337static void
14338pop_f_function_context ()
14339{
14340 struct f_function *p = f_function_chain;
14341 tree link;
5ff904cd 14342
c7e4ee3a
CB
14343 /* Bring back all the labels that were shadowed. */
14344 for (link = shadowed_labels; link; link = TREE_CHAIN (link))
14345 if (DECL_NAME (TREE_VALUE (link)) != 0)
14346 IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link)))
14347 = TREE_VALUE (link);
5ff904cd 14348
c7e4ee3a
CB
14349 if (current_function_decl != error_mark_node
14350 && DECL_SAVED_INSNS (current_function_decl) == 0)
14351 {
14352 /* Stop pointing to the local nodes about to be freed. */
14353 /* But DECL_INITIAL must remain nonzero so we know this was an actual
14354 function definition. */
14355 DECL_INITIAL (current_function_decl) = error_mark_node;
14356 DECL_ARGUMENTS (current_function_decl) = 0;
5ff904cd
JL
14357 }
14358
c7e4ee3a 14359 pop_function_context ();
5ff904cd 14360
c7e4ee3a 14361 f_function_chain = p->next;
5ff904cd 14362
c7e4ee3a
CB
14363 named_labels = p->named_labels;
14364 shadowed_labels = p->shadowed_labels;
14365 current_binding_level = p->binding_level;
5ff904cd 14366
c7e4ee3a
CB
14367 free (p);
14368}
5ff904cd 14369
c7e4ee3a
CB
14370/* Save and reinitialize the variables
14371 used during compilation of a C function. */
5ff904cd 14372
c7e4ee3a
CB
14373static void
14374push_f_function_context ()
14375{
14376 struct f_function *p
14377 = (struct f_function *) xmalloc (sizeof (struct f_function));
5ff904cd 14378
c7e4ee3a
CB
14379 push_function_context ();
14380
14381 p->next = f_function_chain;
14382 f_function_chain = p;
14383
14384 p->named_labels = named_labels;
14385 p->shadowed_labels = shadowed_labels;
14386 p->binding_level = current_binding_level;
14387}
5ff904cd 14388
c7e4ee3a
CB
14389static void
14390push_parm_decl (tree parm)
14391{
14392 int old_immediate_size_expand = immediate_size_expand;
5ff904cd 14393
c7e4ee3a 14394 /* Don't try computing parm sizes now -- wait till fn is called. */
5ff904cd 14395
c7e4ee3a 14396 immediate_size_expand = 0;
5ff904cd 14397
c7e4ee3a 14398 push_obstacks_nochange ();
5ff904cd 14399
c7e4ee3a 14400 /* Fill in arg stuff. */
5ff904cd 14401
c7e4ee3a
CB
14402 DECL_ARG_TYPE (parm) = TREE_TYPE (parm);
14403 DECL_ARG_TYPE_AS_WRITTEN (parm) = TREE_TYPE (parm);
14404 TREE_READONLY (parm) = 1; /* All implementation args are read-only. */
5ff904cd 14405
c7e4ee3a
CB
14406 parm = pushdecl (parm);
14407
14408 immediate_size_expand = old_immediate_size_expand;
14409
14410 finish_decl (parm, NULL_TREE, FALSE);
5ff904cd
JL
14411}
14412
c7e4ee3a 14413/* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL, if appropriate. */
5ff904cd 14414
c7e4ee3a
CB
14415static tree
14416pushdecl_top_level (x)
14417 tree x;
14418{
14419 register tree t;
14420 register struct binding_level *b = current_binding_level;
14421 register tree f = current_function_decl;
5ff904cd 14422
c7e4ee3a
CB
14423 current_binding_level = global_binding_level;
14424 current_function_decl = NULL_TREE;
14425 t = pushdecl (x);
14426 current_binding_level = b;
14427 current_function_decl = f;
14428 return t;
14429}
14430
14431/* Store the list of declarations of the current level.
14432 This is done for the parameter declarations of a function being defined,
14433 after they are modified in the light of any missing parameters. */
14434
14435static tree
14436storedecls (decls)
14437 tree decls;
14438{
14439 return current_binding_level->names = decls;
14440}
14441
14442/* Store the parameter declarations into the current function declaration.
14443 This is called after parsing the parameter declarations, before
14444 digesting the body of the function.
14445
14446 For an old-style definition, modify the function's type
14447 to specify at least the number of arguments. */
5ff904cd
JL
14448
14449static void
c7e4ee3a 14450store_parm_decls (int is_main_program UNUSED)
5ff904cd
JL
14451{
14452 register tree fndecl = current_function_decl;
14453
c7e4ee3a
CB
14454 if (fndecl == error_mark_node)
14455 return;
5ff904cd 14456
c7e4ee3a
CB
14457 /* This is a chain of PARM_DECLs from old-style parm declarations. */
14458 DECL_ARGUMENTS (fndecl) = storedecls (nreverse (getdecls ()));
5ff904cd 14459
c7e4ee3a 14460 /* Initialize the RTL code for the function. */
5ff904cd 14461
c7e4ee3a 14462 init_function_start (fndecl, input_filename, lineno);
56a0044b 14463
c7e4ee3a 14464 /* Set up parameters and prepare for return, for the function. */
5ff904cd 14465
c7e4ee3a
CB
14466 expand_function_start (fndecl, 0);
14467}
5ff904cd 14468
c7e4ee3a
CB
14469static tree
14470start_decl (tree decl, bool is_top_level)
14471{
14472 register tree tem;
14473 bool at_top_level = (current_binding_level == global_binding_level);
14474 bool top_level = is_top_level || at_top_level;
5ff904cd 14475
c7e4ee3a
CB
14476 /* Caller should pass TRUE for is_top_level only if we wouldn't be at top
14477 level anyway. */
14478 assert (!is_top_level || !at_top_level);
5ff904cd 14479
c7e4ee3a
CB
14480 /* The corresponding pop_obstacks is in finish_decl. */
14481 push_obstacks_nochange ();
14482
14483 if (DECL_INITIAL (decl) != NULL_TREE)
14484 {
14485 assert (DECL_INITIAL (decl) == error_mark_node);
14486 assert (!DECL_EXTERNAL (decl));
56a0044b 14487 }
c7e4ee3a
CB
14488 else if (top_level)
14489 assert ((TREE_STATIC (decl) == 1) || DECL_EXTERNAL (decl) == 1);
5ff904cd 14490
c7e4ee3a
CB
14491 /* For Fortran, we by default put things in .common when possible. */
14492 DECL_COMMON (decl) = 1;
5ff904cd 14493
c7e4ee3a
CB
14494 /* Add this decl to the current binding level. TEM may equal DECL or it may
14495 be a previous decl of the same name. */
14496 if (is_top_level)
14497 tem = pushdecl_top_level (decl);
14498 else
14499 tem = pushdecl (decl);
14500
14501 /* For a local variable, define the RTL now. */
14502 if (!top_level
14503 /* But not if this is a duplicate decl and we preserved the rtl from the
14504 previous one (which may or may not happen). */
14505 && DECL_RTL (tem) == 0)
5ff904cd 14506 {
c7e4ee3a
CB
14507 if (TYPE_SIZE (TREE_TYPE (tem)) != 0)
14508 expand_decl (tem);
14509 else if (TREE_CODE (TREE_TYPE (tem)) == ARRAY_TYPE
14510 && DECL_INITIAL (tem) != 0)
14511 expand_decl (tem);
5ff904cd
JL
14512 }
14513
c7e4ee3a 14514 if (DECL_INITIAL (tem) != NULL_TREE)
5ff904cd 14515 {
c7e4ee3a
CB
14516 /* When parsing and digesting the initializer, use temporary storage.
14517 Do this even if we will ignore the value. */
14518 if (at_top_level)
14519 temporary_allocation ();
5ff904cd 14520 }
c7e4ee3a
CB
14521
14522 return tem;
5ff904cd
JL
14523}
14524
c7e4ee3a
CB
14525/* Create the FUNCTION_DECL for a function definition.
14526 DECLSPECS and DECLARATOR are the parts of the declaration;
14527 they describe the function's name and the type it returns,
14528 but twisted together in a fashion that parallels the syntax of C.
5ff904cd 14529
c7e4ee3a
CB
14530 This function creates a binding context for the function body
14531 as well as setting up the FUNCTION_DECL in current_function_decl.
5ff904cd 14532
c7e4ee3a
CB
14533 Returns 1 on success. If the DECLARATOR is not suitable for a function
14534 (it defines a datum instead), we return 0, which tells
14535 yyparse to report a parse error.
5ff904cd 14536
c7e4ee3a
CB
14537 NESTED is nonzero for a function nested within another function. */
14538
14539static void
14540start_function (tree name, tree type, int nested, int public)
5ff904cd 14541{
c7e4ee3a
CB
14542 tree decl1;
14543 tree restype;
14544 int old_immediate_size_expand = immediate_size_expand;
5ff904cd 14545
c7e4ee3a
CB
14546 named_labels = 0;
14547 shadowed_labels = 0;
14548
14549 /* Don't expand any sizes in the return type of the function. */
14550 immediate_size_expand = 0;
14551
14552 if (nested)
5ff904cd 14553 {
c7e4ee3a
CB
14554 assert (!public);
14555 assert (current_function_decl != NULL_TREE);
14556 assert (DECL_CONTEXT (current_function_decl) == NULL_TREE);
14557 }
14558 else
14559 {
14560 assert (current_function_decl == NULL_TREE);
5ff904cd 14561 }
c7e4ee3a
CB
14562
14563 if (TREE_CODE (type) == ERROR_MARK)
14564 decl1 = current_function_decl = error_mark_node;
56a0044b 14565 else
5ff904cd 14566 {
c7e4ee3a
CB
14567 decl1 = build_decl (FUNCTION_DECL,
14568 name,
14569 type);
14570 TREE_PUBLIC (decl1) = public ? 1 : 0;
14571 if (nested)
14572 DECL_INLINE (decl1) = 1;
14573 TREE_STATIC (decl1) = 1;
14574 DECL_EXTERNAL (decl1) = 0;
5ff904cd 14575
c7e4ee3a 14576 announce_function (decl1);
5ff904cd 14577
c7e4ee3a
CB
14578 /* Make the init_value nonzero so pushdecl knows this is not tentative.
14579 error_mark_node is replaced below (in poplevel) with the BLOCK. */
14580 DECL_INITIAL (decl1) = error_mark_node;
5ff904cd 14581
c7e4ee3a
CB
14582 /* Record the decl so that the function name is defined. If we already have
14583 a decl for this name, and it is a FUNCTION_DECL, use the old decl. */
5ff904cd 14584
c7e4ee3a 14585 current_function_decl = pushdecl (decl1);
5ff904cd
JL
14586 }
14587
c7e4ee3a
CB
14588 if (!nested)
14589 ffecom_outer_function_decl_ = current_function_decl;
5ff904cd 14590
c7e4ee3a
CB
14591 pushlevel (0);
14592 current_binding_level->prep_state = 2;
5ff904cd 14593
c7e4ee3a
CB
14594 if (TREE_CODE (current_function_decl) != ERROR_MARK)
14595 {
14596 make_function_rtl (current_function_decl);
5ff904cd 14597
c7e4ee3a
CB
14598 restype = TREE_TYPE (TREE_TYPE (current_function_decl));
14599 DECL_RESULT (current_function_decl)
14600 = build_decl (RESULT_DECL, NULL_TREE, restype);
5ff904cd 14601 }
5ff904cd 14602
c7e4ee3a
CB
14603 if (!nested)
14604 /* Allocate further tree nodes temporarily during compilation of this
14605 function only. */
14606 temporary_allocation ();
5ff904cd 14607
c7e4ee3a
CB
14608 if (!nested && (TREE_CODE (current_function_decl) != ERROR_MARK))
14609 TREE_ADDRESSABLE (current_function_decl) = 1;
14610
14611 immediate_size_expand = old_immediate_size_expand;
14612}
14613\f
14614/* Here are the public functions the GNU back end needs. */
14615
14616tree
14617convert (type, expr)
14618 tree type, expr;
5ff904cd 14619{
c7e4ee3a
CB
14620 register tree e = expr;
14621 register enum tree_code code = TREE_CODE (type);
5ff904cd 14622
c7e4ee3a
CB
14623 if (type == TREE_TYPE (e)
14624 || TREE_CODE (e) == ERROR_MARK)
14625 return e;
14626 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
14627 return fold (build1 (NOP_EXPR, type, e));
14628 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
14629 || code == ERROR_MARK)
14630 return error_mark_node;
14631 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
14632 {
14633 assert ("void value not ignored as it ought to be" == NULL);
14634 return error_mark_node;
14635 }
14636 if (code == VOID_TYPE)
14637 return build1 (CONVERT_EXPR, type, e);
14638 if ((code != RECORD_TYPE)
14639 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
14640 e = ffecom_1 (REALPART_EXPR, TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e))),
14641 e);
14642 if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)
14643 return fold (convert_to_integer (type, e));
14644 if (code == POINTER_TYPE)
14645 return fold (convert_to_pointer (type, e));
14646 if (code == REAL_TYPE)
14647 return fold (convert_to_real (type, e));
14648 if (code == COMPLEX_TYPE)
14649 return fold (convert_to_complex (type, e));
14650 if (code == RECORD_TYPE)
14651 return fold (ffecom_convert_to_complex_ (type, e));
5ff904cd 14652
c7e4ee3a
CB
14653 assert ("conversion to non-scalar type requested" == NULL);
14654 return error_mark_node;
14655}
5ff904cd 14656
c7e4ee3a
CB
14657/* integrate_decl_tree calls this function, but since we don't use the
14658 DECL_LANG_SPECIFIC field, this is a no-op. */
5ff904cd 14659
c7e4ee3a
CB
14660void
14661copy_lang_decl (node)
14662 tree node UNUSED;
14663{
5ff904cd
JL
14664}
14665
c7e4ee3a
CB
14666/* Return the list of declarations of the current level.
14667 Note that this list is in reverse order unless/until
14668 you nreverse it; and when you do nreverse it, you must
14669 store the result back using `storedecls' or you will lose. */
5ff904cd 14670
c7e4ee3a
CB
14671tree
14672getdecls ()
5ff904cd 14673{
c7e4ee3a 14674 return current_binding_level->names;
5ff904cd
JL
14675}
14676
c7e4ee3a 14677/* Nonzero if we are currently in the global binding level. */
5ff904cd 14678
c7e4ee3a
CB
14679int
14680global_bindings_p ()
5ff904cd 14681{
c7e4ee3a
CB
14682 return current_binding_level == global_binding_level;
14683}
5ff904cd 14684
c7e4ee3a
CB
14685/* Print an error message for invalid use of an incomplete type.
14686 VALUE is the expression that was used (or 0 if that isn't known)
14687 and TYPE is the type that was invalid. */
5ff904cd 14688
c7e4ee3a
CB
14689void
14690incomplete_type_error (value, type)
14691 tree value UNUSED;
14692 tree type;
14693{
14694 if (TREE_CODE (type) == ERROR_MARK)
14695 return;
5ff904cd 14696
c7e4ee3a
CB
14697 assert ("incomplete type?!?" == NULL);
14698}
14699
7189a4b0
GK
14700/* Mark ARG for GC. */
14701static void
54551044 14702mark_binding_level (void *arg)
7189a4b0
GK
14703{
14704 struct binding_level *level = *(struct binding_level **) arg;
14705
14706 while (level)
14707 {
14708 ggc_mark_tree (level->names);
14709 ggc_mark_tree (level->blocks);
14710 ggc_mark_tree (level->this_block);
14711 level = level->level_chain;
14712 }
14713}
14714
c7e4ee3a
CB
14715void
14716init_decl_processing ()
5ff904cd 14717{
7189a4b0
GK
14718 static tree *const tree_roots[] = {
14719 &current_function_decl,
14720 &string_type_node,
14721 &ffecom_tree_fun_type_void,
14722 &ffecom_integer_zero_node,
14723 &ffecom_integer_one_node,
14724 &ffecom_tree_subr_type,
14725 &ffecom_tree_ptr_to_subr_type,
14726 &ffecom_tree_blockdata_type,
14727 &ffecom_tree_xargc_,
14728 &ffecom_f2c_integer_type_node,
14729 &ffecom_f2c_ptr_to_integer_type_node,
14730 &ffecom_f2c_address_type_node,
14731 &ffecom_f2c_real_type_node,
14732 &ffecom_f2c_ptr_to_real_type_node,
14733 &ffecom_f2c_doublereal_type_node,
14734 &ffecom_f2c_complex_type_node,
14735 &ffecom_f2c_doublecomplex_type_node,
14736 &ffecom_f2c_longint_type_node,
14737 &ffecom_f2c_logical_type_node,
14738 &ffecom_f2c_flag_type_node,
14739 &ffecom_f2c_ftnlen_type_node,
14740 &ffecom_f2c_ftnlen_zero_node,
14741 &ffecom_f2c_ftnlen_one_node,
14742 &ffecom_f2c_ftnlen_two_node,
14743 &ffecom_f2c_ptr_to_ftnlen_type_node,
14744 &ffecom_f2c_ftnint_type_node,
14745 &ffecom_f2c_ptr_to_ftnint_type_node,
14746 &ffecom_outer_function_decl_,
14747 &ffecom_previous_function_decl_,
14748 &ffecom_which_entrypoint_decl_,
14749 &ffecom_float_zero_,
14750 &ffecom_float_half_,
14751 &ffecom_double_zero_,
14752 &ffecom_double_half_,
14753 &ffecom_func_result_,
14754 &ffecom_func_length_,
14755 &ffecom_multi_type_node_,
14756 &ffecom_multi_retval_,
14757 &named_labels,
14758 &shadowed_labels
14759 };
14760 size_t i;
14761
c7e4ee3a 14762 malloc_init ();
7189a4b0
GK
14763
14764 /* Record our roots. */
14765 for (i = 0; i < sizeof(tree_roots)/sizeof(tree_roots[0]); i++)
14766 ggc_add_tree_root (tree_roots[i], 1);
14767 ggc_add_tree_root (&ffecom_tree_type[0][0],
14768 FFEINFO_basictype*FFEINFO_kindtype);
14769 ggc_add_tree_root (&ffecom_tree_fun_type[0][0],
14770 FFEINFO_basictype*FFEINFO_kindtype);
14771 ggc_add_tree_root (&ffecom_tree_ptr_to_fun_type[0][0],
14772 FFEINFO_basictype*FFEINFO_kindtype);
14773 ggc_add_tree_root (ffecom_gfrt_, FFECOM_gfrt);
14774 ggc_add_root (&current_binding_level, 1, sizeof current_binding_level,
14775 mark_binding_level);
14776 ggc_add_root (&free_binding_level, 1, sizeof current_binding_level,
14777 mark_binding_level);
14778 ggc_add_root (&tracker_head, 1, sizeof tracker_head, mark_tracker_head);
14779
c7e4ee3a
CB
14780 ffe_init_0 ();
14781}
5ff904cd 14782
3b304f5b 14783const char *
c7e4ee3a 14784init_parse (filename)
3b304f5b 14785 const char *filename;
c7e4ee3a 14786{
c7e4ee3a
CB
14787 /* Open input file. */
14788 if (filename == 0 || !strcmp (filename, "-"))
5ff904cd 14789 {
c7e4ee3a
CB
14790 finput = stdin;
14791 filename = "stdin";
5ff904cd 14792 }
c7e4ee3a
CB
14793 else
14794 finput = fopen (filename, "r");
14795 if (finput == 0)
14796 pfatal_with_name (filename);
5ff904cd 14797
c7e4ee3a
CB
14798#ifdef IO_BUFFER_SIZE
14799 setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
14800#endif
5ff904cd 14801
c7e4ee3a
CB
14802 /* Make identifier nodes long enough for the language-specific slots. */
14803 set_identifier_size (sizeof (struct lang_identifier));
14804 decl_printable_name = lang_printable_name;
14805#if BUILT_FOR_270
14806 print_error_function = lang_print_error_function;
14807#endif
5ff904cd 14808
c7e4ee3a
CB
14809 return filename;
14810}
5ff904cd 14811
c7e4ee3a
CB
14812void
14813finish_parse ()
14814{
14815 fclose (finput);
14816}
14817
14818/* Delete the node BLOCK from the current binding level.
14819 This is used for the block inside a stmt expr ({...})
14820 so that the block can be reinserted where appropriate. */
14821
14822static void
14823delete_block (block)
14824 tree block;
14825{
14826 tree t;
14827 if (current_binding_level->blocks == block)
14828 current_binding_level->blocks = TREE_CHAIN (block);
14829 for (t = current_binding_level->blocks; t;)
14830 {
14831 if (TREE_CHAIN (t) == block)
14832 TREE_CHAIN (t) = TREE_CHAIN (block);
14833 else
14834 t = TREE_CHAIN (t);
14835 }
14836 TREE_CHAIN (block) = NULL;
14837 /* Clear TREE_USED which is always set by poplevel.
14838 The flag is set again if insert_block is called. */
14839 TREE_USED (block) = 0;
14840}
14841
14842void
14843insert_block (block)
14844 tree block;
14845{
14846 TREE_USED (block) = 1;
14847 current_binding_level->blocks
14848 = chainon (current_binding_level->blocks, block);
14849}
14850
14851int
14852lang_decode_option (argc, argv)
14853 int argc;
14854 char **argv;
14855{
14856 return ffe_decode_option (argc, argv);
5ff904cd
JL
14857}
14858
c7e4ee3a 14859/* used by print-tree.c */
5ff904cd 14860
c7e4ee3a
CB
14861void
14862lang_print_xnode (file, node, indent)
14863 FILE *file UNUSED;
14864 tree node UNUSED;
14865 int indent UNUSED;
5ff904cd 14866{
c7e4ee3a 14867}
5ff904cd 14868
c7e4ee3a
CB
14869void
14870lang_finish ()
14871{
14872 ffe_terminate_0 ();
5ff904cd 14873
c7e4ee3a
CB
14874 if (ffe_is_ffedebug ())
14875 malloc_pool_display (malloc_pool_image ());
5ff904cd
JL
14876}
14877
dafbd854 14878const char *
c7e4ee3a 14879lang_identify ()
5ff904cd 14880{
c7e4ee3a
CB
14881 return "f77";
14882}
5ff904cd 14883
2e761e49
RH
14884/* Return the typed-based alias set for T, which may be an expression
14885 or a type. Return -1 if we don't do anything special. */
14886
14887HOST_WIDE_INT
14888lang_get_alias_set (t)
5ac9118e 14889 tree t ATTRIBUTE_UNUSED;
2e761e49
RH
14890{
14891 /* We do not wish to use alias-set based aliasing at all. Used in the
14892 extreme (every object with its own set, with equivalences recorded)
14893 it might be helpful, but there are problems when it comes to inlining.
14894 We get on ok with flag_argument_noalias, and alias-set aliasing does
14895 currently limit how stack slots can be reused, which is a lose. */
14896 return 0;
14897}
14898
c7e4ee3a
CB
14899void
14900lang_init_options ()
14901{
14902 /* Set default options for Fortran. */
14903 flag_move_all_movables = 1;
14904 flag_reduce_all_givs = 1;
14905 flag_argument_noalias = 2;
41af162c 14906 flag_errno_math = 0;
c64f913e 14907 flag_complex_divide_method = 1;
c7e4ee3a 14908}
5ff904cd 14909
c7e4ee3a
CB
14910void
14911lang_init ()
14912{
14913 /* If the file is output from cpp, it should contain a first line
14914 `# 1 "real-filename"', and the current design of gcc (toplev.c
14915 in particular and the way it sets up information relied on by
14916 INCLUDE) requires that we read this now, and store the
14917 "real-filename" info in master_input_filename. Ask the lexer
14918 to try doing this. */
14919 ffelex_hash_kludge (finput);
14920}
5ff904cd 14921
c7e4ee3a
CB
14922int
14923mark_addressable (exp)
14924 tree exp;
14925{
14926 register tree x = exp;
14927 while (1)
14928 switch (TREE_CODE (x))
14929 {
14930 case ADDR_EXPR:
14931 case COMPONENT_REF:
14932 case ARRAY_REF:
14933 x = TREE_OPERAND (x, 0);
14934 break;
5ff904cd 14935
c7e4ee3a
CB
14936 case CONSTRUCTOR:
14937 TREE_ADDRESSABLE (x) = 1;
14938 return 1;
5ff904cd 14939
c7e4ee3a
CB
14940 case VAR_DECL:
14941 case CONST_DECL:
14942 case PARM_DECL:
14943 case RESULT_DECL:
14944 if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
14945 && DECL_NONLOCAL (x))
14946 {
14947 if (TREE_PUBLIC (x))
14948 {
14949 assert ("address of global register var requested" == NULL);
14950 return 0;
14951 }
14952 assert ("address of register variable requested" == NULL);
14953 }
14954 else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x))
14955 {
14956 if (TREE_PUBLIC (x))
14957 {
14958 assert ("address of global register var requested" == NULL);
14959 return 0;
14960 }
14961 assert ("address of register var requested" == NULL);
14962 }
14963 put_var_into_stack (x);
5ff904cd 14964
c7e4ee3a
CB
14965 /* drops in */
14966 case FUNCTION_DECL:
14967 TREE_ADDRESSABLE (x) = 1;
14968#if 0 /* poplevel deals with this now. */
14969 if (DECL_CONTEXT (x) == 0)
14970 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (x)) = 1;
14971#endif
5ff904cd 14972
c7e4ee3a
CB
14973 default:
14974 return 1;
14975 }
5ff904cd
JL
14976}
14977
c7e4ee3a
CB
14978/* If DECL has a cleanup, build and return that cleanup here.
14979 This is a callback called by expand_expr. */
5ff904cd 14980
c7e4ee3a
CB
14981tree
14982maybe_build_cleanup (decl)
14983 tree decl UNUSED;
5ff904cd 14984{
c7e4ee3a
CB
14985 /* There are no cleanups in Fortran. */
14986 return NULL_TREE;
5ff904cd
JL
14987}
14988
c7e4ee3a
CB
14989/* Exit a binding level.
14990 Pop the level off, and restore the state of the identifier-decl mappings
14991 that were in effect when this level was entered.
5ff904cd 14992
c7e4ee3a
CB
14993 If KEEP is nonzero, this level had explicit declarations, so
14994 and create a "block" (a BLOCK node) for the level
14995 to record its declarations and subblocks for symbol table output.
5ff904cd 14996
c7e4ee3a
CB
14997 If FUNCTIONBODY is nonzero, this level is the body of a function,
14998 so create a block as if KEEP were set and also clear out all
14999 label names.
5ff904cd 15000
c7e4ee3a
CB
15001 If REVERSE is nonzero, reverse the order of decls before putting
15002 them into the BLOCK. */
5ff904cd 15003
c7e4ee3a
CB
15004tree
15005poplevel (keep, reverse, functionbody)
15006 int keep;
15007 int reverse;
15008 int functionbody;
5ff904cd 15009{
c7e4ee3a
CB
15010 register tree link;
15011 /* The chain of decls was accumulated in reverse order.
15012 Put it into forward order, just for cleanliness. */
15013 tree decls;
15014 tree subblocks = current_binding_level->blocks;
15015 tree block = 0;
15016 tree decl;
15017 int block_previously_created;
5ff904cd 15018
c7e4ee3a
CB
15019 /* Get the decls in the order they were written.
15020 Usually current_binding_level->names is in reverse order.
15021 But parameter decls were previously put in forward order. */
702edf1d 15022
c7e4ee3a
CB
15023 if (reverse)
15024 current_binding_level->names
15025 = decls = nreverse (current_binding_level->names);
15026 else
15027 decls = current_binding_level->names;
5ff904cd 15028
c7e4ee3a
CB
15029 /* Output any nested inline functions within this block
15030 if they weren't already output. */
5ff904cd 15031
c7e4ee3a
CB
15032 for (decl = decls; decl; decl = TREE_CHAIN (decl))
15033 if (TREE_CODE (decl) == FUNCTION_DECL
15034 && ! TREE_ASM_WRITTEN (decl)
15035 && DECL_INITIAL (decl) != 0
15036 && TREE_ADDRESSABLE (decl))
15037 {
15038 /* If this decl was copied from a file-scope decl
15039 on account of a block-scope extern decl,
15040 propagate TREE_ADDRESSABLE to the file-scope decl.
15041
15042 DECL_ABSTRACT_ORIGIN can be set to itself if warn_return_type is
15043 true, since then the decl goes through save_for_inline_copying. */
15044 if (DECL_ABSTRACT_ORIGIN (decl) != 0
15045 && DECL_ABSTRACT_ORIGIN (decl) != decl)
15046 TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1;
15047 else if (DECL_SAVED_INSNS (decl) != 0)
15048 {
15049 push_function_context ();
15050 output_inline_function (decl);
15051 pop_function_context ();
15052 }
15053 }
5ff904cd 15054
c7e4ee3a
CB
15055 /* If there were any declarations or structure tags in that level,
15056 or if this level is a function body,
15057 create a BLOCK to record them for the life of this function. */
5ff904cd 15058
c7e4ee3a
CB
15059 block = 0;
15060 block_previously_created = (current_binding_level->this_block != 0);
15061 if (block_previously_created)
15062 block = current_binding_level->this_block;
15063 else if (keep || functionbody)
15064 block = make_node (BLOCK);
15065 if (block != 0)
15066 {
15067 BLOCK_VARS (block) = decls;
15068 BLOCK_SUBBLOCKS (block) = subblocks;
c7e4ee3a 15069 }
5ff904cd 15070
c7e4ee3a 15071 /* In each subblock, record that this is its superior. */
5ff904cd 15072
c7e4ee3a
CB
15073 for (link = subblocks; link; link = TREE_CHAIN (link))
15074 BLOCK_SUPERCONTEXT (link) = block;
5ff904cd 15075
c7e4ee3a 15076 /* Clear out the meanings of the local variables of this level. */
5ff904cd 15077
c7e4ee3a 15078 for (link = decls; link; link = TREE_CHAIN (link))
5ff904cd 15079 {
c7e4ee3a
CB
15080 if (DECL_NAME (link) != 0)
15081 {
15082 /* If the ident. was used or addressed via a local extern decl,
15083 don't forget that fact. */
15084 if (DECL_EXTERNAL (link))
15085 {
15086 if (TREE_USED (link))
15087 TREE_USED (DECL_NAME (link)) = 1;
15088 if (TREE_ADDRESSABLE (link))
15089 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (link)) = 1;
15090 }
15091 IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = 0;
15092 }
5ff904cd 15093 }
5ff904cd 15094
c7e4ee3a
CB
15095 /* If the level being exited is the top level of a function,
15096 check over all the labels, and clear out the current
15097 (function local) meanings of their names. */
5ff904cd 15098
c7e4ee3a 15099 if (functionbody)
5ff904cd 15100 {
c7e4ee3a
CB
15101 /* If this is the top level block of a function,
15102 the vars are the function's parameters.
15103 Don't leave them in the BLOCK because they are
15104 found in the FUNCTION_DECL instead. */
15105
15106 BLOCK_VARS (block) = 0;
5ff904cd
JL
15107 }
15108
c7e4ee3a
CB
15109 /* Pop the current level, and free the structure for reuse. */
15110
15111 {
15112 register struct binding_level *level = current_binding_level;
15113 current_binding_level = current_binding_level->level_chain;
15114
15115 level->level_chain = free_binding_level;
15116 free_binding_level = level;
15117 }
15118
15119 /* Dispose of the block that we just made inside some higher level. */
15120 if (functionbody
15121 && current_function_decl != error_mark_node)
15122 DECL_INITIAL (current_function_decl) = block;
15123 else if (block)
5ff904cd 15124 {
c7e4ee3a
CB
15125 if (!block_previously_created)
15126 current_binding_level->blocks
15127 = chainon (current_binding_level->blocks, block);
5ff904cd 15128 }
c7e4ee3a
CB
15129 /* If we did not make a block for the level just exited,
15130 any blocks made for inner levels
15131 (since they cannot be recorded as subblocks in that level)
15132 must be carried forward so they will later become subblocks
15133 of something else. */
15134 else if (subblocks)
15135 current_binding_level->blocks
15136 = chainon (current_binding_level->blocks, subblocks);
5ff904cd 15137
c7e4ee3a
CB
15138 if (block)
15139 TREE_USED (block) = 1;
15140 return block;
5ff904cd
JL
15141}
15142
c7e4ee3a
CB
15143void
15144print_lang_decl (file, node, indent)
15145 FILE *file UNUSED;
15146 tree node UNUSED;
15147 int indent UNUSED;
15148{
15149}
5ff904cd 15150
c7e4ee3a
CB
15151void
15152print_lang_identifier (file, node, indent)
15153 FILE *file;
15154 tree node;
15155 int indent;
15156{
15157 print_node (file, "global", IDENTIFIER_GLOBAL_VALUE (node), indent + 4);
15158 print_node (file, "local", IDENTIFIER_LOCAL_VALUE (node), indent + 4);
15159}
5ff904cd 15160
c7e4ee3a
CB
15161void
15162print_lang_statistics ()
15163{
15164}
5ff904cd 15165
c7e4ee3a
CB
15166void
15167print_lang_type (file, node, indent)
15168 FILE *file UNUSED;
15169 tree node UNUSED;
15170 int indent UNUSED;
5ff904cd 15171{
c7e4ee3a 15172}
5ff904cd 15173
c7e4ee3a
CB
15174/* Record a decl-node X as belonging to the current lexical scope.
15175 Check for errors (such as an incompatible declaration for the same
15176 name already seen in the same scope).
5ff904cd 15177
c7e4ee3a
CB
15178 Returns either X or an old decl for the same name.
15179 If an old decl is returned, it may have been smashed
15180 to agree with what X says. */
5ff904cd 15181
c7e4ee3a
CB
15182tree
15183pushdecl (x)
15184 tree x;
15185{
15186 register tree t;
15187 register tree name = DECL_NAME (x);
15188 register struct binding_level *b = current_binding_level;
5ff904cd 15189
c7e4ee3a
CB
15190 if ((TREE_CODE (x) == FUNCTION_DECL)
15191 && (DECL_INITIAL (x) == 0)
15192 && DECL_EXTERNAL (x))
15193 DECL_CONTEXT (x) = NULL_TREE;
56a0044b 15194 else
c7e4ee3a
CB
15195 DECL_CONTEXT (x) = current_function_decl;
15196
15197 if (name)
56a0044b 15198 {
c7e4ee3a
CB
15199 if (IDENTIFIER_INVENTED (name))
15200 {
15201#if BUILT_FOR_270
15202 DECL_ARTIFICIAL (x) = 1;
15203#endif
15204 DECL_IN_SYSTEM_HEADER (x) = 1;
15205 }
5ff904cd 15206
c7e4ee3a 15207 t = lookup_name_current_level (name);
5ff904cd 15208
c7e4ee3a 15209 assert ((t == NULL_TREE) || (DECL_CONTEXT (x) == NULL_TREE));
5ff904cd 15210
c7e4ee3a
CB
15211 /* Don't push non-parms onto list for parms until we understand
15212 why we're doing this and whether it works. */
56a0044b 15213
c7e4ee3a
CB
15214 assert ((b == global_binding_level)
15215 || !ffecom_transform_only_dummies_
15216 || TREE_CODE (x) == PARM_DECL);
5ff904cd 15217
c7e4ee3a
CB
15218 if ((t != NULL_TREE) && duplicate_decls (x, t))
15219 return t;
5ff904cd 15220
c7e4ee3a
CB
15221 /* If we are processing a typedef statement, generate a whole new
15222 ..._TYPE node (which will be just an variant of the existing
15223 ..._TYPE node with identical properties) and then install the
15224 TYPE_DECL node generated to represent the typedef name as the
15225 TYPE_NAME of this brand new (duplicate) ..._TYPE node.
5ff904cd 15226
c7e4ee3a
CB
15227 The whole point here is to end up with a situation where each and every
15228 ..._TYPE node the compiler creates will be uniquely associated with
15229 AT MOST one node representing a typedef name. This way, even though
15230 the compiler substitutes corresponding ..._TYPE nodes for TYPE_DECL
15231 (i.e. "typedef name") nodes very early on, later parts of the
15232 compiler can always do the reverse translation and get back the
15233 corresponding typedef name. For example, given:
5ff904cd 15234
c7e4ee3a 15235 typedef struct S MY_TYPE; MY_TYPE object;
5ff904cd 15236
c7e4ee3a
CB
15237 Later parts of the compiler might only know that `object' was of type
15238 `struct S' if it were not for code just below. With this code
15239 however, later parts of the compiler see something like:
5ff904cd 15240
c7e4ee3a 15241 struct S' == struct S typedef struct S' MY_TYPE; struct S' object;
5ff904cd 15242
c7e4ee3a
CB
15243 And they can then deduce (from the node for type struct S') that the
15244 original object declaration was:
5ff904cd 15245
c7e4ee3a 15246 MY_TYPE object;
5ff904cd 15247
c7e4ee3a
CB
15248 Being able to do this is important for proper support of protoize, and
15249 also for generating precise symbolic debugging information which
15250 takes full account of the programmer's (typedef) vocabulary.
5ff904cd 15251
c7e4ee3a
CB
15252 Obviously, we don't want to generate a duplicate ..._TYPE node if the
15253 TYPE_DECL node that we are now processing really represents a
15254 standard built-in type.
5ff904cd 15255
c7e4ee3a
CB
15256 Since all standard types are effectively declared at line zero in the
15257 source file, we can easily check to see if we are working on a
15258 standard type by checking the current value of lineno. */
15259
15260 if (TREE_CODE (x) == TYPE_DECL)
15261 {
15262 if (DECL_SOURCE_LINE (x) == 0)
15263 {
15264 if (TYPE_NAME (TREE_TYPE (x)) == 0)
15265 TYPE_NAME (TREE_TYPE (x)) = x;
15266 }
15267 else if (TREE_TYPE (x) != error_mark_node)
15268 {
15269 tree tt = TREE_TYPE (x);
15270
15271 tt = build_type_copy (tt);
15272 TYPE_NAME (tt) = x;
15273 TREE_TYPE (x) = tt;
15274 }
15275 }
5ff904cd 15276
c7e4ee3a
CB
15277 /* This name is new in its binding level. Install the new declaration
15278 and return it. */
15279 if (b == global_binding_level)
15280 IDENTIFIER_GLOBAL_VALUE (name) = x;
15281 else
15282 IDENTIFIER_LOCAL_VALUE (name) = x;
15283 }
5ff904cd 15284
c7e4ee3a
CB
15285 /* Put decls on list in reverse order. We will reverse them later if
15286 necessary. */
15287 TREE_CHAIN (x) = b->names;
15288 b->names = x;
5ff904cd 15289
c7e4ee3a 15290 return x;
5ff904cd
JL
15291}
15292
c7e4ee3a 15293/* Nonzero if the current level needs to have a BLOCK made. */
5ff904cd 15294
c7e4ee3a
CB
15295static int
15296kept_level_p ()
5ff904cd 15297{
c7e4ee3a
CB
15298 tree decl;
15299
15300 for (decl = current_binding_level->names;
15301 decl;
15302 decl = TREE_CHAIN (decl))
15303 {
15304 if (TREE_USED (decl) || TREE_CODE (decl) != VAR_DECL
15305 || (DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl)))
15306 /* Currently, there aren't supposed to be non-artificial names
15307 at other than the top block for a function -- they're
15308 believed to always be temps. But it's wise to check anyway. */
15309 return 1;
15310 }
15311 return 0;
5ff904cd
JL
15312}
15313
c7e4ee3a
CB
15314/* Enter a new binding level.
15315 If TAG_TRANSPARENT is nonzero, do so only for the name space of variables,
15316 not for that of tags. */
5ff904cd
JL
15317
15318void
c7e4ee3a
CB
15319pushlevel (tag_transparent)
15320 int tag_transparent;
5ff904cd 15321{
c7e4ee3a 15322 register struct binding_level *newlevel = NULL_BINDING_LEVEL;
5ff904cd 15323
c7e4ee3a 15324 assert (! tag_transparent);
5ff904cd 15325
c7e4ee3a
CB
15326 if (current_binding_level == global_binding_level)
15327 {
15328 named_labels = 0;
15329 }
5ff904cd 15330
c7e4ee3a 15331 /* Reuse or create a struct for this binding level. */
5ff904cd 15332
c7e4ee3a 15333 if (free_binding_level)
77f77701 15334 {
c7e4ee3a
CB
15335 newlevel = free_binding_level;
15336 free_binding_level = free_binding_level->level_chain;
77f77701
DB
15337 }
15338 else
c7e4ee3a
CB
15339 {
15340 newlevel = make_binding_level ();
15341 }
77f77701 15342
c7e4ee3a
CB
15343 /* Add this level to the front of the chain (stack) of levels that
15344 are active. */
71b5e532 15345
c7e4ee3a
CB
15346 *newlevel = clear_binding_level;
15347 newlevel->level_chain = current_binding_level;
15348 current_binding_level = newlevel;
5ff904cd
JL
15349}
15350
c7e4ee3a
CB
15351/* Set the BLOCK node for the innermost scope
15352 (the one we are currently in). */
77f77701 15353
5ff904cd 15354void
c7e4ee3a
CB
15355set_block (block)
15356 register tree block;
5ff904cd 15357{
c7e4ee3a 15358 current_binding_level->this_block = block;
5ff904cd
JL
15359}
15360
c7e4ee3a 15361/* ~~gcc/tree.h *should* declare this, because toplev.c references it. */
5ff904cd 15362
c7e4ee3a 15363/* Can't 'yydebug' a front end not generated by yacc/bison! */
bc289659
ML
15364
15365void
c7e4ee3a
CB
15366set_yydebug (value)
15367 int value;
bc289659 15368{
c7e4ee3a
CB
15369 if (value)
15370 fprintf (stderr, "warning: no yacc/bison-generated output to debug!\n");
bc289659
ML
15371}
15372
c7e4ee3a
CB
15373tree
15374signed_or_unsigned_type (unsignedp, type)
15375 int unsignedp;
15376 tree type;
5ff904cd 15377{
c7e4ee3a 15378 tree type2;
5ff904cd 15379
c7e4ee3a
CB
15380 if (! INTEGRAL_TYPE_P (type))
15381 return type;
15382 if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node))
15383 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
15384 if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
15385 return unsignedp ? unsigned_type_node : integer_type_node;
15386 if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node))
15387 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
15388 if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node))
15389 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
15390 if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node))
15391 return (unsignedp ? long_long_unsigned_type_node
15392 : long_long_integer_type_node);
5ff904cd 15393
c7e4ee3a
CB
15394 type2 = type_for_size (TYPE_PRECISION (type), unsignedp);
15395 if (type2 == NULL_TREE)
15396 return type;
f84639ba 15397
c7e4ee3a 15398 return type2;
5ff904cd
JL
15399}
15400
c7e4ee3a
CB
15401tree
15402signed_type (type)
15403 tree type;
5ff904cd 15404{
c7e4ee3a
CB
15405 tree type1 = TYPE_MAIN_VARIANT (type);
15406 ffeinfoKindtype kt;
15407 tree type2;
5ff904cd 15408
c7e4ee3a
CB
15409 if (type1 == unsigned_char_type_node || type1 == char_type_node)
15410 return signed_char_type_node;
15411 if (type1 == unsigned_type_node)
15412 return integer_type_node;
15413 if (type1 == short_unsigned_type_node)
15414 return short_integer_type_node;
15415 if (type1 == long_unsigned_type_node)
15416 return long_integer_type_node;
15417 if (type1 == long_long_unsigned_type_node)
15418 return long_long_integer_type_node;
15419#if 0 /* gcc/c-* files only */
15420 if (type1 == unsigned_intDI_type_node)
15421 return intDI_type_node;
15422 if (type1 == unsigned_intSI_type_node)
15423 return intSI_type_node;
15424 if (type1 == unsigned_intHI_type_node)
15425 return intHI_type_node;
15426 if (type1 == unsigned_intQI_type_node)
15427 return intQI_type_node;
15428#endif
5ff904cd 15429
c7e4ee3a
CB
15430 type2 = type_for_size (TYPE_PRECISION (type1), 0);
15431 if (type2 != NULL_TREE)
15432 return type2;
5ff904cd 15433
c7e4ee3a
CB
15434 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
15435 {
15436 type2 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
5ff904cd 15437
c7e4ee3a
CB
15438 if (type1 == type2)
15439 return ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
15440 }
15441
15442 return type;
5ff904cd
JL
15443}
15444
c7e4ee3a
CB
15445/* Prepare expr to be an argument of a TRUTH_NOT_EXPR,
15446 or validate its data type for an `if' or `while' statement or ?..: exp.
15447
15448 This preparation consists of taking the ordinary
15449 representation of an expression expr and producing a valid tree
15450 boolean expression describing whether expr is nonzero. We could
15451 simply always do build_binary_op (NE_EXPR, expr, integer_zero_node, 1),
15452 but we optimize comparisons, &&, ||, and !.
15453
15454 The resulting type should always be `integer_type_node'. */
5ff904cd
JL
15455
15456tree
c7e4ee3a
CB
15457truthvalue_conversion (expr)
15458 tree expr;
5ff904cd 15459{
c7e4ee3a
CB
15460 if (TREE_CODE (expr) == ERROR_MARK)
15461 return expr;
5ff904cd 15462
c7e4ee3a
CB
15463#if 0 /* This appears to be wrong for C++. */
15464 /* These really should return error_mark_node after 2.4 is stable.
15465 But not all callers handle ERROR_MARK properly. */
15466 switch (TREE_CODE (TREE_TYPE (expr)))
15467 {
15468 case RECORD_TYPE:
15469 error ("struct type value used where scalar is required");
15470 return integer_zero_node;
5ff904cd 15471
c7e4ee3a
CB
15472 case UNION_TYPE:
15473 error ("union type value used where scalar is required");
15474 return integer_zero_node;
5ff904cd 15475
c7e4ee3a
CB
15476 case ARRAY_TYPE:
15477 error ("array type value used where scalar is required");
15478 return integer_zero_node;
5ff904cd 15479
c7e4ee3a
CB
15480 default:
15481 break;
15482 }
15483#endif /* 0 */
5ff904cd 15484
c7e4ee3a
CB
15485 switch (TREE_CODE (expr))
15486 {
15487 /* It is simpler and generates better code to have only TRUTH_*_EXPR
15488 or comparison expressions as truth values at this level. */
15489#if 0
15490 case COMPONENT_REF:
15491 /* A one-bit unsigned bit-field is already acceptable. */
15492 if (1 == TREE_INT_CST_LOW (DECL_SIZE (TREE_OPERAND (expr, 1)))
15493 && TREE_UNSIGNED (TREE_OPERAND (expr, 1)))
15494 return expr;
15495 break;
15496#endif
15497
15498 case EQ_EXPR:
15499 /* It is simpler and generates better code to have only TRUTH_*_EXPR
15500 or comparison expressions as truth values at this level. */
15501#if 0
15502 if (integer_zerop (TREE_OPERAND (expr, 1)))
15503 return build_unary_op (TRUTH_NOT_EXPR, TREE_OPERAND (expr, 0), 0);
15504#endif
15505 case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
15506 case TRUTH_ANDIF_EXPR:
15507 case TRUTH_ORIF_EXPR:
15508 case TRUTH_AND_EXPR:
15509 case TRUTH_OR_EXPR:
15510 case TRUTH_XOR_EXPR:
15511 TREE_TYPE (expr) = integer_type_node;
15512 return expr;
5ff904cd 15513
c7e4ee3a
CB
15514 case ERROR_MARK:
15515 return expr;
5ff904cd 15516
c7e4ee3a
CB
15517 case INTEGER_CST:
15518 return integer_zerop (expr) ? integer_zero_node : integer_one_node;
5ff904cd 15519
c7e4ee3a
CB
15520 case REAL_CST:
15521 return real_zerop (expr) ? integer_zero_node : integer_one_node;
5ff904cd 15522
c7e4ee3a
CB
15523 case ADDR_EXPR:
15524 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 0)))
15525 return build (COMPOUND_EXPR, integer_type_node,
15526 TREE_OPERAND (expr, 0), integer_one_node);
15527 else
15528 return integer_one_node;
5ff904cd 15529
c7e4ee3a
CB
15530 case COMPLEX_EXPR:
15531 return ffecom_2 ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))
15532 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
15533 integer_type_node,
15534 truthvalue_conversion (TREE_OPERAND (expr, 0)),
15535 truthvalue_conversion (TREE_OPERAND (expr, 1)));
5ff904cd 15536
c7e4ee3a
CB
15537 case NEGATE_EXPR:
15538 case ABS_EXPR:
15539 case FLOAT_EXPR:
15540 case FFS_EXPR:
15541 /* These don't change whether an object is non-zero or zero. */
15542 return truthvalue_conversion (TREE_OPERAND (expr, 0));
5ff904cd 15543
c7e4ee3a
CB
15544 case LROTATE_EXPR:
15545 case RROTATE_EXPR:
15546 /* These don't change whether an object is zero or non-zero, but
15547 we can't ignore them if their second arg has side-effects. */
15548 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)))
15549 return build (COMPOUND_EXPR, integer_type_node, TREE_OPERAND (expr, 1),
15550 truthvalue_conversion (TREE_OPERAND (expr, 0)));
15551 else
15552 return truthvalue_conversion (TREE_OPERAND (expr, 0));
5ff904cd 15553
c7e4ee3a
CB
15554 case COND_EXPR:
15555 /* Distribute the conversion into the arms of a COND_EXPR. */
15556 return fold (build (COND_EXPR, integer_type_node, TREE_OPERAND (expr, 0),
15557 truthvalue_conversion (TREE_OPERAND (expr, 1)),
15558 truthvalue_conversion (TREE_OPERAND (expr, 2))));
5ff904cd 15559
c7e4ee3a
CB
15560 case CONVERT_EXPR:
15561 /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
15562 since that affects how `default_conversion' will behave. */
15563 if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE
15564 || TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)
15565 break;
15566 /* fall through... */
15567 case NOP_EXPR:
15568 /* If this is widening the argument, we can ignore it. */
15569 if (TYPE_PRECISION (TREE_TYPE (expr))
15570 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
15571 return truthvalue_conversion (TREE_OPERAND (expr, 0));
15572 break;
5ff904cd 15573
c7e4ee3a
CB
15574 case MINUS_EXPR:
15575 /* With IEEE arithmetic, x - x may not equal 0, so we can't optimize
15576 this case. */
15577 if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
15578 && TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE)
15579 break;
15580 /* fall through... */
15581 case BIT_XOR_EXPR:
15582 /* This and MINUS_EXPR can be changed into a comparison of the
15583 two objects. */
15584 if (TREE_TYPE (TREE_OPERAND (expr, 0))
15585 == TREE_TYPE (TREE_OPERAND (expr, 1)))
15586 return ffecom_2 (NE_EXPR, integer_type_node,
15587 TREE_OPERAND (expr, 0),
15588 TREE_OPERAND (expr, 1));
15589 return ffecom_2 (NE_EXPR, integer_type_node,
15590 TREE_OPERAND (expr, 0),
15591 fold (build1 (NOP_EXPR,
15592 TREE_TYPE (TREE_OPERAND (expr, 0)),
15593 TREE_OPERAND (expr, 1))));
15594
15595 case BIT_AND_EXPR:
15596 if (integer_onep (TREE_OPERAND (expr, 1)))
15597 return expr;
15598 break;
15599
15600 case MODIFY_EXPR:
15601#if 0 /* No such thing in Fortran. */
15602 if (warn_parentheses && C_EXP_ORIGINAL_CODE (expr) == MODIFY_EXPR)
15603 warning ("suggest parentheses around assignment used as truth value");
15604#endif
15605 break;
15606
15607 default:
15608 break;
5ff904cd
JL
15609 }
15610
c7e4ee3a
CB
15611 if (TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE)
15612 return (ffecom_2
15613 ((TREE_SIDE_EFFECTS (expr)
15614 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
15615 integer_type_node,
15616 truthvalue_conversion (ffecom_1 (REALPART_EXPR,
15617 TREE_TYPE (TREE_TYPE (expr)),
15618 expr)),
15619 truthvalue_conversion (ffecom_1 (IMAGPART_EXPR,
15620 TREE_TYPE (TREE_TYPE (expr)),
15621 expr))));
15622
15623 return ffecom_2 (NE_EXPR, integer_type_node,
15624 expr,
15625 convert (TREE_TYPE (expr), integer_zero_node));
15626}
15627
15628tree
15629type_for_mode (mode, unsignedp)
15630 enum machine_mode mode;
15631 int unsignedp;
15632{
15633 int i;
15634 int j;
15635 tree t;
5ff904cd 15636
c7e4ee3a
CB
15637 if (mode == TYPE_MODE (integer_type_node))
15638 return unsignedp ? unsigned_type_node : integer_type_node;
5ff904cd 15639
c7e4ee3a
CB
15640 if (mode == TYPE_MODE (signed_char_type_node))
15641 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
5ff904cd 15642
c7e4ee3a
CB
15643 if (mode == TYPE_MODE (short_integer_type_node))
15644 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
5ff904cd 15645
c7e4ee3a
CB
15646 if (mode == TYPE_MODE (long_integer_type_node))
15647 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
5ff904cd 15648
c7e4ee3a
CB
15649 if (mode == TYPE_MODE (long_long_integer_type_node))
15650 return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node;
5ff904cd 15651
fed3cef0
RK
15652#if HOST_BITS_PER_WIDE_INT >= 64
15653 if (mode == TYPE_MODE (intTI_type_node))
15654 return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
15655#endif
15656
c7e4ee3a
CB
15657 if (mode == TYPE_MODE (float_type_node))
15658 return float_type_node;
5ff904cd 15659
c7e4ee3a
CB
15660 if (mode == TYPE_MODE (double_type_node))
15661 return double_type_node;
5ff904cd 15662
c7e4ee3a
CB
15663 if (mode == TYPE_MODE (build_pointer_type (char_type_node)))
15664 return build_pointer_type (char_type_node);
5ff904cd 15665
c7e4ee3a
CB
15666 if (mode == TYPE_MODE (build_pointer_type (integer_type_node)))
15667 return build_pointer_type (integer_type_node);
5ff904cd 15668
c7e4ee3a
CB
15669 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
15670 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
15671 {
15672 if (((t = ffecom_tree_type[i][j]) != NULL_TREE)
15673 && (mode == TYPE_MODE (t)))
15674 {
15675 if ((i == FFEINFO_basictypeINTEGER) && unsignedp)
15676 return ffecom_tree_type[FFEINFO_basictypeHOLLERITH][j];
15677 else
15678 return t;
15679 }
15680 }
5ff904cd 15681
c7e4ee3a 15682 return 0;
5ff904cd
JL
15683}
15684
c7e4ee3a
CB
15685tree
15686type_for_size (bits, unsignedp)
15687 unsigned bits;
15688 int unsignedp;
5ff904cd 15689{
c7e4ee3a
CB
15690 ffeinfoKindtype kt;
15691 tree type_node;
5ff904cd 15692
c7e4ee3a
CB
15693 if (bits == TYPE_PRECISION (integer_type_node))
15694 return unsignedp ? unsigned_type_node : integer_type_node;
5ff904cd 15695
c7e4ee3a
CB
15696 if (bits == TYPE_PRECISION (signed_char_type_node))
15697 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
5ff904cd 15698
c7e4ee3a
CB
15699 if (bits == TYPE_PRECISION (short_integer_type_node))
15700 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
5ff904cd 15701
c7e4ee3a
CB
15702 if (bits == TYPE_PRECISION (long_integer_type_node))
15703 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
5ff904cd 15704
c7e4ee3a
CB
15705 if (bits == TYPE_PRECISION (long_long_integer_type_node))
15706 return (unsignedp ? long_long_unsigned_type_node
15707 : long_long_integer_type_node);
5ff904cd 15708
c7e4ee3a 15709 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
5ff904cd 15710 {
c7e4ee3a 15711 type_node = ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
5ff904cd 15712
c7e4ee3a
CB
15713 if ((type_node != NULL_TREE) && (bits == TYPE_PRECISION (type_node)))
15714 return unsignedp ? ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt]
15715 : type_node;
15716 }
5ff904cd 15717
c7e4ee3a
CB
15718 return 0;
15719}
5ff904cd 15720
c7e4ee3a
CB
15721tree
15722unsigned_type (type)
15723 tree type;
15724{
15725 tree type1 = TYPE_MAIN_VARIANT (type);
15726 ffeinfoKindtype kt;
15727 tree type2;
5ff904cd 15728
c7e4ee3a
CB
15729 if (type1 == signed_char_type_node || type1 == char_type_node)
15730 return unsigned_char_type_node;
15731 if (type1 == integer_type_node)
15732 return unsigned_type_node;
15733 if (type1 == short_integer_type_node)
15734 return short_unsigned_type_node;
15735 if (type1 == long_integer_type_node)
15736 return long_unsigned_type_node;
15737 if (type1 == long_long_integer_type_node)
15738 return long_long_unsigned_type_node;
15739#if 0 /* gcc/c-* files only */
15740 if (type1 == intDI_type_node)
15741 return unsigned_intDI_type_node;
15742 if (type1 == intSI_type_node)
15743 return unsigned_intSI_type_node;
15744 if (type1 == intHI_type_node)
15745 return unsigned_intHI_type_node;
15746 if (type1 == intQI_type_node)
15747 return unsigned_intQI_type_node;
15748#endif
5ff904cd 15749
c7e4ee3a
CB
15750 type2 = type_for_size (TYPE_PRECISION (type1), 1);
15751 if (type2 != NULL_TREE)
15752 return type2;
5ff904cd 15753
c7e4ee3a
CB
15754 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
15755 {
15756 type2 = ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
5ff904cd 15757
c7e4ee3a
CB
15758 if (type1 == type2)
15759 return ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
15760 }
5ff904cd 15761
c7e4ee3a
CB
15762 return type;
15763}
5ff904cd 15764
7189a4b0
GK
15765/* Callback routines for garbage collection. */
15766
15767int ggc_p = 1;
15768
15769void
15770lang_mark_tree (t)
15771 union tree_node *t ATTRIBUTE_UNUSED;
15772{
15773 if (TREE_CODE (t) == IDENTIFIER_NODE)
15774 {
15775 struct lang_identifier *i = (struct lang_identifier *) t;
15776 ggc_mark_tree (IDENTIFIER_GLOBAL_VALUE (i));
15777 ggc_mark_tree (IDENTIFIER_LOCAL_VALUE (i));
15778 ggc_mark_tree (IDENTIFIER_LABEL_VALUE (i));
15779 }
15780 else if (TYPE_P (t) && TYPE_LANG_SPECIFIC (t))
15781 ggc_mark (TYPE_LANG_SPECIFIC (t));
15782}
15783
15784void
15785lang_mark_false_label_stack (l)
15786 struct label_node *l;
15787{
15788 /* Fortran doesn't use false_label_stack. It better be NULL. */
15789 if (l != NULL)
15790 abort();
15791}
15792
c7e4ee3a
CB
15793#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
15794\f
15795#if FFECOM_GCC_INCLUDE
5ff904cd 15796
c7e4ee3a 15797/* From gcc/cccp.c, the code to handle -I. */
5ff904cd 15798
c7e4ee3a
CB
15799/* Skip leading "./" from a directory name.
15800 This may yield the empty string, which represents the current directory. */
5ff904cd 15801
c7e4ee3a
CB
15802static const char *
15803skip_redundant_dir_prefix (const char *dir)
15804{
15805 while (dir[0] == '.' && dir[1] == '/')
15806 for (dir += 2; *dir == '/'; dir++)
15807 continue;
15808 if (dir[0] == '.' && !dir[1])
15809 dir++;
15810 return dir;
15811}
5ff904cd 15812
c7e4ee3a
CB
15813/* The file_name_map structure holds a mapping of file names for a
15814 particular directory. This mapping is read from the file named
15815 FILE_NAME_MAP_FILE in that directory. Such a file can be used to
15816 map filenames on a file system with severe filename restrictions,
15817 such as DOS. The format of the file name map file is just a series
15818 of lines with two tokens on each line. The first token is the name
15819 to map, and the second token is the actual name to use. */
5ff904cd 15820
c7e4ee3a
CB
15821struct file_name_map
15822{
15823 struct file_name_map *map_next;
15824 char *map_from;
15825 char *map_to;
15826};
5ff904cd 15827
c7e4ee3a 15828#define FILE_NAME_MAP_FILE "header.gcc"
5ff904cd 15829
c7e4ee3a
CB
15830/* Current maximum length of directory names in the search path
15831 for include files. (Altered as we get more of them.) */
5ff904cd 15832
c7e4ee3a 15833static int max_include_len = 0;
5ff904cd 15834
c7e4ee3a
CB
15835struct file_name_list
15836 {
15837 struct file_name_list *next;
15838 char *fname;
15839 /* Mapping of file names for this directory. */
15840 struct file_name_map *name_map;
15841 /* Non-zero if name_map is valid. */
15842 int got_name_map;
15843 };
5ff904cd 15844
c7e4ee3a
CB
15845static struct file_name_list *include = NULL; /* First dir to search */
15846static struct file_name_list *last_include = NULL; /* Last in chain */
5ff904cd 15847
c7e4ee3a
CB
15848/* I/O buffer structure.
15849 The `fname' field is nonzero for source files and #include files
15850 and for the dummy text used for -D and -U.
15851 It is zero for rescanning results of macro expansion
15852 and for expanding macro arguments. */
15853#define INPUT_STACK_MAX 400
15854static struct file_buf {
b0791fa9 15855 const char *fname;
c7e4ee3a 15856 /* Filename specified with #line command. */
b0791fa9 15857 const char *nominal_fname;
c7e4ee3a
CB
15858 /* Record where in the search path this file was found.
15859 For #include_next. */
15860 struct file_name_list *dir;
15861 ffewhereLine line;
15862 ffewhereColumn column;
15863} instack[INPUT_STACK_MAX];
5ff904cd 15864
c7e4ee3a
CB
15865static int last_error_tick = 0; /* Incremented each time we print it. */
15866static int input_file_stack_tick = 0; /* Incremented when status changes. */
5ff904cd 15867
c7e4ee3a
CB
15868/* Current nesting level of input sources.
15869 `instack[indepth]' is the level currently being read. */
15870static int indepth = -1;
5ff904cd 15871
c7e4ee3a 15872typedef struct file_buf FILE_BUF;
5ff904cd 15873
c7e4ee3a 15874typedef unsigned char U_CHAR;
5ff904cd 15875
c7e4ee3a
CB
15876/* table to tell if char can be part of a C identifier. */
15877U_CHAR is_idchar[256];
15878/* table to tell if char can be first char of a c identifier. */
15879U_CHAR is_idstart[256];
15880/* table to tell if c is horizontal space. */
15881U_CHAR is_hor_space[256];
15882/* table to tell if c is horizontal or vertical space. */
15883static U_CHAR is_space[256];
5ff904cd 15884
c7e4ee3a
CB
15885#define SKIP_WHITE_SPACE(p) do { while (is_hor_space[*p]) p++; } while (0)
15886#define SKIP_ALL_WHITE_SPACE(p) do { while (is_space[*p]) p++; } while (0)
5ff904cd 15887
c7e4ee3a
CB
15888/* Nonzero means -I- has been seen,
15889 so don't look for #include "foo" the source-file directory. */
15890static int ignore_srcdir;
5ff904cd 15891
c7e4ee3a
CB
15892#ifndef INCLUDE_LEN_FUDGE
15893#define INCLUDE_LEN_FUDGE 0
15894#endif
5ff904cd 15895
c7e4ee3a
CB
15896static void append_include_chain (struct file_name_list *first,
15897 struct file_name_list *last);
15898static FILE *open_include_file (char *filename,
15899 struct file_name_list *searchptr);
15900static void print_containing_files (ffebadSeverity sev);
15901static const char *skip_redundant_dir_prefix (const char *);
15902static char *read_filename_string (int ch, FILE *f);
15903static struct file_name_map *read_name_map (const char *dirname);
5ff904cd 15904
c7e4ee3a
CB
15905/* Append a chain of `struct file_name_list's
15906 to the end of the main include chain.
15907 FIRST is the beginning of the chain to append, and LAST is the end. */
5ff904cd 15908
c7e4ee3a
CB
15909static void
15910append_include_chain (first, last)
15911 struct file_name_list *first, *last;
5ff904cd 15912{
c7e4ee3a 15913 struct file_name_list *dir;
5ff904cd 15914
c7e4ee3a
CB
15915 if (!first || !last)
15916 return;
5ff904cd 15917
c7e4ee3a
CB
15918 if (include == 0)
15919 include = first;
15920 else
15921 last_include->next = first;
5ff904cd 15922
c7e4ee3a
CB
15923 for (dir = first; ; dir = dir->next) {
15924 int len = strlen (dir->fname) + INCLUDE_LEN_FUDGE;
15925 if (len > max_include_len)
15926 max_include_len = len;
15927 if (dir == last)
15928 break;
15929 }
15930
15931 last->next = NULL;
15932 last_include = last;
5ff904cd
JL
15933}
15934
c7e4ee3a
CB
15935/* Try to open include file FILENAME. SEARCHPTR is the directory
15936 being tried from the include file search path. This function maps
15937 filenames on file systems based on information read by
15938 read_name_map. */
15939
15940static FILE *
15941open_include_file (filename, searchptr)
15942 char *filename;
15943 struct file_name_list *searchptr;
5ff904cd 15944{
c7e4ee3a
CB
15945 register struct file_name_map *map;
15946 register char *from;
15947 char *p, *dir;
5ff904cd 15948
c7e4ee3a
CB
15949 if (searchptr && ! searchptr->got_name_map)
15950 {
15951 searchptr->name_map = read_name_map (searchptr->fname
15952 ? searchptr->fname : ".");
15953 searchptr->got_name_map = 1;
15954 }
5ff904cd 15955
c7e4ee3a
CB
15956 /* First check the mapping for the directory we are using. */
15957 if (searchptr && searchptr->name_map)
15958 {
15959 from = filename;
15960 if (searchptr->fname)
15961 from += strlen (searchptr->fname) + 1;
15962 for (map = searchptr->name_map; map; map = map->map_next)
15963 {
15964 if (! strcmp (map->map_from, from))
15965 {
15966 /* Found a match. */
15967 return fopen (map->map_to, "r");
15968 }
15969 }
15970 }
5ff904cd 15971
c7e4ee3a
CB
15972 /* Try to find a mapping file for the particular directory we are
15973 looking in. Thus #include <sys/types.h> will look up sys/types.h
15974 in /usr/include/header.gcc and look up types.h in
15975 /usr/include/sys/header.gcc. */
15976 p = rindex (filename, '/');
15977#ifdef DIR_SEPARATOR
15978 if (! p) p = rindex (filename, DIR_SEPARATOR);
15979 else {
15980 char *tmp = rindex (filename, DIR_SEPARATOR);
15981 if (tmp != NULL && tmp > p) p = tmp;
15982 }
15983#endif
15984 if (! p)
15985 p = filename;
15986 if (searchptr
15987 && searchptr->fname
15988 && strlen (searchptr->fname) == (size_t) (p - filename)
15989 && ! strncmp (searchptr->fname, filename, (int) (p - filename)))
15990 {
15991 /* FILENAME is in SEARCHPTR, which we've already checked. */
15992 return fopen (filename, "r");
15993 }
15994
15995 if (p == filename)
15996 {
15997 from = filename;
15998 map = read_name_map (".");
15999 }
16000 else
5ff904cd 16001 {
c7e4ee3a
CB
16002 dir = (char *) xmalloc (p - filename + 1);
16003 memcpy (dir, filename, p - filename);
16004 dir[p - filename] = '\0';
16005 from = p + 1;
16006 map = read_name_map (dir);
16007 free (dir);
5ff904cd 16008 }
c7e4ee3a
CB
16009 for (; map; map = map->map_next)
16010 if (! strcmp (map->map_from, from))
16011 return fopen (map->map_to, "r");
5ff904cd 16012
c7e4ee3a 16013 return fopen (filename, "r");
5ff904cd
JL
16014}
16015
c7e4ee3a
CB
16016/* Print the file names and line numbers of the #include
16017 commands which led to the current file. */
5ff904cd 16018
c7e4ee3a
CB
16019static void
16020print_containing_files (ffebadSeverity sev)
16021{
16022 FILE_BUF *ip = NULL;
16023 int i;
16024 int first = 1;
16025 const char *str1;
16026 const char *str2;
5ff904cd 16027
c7e4ee3a
CB
16028 /* If stack of files hasn't changed since we last printed
16029 this info, don't repeat it. */
16030 if (last_error_tick == input_file_stack_tick)
16031 return;
5ff904cd 16032
c7e4ee3a
CB
16033 for (i = indepth; i >= 0; i--)
16034 if (instack[i].fname != NULL) {
16035 ip = &instack[i];
16036 break;
16037 }
5ff904cd 16038
c7e4ee3a
CB
16039 /* Give up if we don't find a source file. */
16040 if (ip == NULL)
16041 return;
5ff904cd 16042
c7e4ee3a
CB
16043 /* Find the other, outer source files. */
16044 for (i--; i >= 0; i--)
16045 if (instack[i].fname != NULL)
16046 {
16047 ip = &instack[i];
16048 if (first)
16049 {
16050 first = 0;
16051 str1 = "In file included";
16052 }
16053 else
16054 {
16055 str1 = "... ...";
16056 }
5ff904cd 16057
c7e4ee3a
CB
16058 if (i == 1)
16059 str2 = ":";
16060 else
16061 str2 = "";
5ff904cd 16062
c7e4ee3a
CB
16063 ffebad_start_msg ("%A from %B at %0%C", sev);
16064 ffebad_here (0, ip->line, ip->column);
16065 ffebad_string (str1);
16066 ffebad_string (ip->nominal_fname);
16067 ffebad_string (str2);
16068 ffebad_finish ();
16069 }
5ff904cd 16070
c7e4ee3a
CB
16071 /* Record we have printed the status as of this time. */
16072 last_error_tick = input_file_stack_tick;
16073}
5ff904cd 16074
c7e4ee3a
CB
16075/* Read a space delimited string of unlimited length from a stdio
16076 file. */
5ff904cd 16077
c7e4ee3a
CB
16078static char *
16079read_filename_string (ch, f)
16080 int ch;
16081 FILE *f;
16082{
16083 char *alloc, *set;
16084 int len;
5ff904cd 16085
c7e4ee3a
CB
16086 len = 20;
16087 set = alloc = xmalloc (len + 1);
16088 if (! is_space[ch])
16089 {
16090 *set++ = ch;
16091 while ((ch = getc (f)) != EOF && ! is_space[ch])
16092 {
16093 if (set - alloc == len)
16094 {
16095 len *= 2;
16096 alloc = xrealloc (alloc, len + 1);
16097 set = alloc + len / 2;
16098 }
16099 *set++ = ch;
16100 }
16101 }
16102 *set = '\0';
16103 ungetc (ch, f);
16104 return alloc;
16105}
5ff904cd 16106
c7e4ee3a 16107/* Read the file name map file for DIRNAME. */
5ff904cd 16108
c7e4ee3a
CB
16109static struct file_name_map *
16110read_name_map (dirname)
16111 const char *dirname;
16112{
16113 /* This structure holds a linked list of file name maps, one per
16114 directory. */
16115 struct file_name_map_list
16116 {
16117 struct file_name_map_list *map_list_next;
16118 char *map_list_name;
16119 struct file_name_map *map_list_map;
16120 };
16121 static struct file_name_map_list *map_list;
16122 register struct file_name_map_list *map_list_ptr;
16123 char *name;
16124 FILE *f;
16125 size_t dirlen;
16126 int separator_needed;
5ff904cd 16127
c7e4ee3a 16128 dirname = skip_redundant_dir_prefix (dirname);
5ff904cd 16129
c7e4ee3a
CB
16130 for (map_list_ptr = map_list; map_list_ptr;
16131 map_list_ptr = map_list_ptr->map_list_next)
16132 if (! strcmp (map_list_ptr->map_list_name, dirname))
16133 return map_list_ptr->map_list_map;
5ff904cd 16134
c7e4ee3a
CB
16135 map_list_ptr = ((struct file_name_map_list *)
16136 xmalloc (sizeof (struct file_name_map_list)));
16137 map_list_ptr->map_list_name = xstrdup (dirname);
16138 map_list_ptr->map_list_map = NULL;
5ff904cd 16139
c7e4ee3a
CB
16140 dirlen = strlen (dirname);
16141 separator_needed = dirlen != 0 && dirname[dirlen - 1] != '/';
16142 name = (char *) xmalloc (dirlen + strlen (FILE_NAME_MAP_FILE) + 2);
16143 strcpy (name, dirname);
16144 name[dirlen] = '/';
16145 strcpy (name + dirlen + separator_needed, FILE_NAME_MAP_FILE);
16146 f = fopen (name, "r");
16147 free (name);
16148 if (!f)
16149 map_list_ptr->map_list_map = NULL;
16150 else
16151 {
16152 int ch;
5ff904cd 16153
c7e4ee3a
CB
16154 while ((ch = getc (f)) != EOF)
16155 {
16156 char *from, *to;
16157 struct file_name_map *ptr;
16158
16159 if (is_space[ch])
16160 continue;
16161 from = read_filename_string (ch, f);
16162 while ((ch = getc (f)) != EOF && is_hor_space[ch])
16163 ;
16164 to = read_filename_string (ch, f);
5ff904cd 16165
c7e4ee3a
CB
16166 ptr = ((struct file_name_map *)
16167 xmalloc (sizeof (struct file_name_map)));
16168 ptr->map_from = from;
5ff904cd 16169
c7e4ee3a
CB
16170 /* Make the real filename absolute. */
16171 if (*to == '/')
16172 ptr->map_to = to;
16173 else
16174 {
16175 ptr->map_to = xmalloc (dirlen + strlen (to) + 2);
16176 strcpy (ptr->map_to, dirname);
16177 ptr->map_to[dirlen] = '/';
16178 strcpy (ptr->map_to + dirlen + separator_needed, to);
16179 free (to);
16180 }
5ff904cd 16181
c7e4ee3a
CB
16182 ptr->map_next = map_list_ptr->map_list_map;
16183 map_list_ptr->map_list_map = ptr;
5ff904cd 16184
c7e4ee3a
CB
16185 while ((ch = getc (f)) != '\n')
16186 if (ch == EOF)
16187 break;
16188 }
16189 fclose (f);
5ff904cd
JL
16190 }
16191
c7e4ee3a
CB
16192 map_list_ptr->map_list_next = map_list;
16193 map_list = map_list_ptr;
5ff904cd 16194
c7e4ee3a 16195 return map_list_ptr->map_list_map;
5ff904cd
JL
16196}
16197
c7e4ee3a 16198static void
b0791fa9 16199ffecom_file_ (const char *name)
5ff904cd 16200{
c7e4ee3a 16201 FILE_BUF *fp;
5ff904cd 16202
c7e4ee3a
CB
16203 /* Do partial setup of input buffer for the sake of generating
16204 early #line directives (when -g is in effect). */
5ff904cd 16205
c7e4ee3a
CB
16206 fp = &instack[++indepth];
16207 memset ((char *) fp, 0, sizeof (FILE_BUF));
16208 if (name == NULL)
16209 name = "";
16210 fp->nominal_fname = fp->fname = name;
16211}
5ff904cd 16212
c7e4ee3a 16213/* Initialize syntactic classifications of characters. */
5ff904cd 16214
c7e4ee3a
CB
16215static void
16216ffecom_initialize_char_syntax_ ()
16217{
16218 register int i;
5ff904cd 16219
c7e4ee3a
CB
16220 /*
16221 * Set up is_idchar and is_idstart tables. These should be
16222 * faster than saying (is_alpha (c) || c == '_'), etc.
16223 * Set up these things before calling any routines tthat
16224 * refer to them.
16225 */
16226 for (i = 'a'; i <= 'z'; i++) {
16227 is_idchar[i - 'a' + 'A'] = 1;
16228 is_idchar[i] = 1;
16229 is_idstart[i - 'a' + 'A'] = 1;
16230 is_idstart[i] = 1;
16231 }
16232 for (i = '0'; i <= '9'; i++)
16233 is_idchar[i] = 1;
16234 is_idchar['_'] = 1;
16235 is_idstart['_'] = 1;
5ff904cd 16236
c7e4ee3a
CB
16237 /* horizontal space table */
16238 is_hor_space[' '] = 1;
16239 is_hor_space['\t'] = 1;
16240 is_hor_space['\v'] = 1;
16241 is_hor_space['\f'] = 1;
16242 is_hor_space['\r'] = 1;
5ff904cd 16243
c7e4ee3a
CB
16244 is_space[' '] = 1;
16245 is_space['\t'] = 1;
16246 is_space['\v'] = 1;
16247 is_space['\f'] = 1;
16248 is_space['\n'] = 1;
16249 is_space['\r'] = 1;
16250}
5ff904cd 16251
c7e4ee3a
CB
16252static void
16253ffecom_close_include_ (FILE *f)
16254{
16255 fclose (f);
5ff904cd 16256
c7e4ee3a
CB
16257 indepth--;
16258 input_file_stack_tick++;
5ff904cd 16259
c7e4ee3a
CB
16260 ffewhere_line_kill (instack[indepth].line);
16261 ffewhere_column_kill (instack[indepth].column);
16262}
5ff904cd 16263
c7e4ee3a
CB
16264static int
16265ffecom_decode_include_option_ (char *spec)
16266{
16267 struct file_name_list *dirtmp;
16268
16269 if (! ignore_srcdir && !strcmp (spec, "-"))
16270 ignore_srcdir = 1;
16271 else
16272 {
16273 dirtmp = (struct file_name_list *)
16274 xmalloc (sizeof (struct file_name_list));
16275 dirtmp->next = 0; /* New one goes on the end */
16276 if (spec[0] != 0)
16277 dirtmp->fname = spec;
16278 else
16279 fatal ("Directory name must immediately follow -I option with no intervening spaces, as in `-Idir', not `-I dir'");
16280 dirtmp->got_name_map = 0;
16281 append_include_chain (dirtmp, dirtmp);
16282 }
16283 return 1;
5ff904cd
JL
16284}
16285
c7e4ee3a
CB
16286/* Open INCLUDEd file. */
16287
16288static FILE *
16289ffecom_open_include_ (char *name, ffewhereLine l, ffewhereColumn c)
5ff904cd 16290{
c7e4ee3a
CB
16291 char *fbeg = name;
16292 size_t flen = strlen (fbeg);
16293 struct file_name_list *search_start = include; /* Chain of dirs to search */
16294 struct file_name_list dsp[1]; /* First in chain, if #include "..." */
16295 struct file_name_list *searchptr = 0;
16296 char *fname; /* Dynamically allocated fname buffer */
16297 FILE *f;
16298 FILE_BUF *fp;
5ff904cd 16299
c7e4ee3a
CB
16300 if (flen == 0)
16301 return NULL;
5ff904cd 16302
c7e4ee3a 16303 dsp[0].fname = NULL;
5ff904cd 16304
c7e4ee3a
CB
16305 /* If -I- was specified, don't search current dir, only spec'd ones. */
16306 if (!ignore_srcdir)
16307 {
16308 for (fp = &instack[indepth]; fp >= instack; fp--)
16309 {
16310 int n;
16311 char *ep;
b0791fa9 16312 const char *nam;
5ff904cd 16313
c7e4ee3a
CB
16314 if ((nam = fp->nominal_fname) != NULL)
16315 {
16316 /* Found a named file. Figure out dir of the file,
16317 and put it in front of the search list. */
16318 dsp[0].next = search_start;
16319 search_start = dsp;
16320#ifndef VMS
16321 ep = rindex (nam, '/');
16322#ifdef DIR_SEPARATOR
16323 if (ep == NULL) ep = rindex (nam, DIR_SEPARATOR);
16324 else {
16325 char *tmp = rindex (nam, DIR_SEPARATOR);
16326 if (tmp != NULL && tmp > ep) ep = tmp;
16327 }
16328#endif
16329#else /* VMS */
16330 ep = rindex (nam, ']');
16331 if (ep == NULL) ep = rindex (nam, '>');
16332 if (ep == NULL) ep = rindex (nam, ':');
16333 if (ep != NULL) ep++;
16334#endif /* VMS */
16335 if (ep != NULL)
16336 {
16337 n = ep - nam;
16338 dsp[0].fname = (char *) xmalloc (n + 1);
16339 strncpy (dsp[0].fname, nam, n);
16340 dsp[0].fname[n] = '\0';
16341 if (n + INCLUDE_LEN_FUDGE > max_include_len)
16342 max_include_len = n + INCLUDE_LEN_FUDGE;
16343 }
16344 else
16345 dsp[0].fname = NULL; /* Current directory */
16346 dsp[0].got_name_map = 0;
16347 break;
16348 }
16349 }
16350 }
5ff904cd 16351
c7e4ee3a
CB
16352 /* Allocate this permanently, because it gets stored in the definitions
16353 of macros. */
16354 fname = xmalloc (max_include_len + flen + 4);
16355 /* + 2 above for slash and terminating null. */
16356 /* + 2 added for '.h' on VMS (to support '#include filename') (NOT USED
16357 for g77 yet). */
5ff904cd 16358
c7e4ee3a 16359 /* If specified file name is absolute, just open it. */
5ff904cd 16360
c7e4ee3a
CB
16361 if (*fbeg == '/'
16362#ifdef DIR_SEPARATOR
16363 || *fbeg == DIR_SEPARATOR
16364#endif
16365 )
16366 {
16367 strncpy (fname, (char *) fbeg, flen);
16368 fname[flen] = 0;
16369 f = open_include_file (fname, NULL_PTR);
5ff904cd 16370 }
c7e4ee3a
CB
16371 else
16372 {
16373 f = NULL;
5ff904cd 16374
c7e4ee3a
CB
16375 /* Search directory path, trying to open the file.
16376 Copy each filename tried into FNAME. */
5ff904cd 16377
c7e4ee3a
CB
16378 for (searchptr = search_start; searchptr; searchptr = searchptr->next)
16379 {
16380 if (searchptr->fname)
16381 {
16382 /* The empty string in a search path is ignored.
16383 This makes it possible to turn off entirely
16384 a standard piece of the list. */
16385 if (searchptr->fname[0] == 0)
16386 continue;
16387 strcpy (fname, skip_redundant_dir_prefix (searchptr->fname));
16388 if (fname[0] && fname[strlen (fname) - 1] != '/')
16389 strcat (fname, "/");
16390 fname[strlen (fname) + flen] = 0;
16391 }
16392 else
16393 fname[0] = 0;
5ff904cd 16394
c7e4ee3a
CB
16395 strncat (fname, fbeg, flen);
16396#ifdef VMS
16397 /* Change this 1/2 Unix 1/2 VMS file specification into a
16398 full VMS file specification */
16399 if (searchptr->fname && (searchptr->fname[0] != 0))
16400 {
16401 /* Fix up the filename */
16402 hack_vms_include_specification (fname);
16403 }
16404 else
16405 {
16406 /* This is a normal VMS filespec, so use it unchanged. */
16407 strncpy (fname, (char *) fbeg, flen);
16408 fname[flen] = 0;
16409#if 0 /* Not for g77. */
16410 /* if it's '#include filename', add the missing .h */
16411 if (index (fname, '.') == NULL)
16412 strcat (fname, ".h");
5ff904cd 16413#endif
c7e4ee3a
CB
16414 }
16415#endif /* VMS */
16416 f = open_include_file (fname, searchptr);
16417#ifdef EACCES
16418 if (f == NULL && errno == EACCES)
16419 {
16420 print_containing_files (FFEBAD_severityWARNING);
16421 ffebad_start_msg ("At %0, INCLUDE file %A exists, but is not readable",
16422 FFEBAD_severityWARNING);
16423 ffebad_string (fname);
16424 ffebad_here (0, l, c);
16425 ffebad_finish ();
16426 }
16427#endif
16428 if (f != NULL)
16429 break;
16430 }
16431 }
5ff904cd 16432
c7e4ee3a 16433 if (f == NULL)
5ff904cd 16434 {
c7e4ee3a 16435 /* A file that was not found. */
5ff904cd 16436
c7e4ee3a
CB
16437 strncpy (fname, (char *) fbeg, flen);
16438 fname[flen] = 0;
16439 print_containing_files (ffebad_severity (FFEBAD_OPEN_INCLUDE));
16440 ffebad_start (FFEBAD_OPEN_INCLUDE);
16441 ffebad_here (0, l, c);
16442 ffebad_string (fname);
16443 ffebad_finish ();
5ff904cd
JL
16444 }
16445
c7e4ee3a
CB
16446 if (dsp[0].fname != NULL)
16447 free (dsp[0].fname);
5ff904cd 16448
c7e4ee3a
CB
16449 if (f == NULL)
16450 return NULL;
5ff904cd 16451
c7e4ee3a
CB
16452 if (indepth >= (INPUT_STACK_MAX - 1))
16453 {
16454 print_containing_files (FFEBAD_severityFATAL);
16455 ffebad_start_msg ("At %0, INCLUDE nesting too deep",
16456 FFEBAD_severityFATAL);
16457 ffebad_string (fname);
16458 ffebad_here (0, l, c);
16459 ffebad_finish ();
16460 return NULL;
16461 }
5ff904cd 16462
c7e4ee3a
CB
16463 instack[indepth].line = ffewhere_line_use (l);
16464 instack[indepth].column = ffewhere_column_use (c);
5ff904cd 16465
c7e4ee3a
CB
16466 fp = &instack[indepth + 1];
16467 memset ((char *) fp, 0, sizeof (FILE_BUF));
16468 fp->nominal_fname = fp->fname = fname;
16469 fp->dir = searchptr;
5ff904cd 16470
c7e4ee3a
CB
16471 indepth++;
16472 input_file_stack_tick++;
5ff904cd 16473
c7e4ee3a
CB
16474 return f;
16475}
16476#endif /* FFECOM_GCC_INCLUDE */
5ff904cd 16477
c7e4ee3a
CB
16478/**INDENT* (Do not reformat this comment even with -fca option.)
16479 Data-gathering files: Given the source file listed below, compiled with
16480 f2c I obtained the output file listed after that, and from the output
16481 file I derived the above code.
5ff904cd 16482
c7e4ee3a
CB
16483-------- (begin input file to f2c)
16484 implicit none
16485 character*10 A1,A2
16486 complex C1,C2
16487 integer I1,I2
16488 real R1,R2
16489 double precision D1,D2
16490C
16491 call getem(A1,A2,C1,C2,I1,I2,R1,R2,D1,D2)
16492c /
16493 call fooI(I1/I2)
16494 call fooR(R1/I1)
16495 call fooD(D1/I1)
16496 call fooC(C1/I1)
16497 call fooR(R1/R2)
16498 call fooD(R1/D1)
16499 call fooD(D1/D2)
16500 call fooD(D1/R1)
16501 call fooC(C1/C2)
16502 call fooC(C1/R1)
16503 call fooZ(C1/D1)
16504c **
16505 call fooI(I1**I2)
16506 call fooR(R1**I1)
16507 call fooD(D1**I1)
16508 call fooC(C1**I1)
16509 call fooR(R1**R2)
16510 call fooD(R1**D1)
16511 call fooD(D1**D2)
16512 call fooD(D1**R1)
16513 call fooC(C1**C2)
16514 call fooC(C1**R1)
16515 call fooZ(C1**D1)
16516c FFEINTRIN_impABS
16517 call fooR(ABS(R1))
16518c FFEINTRIN_impACOS
16519 call fooR(ACOS(R1))
16520c FFEINTRIN_impAIMAG
16521 call fooR(AIMAG(C1))
16522c FFEINTRIN_impAINT
16523 call fooR(AINT(R1))
16524c FFEINTRIN_impALOG
16525 call fooR(ALOG(R1))
16526c FFEINTRIN_impALOG10
16527 call fooR(ALOG10(R1))
16528c FFEINTRIN_impAMAX0
16529 call fooR(AMAX0(I1,I2))
16530c FFEINTRIN_impAMAX1
16531 call fooR(AMAX1(R1,R2))
16532c FFEINTRIN_impAMIN0
16533 call fooR(AMIN0(I1,I2))
16534c FFEINTRIN_impAMIN1
16535 call fooR(AMIN1(R1,R2))
16536c FFEINTRIN_impAMOD
16537 call fooR(AMOD(R1,R2))
16538c FFEINTRIN_impANINT
16539 call fooR(ANINT(R1))
16540c FFEINTRIN_impASIN
16541 call fooR(ASIN(R1))
16542c FFEINTRIN_impATAN
16543 call fooR(ATAN(R1))
16544c FFEINTRIN_impATAN2
16545 call fooR(ATAN2(R1,R2))
16546c FFEINTRIN_impCABS
16547 call fooR(CABS(C1))
16548c FFEINTRIN_impCCOS
16549 call fooC(CCOS(C1))
16550c FFEINTRIN_impCEXP
16551 call fooC(CEXP(C1))
16552c FFEINTRIN_impCHAR
16553 call fooA(CHAR(I1))
16554c FFEINTRIN_impCLOG
16555 call fooC(CLOG(C1))
16556c FFEINTRIN_impCONJG
16557 call fooC(CONJG(C1))
16558c FFEINTRIN_impCOS
16559 call fooR(COS(R1))
16560c FFEINTRIN_impCOSH
16561 call fooR(COSH(R1))
16562c FFEINTRIN_impCSIN
16563 call fooC(CSIN(C1))
16564c FFEINTRIN_impCSQRT
16565 call fooC(CSQRT(C1))
16566c FFEINTRIN_impDABS
16567 call fooD(DABS(D1))
16568c FFEINTRIN_impDACOS
16569 call fooD(DACOS(D1))
16570c FFEINTRIN_impDASIN
16571 call fooD(DASIN(D1))
16572c FFEINTRIN_impDATAN
16573 call fooD(DATAN(D1))
16574c FFEINTRIN_impDATAN2
16575 call fooD(DATAN2(D1,D2))
16576c FFEINTRIN_impDCOS
16577 call fooD(DCOS(D1))
16578c FFEINTRIN_impDCOSH
16579 call fooD(DCOSH(D1))
16580c FFEINTRIN_impDDIM
16581 call fooD(DDIM(D1,D2))
16582c FFEINTRIN_impDEXP
16583 call fooD(DEXP(D1))
16584c FFEINTRIN_impDIM
16585 call fooR(DIM(R1,R2))
16586c FFEINTRIN_impDINT
16587 call fooD(DINT(D1))
16588c FFEINTRIN_impDLOG
16589 call fooD(DLOG(D1))
16590c FFEINTRIN_impDLOG10
16591 call fooD(DLOG10(D1))
16592c FFEINTRIN_impDMAX1
16593 call fooD(DMAX1(D1,D2))
16594c FFEINTRIN_impDMIN1
16595 call fooD(DMIN1(D1,D2))
16596c FFEINTRIN_impDMOD
16597 call fooD(DMOD(D1,D2))
16598c FFEINTRIN_impDNINT
16599 call fooD(DNINT(D1))
16600c FFEINTRIN_impDPROD
16601 call fooD(DPROD(R1,R2))
16602c FFEINTRIN_impDSIGN
16603 call fooD(DSIGN(D1,D2))
16604c FFEINTRIN_impDSIN
16605 call fooD(DSIN(D1))
16606c FFEINTRIN_impDSINH
16607 call fooD(DSINH(D1))
16608c FFEINTRIN_impDSQRT
16609 call fooD(DSQRT(D1))
16610c FFEINTRIN_impDTAN
16611 call fooD(DTAN(D1))
16612c FFEINTRIN_impDTANH
16613 call fooD(DTANH(D1))
16614c FFEINTRIN_impEXP
16615 call fooR(EXP(R1))
16616c FFEINTRIN_impIABS
16617 call fooI(IABS(I1))
16618c FFEINTRIN_impICHAR
16619 call fooI(ICHAR(A1))
16620c FFEINTRIN_impIDIM
16621 call fooI(IDIM(I1,I2))
16622c FFEINTRIN_impIDNINT
16623 call fooI(IDNINT(D1))
16624c FFEINTRIN_impINDEX
16625 call fooI(INDEX(A1,A2))
16626c FFEINTRIN_impISIGN
16627 call fooI(ISIGN(I1,I2))
16628c FFEINTRIN_impLEN
16629 call fooI(LEN(A1))
16630c FFEINTRIN_impLGE
16631 call fooL(LGE(A1,A2))
16632c FFEINTRIN_impLGT
16633 call fooL(LGT(A1,A2))
16634c FFEINTRIN_impLLE
16635 call fooL(LLE(A1,A2))
16636c FFEINTRIN_impLLT
16637 call fooL(LLT(A1,A2))
16638c FFEINTRIN_impMAX0
16639 call fooI(MAX0(I1,I2))
16640c FFEINTRIN_impMAX1
16641 call fooI(MAX1(R1,R2))
16642c FFEINTRIN_impMIN0
16643 call fooI(MIN0(I1,I2))
16644c FFEINTRIN_impMIN1
16645 call fooI(MIN1(R1,R2))
16646c FFEINTRIN_impMOD
16647 call fooI(MOD(I1,I2))
16648c FFEINTRIN_impNINT
16649 call fooI(NINT(R1))
16650c FFEINTRIN_impSIGN
16651 call fooR(SIGN(R1,R2))
16652c FFEINTRIN_impSIN
16653 call fooR(SIN(R1))
16654c FFEINTRIN_impSINH
16655 call fooR(SINH(R1))
16656c FFEINTRIN_impSQRT
16657 call fooR(SQRT(R1))
16658c FFEINTRIN_impTAN
16659 call fooR(TAN(R1))
16660c FFEINTRIN_impTANH
16661 call fooR(TANH(R1))
16662c FFEINTRIN_imp_CMPLX_C
16663 call fooC(cmplx(C1,C2))
16664c FFEINTRIN_imp_CMPLX_D
16665 call fooZ(cmplx(D1,D2))
16666c FFEINTRIN_imp_CMPLX_I
16667 call fooC(cmplx(I1,I2))
16668c FFEINTRIN_imp_CMPLX_R
16669 call fooC(cmplx(R1,R2))
16670c FFEINTRIN_imp_DBLE_C
16671 call fooD(dble(C1))
16672c FFEINTRIN_imp_DBLE_D
16673 call fooD(dble(D1))
16674c FFEINTRIN_imp_DBLE_I
16675 call fooD(dble(I1))
16676c FFEINTRIN_imp_DBLE_R
16677 call fooD(dble(R1))
16678c FFEINTRIN_imp_INT_C
16679 call fooI(int(C1))
16680c FFEINTRIN_imp_INT_D
16681 call fooI(int(D1))
16682c FFEINTRIN_imp_INT_I
16683 call fooI(int(I1))
16684c FFEINTRIN_imp_INT_R
16685 call fooI(int(R1))
16686c FFEINTRIN_imp_REAL_C
16687 call fooR(real(C1))
16688c FFEINTRIN_imp_REAL_D
16689 call fooR(real(D1))
16690c FFEINTRIN_imp_REAL_I
16691 call fooR(real(I1))
16692c FFEINTRIN_imp_REAL_R
16693 call fooR(real(R1))
16694c
16695c FFEINTRIN_imp_INT_D:
16696c
16697c FFEINTRIN_specIDINT
16698 call fooI(IDINT(D1))
16699c
16700c FFEINTRIN_imp_INT_R:
16701c
16702c FFEINTRIN_specIFIX
16703 call fooI(IFIX(R1))
16704c FFEINTRIN_specINT
16705 call fooI(INT(R1))
16706c
16707c FFEINTRIN_imp_REAL_D:
16708c
16709c FFEINTRIN_specSNGL
16710 call fooR(SNGL(D1))
16711c
16712c FFEINTRIN_imp_REAL_I:
16713c
16714c FFEINTRIN_specFLOAT
16715 call fooR(FLOAT(I1))
16716c FFEINTRIN_specREAL
16717 call fooR(REAL(I1))
16718c
16719 end
16720-------- (end input file to f2c)
5ff904cd 16721
c7e4ee3a
CB
16722-------- (begin output from providing above input file as input to:
16723-------- `f2c | gcc -E -C - | sed -e "s:/[*]*://:g" -e "s:[*]*[/]://:g" \
16724-------- -e "s:^#.*$::g"')
5ff904cd 16725
c7e4ee3a
CB
16726// -- translated by f2c (version 19950223).
16727 You must link the resulting object file with the libraries:
16728 -lf2c -lm (in that order)
16729//
5ff904cd 16730
5ff904cd 16731
c7e4ee3a 16732// f2c.h -- Standard Fortran to C header file //
5ff904cd 16733
c7e4ee3a 16734/// barf [ba:rf] 2. "He suggested using FORTRAN, and everybody barfed."
5ff904cd 16735
c7e4ee3a 16736 - From The Shogakukan DICTIONARY OF NEW ENGLISH (Second edition) //
5ff904cd 16737
5ff904cd 16738
5ff904cd 16739
5ff904cd 16740
c7e4ee3a
CB
16741// F2C_INTEGER will normally be `int' but would be `long' on 16-bit systems //
16742// we assume short, float are OK //
16743typedef long int // long int // integer;
16744typedef char *address;
16745typedef short int shortint;
16746typedef float real;
16747typedef double doublereal;
16748typedef struct { real r, i; } complex;
16749typedef struct { doublereal r, i; } doublecomplex;
16750typedef long int // long int // logical;
16751typedef short int shortlogical;
16752typedef char logical1;
16753typedef char integer1;
16754// typedef long long longint; // // system-dependent //
5ff904cd 16755
5ff904cd 16756
5ff904cd 16757
5ff904cd 16758
c7e4ee3a 16759// Extern is for use with -E //
5ff904cd 16760
5ff904cd 16761
5ff904cd 16762
5ff904cd 16763
c7e4ee3a 16764// I/O stuff //
5ff904cd 16765
5ff904cd 16766
5ff904cd 16767
5ff904cd 16768
5ff904cd 16769
5ff904cd 16770
5ff904cd 16771
5ff904cd 16772
c7e4ee3a
CB
16773typedef long int // int or long int // flag;
16774typedef long int // int or long int // ftnlen;
16775typedef long int // int or long int // ftnint;
5ff904cd 16776
5ff904cd 16777
c7e4ee3a
CB
16778//external read, write//
16779typedef struct
16780{ flag cierr;
16781 ftnint ciunit;
16782 flag ciend;
16783 char *cifmt;
16784 ftnint cirec;
16785} cilist;
5ff904cd 16786
c7e4ee3a
CB
16787//internal read, write//
16788typedef struct
16789{ flag icierr;
16790 char *iciunit;
16791 flag iciend;
16792 char *icifmt;
16793 ftnint icirlen;
16794 ftnint icirnum;
16795} icilist;
5ff904cd 16796
c7e4ee3a
CB
16797//open//
16798typedef struct
16799{ flag oerr;
16800 ftnint ounit;
16801 char *ofnm;
16802 ftnlen ofnmlen;
16803 char *osta;
16804 char *oacc;
16805 char *ofm;
16806 ftnint orl;
16807 char *oblnk;
16808} olist;
5ff904cd 16809
c7e4ee3a
CB
16810//close//
16811typedef struct
16812{ flag cerr;
16813 ftnint cunit;
16814 char *csta;
16815} cllist;
5ff904cd 16816
c7e4ee3a
CB
16817//rewind, backspace, endfile//
16818typedef struct
16819{ flag aerr;
16820 ftnint aunit;
16821} alist;
5ff904cd 16822
c7e4ee3a
CB
16823// inquire //
16824typedef struct
16825{ flag inerr;
16826 ftnint inunit;
16827 char *infile;
16828 ftnlen infilen;
16829 ftnint *inex; //parameters in standard's order//
16830 ftnint *inopen;
16831 ftnint *innum;
16832 ftnint *innamed;
16833 char *inname;
16834 ftnlen innamlen;
16835 char *inacc;
16836 ftnlen inacclen;
16837 char *inseq;
16838 ftnlen inseqlen;
16839 char *indir;
16840 ftnlen indirlen;
16841 char *infmt;
16842 ftnlen infmtlen;
16843 char *inform;
16844 ftnint informlen;
16845 char *inunf;
16846 ftnlen inunflen;
16847 ftnint *inrecl;
16848 ftnint *innrec;
16849 char *inblank;
16850 ftnlen inblanklen;
16851} inlist;
5ff904cd 16852
5ff904cd 16853
5ff904cd 16854
c7e4ee3a
CB
16855union Multitype { // for multiple entry points //
16856 integer1 g;
16857 shortint h;
16858 integer i;
16859 // longint j; //
16860 real r;
16861 doublereal d;
16862 complex c;
16863 doublecomplex z;
16864 };
16865
16866typedef union Multitype Multitype;
5ff904cd 16867
c7e4ee3a 16868typedef long Long; // No longer used; formerly in Namelist //
5ff904cd 16869
c7e4ee3a
CB
16870struct Vardesc { // for Namelist //
16871 char *name;
16872 char *addr;
16873 ftnlen *dims;
16874 int type;
16875 };
16876typedef struct Vardesc Vardesc;
5ff904cd 16877
c7e4ee3a
CB
16878struct Namelist {
16879 char *name;
16880 Vardesc **vars;
16881 int nvars;
16882 };
16883typedef struct Namelist Namelist;
5ff904cd 16884
5ff904cd 16885
5ff904cd 16886
5ff904cd 16887
5ff904cd 16888
5ff904cd 16889
5ff904cd 16890
5ff904cd 16891
c7e4ee3a 16892// procedure parameter types for -A and -C++ //
5ff904cd 16893
5ff904cd 16894
5ff904cd 16895
5ff904cd 16896
c7e4ee3a
CB
16897typedef int // Unknown procedure type // (*U_fp)();
16898typedef shortint (*J_fp)();
16899typedef integer (*I_fp)();
16900typedef real (*R_fp)();
16901typedef doublereal (*D_fp)(), (*E_fp)();
16902typedef // Complex // void (*C_fp)();
16903typedef // Double Complex // void (*Z_fp)();
16904typedef logical (*L_fp)();
16905typedef shortlogical (*K_fp)();
16906typedef // Character // void (*H_fp)();
16907typedef // Subroutine // int (*S_fp)();
5ff904cd 16908
c7e4ee3a
CB
16909// E_fp is for real functions when -R is not specified //
16910typedef void C_f; // complex function //
16911typedef void H_f; // character function //
16912typedef void Z_f; // double complex function //
16913typedef doublereal E_f; // real function with -R not specified //
5ff904cd 16914
c7e4ee3a 16915// undef any lower-case symbols that your C compiler predefines, e.g.: //
5ff904cd 16916
5ff904cd 16917
c7e4ee3a
CB
16918// (No such symbols should be defined in a strict ANSI C compiler.
16919 We can avoid trouble with f2c-translated code by using
16920 gcc -ansi [-traditional].) //
16921
5ff904cd 16922
5ff904cd 16923
5ff904cd 16924
5ff904cd 16925
5ff904cd 16926
5ff904cd 16927
5ff904cd 16928
5ff904cd 16929
5ff904cd 16930
5ff904cd 16931
5ff904cd 16932
5ff904cd 16933
5ff904cd 16934
5ff904cd 16935
5ff904cd 16936
5ff904cd 16937
5ff904cd 16938
5ff904cd 16939
5ff904cd 16940
5ff904cd 16941
5ff904cd 16942
5ff904cd 16943
c7e4ee3a
CB
16944// Main program // MAIN__()
16945{
16946 // System generated locals //
16947 integer i__1;
16948 real r__1, r__2;
16949 doublereal d__1, d__2;
16950 complex q__1;
16951 doublecomplex z__1, z__2, z__3;
16952 logical L__1;
16953 char ch__1[1];
16954
16955 // Builtin functions //
16956 void c_div();
16957 integer pow_ii();
16958 double pow_ri(), pow_di();
16959 void pow_ci();
16960 double pow_dd();
16961 void pow_zz();
16962 double acos(), r_imag(), r_int(), log(), r_lg10(), r_mod(), r_nint(),
16963 asin(), atan(), atan2(), c_abs();
16964 void c_cos(), c_exp(), c_log(), r_cnjg();
16965 double cos(), cosh();
16966 void c_sin(), c_sqrt();
16967 double d_dim(), exp(), r_dim(), d_int(), d_lg10(), d_mod(), d_nint(),
16968 d_sign(), sin(), sinh(), sqrt(), tan(), tanh();
16969 integer i_dim(), i_dnnt(), i_indx(), i_sign(), i_len();
16970 logical l_ge(), l_gt(), l_le(), l_lt();
16971 integer i_nint();
16972 double r_sign();
16973
16974 // Local variables //
16975 extern // Subroutine // int fooa_(), fooc_(), food_(), fooi_(), foor_(),
16976 fool_(), fooz_(), getem_();
16977 static char a1[10], a2[10];
16978 static complex c1, c2;
16979 static doublereal d1, d2;
16980 static integer i1, i2;
16981 static real r1, r2;
16982
16983
16984 getem_(a1, a2, &c1, &c2, &i1, &i2, &r1, &r2, &d1, &d2, 10L, 10L);
16985// / //
16986 i__1 = i1 / i2;
16987 fooi_(&i__1);
16988 r__1 = r1 / i1;
16989 foor_(&r__1);
16990 d__1 = d1 / i1;
16991 food_(&d__1);
16992 d__1 = (doublereal) i1;
16993 q__1.r = c1.r / d__1, q__1.i = c1.i / d__1;
16994 fooc_(&q__1);
16995 r__1 = r1 / r2;
16996 foor_(&r__1);
16997 d__1 = r1 / d1;
16998 food_(&d__1);
16999 d__1 = d1 / d2;
17000 food_(&d__1);
17001 d__1 = d1 / r1;
17002 food_(&d__1);
17003 c_div(&q__1, &c1, &c2);
17004 fooc_(&q__1);
17005 q__1.r = c1.r / r1, q__1.i = c1.i / r1;
17006 fooc_(&q__1);
17007 z__1.r = c1.r / d1, z__1.i = c1.i / d1;
17008 fooz_(&z__1);
17009// ** //
17010 i__1 = pow_ii(&i1, &i2);
17011 fooi_(&i__1);
17012 r__1 = pow_ri(&r1, &i1);
17013 foor_(&r__1);
17014 d__1 = pow_di(&d1, &i1);
17015 food_(&d__1);
17016 pow_ci(&q__1, &c1, &i1);
17017 fooc_(&q__1);
17018 d__1 = (doublereal) r1;
17019 d__2 = (doublereal) r2;
17020 r__1 = pow_dd(&d__1, &d__2);
17021 foor_(&r__1);
17022 d__2 = (doublereal) r1;
17023 d__1 = pow_dd(&d__2, &d1);
17024 food_(&d__1);
17025 d__1 = pow_dd(&d1, &d2);
17026 food_(&d__1);
17027 d__2 = (doublereal) r1;
17028 d__1 = pow_dd(&d1, &d__2);
17029 food_(&d__1);
17030 z__2.r = c1.r, z__2.i = c1.i;
17031 z__3.r = c2.r, z__3.i = c2.i;
17032 pow_zz(&z__1, &z__2, &z__3);
17033 q__1.r = z__1.r, q__1.i = z__1.i;
17034 fooc_(&q__1);
17035 z__2.r = c1.r, z__2.i = c1.i;
17036 z__3.r = r1, z__3.i = 0.;
17037 pow_zz(&z__1, &z__2, &z__3);
17038 q__1.r = z__1.r, q__1.i = z__1.i;
17039 fooc_(&q__1);
17040 z__2.r = c1.r, z__2.i = c1.i;
17041 z__3.r = d1, z__3.i = 0.;
17042 pow_zz(&z__1, &z__2, &z__3);
17043 fooz_(&z__1);
17044// FFEINTRIN_impABS //
17045 r__1 = (doublereal)(( r1 ) >= 0 ? ( r1 ) : -( r1 )) ;
17046 foor_(&r__1);
17047// FFEINTRIN_impACOS //
17048 r__1 = acos(r1);
17049 foor_(&r__1);
17050// FFEINTRIN_impAIMAG //
17051 r__1 = r_imag(&c1);
17052 foor_(&r__1);
17053// FFEINTRIN_impAINT //
17054 r__1 = r_int(&r1);
17055 foor_(&r__1);
17056// FFEINTRIN_impALOG //
17057 r__1 = log(r1);
17058 foor_(&r__1);
17059// FFEINTRIN_impALOG10 //
17060 r__1 = r_lg10(&r1);
17061 foor_(&r__1);
17062// FFEINTRIN_impAMAX0 //
17063 r__1 = (real) (( i1 ) >= ( i2 ) ? ( i1 ) : ( i2 )) ;
17064 foor_(&r__1);
17065// FFEINTRIN_impAMAX1 //
17066 r__1 = (doublereal)(( r1 ) >= ( r2 ) ? ( r1 ) : ( r2 )) ;
17067 foor_(&r__1);
17068// FFEINTRIN_impAMIN0 //
17069 r__1 = (real) (( i1 ) <= ( i2 ) ? ( i1 ) : ( i2 )) ;
17070 foor_(&r__1);
17071// FFEINTRIN_impAMIN1 //
17072 r__1 = (doublereal)(( r1 ) <= ( r2 ) ? ( r1 ) : ( r2 )) ;
17073 foor_(&r__1);
17074// FFEINTRIN_impAMOD //
17075 r__1 = r_mod(&r1, &r2);
17076 foor_(&r__1);
17077// FFEINTRIN_impANINT //
17078 r__1 = r_nint(&r1);
17079 foor_(&r__1);
17080// FFEINTRIN_impASIN //
17081 r__1 = asin(r1);
17082 foor_(&r__1);
17083// FFEINTRIN_impATAN //
17084 r__1 = atan(r1);
17085 foor_(&r__1);
17086// FFEINTRIN_impATAN2 //
17087 r__1 = atan2(r1, r2);
17088 foor_(&r__1);
17089// FFEINTRIN_impCABS //
17090 r__1 = c_abs(&c1);
17091 foor_(&r__1);
17092// FFEINTRIN_impCCOS //
17093 c_cos(&q__1, &c1);
17094 fooc_(&q__1);
17095// FFEINTRIN_impCEXP //
17096 c_exp(&q__1, &c1);
17097 fooc_(&q__1);
17098// FFEINTRIN_impCHAR //
17099 *(unsigned char *)&ch__1[0] = i1;
17100 fooa_(ch__1, 1L);
17101// FFEINTRIN_impCLOG //
17102 c_log(&q__1, &c1);
17103 fooc_(&q__1);
17104// FFEINTRIN_impCONJG //
17105 r_cnjg(&q__1, &c1);
17106 fooc_(&q__1);
17107// FFEINTRIN_impCOS //
17108 r__1 = cos(r1);
17109 foor_(&r__1);
17110// FFEINTRIN_impCOSH //
17111 r__1 = cosh(r1);
17112 foor_(&r__1);
17113// FFEINTRIN_impCSIN //
17114 c_sin(&q__1, &c1);
17115 fooc_(&q__1);
17116// FFEINTRIN_impCSQRT //
17117 c_sqrt(&q__1, &c1);
17118 fooc_(&q__1);
17119// FFEINTRIN_impDABS //
17120 d__1 = (( d1 ) >= 0 ? ( d1 ) : -( d1 )) ;
17121 food_(&d__1);
17122// FFEINTRIN_impDACOS //
17123 d__1 = acos(d1);
17124 food_(&d__1);
17125// FFEINTRIN_impDASIN //
17126 d__1 = asin(d1);
17127 food_(&d__1);
17128// FFEINTRIN_impDATAN //
17129 d__1 = atan(d1);
17130 food_(&d__1);
17131// FFEINTRIN_impDATAN2 //
17132 d__1 = atan2(d1, d2);
17133 food_(&d__1);
17134// FFEINTRIN_impDCOS //
17135 d__1 = cos(d1);
17136 food_(&d__1);
17137// FFEINTRIN_impDCOSH //
17138 d__1 = cosh(d1);
17139 food_(&d__1);
17140// FFEINTRIN_impDDIM //
17141 d__1 = d_dim(&d1, &d2);
17142 food_(&d__1);
17143// FFEINTRIN_impDEXP //
17144 d__1 = exp(d1);
17145 food_(&d__1);
17146// FFEINTRIN_impDIM //
17147 r__1 = r_dim(&r1, &r2);
17148 foor_(&r__1);
17149// FFEINTRIN_impDINT //
17150 d__1 = d_int(&d1);
17151 food_(&d__1);
17152// FFEINTRIN_impDLOG //
17153 d__1 = log(d1);
17154 food_(&d__1);
17155// FFEINTRIN_impDLOG10 //
17156 d__1 = d_lg10(&d1);
17157 food_(&d__1);
17158// FFEINTRIN_impDMAX1 //
17159 d__1 = (( d1 ) >= ( d2 ) ? ( d1 ) : ( d2 )) ;
17160 food_(&d__1);
17161// FFEINTRIN_impDMIN1 //
17162 d__1 = (( d1 ) <= ( d2 ) ? ( d1 ) : ( d2 )) ;
17163 food_(&d__1);
17164// FFEINTRIN_impDMOD //
17165 d__1 = d_mod(&d1, &d2);
17166 food_(&d__1);
17167// FFEINTRIN_impDNINT //
17168 d__1 = d_nint(&d1);
17169 food_(&d__1);
17170// FFEINTRIN_impDPROD //
17171 d__1 = (doublereal) r1 * r2;
17172 food_(&d__1);
17173// FFEINTRIN_impDSIGN //
17174 d__1 = d_sign(&d1, &d2);
17175 food_(&d__1);
17176// FFEINTRIN_impDSIN //
17177 d__1 = sin(d1);
17178 food_(&d__1);
17179// FFEINTRIN_impDSINH //
17180 d__1 = sinh(d1);
17181 food_(&d__1);
17182// FFEINTRIN_impDSQRT //
17183 d__1 = sqrt(d1);
17184 food_(&d__1);
17185// FFEINTRIN_impDTAN //
17186 d__1 = tan(d1);
17187 food_(&d__1);
17188// FFEINTRIN_impDTANH //
17189 d__1 = tanh(d1);
17190 food_(&d__1);
17191// FFEINTRIN_impEXP //
17192 r__1 = exp(r1);
17193 foor_(&r__1);
17194// FFEINTRIN_impIABS //
17195 i__1 = (( i1 ) >= 0 ? ( i1 ) : -( i1 )) ;
17196 fooi_(&i__1);
17197// FFEINTRIN_impICHAR //
17198 i__1 = *(unsigned char *)a1;
17199 fooi_(&i__1);
17200// FFEINTRIN_impIDIM //
17201 i__1 = i_dim(&i1, &i2);
17202 fooi_(&i__1);
17203// FFEINTRIN_impIDNINT //
17204 i__1 = i_dnnt(&d1);
17205 fooi_(&i__1);
17206// FFEINTRIN_impINDEX //
17207 i__1 = i_indx(a1, a2, 10L, 10L);
17208 fooi_(&i__1);
17209// FFEINTRIN_impISIGN //
17210 i__1 = i_sign(&i1, &i2);
17211 fooi_(&i__1);
17212// FFEINTRIN_impLEN //
17213 i__1 = i_len(a1, 10L);
17214 fooi_(&i__1);
17215// FFEINTRIN_impLGE //
17216 L__1 = l_ge(a1, a2, 10L, 10L);
17217 fool_(&L__1);
17218// FFEINTRIN_impLGT //
17219 L__1 = l_gt(a1, a2, 10L, 10L);
17220 fool_(&L__1);
17221// FFEINTRIN_impLLE //
17222 L__1 = l_le(a1, a2, 10L, 10L);
17223 fool_(&L__1);
17224// FFEINTRIN_impLLT //
17225 L__1 = l_lt(a1, a2, 10L, 10L);
17226 fool_(&L__1);
17227// FFEINTRIN_impMAX0 //
17228 i__1 = (( i1 ) >= ( i2 ) ? ( i1 ) : ( i2 )) ;
17229 fooi_(&i__1);
17230// FFEINTRIN_impMAX1 //
17231 i__1 = (integer) (doublereal)(( r1 ) >= ( r2 ) ? ( r1 ) : ( r2 )) ;
17232 fooi_(&i__1);
17233// FFEINTRIN_impMIN0 //
17234 i__1 = (( i1 ) <= ( i2 ) ? ( i1 ) : ( i2 )) ;
17235 fooi_(&i__1);
17236// FFEINTRIN_impMIN1 //
17237 i__1 = (integer) (doublereal)(( r1 ) <= ( r2 ) ? ( r1 ) : ( r2 )) ;
17238 fooi_(&i__1);
17239// FFEINTRIN_impMOD //
17240 i__1 = i1 % i2;
17241 fooi_(&i__1);
17242// FFEINTRIN_impNINT //
17243 i__1 = i_nint(&r1);
17244 fooi_(&i__1);
17245// FFEINTRIN_impSIGN //
17246 r__1 = r_sign(&r1, &r2);
17247 foor_(&r__1);
17248// FFEINTRIN_impSIN //
17249 r__1 = sin(r1);
17250 foor_(&r__1);
17251// FFEINTRIN_impSINH //
17252 r__1 = sinh(r1);
17253 foor_(&r__1);
17254// FFEINTRIN_impSQRT //
17255 r__1 = sqrt(r1);
17256 foor_(&r__1);
17257// FFEINTRIN_impTAN //
17258 r__1 = tan(r1);
17259 foor_(&r__1);
17260// FFEINTRIN_impTANH //
17261 r__1 = tanh(r1);
17262 foor_(&r__1);
17263// FFEINTRIN_imp_CMPLX_C //
17264 r__1 = c1.r;
17265 r__2 = c2.r;
17266 q__1.r = r__1, q__1.i = r__2;
17267 fooc_(&q__1);
17268// FFEINTRIN_imp_CMPLX_D //
17269 z__1.r = d1, z__1.i = d2;
17270 fooz_(&z__1);
17271// FFEINTRIN_imp_CMPLX_I //
17272 r__1 = (real) i1;
17273 r__2 = (real) i2;
17274 q__1.r = r__1, q__1.i = r__2;
17275 fooc_(&q__1);
17276// FFEINTRIN_imp_CMPLX_R //
17277 q__1.r = r1, q__1.i = r2;
17278 fooc_(&q__1);
17279// FFEINTRIN_imp_DBLE_C //
17280 d__1 = (doublereal) c1.r;
17281 food_(&d__1);
17282// FFEINTRIN_imp_DBLE_D //
17283 d__1 = d1;
17284 food_(&d__1);
17285// FFEINTRIN_imp_DBLE_I //
17286 d__1 = (doublereal) i1;
17287 food_(&d__1);
17288// FFEINTRIN_imp_DBLE_R //
17289 d__1 = (doublereal) r1;
17290 food_(&d__1);
17291// FFEINTRIN_imp_INT_C //
17292 i__1 = (integer) c1.r;
17293 fooi_(&i__1);
17294// FFEINTRIN_imp_INT_D //
17295 i__1 = (integer) d1;
17296 fooi_(&i__1);
17297// FFEINTRIN_imp_INT_I //
17298 i__1 = i1;
17299 fooi_(&i__1);
17300// FFEINTRIN_imp_INT_R //
17301 i__1 = (integer) r1;
17302 fooi_(&i__1);
17303// FFEINTRIN_imp_REAL_C //
17304 r__1 = c1.r;
17305 foor_(&r__1);
17306// FFEINTRIN_imp_REAL_D //
17307 r__1 = (real) d1;
17308 foor_(&r__1);
17309// FFEINTRIN_imp_REAL_I //
17310 r__1 = (real) i1;
17311 foor_(&r__1);
17312// FFEINTRIN_imp_REAL_R //
17313 r__1 = r1;
17314 foor_(&r__1);
17315
17316// FFEINTRIN_imp_INT_D: //
17317
17318// FFEINTRIN_specIDINT //
17319 i__1 = (integer) d1;
17320 fooi_(&i__1);
17321
17322// FFEINTRIN_imp_INT_R: //
17323
17324// FFEINTRIN_specIFIX //
17325 i__1 = (integer) r1;
17326 fooi_(&i__1);
17327// FFEINTRIN_specINT //
17328 i__1 = (integer) r1;
17329 fooi_(&i__1);
17330
17331// FFEINTRIN_imp_REAL_D: //
5ff904cd 17332
c7e4ee3a
CB
17333// FFEINTRIN_specSNGL //
17334 r__1 = (real) d1;
17335 foor_(&r__1);
5ff904cd 17336
c7e4ee3a 17337// FFEINTRIN_imp_REAL_I: //
5ff904cd 17338
c7e4ee3a
CB
17339// FFEINTRIN_specFLOAT //
17340 r__1 = (real) i1;
17341 foor_(&r__1);
17342// FFEINTRIN_specREAL //
17343 r__1 = (real) i1;
17344 foor_(&r__1);
5ff904cd 17345
c7e4ee3a 17346} // MAIN__ //
5ff904cd 17347
c7e4ee3a 17348-------- (end output file from f2c)
5ff904cd 17349
c7e4ee3a 17350*/
This page took 2.613885 seconds and 5 git commands to generate.