]> gcc.gnu.org Git - gcc.git/blame - gcc/f/com.c
tree.h (INT_CST_LT, [...]): Remove unneeded casts.
[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
5ff904cd
JL
91#include "flags.j"
92#include "rtl.j"
8b45da67 93#include "toplev.j"
5ff904cd 94#include "tree.j"
95a1b676 95#include "output.j" /* Must follow tree.j so TREE_CODE is defined! */
5ff904cd 96#include "convert.j"
7189a4b0 97#include "ggc.j"
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,
715 char *array_name)
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);
765 sprintf (&var[0], "%s[%s-substring]",
766 array_name,
767 dim ? "end" : "start");
768 len = strlen (var) + 1;
769 break;
770
771 case 1:
772 len = strlen (array_name) + 1;
773 var = array_name;
774 break;
775
776 default:
777 var = xmalloc (strlen (array_name) + 40);
778 sprintf (&var[0], "%s[subscript-%d-of-%d]",
779 array_name,
780 dim + 1, total_dims);
781 len = strlen (var) + 1;
782 break;
783 }
784
785 arg1 = build_string (len, var);
786
787 if (total_dims != 1)
788 free (var);
789
790 TREE_TYPE (arg1)
791 = build_type_variant (build_array_type (char_type_node,
792 build_range_type
793 (integer_type_node,
794 integer_one_node,
795 build_int_2 (len, 0))),
796 1, 0);
797 TREE_CONSTANT (arg1) = 1;
798 TREE_STATIC (arg1) = 1;
799 arg1 = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg1)),
800 arg1);
801
802 /* s_rnge adds one to the element to print it, so bias against
803 that -- want to print a faithful *subscript* value. */
804 arg2 = convert (ffecom_f2c_ftnint_type_node,
805 ffecom_2 (MINUS_EXPR,
806 TREE_TYPE (element),
807 element,
808 convert (TREE_TYPE (element),
809 integer_one_node)));
810
811 proc = xmalloc ((len = strlen (input_filename)
812 + IDENTIFIER_LENGTH (DECL_NAME (current_function_decl))
813 + 2));
814
815 sprintf (&proc[0], "%s/%s",
816 input_filename,
817 IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));
818 arg3 = build_string (len, proc);
819
820 free (proc);
821
822 TREE_TYPE (arg3)
823 = build_type_variant (build_array_type (char_type_node,
824 build_range_type
825 (integer_type_node,
826 integer_one_node,
827 build_int_2 (len, 0))),
828 1, 0);
829 TREE_CONSTANT (arg3) = 1;
830 TREE_STATIC (arg3) = 1;
831 arg3 = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg3)),
832 arg3);
833
834 arg4 = convert (ffecom_f2c_ftnint_type_node,
835 build_int_2 (lineno, 0));
836
837 arg1 = build_tree_list (NULL_TREE, arg1);
838 arg2 = build_tree_list (NULL_TREE, arg2);
839 arg3 = build_tree_list (NULL_TREE, arg3);
840 arg4 = build_tree_list (NULL_TREE, arg4);
841 TREE_CHAIN (arg3) = arg4;
842 TREE_CHAIN (arg2) = arg3;
843 TREE_CHAIN (arg1) = arg2;
844
845 args = arg1;
846 }
847 die = ffecom_call_gfrt (FFECOM_gfrtRANGE,
848 args, NULL_TREE);
849 TREE_SIDE_EFFECTS (die) = 1;
850
851 element = ffecom_3 (COND_EXPR,
852 TREE_TYPE (element),
853 cond,
854 element,
855 die);
856
857 return element;
858}
859
860/* Return the computed element of an array reference.
861
ff852b44
CB
862 `item' is NULL_TREE, or the transformed pointer to the array.
863 `expr' is the original opARRAYREF expression, which is transformed
864 if `item' is NULL_TREE.
865 `want_ptr' is non-zero if a pointer to the element, instead of
6b55276e
CB
866 the element itself, is to be returned. */
867
868static tree
869ffecom_arrayref_ (tree item, ffebld expr, int want_ptr)
870{
871 ffebld dims[FFECOM_dimensionsMAX];
872 int i;
873 int total_dims;
ff852b44
CB
874 int flatten = ffe_is_flatten_arrays ();
875 int need_ptr;
6b55276e
CB
876 tree array;
877 tree element;
ff852b44
CB
878 tree tree_type;
879 tree tree_type_x;
6b55276e 880 char *array_name;
ff852b44
CB
881 ffetype type;
882 ffebld list;
6b55276e
CB
883
884 if (ffebld_op (ffebld_left (expr)) == FFEBLD_opSYMTER)
885 array_name = ffesymbol_text (ffebld_symter (ffebld_left (expr)));
886 else
887 array_name = "[expr?]";
888
889 /* Build up ARRAY_REFs in reverse order (since we're column major
890 here in Fortran land). */
891
ff852b44
CB
892 for (i = 0, list = ffebld_right (expr);
893 list != NULL;
894 ++i, list = ffebld_trail (list))
895 {
896 dims[i] = ffebld_head (list);
897 type = ffeinfo_type (ffebld_basictype (dims[i]),
898 ffebld_kindtype (dims[i]));
899 if (! flatten
900 && ffecom_typesize_pointer_ > ffecom_typesize_integer1_
901 && ffetype_size (type) > ffecom_typesize_integer1_)
902 /* E.g. ARRAY(INDEX), given INTEGER*8 INDEX, on a system with 64-bit
903 pointers and 32-bit integers. Do the full 64-bit pointer
904 arithmetic, for codes using arrays for nonstandard heap-like
905 work. */
906 flatten = 1;
907 }
6b55276e
CB
908
909 total_dims = i;
910
ff852b44
CB
911 need_ptr = want_ptr || flatten;
912
913 if (! item)
914 {
915 if (need_ptr)
916 item = ffecom_ptr_to_expr (ffebld_left (expr));
917 else
918 item = ffecom_expr (ffebld_left (expr));
919
920 if (item == error_mark_node)
921 return item;
922
923 if (ffeinfo_where (ffebld_info (expr)) == FFEINFO_whereFLEETING
924 && ! mark_addressable (item))
925 return error_mark_node;
926 }
927
928 if (item == error_mark_node)
929 return item;
930
6b55276e
CB
931 if (need_ptr)
932 {
ff852b44
CB
933 tree min;
934
6b55276e
CB
935 for (--i, array = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item)));
936 i >= 0;
937 --i, array = TYPE_MAIN_VARIANT (TREE_TYPE (array)))
938 {
ff852b44
CB
939 min = TYPE_MIN_VALUE (TYPE_DOMAIN (array));
940 element = ffecom_expr_ (dims[i], NULL, NULL, NULL, FALSE, TRUE);
02f06e64 941 if (flag_bounds_check)
6b55276e
CB
942 element = ffecom_subscript_check_ (array, element, i, total_dims,
943 array_name);
ff852b44
CB
944 if (element == error_mark_node)
945 return element;
946
947 /* Widen integral arithmetic as desired while preserving
948 signedness. */
949 tree_type = TREE_TYPE (element);
950 tree_type_x = tree_type;
951 if (tree_type
952 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
953 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
954 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
955
956 if (TREE_TYPE (min) != tree_type_x)
957 min = convert (tree_type_x, min);
958 if (TREE_TYPE (element) != tree_type_x)
959 element = convert (tree_type_x, element);
960
6b55276e
CB
961 item = ffecom_2 (PLUS_EXPR,
962 build_pointer_type (TREE_TYPE (array)),
963 item,
964 size_binop (MULT_EXPR,
965 size_in_bytes (TREE_TYPE (array)),
fed3cef0
RK
966 convert (sizetype,
967 fold (build (MINUS_EXPR,
968 tree_type_x,
969 element, min)))));
6b55276e
CB
970 }
971 if (! want_ptr)
972 {
973 item = ffecom_1 (INDIRECT_REF,
974 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item))),
975 item);
976 }
977 }
978 else
979 {
980 for (--i;
981 i >= 0;
982 --i)
983 {
984 array = TYPE_MAIN_VARIANT (TREE_TYPE (item));
985
986 element = ffecom_expr_ (dims[i], NULL, NULL, NULL, FALSE, TRUE);
02f06e64 987 if (flag_bounds_check)
6b55276e
CB
988 element = ffecom_subscript_check_ (array, element, i, total_dims,
989 array_name);
ff852b44
CB
990 if (element == error_mark_node)
991 return element;
992
993 /* Widen integral arithmetic as desired while preserving
994 signedness. */
995 tree_type = TREE_TYPE (element);
996 tree_type_x = tree_type;
997 if (tree_type
998 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
999 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
1000 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
1001
1002 element = convert (tree_type_x, element);
1003
6b55276e
CB
1004 item = ffecom_2 (ARRAY_REF,
1005 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item))),
1006 item,
1007 element);
1008 }
1009 }
1010
1011 return item;
1012}
1013
5ff904cd
JL
1014/* This is like gcc's stabilize_reference -- in fact, most of the code
1015 comes from that -- but it handles the situation where the reference
1016 is going to have its subparts picked at, and it shouldn't change
1017 (or trigger extra invocations of functions in the subtrees) due to
1018 this. save_expr is a bit overzealous, because we don't need the
1019 entire thing calculated and saved like a temp. So, for DECLs, no
1020 change is needed, because these are stable aggregates, and ARRAY_REF
1021 and such might well be stable too, but for things like calculations,
1022 we do need to calculate a snapshot of a value before picking at it. */
1023
1024#if FFECOM_targetCURRENT == FFECOM_targetGCC
1025static tree
1026ffecom_stabilize_aggregate_ (tree ref)
1027{
1028 tree result;
1029 enum tree_code code = TREE_CODE (ref);
1030
1031 switch (code)
1032 {
1033 case VAR_DECL:
1034 case PARM_DECL:
1035 case RESULT_DECL:
1036 /* No action is needed in this case. */
1037 return ref;
1038
1039 case NOP_EXPR:
1040 case CONVERT_EXPR:
1041 case FLOAT_EXPR:
1042 case FIX_TRUNC_EXPR:
1043 case FIX_FLOOR_EXPR:
1044 case FIX_ROUND_EXPR:
1045 case FIX_CEIL_EXPR:
1046 result = build_nt (code, stabilize_reference (TREE_OPERAND (ref, 0)));
1047 break;
1048
1049 case INDIRECT_REF:
1050 result = build_nt (INDIRECT_REF,
1051 stabilize_reference_1 (TREE_OPERAND (ref, 0)));
1052 break;
1053
1054 case COMPONENT_REF:
1055 result = build_nt (COMPONENT_REF,
1056 stabilize_reference (TREE_OPERAND (ref, 0)),
1057 TREE_OPERAND (ref, 1));
1058 break;
1059
1060 case BIT_FIELD_REF:
1061 result = build_nt (BIT_FIELD_REF,
1062 stabilize_reference (TREE_OPERAND (ref, 0)),
1063 stabilize_reference_1 (TREE_OPERAND (ref, 1)),
1064 stabilize_reference_1 (TREE_OPERAND (ref, 2)));
1065 break;
1066
1067 case ARRAY_REF:
1068 result = build_nt (ARRAY_REF,
1069 stabilize_reference (TREE_OPERAND (ref, 0)),
1070 stabilize_reference_1 (TREE_OPERAND (ref, 1)));
1071 break;
1072
1073 case COMPOUND_EXPR:
1074 result = build_nt (COMPOUND_EXPR,
1075 stabilize_reference_1 (TREE_OPERAND (ref, 0)),
1076 stabilize_reference (TREE_OPERAND (ref, 1)));
1077 break;
1078
1079 case RTL_EXPR:
1080 result = build1 (INDIRECT_REF, TREE_TYPE (ref),
1081 save_expr (build1 (ADDR_EXPR,
1082 build_pointer_type (TREE_TYPE (ref)),
1083 ref)));
1084 break;
1085
1086
1087 default:
1088 return save_expr (ref);
1089
1090 case ERROR_MARK:
1091 return error_mark_node;
1092 }
1093
1094 TREE_TYPE (result) = TREE_TYPE (ref);
1095 TREE_READONLY (result) = TREE_READONLY (ref);
1096 TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (ref);
1097 TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (ref);
1098 TREE_RAISES (result) = TREE_RAISES (ref);
1099
1100 return result;
1101}
1102#endif
1103
1104/* A rip-off of gcc's convert.c convert_to_complex function,
1105 reworked to handle complex implemented as C structures
1106 (RECORD_TYPE with two fields, real and imaginary `r' and `i'). */
1107
1108#if FFECOM_targetCURRENT == FFECOM_targetGCC
1109static tree
1110ffecom_convert_to_complex_ (tree type, tree expr)
1111{
1112 register enum tree_code form = TREE_CODE (TREE_TYPE (expr));
1113 tree subtype;
1114
1115 assert (TREE_CODE (type) == RECORD_TYPE);
1116
1117 subtype = TREE_TYPE (TYPE_FIELDS (type));
1118
1119 if (form == REAL_TYPE || form == INTEGER_TYPE || form == ENUMERAL_TYPE)
1120 {
1121 expr = convert (subtype, expr);
1122 return ffecom_2 (COMPLEX_EXPR, type, expr,
1123 convert (subtype, integer_zero_node));
1124 }
1125
1126 if (form == RECORD_TYPE)
1127 {
1128 tree elt_type = TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr)));
1129 if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype))
1130 return expr;
1131 else
1132 {
1133 expr = save_expr (expr);
1134 return ffecom_2 (COMPLEX_EXPR,
1135 type,
1136 convert (subtype,
1137 ffecom_1 (REALPART_EXPR,
1138 TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))),
1139 expr)),
1140 convert (subtype,
1141 ffecom_1 (IMAGPART_EXPR,
1142 TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))),
1143 expr)));
1144 }
1145 }
1146
1147 if (form == POINTER_TYPE || form == REFERENCE_TYPE)
1148 error ("pointer value used where a complex was expected");
1149 else
1150 error ("aggregate value used where a complex was expected");
1151
1152 return ffecom_2 (COMPLEX_EXPR, type,
1153 convert (subtype, integer_zero_node),
1154 convert (subtype, integer_zero_node));
1155}
1156#endif
1157
1158/* Like gcc's convert(), but crashes if widening might happen. */
1159
1160#if FFECOM_targetCURRENT == FFECOM_targetGCC
1161static tree
1162ffecom_convert_narrow_ (type, expr)
1163 tree type, expr;
1164{
1165 register tree e = expr;
1166 register enum tree_code code = TREE_CODE (type);
1167
1168 if (type == TREE_TYPE (e)
1169 || TREE_CODE (e) == ERROR_MARK)
1170 return e;
1171 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
1172 return fold (build1 (NOP_EXPR, type, e));
1173 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
1174 || code == ERROR_MARK)
1175 return error_mark_node;
1176 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
1177 {
1178 assert ("void value not ignored as it ought to be" == NULL);
1179 return error_mark_node;
1180 }
1181 assert (code != VOID_TYPE);
1182 if ((code != RECORD_TYPE)
1183 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
1184 assert ("converting COMPLEX to REAL" == NULL);
1185 assert (code != ENUMERAL_TYPE);
1186 if (code == INTEGER_TYPE)
1187 {
a74de6ea
CB
1188 assert ((TREE_CODE (TREE_TYPE (e)) == INTEGER_TYPE
1189 && TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (e)))
1190 || (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE
1191 && (TYPE_PRECISION (type)
1192 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e))))));
5ff904cd
JL
1193 return fold (convert_to_integer (type, e));
1194 }
1195 if (code == POINTER_TYPE)
1196 {
1197 assert (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE);
1198 return fold (convert_to_pointer (type, e));
1199 }
1200 if (code == REAL_TYPE)
1201 {
1202 assert (TREE_CODE (TREE_TYPE (e)) == REAL_TYPE);
1203 assert (TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (e)));
1204 return fold (convert_to_real (type, e));
1205 }
1206 if (code == COMPLEX_TYPE)
1207 {
1208 assert (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE);
1209 assert (TYPE_PRECISION (TREE_TYPE (type)) <= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e))));
1210 return fold (convert_to_complex (type, e));
1211 }
1212 if (code == RECORD_TYPE)
1213 {
1214 assert (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE);
270fc4e8
CB
1215 /* Check that at least the first field name agrees. */
1216 assert (DECL_NAME (TYPE_FIELDS (type))
1217 == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e))));
5ff904cd
JL
1218 assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1219 <= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))));
270fc4e8
CB
1220 if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1221 == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))))
1222 return e;
5ff904cd
JL
1223 return fold (ffecom_convert_to_complex_ (type, e));
1224 }
1225
1226 assert ("conversion to non-scalar type requested" == NULL);
1227 return error_mark_node;
1228}
1229#endif
1230
1231/* Like gcc's convert(), but crashes if narrowing might happen. */
1232
1233#if FFECOM_targetCURRENT == FFECOM_targetGCC
1234static tree
1235ffecom_convert_widen_ (type, expr)
1236 tree type, expr;
1237{
1238 register tree e = expr;
1239 register enum tree_code code = TREE_CODE (type);
1240
1241 if (type == TREE_TYPE (e)
1242 || TREE_CODE (e) == ERROR_MARK)
1243 return e;
1244 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
1245 return fold (build1 (NOP_EXPR, type, e));
1246 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
1247 || code == ERROR_MARK)
1248 return error_mark_node;
1249 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
1250 {
1251 assert ("void value not ignored as it ought to be" == NULL);
1252 return error_mark_node;
1253 }
1254 assert (code != VOID_TYPE);
1255 if ((code != RECORD_TYPE)
1256 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
1257 assert ("narrowing COMPLEX to REAL" == NULL);
1258 assert (code != ENUMERAL_TYPE);
1259 if (code == INTEGER_TYPE)
1260 {
a74de6ea
CB
1261 assert ((TREE_CODE (TREE_TYPE (e)) == INTEGER_TYPE
1262 && TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (e)))
1263 || (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE
1264 && (TYPE_PRECISION (type)
1265 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e))))));
5ff904cd
JL
1266 return fold (convert_to_integer (type, e));
1267 }
1268 if (code == POINTER_TYPE)
1269 {
1270 assert (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE);
1271 return fold (convert_to_pointer (type, e));
1272 }
1273 if (code == REAL_TYPE)
1274 {
1275 assert (TREE_CODE (TREE_TYPE (e)) == REAL_TYPE);
1276 assert (TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (e)));
1277 return fold (convert_to_real (type, e));
1278 }
1279 if (code == COMPLEX_TYPE)
1280 {
1281 assert (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE);
1282 assert (TYPE_PRECISION (TREE_TYPE (type)) >= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e))));
1283 return fold (convert_to_complex (type, e));
1284 }
1285 if (code == RECORD_TYPE)
1286 {
1287 assert (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE);
270fc4e8
CB
1288 /* Check that at least the first field name agrees. */
1289 assert (DECL_NAME (TYPE_FIELDS (type))
1290 == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e))));
5ff904cd
JL
1291 assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1292 >= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))));
270fc4e8
CB
1293 if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1294 == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))))
1295 return e;
5ff904cd
JL
1296 return fold (ffecom_convert_to_complex_ (type, e));
1297 }
1298
1299 assert ("conversion to non-scalar type requested" == NULL);
1300 return error_mark_node;
1301}
1302#endif
1303
1304/* Handles making a COMPLEX type, either the standard
1305 (but buggy?) gbe way, or the safer (but less elegant?)
1306 f2c way. */
1307
1308#if FFECOM_targetCURRENT == FFECOM_targetGCC
1309static tree
1310ffecom_make_complex_type_ (tree subtype)
1311{
1312 tree type;
1313 tree realfield;
1314 tree imagfield;
1315
1316 if (ffe_is_emulate_complex ())
1317 {
1318 type = make_node (RECORD_TYPE);
1319 realfield = ffecom_decl_field (type, NULL_TREE, "r", subtype);
1320 imagfield = ffecom_decl_field (type, realfield, "i", subtype);
1321 TYPE_FIELDS (type) = realfield;
1322 layout_type (type);
1323 }
1324 else
1325 {
1326 type = make_node (COMPLEX_TYPE);
1327 TREE_TYPE (type) = subtype;
1328 layout_type (type);
1329 }
1330
1331 return type;
1332}
1333#endif
1334
1335/* Chooses either the gbe or the f2c way to build a
1336 complex constant. */
1337
1338#if FFECOM_targetCURRENT == FFECOM_targetGCC
1339static tree
1340ffecom_build_complex_constant_ (tree type, tree realpart, tree imagpart)
1341{
1342 tree bothparts;
1343
1344 if (ffe_is_emulate_complex ())
1345 {
1346 bothparts = build_tree_list (TYPE_FIELDS (type), realpart);
1347 TREE_CHAIN (bothparts) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), imagpart);
1348 bothparts = build (CONSTRUCTOR, type, NULL_TREE, bothparts);
1349 }
1350 else
1351 {
1352 bothparts = build_complex (type, realpart, imagpart);
1353 }
1354
1355 return bothparts;
1356}
1357#endif
1358
1359#if FFECOM_targetCURRENT == FFECOM_targetGCC
1360static tree
26f096f9 1361ffecom_arglist_expr_ (const char *c, ffebld expr)
5ff904cd
JL
1362{
1363 tree list;
1364 tree *plist = &list;
1365 tree trail = NULL_TREE; /* Append char length args here. */
1366 tree *ptrail = &trail;
1367 tree length;
1368 ffebld exprh;
1369 tree item;
1370 bool ptr = FALSE;
1371 tree wanted = NULL_TREE;
e2fa159e
JL
1372 static char zed[] = "0";
1373
1374 if (c == NULL)
1375 c = &zed[0];
5ff904cd
JL
1376
1377 while (expr != NULL)
1378 {
1379 if (*c != '\0')
1380 {
1381 ptr = FALSE;
1382 if (*c == '&')
1383 {
1384 ptr = TRUE;
1385 ++c;
1386 }
1387 switch (*(c++))
1388 {
1389 case '\0':
1390 ptr = TRUE;
1391 wanted = NULL_TREE;
1392 break;
1393
1394 case 'a':
1395 assert (ptr);
1396 wanted = NULL_TREE;
1397 break;
1398
1399 case 'c':
1400 wanted = ffecom_f2c_complex_type_node;
1401 break;
1402
1403 case 'd':
1404 wanted = ffecom_f2c_doublereal_type_node;
1405 break;
1406
1407 case 'e':
1408 wanted = ffecom_f2c_doublecomplex_type_node;
1409 break;
1410
1411 case 'f':
1412 wanted = ffecom_f2c_real_type_node;
1413 break;
1414
1415 case 'i':
1416 wanted = ffecom_f2c_integer_type_node;
1417 break;
1418
1419 case 'j':
1420 wanted = ffecom_f2c_longint_type_node;
1421 break;
1422
1423 default:
1424 assert ("bad argstring code" == NULL);
1425 wanted = NULL_TREE;
1426 break;
1427 }
1428 }
1429
1430 exprh = ffebld_head (expr);
1431 if (exprh == NULL)
1432 wanted = NULL_TREE;
1433
1434 if ((wanted == NULL_TREE)
1435 || (ptr
1436 && (TYPE_MODE
1437 (ffecom_tree_type[ffeinfo_basictype (ffebld_info (exprh))]
1438 [ffeinfo_kindtype (ffebld_info (exprh))])
1439 == TYPE_MODE (wanted))))
1440 *plist
1441 = build_tree_list (NULL_TREE,
1442 ffecom_arg_ptr_to_expr (exprh,
1443 &length));
1444 else
1445 {
1446 item = ffecom_arg_expr (exprh, &length);
1447 item = ffecom_convert_widen_ (wanted, item);
1448 if (ptr)
1449 {
1450 item = ffecom_1 (ADDR_EXPR,
1451 build_pointer_type (TREE_TYPE (item)),
1452 item);
1453 }
1454 *plist
1455 = build_tree_list (NULL_TREE,
1456 item);
1457 }
1458
1459 plist = &TREE_CHAIN (*plist);
1460 expr = ffebld_trail (expr);
1461 if (length != NULL_TREE)
1462 {
1463 *ptrail = build_tree_list (NULL_TREE, length);
1464 ptrail = &TREE_CHAIN (*ptrail);
1465 }
1466 }
1467
e2fa159e
JL
1468 /* We've run out of args in the call; if the implementation expects
1469 more, supply null pointers for them, which the implementation can
1470 check to see if an arg was omitted. */
1471
1472 while (*c != '\0' && *c != '0')
1473 {
1474 if (*c == '&')
1475 ++c;
1476 else
1477 assert ("missing arg to run-time routine!" == NULL);
1478
1479 switch (*(c++))
1480 {
1481 case '\0':
1482 case 'a':
1483 case 'c':
1484 case 'd':
1485 case 'e':
1486 case 'f':
1487 case 'i':
1488 case 'j':
1489 break;
1490
1491 default:
1492 assert ("bad arg string code" == NULL);
1493 break;
1494 }
1495 *plist
1496 = build_tree_list (NULL_TREE,
1497 null_pointer_node);
1498 plist = &TREE_CHAIN (*plist);
1499 }
1500
5ff904cd
JL
1501 *plist = trail;
1502
1503 return list;
1504}
1505#endif
1506
1507#if FFECOM_targetCURRENT == FFECOM_targetGCC
1508static tree
1509ffecom_widest_expr_type_ (ffebld list)
1510{
1511 ffebld item;
1512 ffebld widest = NULL;
1513 ffetype type;
1514 ffetype widest_type = NULL;
1515 tree t;
1516
1517 for (; list != NULL; list = ffebld_trail (list))
1518 {
1519 item = ffebld_head (list);
1520 if (item == NULL)
1521 continue;
1522 if ((widest != NULL)
1523 && (ffeinfo_basictype (ffebld_info (item))
1524 != ffeinfo_basictype (ffebld_info (widest))))
1525 continue;
1526 type = ffeinfo_type (ffeinfo_basictype (ffebld_info (item)),
1527 ffeinfo_kindtype (ffebld_info (item)));
1528 if ((widest == FFEINFO_kindtypeNONE)
1529 || (ffetype_size (type)
1530 > ffetype_size (widest_type)))
1531 {
1532 widest = item;
1533 widest_type = type;
1534 }
1535 }
1536
1537 assert (widest != NULL);
1538 t = ffecom_tree_type[ffeinfo_basictype (ffebld_info (widest))]
1539 [ffeinfo_kindtype (ffebld_info (widest))];
1540 assert (t != NULL_TREE);
1541 return t;
1542}
1543#endif
1544
d6cd84e0
CB
1545/* Check whether a partial overlap between two expressions is possible.
1546
1547 Can *starting* to write a portion of expr1 change the value
1548 computed (perhaps already, *partially*) by expr2?
1549
1550 Currently, this is a concern only for a COMPLEX expr1. But if it
1551 isn't in COMMON or local EQUIVALENCE, since we don't support
1552 aliasing of arguments, it isn't a concern. */
1553
1554static bool
b0791fa9 1555ffecom_possible_partial_overlap_ (ffebld expr1, ffebld expr2 ATTRIBUTE_UNUSED)
d6cd84e0
CB
1556{
1557 ffesymbol sym;
1558 ffestorag st;
1559
1560 switch (ffebld_op (expr1))
1561 {
1562 case FFEBLD_opSYMTER:
1563 sym = ffebld_symter (expr1);
1564 break;
1565
1566 case FFEBLD_opARRAYREF:
1567 if (ffebld_op (ffebld_left (expr1)) != FFEBLD_opSYMTER)
1568 return FALSE;
1569 sym = ffebld_symter (ffebld_left (expr1));
1570 break;
1571
1572 default:
1573 return FALSE;
1574 }
1575
1576 if (ffesymbol_where (sym) != FFEINFO_whereCOMMON
1577 && (ffesymbol_where (sym) != FFEINFO_whereLOCAL
1578 || ! (st = ffesymbol_storage (sym))
1579 || ! ffestorag_parent (st)))
1580 return FALSE;
1581
1582 /* It's in COMMON or local EQUIVALENCE. */
1583
1584 return TRUE;
1585}
1586
5ff904cd
JL
1587/* Check whether dest and source might overlap. ffebld versions of these
1588 might or might not be passed, will be NULL if not.
1589
1590 The test is really whether source_tree is modifiable and, if modified,
1591 might overlap destination such that the value(s) in the destination might
1592 change before it is finally modified. dest_* are the canonized
1593 destination itself. */
1594
1595#if FFECOM_targetCURRENT == FFECOM_targetGCC
1596static bool
1597ffecom_overlap_ (tree dest_decl, tree dest_offset, tree dest_size,
1598 tree source_tree, ffebld source UNUSED,
1599 bool scalar_arg)
1600{
1601 tree source_decl;
1602 tree source_offset;
1603 tree source_size;
1604 tree t;
1605
1606 if (source_tree == NULL_TREE)
1607 return FALSE;
1608
1609 switch (TREE_CODE (source_tree))
1610 {
1611 case ERROR_MARK:
1612 case IDENTIFIER_NODE:
1613 case INTEGER_CST:
1614 case REAL_CST:
1615 case COMPLEX_CST:
1616 case STRING_CST:
1617 case CONST_DECL:
1618 case VAR_DECL:
1619 case RESULT_DECL:
1620 case FIELD_DECL:
1621 case MINUS_EXPR:
1622 case MULT_EXPR:
1623 case TRUNC_DIV_EXPR:
1624 case CEIL_DIV_EXPR:
1625 case FLOOR_DIV_EXPR:
1626 case ROUND_DIV_EXPR:
1627 case TRUNC_MOD_EXPR:
1628 case CEIL_MOD_EXPR:
1629 case FLOOR_MOD_EXPR:
1630 case ROUND_MOD_EXPR:
1631 case RDIV_EXPR:
1632 case EXACT_DIV_EXPR:
1633 case FIX_TRUNC_EXPR:
1634 case FIX_CEIL_EXPR:
1635 case FIX_FLOOR_EXPR:
1636 case FIX_ROUND_EXPR:
1637 case FLOAT_EXPR:
1638 case EXPON_EXPR:
1639 case NEGATE_EXPR:
1640 case MIN_EXPR:
1641 case MAX_EXPR:
1642 case ABS_EXPR:
1643 case FFS_EXPR:
1644 case LSHIFT_EXPR:
1645 case RSHIFT_EXPR:
1646 case LROTATE_EXPR:
1647 case RROTATE_EXPR:
1648 case BIT_IOR_EXPR:
1649 case BIT_XOR_EXPR:
1650 case BIT_AND_EXPR:
1651 case BIT_ANDTC_EXPR:
1652 case BIT_NOT_EXPR:
1653 case TRUTH_ANDIF_EXPR:
1654 case TRUTH_ORIF_EXPR:
1655 case TRUTH_AND_EXPR:
1656 case TRUTH_OR_EXPR:
1657 case TRUTH_XOR_EXPR:
1658 case TRUTH_NOT_EXPR:
1659 case LT_EXPR:
1660 case LE_EXPR:
1661 case GT_EXPR:
1662 case GE_EXPR:
1663 case EQ_EXPR:
1664 case NE_EXPR:
1665 case COMPLEX_EXPR:
1666 case CONJ_EXPR:
1667 case REALPART_EXPR:
1668 case IMAGPART_EXPR:
1669 case LABEL_EXPR:
1670 case COMPONENT_REF:
1671 return FALSE;
1672
1673 case COMPOUND_EXPR:
1674 return ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1675 TREE_OPERAND (source_tree, 1), NULL,
1676 scalar_arg);
1677
1678 case MODIFY_EXPR:
1679 return ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1680 TREE_OPERAND (source_tree, 0), NULL,
1681 scalar_arg);
1682
1683 case CONVERT_EXPR:
1684 case NOP_EXPR:
1685 case NON_LVALUE_EXPR:
1686 case PLUS_EXPR:
1687 if (TREE_CODE (TREE_TYPE (source_tree)) != POINTER_TYPE)
1688 return TRUE;
1689
1690 ffecom_tree_canonize_ptr_ (&source_decl, &source_offset,
1691 source_tree);
1692 source_size = TYPE_SIZE (TREE_TYPE (TREE_TYPE (source_tree)));
1693 break;
1694
1695 case COND_EXPR:
1696 return
1697 ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1698 TREE_OPERAND (source_tree, 1), NULL,
1699 scalar_arg)
1700 || ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1701 TREE_OPERAND (source_tree, 2), NULL,
1702 scalar_arg);
1703
1704
1705 case ADDR_EXPR:
1706 ffecom_tree_canonize_ref_ (&source_decl, &source_offset,
1707 &source_size,
1708 TREE_OPERAND (source_tree, 0));
1709 break;
1710
1711 case PARM_DECL:
1712 if (TREE_CODE (TREE_TYPE (source_tree)) != POINTER_TYPE)
1713 return TRUE;
1714
1715 source_decl = source_tree;
1716 source_offset = size_zero_node;
1717 source_size = TYPE_SIZE (TREE_TYPE (TREE_TYPE (source_tree)));
1718 break;
1719
1720 case SAVE_EXPR:
1721 case REFERENCE_EXPR:
1722 case PREDECREMENT_EXPR:
1723 case PREINCREMENT_EXPR:
1724 case POSTDECREMENT_EXPR:
1725 case POSTINCREMENT_EXPR:
1726 case INDIRECT_REF:
1727 case ARRAY_REF:
1728 case CALL_EXPR:
1729 default:
1730 return TRUE;
1731 }
1732
1733 /* Come here when source_decl, source_offset, and source_size filled
1734 in appropriately. */
1735
1736 if (source_decl == NULL_TREE)
1737 return FALSE; /* No decl involved, so no overlap. */
1738
1739 if (source_decl != dest_decl)
1740 return FALSE; /* Different decl, no overlap. */
1741
1742 if (TREE_CODE (dest_size) == ERROR_MARK)
1743 return TRUE; /* Assignment into entire assumed-size
1744 array? Shouldn't happen.... */
1745
1746 t = ffecom_2 (LE_EXPR, integer_type_node,
1747 ffecom_2 (PLUS_EXPR, TREE_TYPE (dest_offset),
1748 dest_offset,
1749 convert (TREE_TYPE (dest_offset),
1750 dest_size)),
1751 convert (TREE_TYPE (dest_offset),
1752 source_offset));
1753
1754 if (integer_onep (t))
1755 return FALSE; /* Destination precedes source. */
1756
1757 if (!scalar_arg
1758 || (source_size == NULL_TREE)
1759 || (TREE_CODE (source_size) == ERROR_MARK)
1760 || integer_zerop (source_size))
1761 return TRUE; /* No way to tell if dest follows source. */
1762
1763 t = ffecom_2 (LE_EXPR, integer_type_node,
1764 ffecom_2 (PLUS_EXPR, TREE_TYPE (source_offset),
1765 source_offset,
1766 convert (TREE_TYPE (source_offset),
1767 source_size)),
1768 convert (TREE_TYPE (source_offset),
1769 dest_offset));
1770
1771 if (integer_onep (t))
1772 return FALSE; /* Destination follows source. */
1773
1774 return TRUE; /* Destination and source overlap. */
1775}
1776#endif
1777
1778/* Check whether dest might overlap any of a list of arguments or is
1779 in a COMMON area the callee might know about (and thus modify). */
1780
1781#if FFECOM_targetCURRENT == FFECOM_targetGCC
1782static bool
1783ffecom_args_overlapping_ (tree dest_tree, ffebld dest UNUSED,
1784 tree args, tree callee_commons,
1785 bool scalar_args)
1786{
1787 tree arg;
1788 tree dest_decl;
1789 tree dest_offset;
1790 tree dest_size;
1791
1792 ffecom_tree_canonize_ref_ (&dest_decl, &dest_offset, &dest_size,
1793 dest_tree);
1794
1795 if (dest_decl == NULL_TREE)
1796 return FALSE; /* Seems unlikely! */
1797
1798 /* If the decl cannot be determined reliably, or if its in COMMON
1799 and the callee isn't known to not futz with COMMON via other
1800 means, overlap might happen. */
1801
1802 if ((TREE_CODE (dest_decl) == ERROR_MARK)
1803 || ((callee_commons != NULL_TREE)
1804 && TREE_PUBLIC (dest_decl)))
1805 return TRUE;
1806
1807 for (; args != NULL_TREE; args = TREE_CHAIN (args))
1808 {
1809 if (((arg = TREE_VALUE (args)) != NULL_TREE)
1810 && ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1811 arg, NULL, scalar_args))
1812 return TRUE;
1813 }
1814
1815 return FALSE;
1816}
1817#endif
1818
1819/* Build a string for a variable name as used by NAMELIST. This means that
1820 if we're using the f2c library, we build an uppercase string, since
1821 f2c does this. */
1822
1823#if FFECOM_targetCURRENT == FFECOM_targetGCC
1824static tree
26f096f9 1825ffecom_build_f2c_string_ (int i, const char *s)
5ff904cd
JL
1826{
1827 if (!ffe_is_f2c_library ())
1828 return build_string (i, s);
1829
1830 {
1831 char *tmp;
26f096f9 1832 const char *p;
5ff904cd
JL
1833 char *q;
1834 char space[34];
1835 tree t;
1836
1837 if (((size_t) i) > ARRAY_SIZE (space))
1838 tmp = malloc_new_ks (malloc_pool_image (), "f2c_string", i);
1839 else
1840 tmp = &space[0];
1841
1842 for (p = s, q = tmp; *p != '\0'; ++p, ++q)
1843 *q = ffesrc_toupper (*p);
1844 *q = '\0';
1845
1846 t = build_string (i, tmp);
1847
1848 if (((size_t) i) > ARRAY_SIZE (space))
1849 malloc_kill_ks (malloc_pool_image (), tmp, i);
1850
1851 return t;
1852 }
1853}
1854
1855#endif
1856/* Returns CALL_EXPR or equivalent with given type (pass NULL_TREE for
1857 type to just get whatever the function returns), handling the
1858 f2c value-returning convention, if required, by prepending
1859 to the arglist a pointer to a temporary to receive the return value. */
1860
1861#if FFECOM_targetCURRENT == FFECOM_targetGCC
1862static tree
1863ffecom_call_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex,
1864 tree type, tree args, tree dest_tree,
1865 ffebld dest, bool *dest_used, tree callee_commons,
c7e4ee3a 1866 bool scalar_args, tree hook)
5ff904cd
JL
1867{
1868 tree item;
1869 tree tempvar;
1870
1871 if (dest_used != NULL)
1872 *dest_used = FALSE;
1873
1874 if (is_f2c_complex)
1875 {
1876 if ((dest_used == NULL)
1877 || (dest == NULL)
1878 || (ffeinfo_basictype (ffebld_info (dest))
1879 != FFEINFO_basictypeCOMPLEX)
1880 || (ffeinfo_kindtype (ffebld_info (dest)) != kt)
1881 || ((type != NULL_TREE) && (TREE_TYPE (dest_tree) != type))
1882 || ffecom_args_overlapping_ (dest_tree, dest, args,
1883 callee_commons,
1884 scalar_args))
1885 {
c7e4ee3a
CB
1886#ifdef HOHO
1887 tempvar = ffecom_make_tempvar (ffecom_tree_type
5ff904cd
JL
1888 [FFEINFO_basictypeCOMPLEX][kt],
1889 FFETARGET_charactersizeNONE,
c7e4ee3a
CB
1890 -1);
1891#else
1892 tempvar = hook;
1893 assert (tempvar);
1894#endif
5ff904cd
JL
1895 }
1896 else
1897 {
1898 *dest_used = TRUE;
1899 tempvar = dest_tree;
1900 type = NULL_TREE;
1901 }
1902
1903 item
1904 = build_tree_list (NULL_TREE,
1905 ffecom_1 (ADDR_EXPR,
c7e4ee3a 1906 build_pointer_type (TREE_TYPE (tempvar)),
5ff904cd
JL
1907 tempvar));
1908 TREE_CHAIN (item) = args;
1909
1910 item = ffecom_3s (CALL_EXPR, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), fn,
1911 item, NULL_TREE);
1912
1913 if (tempvar != dest_tree)
1914 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), item, tempvar);
1915 }
1916 else
1917 item = ffecom_3s (CALL_EXPR, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), fn,
1918 args, NULL_TREE);
1919
1920 if ((type != NULL_TREE) && (TREE_TYPE (item) != type))
1921 item = ffecom_convert_narrow_ (type, item);
1922
1923 return item;
1924}
1925#endif
1926
1927/* Given two arguments, transform them and make a call to the given
1928 function via ffecom_call_. */
1929
1930#if FFECOM_targetCURRENT == FFECOM_targetGCC
1931static tree
1932ffecom_call_binop_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex,
1933 tree type, ffebld left, ffebld right,
1934 tree dest_tree, ffebld dest, bool *dest_used,
c7e4ee3a 1935 tree callee_commons, bool scalar_args, tree hook)
5ff904cd
JL
1936{
1937 tree left_tree;
1938 tree right_tree;
1939 tree left_length;
1940 tree right_length;
1941
5ff904cd
JL
1942 left_tree = ffecom_arg_ptr_to_expr (left, &left_length);
1943 right_tree = ffecom_arg_ptr_to_expr (right, &right_length);
5ff904cd
JL
1944
1945 left_tree = build_tree_list (NULL_TREE, left_tree);
1946 right_tree = build_tree_list (NULL_TREE, right_tree);
1947 TREE_CHAIN (left_tree) = right_tree;
1948
1949 if (left_length != NULL_TREE)
1950 {
1951 left_length = build_tree_list (NULL_TREE, left_length);
1952 TREE_CHAIN (right_tree) = left_length;
1953 }
1954
1955 if (right_length != NULL_TREE)
1956 {
1957 right_length = build_tree_list (NULL_TREE, right_length);
1958 if (left_length != NULL_TREE)
1959 TREE_CHAIN (left_length) = right_length;
1960 else
1961 TREE_CHAIN (right_tree) = right_length;
1962 }
1963
1964 return ffecom_call_ (fn, kt, is_f2c_complex, type, left_tree,
1965 dest_tree, dest, dest_used, callee_commons,
c7e4ee3a 1966 scalar_args, hook);
5ff904cd
JL
1967}
1968#endif
1969
c7e4ee3a 1970/* Return ptr/length args for char subexpression
5ff904cd
JL
1971
1972 Handles CHARACTER-type CONTER, SYMTER, SUBSTR, ARRAYREF, and FUNCREF
1973 subexpressions by constructing the appropriate trees for the ptr-to-
1974 character-text and length-of-character-text arguments in a calling
86fc7a6c
CB
1975 sequence.
1976
1977 Note that if with_null is TRUE, and the expression is an opCONTER,
1978 a null byte is appended to the string. */
5ff904cd
JL
1979
1980#if FFECOM_targetCURRENT == FFECOM_targetGCC
1981static void
86fc7a6c 1982ffecom_char_args_x_ (tree *xitem, tree *length, ffebld expr, bool with_null)
5ff904cd
JL
1983{
1984 tree item;
1985 tree high;
1986 ffetargetCharacter1 val;
86fc7a6c 1987 ffetargetCharacterSize newlen;
5ff904cd
JL
1988
1989 switch (ffebld_op (expr))
1990 {
1991 case FFEBLD_opCONTER:
1992 val = ffebld_constant_character1 (ffebld_conter (expr));
86fc7a6c
CB
1993 newlen = ffetarget_length_character1 (val);
1994 if (with_null)
1995 {
c7e4ee3a 1996 /* Begin FFETARGET-NULL-KLUDGE. */
86fc7a6c 1997 if (newlen != 0)
c7e4ee3a 1998 ++newlen;
86fc7a6c
CB
1999 }
2000 *length = build_int_2 (newlen, 0);
5ff904cd 2001 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
86fc7a6c 2002 high = build_int_2 (newlen, 0);
5ff904cd 2003 TREE_TYPE (high) = ffecom_f2c_ftnlen_type_node;
c7e4ee3a 2004 item = build_string (newlen,
5ff904cd 2005 ffetarget_text_character1 (val));
c7e4ee3a 2006 /* End FFETARGET-NULL-KLUDGE. */
5ff904cd
JL
2007 TREE_TYPE (item)
2008 = build_type_variant
2009 (build_array_type
2010 (char_type_node,
2011 build_range_type
2012 (ffecom_f2c_ftnlen_type_node,
2013 ffecom_f2c_ftnlen_one_node,
2014 high)),
2015 1, 0);
2016 TREE_CONSTANT (item) = 1;
2017 TREE_STATIC (item) = 1;
2018 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
2019 item);
2020 break;
2021
2022 case FFEBLD_opSYMTER:
2023 {
2024 ffesymbol s = ffebld_symter (expr);
2025
2026 item = ffesymbol_hook (s).decl_tree;
2027 if (item == NULL_TREE)
2028 {
2029 s = ffecom_sym_transform_ (s);
2030 item = ffesymbol_hook (s).decl_tree;
2031 }
2032 if (ffesymbol_kind (s) == FFEINFO_kindENTITY)
2033 {
2034 if (ffesymbol_size (s) == FFETARGET_charactersizeNONE)
2035 *length = ffesymbol_hook (s).length_tree;
2036 else
2037 {
2038 *length = build_int_2 (ffesymbol_size (s), 0);
2039 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
2040 }
2041 }
2042 else if (item == error_mark_node)
2043 *length = error_mark_node;
c7e4ee3a
CB
2044 else
2045 /* FFEINFO_kindFUNCTION. */
5ff904cd
JL
2046 *length = NULL_TREE;
2047 if (!ffesymbol_hook (s).addr
2048 && (item != error_mark_node))
2049 item = ffecom_1 (ADDR_EXPR,
2050 build_pointer_type (TREE_TYPE (item)),
2051 item);
2052 }
2053 break;
2054
2055 case FFEBLD_opARRAYREF:
2056 {
5ff904cd 2057 ffecom_char_args_ (&item, length, ffebld_left (expr));
5ff904cd
JL
2058
2059 if (item == error_mark_node || *length == error_mark_node)
2060 {
2061 item = *length = error_mark_node;
2062 break;
2063 }
2064
6b55276e 2065 item = ffecom_arrayref_ (item, expr, 1);
5ff904cd
JL
2066 }
2067 break;
2068
2069 case FFEBLD_opSUBSTR:
2070 {
2071 ffebld start;
2072 ffebld end;
2073 ffebld thing = ffebld_right (expr);
2074 tree start_tree;
2075 tree end_tree;
6b55276e
CB
2076 char *char_name;
2077 ffebld left_symter;
2078 tree array;
5ff904cd
JL
2079
2080 assert (ffebld_op (thing) == FFEBLD_opITEM);
2081 start = ffebld_head (thing);
2082 thing = ffebld_trail (thing);
2083 assert (ffebld_trail (thing) == NULL);
2084 end = ffebld_head (thing);
2085
6b55276e
CB
2086 /* Determine name for pretty-printing range-check errors. */
2087 for (left_symter = ffebld_left (expr);
2088 left_symter && ffebld_op (left_symter) == FFEBLD_opARRAYREF;
2089 left_symter = ffebld_left (left_symter))
2090 ;
2091 if (ffebld_op (left_symter) == FFEBLD_opSYMTER)
2092 char_name = ffesymbol_text (ffebld_symter (left_symter));
2093 else
2094 char_name = "[expr?]";
2095
5ff904cd 2096 ffecom_char_args_ (&item, length, ffebld_left (expr));
5ff904cd
JL
2097
2098 if (item == error_mark_node || *length == error_mark_node)
2099 {
2100 item = *length = error_mark_node;
2101 break;
2102 }
2103
6b55276e
CB
2104 array = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item)));
2105
ff852b44
CB
2106 /* ~~~~Handle INTEGER*8 start/end, a la FFEBLD_opARRAYREF. */
2107
5ff904cd
JL
2108 if (start == NULL)
2109 {
2110 if (end == NULL)
2111 ;
2112 else
2113 {
6b55276e 2114 end_tree = ffecom_expr (end);
02f06e64 2115 if (flag_bounds_check)
6b55276e
CB
2116 end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0,
2117 char_name);
5ff904cd 2118 end_tree = convert (ffecom_f2c_ftnlen_type_node,
6b55276e 2119 end_tree);
5ff904cd
JL
2120
2121 if (end_tree == error_mark_node)
2122 {
2123 item = *length = error_mark_node;
2124 break;
2125 }
2126
2127 *length = end_tree;
2128 }
2129 }
2130 else
2131 {
6b55276e 2132 start_tree = ffecom_expr (start);
02f06e64 2133 if (flag_bounds_check)
6b55276e
CB
2134 start_tree = ffecom_subscript_check_ (array, start_tree, 0, 0,
2135 char_name);
5ff904cd 2136 start_tree = convert (ffecom_f2c_ftnlen_type_node,
6b55276e 2137 start_tree);
5ff904cd
JL
2138
2139 if (start_tree == error_mark_node)
2140 {
2141 item = *length = error_mark_node;
2142 break;
2143 }
2144
2145 start_tree = ffecom_save_tree (start_tree);
2146
2147 item = ffecom_2 (PLUS_EXPR, TREE_TYPE (item),
2148 item,
2149 ffecom_2 (MINUS_EXPR,
2150 TREE_TYPE (start_tree),
2151 start_tree,
2152 ffecom_f2c_ftnlen_one_node));
2153
2154 if (end == NULL)
2155 {
2156 *length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
2157 ffecom_f2c_ftnlen_one_node,
2158 ffecom_2 (MINUS_EXPR,
2159 ffecom_f2c_ftnlen_type_node,
2160 *length,
2161 start_tree));
2162 }
2163 else
2164 {
6b55276e 2165 end_tree = ffecom_expr (end);
02f06e64 2166 if (flag_bounds_check)
6b55276e
CB
2167 end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0,
2168 char_name);
5ff904cd 2169 end_tree = convert (ffecom_f2c_ftnlen_type_node,
6b55276e 2170 end_tree);
5ff904cd
JL
2171
2172 if (end_tree == error_mark_node)
2173 {
2174 item = *length = error_mark_node;
2175 break;
2176 }
2177
2178 *length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
2179 ffecom_f2c_ftnlen_one_node,
2180 ffecom_2 (MINUS_EXPR,
2181 ffecom_f2c_ftnlen_type_node,
2182 end_tree, start_tree));
2183 }
2184 }
2185 }
2186 break;
2187
2188 case FFEBLD_opFUNCREF:
2189 {
2190 ffesymbol s = ffebld_symter (ffebld_left (expr));
2191 tree tempvar;
2192 tree args;
2193 ffetargetCharacterSize size = ffeinfo_size (ffebld_info (expr));
2194 ffecomGfrt ix;
2195
2196 if (size == FFETARGET_charactersizeNONE)
c7e4ee3a
CB
2197 /* ~~Kludge alert! This should someday be fixed. */
2198 size = 24;
5ff904cd
JL
2199
2200 *length = build_int_2 (size, 0);
2201 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
2202
2203 if (ffeinfo_where (ffebld_info (ffebld_left (expr)))
2204 == FFEINFO_whereINTRINSIC)
2205 {
2206 if (size == 1)
c7e4ee3a
CB
2207 {
2208 /* Invocation of an intrinsic returning CHARACTER*1. */
5ff904cd
JL
2209 item = ffecom_expr_intrinsic_ (expr, NULL_TREE,
2210 NULL, NULL);
2211 break;
2212 }
2213 ix = ffeintrin_gfrt_direct (ffebld_symter_implementation (ffebld_left (expr)));
2214 assert (ix != FFECOM_gfrt);
2215 item = ffecom_gfrt_tree_ (ix);
2216 }
2217 else
2218 {
2219 ix = FFECOM_gfrt;
2220 item = ffesymbol_hook (s).decl_tree;
2221 if (item == NULL_TREE)
2222 {
2223 s = ffecom_sym_transform_ (s);
2224 item = ffesymbol_hook (s).decl_tree;
2225 }
2226 if (item == error_mark_node)
2227 {
2228 item = *length = error_mark_node;
2229 break;
2230 }
2231
2232 if (!ffesymbol_hook (s).addr)
2233 item = ffecom_1_fn (item);
2234 }
2235
c7e4ee3a 2236#ifdef HOHO
5ff904cd 2237 tempvar = ffecom_push_tempvar (char_type_node, size, -1, TRUE);
c7e4ee3a
CB
2238#else
2239 tempvar = ffebld_nonter_hook (expr);
2240 assert (tempvar);
2241#endif
5ff904cd
JL
2242 tempvar = ffecom_1 (ADDR_EXPR,
2243 build_pointer_type (TREE_TYPE (tempvar)),
2244 tempvar);
2245
5ff904cd
JL
2246 args = build_tree_list (NULL_TREE, tempvar);
2247
2248 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT) /* Sfunc args by value. */
2249 TREE_CHAIN (args) = ffecom_list_expr (ffebld_right (expr));
2250 else
2251 {
2252 TREE_CHAIN (args) = build_tree_list (NULL_TREE, *length);
2253 if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC)
2254 {
2255 TREE_CHAIN (TREE_CHAIN (args))
2256 = ffecom_arglist_expr_ (ffecom_gfrt_args_ (ix),
2257 ffebld_right (expr));
2258 }
2259 else
2260 {
2261 TREE_CHAIN (TREE_CHAIN (args))
2262 = ffecom_list_ptr_to_expr (ffebld_right (expr));
2263 }
2264 }
2265
2266 item = ffecom_3s (CALL_EXPR,
2267 TREE_TYPE (TREE_TYPE (TREE_TYPE (item))),
2268 item, args, NULL_TREE);
2269 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), item,
2270 tempvar);
5ff904cd
JL
2271 }
2272 break;
2273
2274 case FFEBLD_opCONVERT:
2275
5ff904cd 2276 ffecom_char_args_ (&item, length, ffebld_left (expr));
5ff904cd
JL
2277
2278 if (item == error_mark_node || *length == error_mark_node)
2279 {
2280 item = *length = error_mark_node;
2281 break;
2282 }
2283
2284 if ((ffebld_size_known (ffebld_left (expr))
2285 == FFETARGET_charactersizeNONE)
2286 || (ffebld_size_known (ffebld_left (expr)) < (ffebld_size (expr))))
2287 { /* Possible blank-padding needed, copy into
2288 temporary. */
2289 tree tempvar;
2290 tree args;
2291 tree newlen;
2292
c7e4ee3a
CB
2293#ifdef HOHO
2294 tempvar = ffecom_make_tempvar (char_type_node,
2295 ffebld_size (expr), -1);
2296#else
2297 tempvar = ffebld_nonter_hook (expr);
2298 assert (tempvar);
2299#endif
5ff904cd
JL
2300 tempvar = ffecom_1 (ADDR_EXPR,
2301 build_pointer_type (TREE_TYPE (tempvar)),
2302 tempvar);
2303
2304 newlen = build_int_2 (ffebld_size (expr), 0);
2305 TREE_TYPE (newlen) = ffecom_f2c_ftnlen_type_node;
2306
2307 args = build_tree_list (NULL_TREE, tempvar);
2308 TREE_CHAIN (args) = build_tree_list (NULL_TREE, item);
2309 TREE_CHAIN (TREE_CHAIN (args)) = build_tree_list (NULL_TREE, newlen);
2310 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (args)))
2311 = build_tree_list (NULL_TREE, *length);
2312
c7e4ee3a 2313 item = ffecom_call_gfrt (FFECOM_gfrtCOPY, args, NULL_TREE);
5ff904cd
JL
2314 TREE_SIDE_EFFECTS (item) = 1;
2315 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), fold (item),
2316 tempvar);
2317 *length = newlen;
2318 }
2319 else
2320 { /* Just truncate the length. */
2321 *length = build_int_2 (ffebld_size (expr), 0);
2322 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
2323 }
2324 break;
2325
2326 default:
2327 assert ("bad op for single char arg expr" == NULL);
2328 item = NULL_TREE;
2329 break;
2330 }
2331
2332 *xitem = item;
2333}
2334#endif
2335
2336/* Check the size of the type to be sure it doesn't overflow the
2337 "portable" capacities of the compiler back end. `dummy' types
2338 can generally overflow the normal sizes as long as the computations
2339 themselves don't overflow. A particular target of the back end
2340 must still enforce its size requirements, though, and the back
2341 end takes care of this in stor-layout.c. */
2342
2343#if FFECOM_targetCURRENT == FFECOM_targetGCC
2344static tree
2345ffecom_check_size_overflow_ (ffesymbol s, tree type, bool dummy)
2346{
2347 if (TREE_CODE (type) == ERROR_MARK)
2348 return type;
2349
2350 if (TYPE_SIZE (type) == NULL_TREE)
2351 return type;
2352
2353 if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
2354 return type;
2355
2356 if ((tree_int_cst_sgn (TYPE_SIZE (type)) < 0)
2b0c2df0
CB
2357 || (!dummy && (((TREE_INT_CST_HIGH (TYPE_SIZE (type)) != 0))
2358 || TREE_OVERFLOW (TYPE_SIZE (type)))))
5ff904cd
JL
2359 {
2360 ffebad_start (FFEBAD_ARRAY_LARGE);
2361 ffebad_string (ffesymbol_text (s));
2362 ffebad_here (0, ffesymbol_where_line (s), ffesymbol_where_column (s));
2363 ffebad_finish ();
2364
2365 return error_mark_node;
2366 }
2367
2368 return type;
2369}
2370#endif
2371
2372/* Builds a length argument (PARM_DECL). Also wraps type in an array type
2373 where the dimension info is (1:size) where <size> is ffesymbol_size(s) if
2374 known, length_arg if not known (FFETARGET_charactersizeNONE). */
2375
2376#if FFECOM_targetCURRENT == FFECOM_targetGCC
2377static tree
2378ffecom_char_enhance_arg_ (tree *xtype, ffesymbol s)
2379{
2380 ffetargetCharacterSize sz = ffesymbol_size (s);
2381 tree highval;
2382 tree tlen;
2383 tree type = *xtype;
2384
2385 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT)
2386 tlen = NULL_TREE; /* A statement function, no length passed. */
2387 else
2388 {
2389 if (ffesymbol_where (s) == FFEINFO_whereDUMMY)
2390 tlen = ffecom_get_invented_identifier ("__g77_length_%s",
14657de8 2391 ffesymbol_text (s));
5ff904cd 2392 else
14657de8 2393 tlen = ffecom_get_invented_identifier ("__g77_%s", "length");
5ff904cd
JL
2394 tlen = build_decl (PARM_DECL, tlen, ffecom_f2c_ftnlen_type_node);
2395#if BUILT_FOR_270
2396 DECL_ARTIFICIAL (tlen) = 1;
2397#endif
2398 }
2399
2400 if (sz == FFETARGET_charactersizeNONE)
2401 {
2402 assert (tlen != NULL_TREE);
2b0c2df0 2403 highval = variable_size (tlen);
5ff904cd
JL
2404 }
2405 else
2406 {
2407 highval = build_int_2 (sz, 0);
2408 TREE_TYPE (highval) = ffecom_f2c_ftnlen_type_node;
2409 }
2410
2411 type = build_array_type (type,
2412 build_range_type (ffecom_f2c_ftnlen_type_node,
2413 ffecom_f2c_ftnlen_one_node,
2414 highval));
2415
2416 *xtype = type;
2417 return tlen;
2418}
2419
2420#endif
2421/* ffecom_concat_list_gather_ -- Gather list of concatenated string exprs
2422
2423 ffecomConcatList_ catlist;
2424 ffebld expr; // expr of CHARACTER basictype.
2425 ffetargetCharacterSize max; // max chars to gather or _...NONE if no max
2426 catlist = ffecom_concat_list_gather_(catlist,expr,max);
2427
2428 Scans expr for character subexpressions, updates and returns catlist
2429 accordingly. */
2430
2431#if FFECOM_targetCURRENT == FFECOM_targetGCC
2432static ffecomConcatList_
2433ffecom_concat_list_gather_ (ffecomConcatList_ catlist, ffebld expr,
2434 ffetargetCharacterSize max)
2435{
2436 ffetargetCharacterSize sz;
2437
2438recurse: /* :::::::::::::::::::: */
2439
2440 if (expr == NULL)
2441 return catlist;
2442
2443 if ((max != FFETARGET_charactersizeNONE) && (catlist.minlen >= max))
2444 return catlist; /* Don't append any more items. */
2445
2446 switch (ffebld_op (expr))
2447 {
2448 case FFEBLD_opCONTER:
2449 case FFEBLD_opSYMTER:
2450 case FFEBLD_opARRAYREF:
2451 case FFEBLD_opFUNCREF:
2452 case FFEBLD_opSUBSTR:
2453 case FFEBLD_opCONVERT: /* Callers should strip this off beforehand
2454 if they don't need to preserve it. */
2455 if (catlist.count == catlist.max)
2456 { /* Make a (larger) list. */
2457 ffebld *newx;
2458 int newmax;
2459
2460 newmax = (catlist.max == 0) ? 8 : catlist.max * 2;
2461 newx = malloc_new_ks (malloc_pool_image (), "catlist",
2462 newmax * sizeof (newx[0]));
2463 if (catlist.max != 0)
2464 {
2465 memcpy (newx, catlist.exprs, catlist.max * sizeof (newx[0]));
2466 malloc_kill_ks (malloc_pool_image (), catlist.exprs,
2467 catlist.max * sizeof (newx[0]));
2468 }
2469 catlist.max = newmax;
2470 catlist.exprs = newx;
2471 }
2472 if ((sz = ffebld_size_known (expr)) != FFETARGET_charactersizeNONE)
2473 catlist.minlen += sz;
2474 else
2475 ++catlist.minlen; /* Not true for F90; can be 0 length. */
2476 if ((sz = ffebld_size_max (expr)) == FFETARGET_charactersizeNONE)
2477 catlist.maxlen = sz;
2478 else
2479 catlist.maxlen += sz;
2480 if ((max != FFETARGET_charactersizeNONE) && (catlist.minlen > max))
2481 { /* This item overlaps (or is beyond) the end
2482 of the destination. */
2483 switch (ffebld_op (expr))
2484 {
2485 case FFEBLD_opCONTER:
2486 case FFEBLD_opSYMTER:
2487 case FFEBLD_opARRAYREF:
2488 case FFEBLD_opFUNCREF:
2489 case FFEBLD_opSUBSTR:
c7e4ee3a
CB
2490 /* ~~Do useful truncations here. */
2491 break;
5ff904cd
JL
2492
2493 default:
2494 assert ("op changed or inconsistent switches!" == NULL);
2495 break;
2496 }
2497 }
2498 catlist.exprs[catlist.count++] = expr;
2499 return catlist;
2500
2501 case FFEBLD_opPAREN:
2502 expr = ffebld_left (expr);
2503 goto recurse; /* :::::::::::::::::::: */
2504
2505 case FFEBLD_opCONCATENATE:
2506 catlist = ffecom_concat_list_gather_ (catlist, ffebld_left (expr), max);
2507 expr = ffebld_right (expr);
2508 goto recurse; /* :::::::::::::::::::: */
2509
2510#if 0 /* Breaks passing small actual arg to larger
2511 dummy arg of sfunc */
2512 case FFEBLD_opCONVERT:
2513 expr = ffebld_left (expr);
2514 {
2515 ffetargetCharacterSize cmax;
2516
2517 cmax = catlist.len + ffebld_size_known (expr);
2518
2519 if ((max == FFETARGET_charactersizeNONE) || (max > cmax))
2520 max = cmax;
2521 }
2522 goto recurse; /* :::::::::::::::::::: */
2523#endif
2524
2525 case FFEBLD_opANY:
2526 return catlist;
2527
2528 default:
2529 assert ("bad op in _gather_" == NULL);
2530 return catlist;
2531 }
2532}
2533
2534#endif
2535/* ffecom_concat_list_kill_ -- Kill list of concatenated string exprs
2536
2537 ffecomConcatList_ catlist;
2538 ffecom_concat_list_kill_(catlist);
2539
2540 Anything allocated within the list info is deallocated. */
2541
2542#if FFECOM_targetCURRENT == FFECOM_targetGCC
2543static void
2544ffecom_concat_list_kill_ (ffecomConcatList_ catlist)
2545{
2546 if (catlist.max != 0)
2547 malloc_kill_ks (malloc_pool_image (), catlist.exprs,
2548 catlist.max * sizeof (catlist.exprs[0]));
2549}
2550
2551#endif
c7e4ee3a 2552/* Make list of concatenated string exprs.
5ff904cd
JL
2553
2554 Returns a flattened list of concatenated subexpressions given a
2555 tree of such expressions. */
2556
2557#if FFECOM_targetCURRENT == FFECOM_targetGCC
2558static ffecomConcatList_
2559ffecom_concat_list_new_ (ffebld expr, ffetargetCharacterSize max)
2560{
2561 ffecomConcatList_ catlist;
2562
2563 catlist.maxlen = catlist.minlen = catlist.max = catlist.count = 0;
2564 return ffecom_concat_list_gather_ (catlist, expr, max);
2565}
2566
2567#endif
2568
2569/* Provide some kind of useful info on member of aggregate area,
2570 since current g77/gcc technology does not provide debug info
2571 on these members. */
2572
2573#if FFECOM_targetCURRENT == FFECOM_targetGCC
2574static void
26f096f9 2575ffecom_debug_kludge_ (tree aggr, const char *aggr_type, ffesymbol member,
5ff904cd
JL
2576 tree member_type UNUSED, ffetargetOffset offset)
2577{
2578 tree value;
2579 tree decl;
2580 int len;
2581 char *buff;
2582 char space[120];
2583#if 0
2584 tree type_id;
2585
2586 for (type_id = member_type;
2587 TREE_CODE (type_id) != IDENTIFIER_NODE;
2588 )
2589 {
2590 switch (TREE_CODE (type_id))
2591 {
2592 case INTEGER_TYPE:
2593 case REAL_TYPE:
2594 type_id = TYPE_NAME (type_id);
2595 break;
2596
2597 case ARRAY_TYPE:
2598 case COMPLEX_TYPE:
2599 type_id = TREE_TYPE (type_id);
2600 break;
2601
2602 default:
2603 assert ("no IDENTIFIER_NODE for type!" == NULL);
2604 type_id = error_mark_node;
2605 break;
2606 }
2607 }
2608#endif
2609
2610 if (ffecom_transform_only_dummies_
2611 || !ffe_is_debug_kludge ())
2612 return; /* Can't do this yet, maybe later. */
2613
2614 len = 60
2615 + strlen (aggr_type)
2616 + IDENTIFIER_LENGTH (DECL_NAME (aggr));
2617#if 0
2618 + IDENTIFIER_LENGTH (type_id);
2619#endif
2620
2621 if (((size_t) len) >= ARRAY_SIZE (space))
2622 buff = malloc_new_ks (malloc_pool_image (), "debug_kludge", len + 1);
2623 else
2624 buff = &space[0];
2625
2626 sprintf (&buff[0], "At (%s) `%s' plus %ld bytes",
2627 aggr_type,
2628 IDENTIFIER_POINTER (DECL_NAME (aggr)),
2629 (long int) offset);
2630
2631 value = build_string (len, buff);
2632 TREE_TYPE (value)
2633 = build_type_variant (build_array_type (char_type_node,
2634 build_range_type
2635 (integer_type_node,
2636 integer_one_node,
2637 build_int_2 (strlen (buff), 0))),
2638 1, 0);
2639 decl = build_decl (VAR_DECL,
2640 ffecom_get_identifier_ (ffesymbol_text (member)),
2641 TREE_TYPE (value));
2642 TREE_CONSTANT (decl) = 1;
2643 TREE_STATIC (decl) = 1;
2644 DECL_INITIAL (decl) = error_mark_node;
2645 DECL_IN_SYSTEM_HEADER (decl) = 1; /* Don't let -Wunused complain. */
2646 decl = start_decl (decl, FALSE);
2647 finish_decl (decl, value, FALSE);
2648
2649 if (buff != &space[0])
2650 malloc_kill_ks (malloc_pool_image (), buff, len + 1);
2651}
2652#endif
2653
2654/* ffecom_do_entry_ -- Do compilation of a particular entrypoint
2655
2656 ffesymbol fn; // the SUBROUTINE, FUNCTION, or ENTRY symbol itself
2657 int i; // entry# for this entrypoint (used by master fn)
2658 ffecom_do_entrypoint_(s,i);
2659
2660 Makes a public entry point that calls our private master fn (already
2661 compiled). */
2662
2663#if FFECOM_targetCURRENT == FFECOM_targetGCC
2664static void
2665ffecom_do_entry_ (ffesymbol fn, int entrynum)
2666{
2667 ffebld item;
2668 tree type; /* Type of function. */
2669 tree multi_retval; /* Var holding return value (union). */
2670 tree result; /* Var holding result. */
2671 ffeinfoBasictype bt;
2672 ffeinfoKindtype kt;
2673 ffeglobal g;
2674 ffeglobalType gt;
2675 bool charfunc; /* All entry points return same type
2676 CHARACTER. */
2677 bool cmplxfunc; /* Use f2c way of returning COMPLEX. */
2678 bool multi; /* Master fn has multiple return types. */
2679 bool altreturning = FALSE; /* This entry point has alternate returns. */
2680 int yes;
44d2eabc
JL
2681 int old_lineno = lineno;
2682 char *old_input_filename = input_filename;
2683
2684 input_filename = ffesymbol_where_filename (fn);
2685 lineno = ffesymbol_where_filelinenum (fn);
5ff904cd
JL
2686
2687 /* c-parse.y indeed does call suspend_momentary and not only ignores the
2688 return value, but also never calls resume_momentary, when starting an
2689 outer function (see "fndef:", "setspecs:", and so on). So g77 does the
2690 same thing. It shouldn't be a problem since start_function calls
2691 temporary_allocation, but it might be necessary. If it causes a problem
2692 here, then maybe there's a bug lurking in gcc. NOTE: This identical
2693 comment appears twice in thist file. */
2694
2695 suspend_momentary ();
2696
2697 ffecom_doing_entry_ = TRUE; /* Don't bother with array dimensions. */
2698
2699 switch (ffecom_primary_entry_kind_)
2700 {
2701 case FFEINFO_kindFUNCTION:
2702
2703 /* Determine actual return type for function. */
2704
2705 gt = FFEGLOBAL_typeFUNC;
2706 bt = ffesymbol_basictype (fn);
2707 kt = ffesymbol_kindtype (fn);
2708 if (bt == FFEINFO_basictypeNONE)
2709 {
2710 ffeimplic_establish_symbol (fn);
2711 if (ffesymbol_funcresult (fn) != NULL)
2712 ffeimplic_establish_symbol (ffesymbol_funcresult (fn));
2713 bt = ffesymbol_basictype (fn);
2714 kt = ffesymbol_kindtype (fn);
2715 }
2716
2717 if (bt == FFEINFO_basictypeCHARACTER)
2718 charfunc = TRUE, cmplxfunc = FALSE;
2719 else if ((bt == FFEINFO_basictypeCOMPLEX)
2720 && ffesymbol_is_f2c (fn))
2721 charfunc = FALSE, cmplxfunc = TRUE;
2722 else
2723 charfunc = cmplxfunc = FALSE;
2724
2725 if (charfunc)
2726 type = ffecom_tree_fun_type_void;
2727 else if (ffesymbol_is_f2c (fn))
2728 type = ffecom_tree_fun_type[bt][kt];
2729 else
2730 type = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
2731
2732 if ((type == NULL_TREE)
2733 || (TREE_TYPE (type) == NULL_TREE))
2734 type = ffecom_tree_fun_type_void; /* _sym_exec_transition. */
2735
2736 multi = (ffecom_master_bt_ == FFEINFO_basictypeNONE);
2737 break;
2738
2739 case FFEINFO_kindSUBROUTINE:
2740 gt = FFEGLOBAL_typeSUBR;
2741 bt = FFEINFO_basictypeNONE;
2742 kt = FFEINFO_kindtypeNONE;
2743 if (ffecom_is_altreturning_)
2744 { /* Am _I_ altreturning? */
2745 for (item = ffesymbol_dummyargs (fn);
2746 item != NULL;
2747 item = ffebld_trail (item))
2748 {
2749 if (ffebld_op (ffebld_head (item)) == FFEBLD_opSTAR)
2750 {
2751 altreturning = TRUE;
2752 break;
2753 }
2754 }
2755 if (altreturning)
2756 type = ffecom_tree_subr_type;
2757 else
2758 type = ffecom_tree_fun_type_void;
2759 }
2760 else
2761 type = ffecom_tree_fun_type_void;
2762 charfunc = FALSE;
2763 cmplxfunc = FALSE;
2764 multi = FALSE;
2765 break;
2766
2767 default:
2768 assert ("say what??" == NULL);
2769 /* Fall through. */
2770 case FFEINFO_kindANY:
2771 gt = FFEGLOBAL_typeANY;
2772 bt = FFEINFO_basictypeNONE;
2773 kt = FFEINFO_kindtypeNONE;
2774 type = error_mark_node;
2775 charfunc = FALSE;
2776 cmplxfunc = FALSE;
2777 multi = FALSE;
2778 break;
2779 }
2780
2781 /* build_decl uses the current lineno and input_filename to set the decl
2782 source info. So, I've putzed with ffestd and ffeste code to update that
2783 source info to point to the appropriate statement just before calling
2784 ffecom_do_entrypoint (which calls this fn). */
2785
2786 start_function (ffecom_get_external_identifier_ (fn),
2787 type,
2788 0, /* nested/inline */
2789 1); /* TREE_PUBLIC */
2790
2791 if (((g = ffesymbol_global (fn)) != NULL)
2792 && ((ffeglobal_type (g) == gt)
2793 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
2794 {
2795 ffeglobal_set_hook (g, current_function_decl);
2796 }
2797
2798 /* Reset args in master arg list so they get retransitioned. */
2799
2800 for (item = ffecom_master_arglist_;
2801 item != NULL;
2802 item = ffebld_trail (item))
2803 {
2804 ffebld arg;
2805 ffesymbol s;
2806
2807 arg = ffebld_head (item);
2808 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2809 continue; /* Alternate return or some such thing. */
2810 s = ffebld_symter (arg);
2811 ffesymbol_hook (s).decl_tree = NULL_TREE;
2812 ffesymbol_hook (s).length_tree = NULL_TREE;
2813 }
2814
2815 /* Build dummy arg list for this entry point. */
2816
2817 yes = suspend_momentary ();
2818
2819 if (charfunc || cmplxfunc)
2820 { /* Prepend arg for where result goes. */
2821 tree type;
2822 tree length;
2823
2824 if (charfunc)
2825 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
2826 else
2827 type = ffecom_tree_type[FFEINFO_basictypeCOMPLEX][kt];
2828
14657de8 2829 result = ffecom_get_invented_identifier ("__g77_%s", "result");
5ff904cd
JL
2830
2831 /* Make length arg _and_ enhance type info for CHAR arg itself. */
2832
2833 if (charfunc)
2834 length = ffecom_char_enhance_arg_ (&type, fn);
2835 else
2836 length = NULL_TREE; /* Not ref'd if !charfunc. */
2837
2838 type = build_pointer_type (type);
2839 result = build_decl (PARM_DECL, result, type);
2840
2841 push_parm_decl (result);
2842 ffecom_func_result_ = result;
2843
2844 if (charfunc)
2845 {
2846 push_parm_decl (length);
2847 ffecom_func_length_ = length;
2848 }
2849 }
2850 else
2851 result = DECL_RESULT (current_function_decl);
2852
2853 ffecom_push_dummy_decls_ (ffesymbol_dummyargs (fn), FALSE);
2854
2855 resume_momentary (yes);
2856
2857 store_parm_decls (0);
2858
c7e4ee3a
CB
2859 ffecom_start_compstmt ();
2860 /* Disallow temp vars at this level. */
2861 current_binding_level->prep_state = 2;
5ff904cd
JL
2862
2863 /* Make local var to hold return type for multi-type master fn. */
2864
2865 if (multi)
2866 {
2867 yes = suspend_momentary ();
2868
2869 multi_retval = ffecom_get_invented_identifier ("__g77_%s",
14657de8 2870 "multi_retval");
5ff904cd
JL
2871 multi_retval = build_decl (VAR_DECL, multi_retval,
2872 ffecom_multi_type_node_);
2873 multi_retval = start_decl (multi_retval, FALSE);
2874 finish_decl (multi_retval, NULL_TREE, FALSE);
2875
2876 resume_momentary (yes);
2877 }
2878 else
2879 multi_retval = NULL_TREE; /* Not actually ref'd if !multi. */
2880
2881 /* Here we emit the actual code for the entry point. */
2882
2883 {
2884 ffebld list;
2885 ffebld arg;
2886 ffesymbol s;
2887 tree arglist = NULL_TREE;
2888 tree *plist = &arglist;
2889 tree prepend;
2890 tree call;
2891 tree actarg;
2892 tree master_fn;
2893
2894 /* Prepare actual arg list based on master arg list. */
2895
2896 for (list = ffecom_master_arglist_;
2897 list != NULL;
2898 list = ffebld_trail (list))
2899 {
2900 arg = ffebld_head (list);
2901 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2902 continue;
2903 s = ffebld_symter (arg);
702edf1d
CB
2904 if (ffesymbol_hook (s).decl_tree == NULL_TREE
2905 || ffesymbol_hook (s).decl_tree == error_mark_node)
5ff904cd
JL
2906 actarg = null_pointer_node; /* We don't have this arg. */
2907 else
2908 actarg = ffesymbol_hook (s).decl_tree;
2909 *plist = build_tree_list (NULL_TREE, actarg);
2910 plist = &TREE_CHAIN (*plist);
2911 }
2912
2913 /* This code appends the length arguments for character
2914 variables/arrays. */
2915
2916 for (list = ffecom_master_arglist_;
2917 list != NULL;
2918 list = ffebld_trail (list))
2919 {
2920 arg = ffebld_head (list);
2921 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2922 continue;
2923 s = ffebld_symter (arg);
2924 if (ffesymbol_basictype (s) != FFEINFO_basictypeCHARACTER)
2925 continue; /* Only looking for CHARACTER arguments. */
2926 if (ffesymbol_kind (s) != FFEINFO_kindENTITY)
2927 continue; /* Only looking for variables and arrays. */
702edf1d
CB
2928 if (ffesymbol_hook (s).length_tree == NULL_TREE
2929 || ffesymbol_hook (s).length_tree == error_mark_node)
5ff904cd
JL
2930 actarg = ffecom_f2c_ftnlen_zero_node; /* We don't have this arg. */
2931 else
2932 actarg = ffesymbol_hook (s).length_tree;
2933 *plist = build_tree_list (NULL_TREE, actarg);
2934 plist = &TREE_CHAIN (*plist);
2935 }
2936
2937 /* Prepend character-value return info to actual arg list. */
2938
2939 if (charfunc)
2940 {
2941 prepend = build_tree_list (NULL_TREE, ffecom_func_result_);
2942 TREE_CHAIN (prepend)
2943 = build_tree_list (NULL_TREE, ffecom_func_length_);
2944 TREE_CHAIN (TREE_CHAIN (prepend)) = arglist;
2945 arglist = prepend;
2946 }
2947
2948 /* Prepend multi-type return value to actual arg list. */
2949
2950 if (multi)
2951 {
2952 prepend
2953 = build_tree_list (NULL_TREE,
2954 ffecom_1 (ADDR_EXPR,
2955 build_pointer_type (TREE_TYPE (multi_retval)),
2956 multi_retval));
2957 TREE_CHAIN (prepend) = arglist;
2958 arglist = prepend;
2959 }
2960
2961 /* Prepend my entry-point number to the actual arg list. */
2962
2963 prepend = build_tree_list (NULL_TREE, build_int_2 (entrynum, 0));
2964 TREE_CHAIN (prepend) = arglist;
2965 arglist = prepend;
2966
2967 /* Build the call to the master function. */
2968
2969 master_fn = ffecom_1_fn (ffecom_previous_function_decl_);
2970 call = ffecom_3s (CALL_EXPR,
2971 TREE_TYPE (TREE_TYPE (TREE_TYPE (master_fn))),
2972 master_fn, arglist, NULL_TREE);
2973
2974 /* Decide whether the master function is a function or subroutine, and
2975 handle the return value for my entry point. */
2976
2977 if (charfunc || ((ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE)
2978 && !altreturning))
2979 {
2980 expand_expr_stmt (call);
2981 expand_null_return ();
2982 }
2983 else if (multi && cmplxfunc)
2984 {
2985 expand_expr_stmt (call);
2986 result
2987 = ffecom_1 (INDIRECT_REF,
2988 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result))),
2989 result);
2990 result = ffecom_modify (NULL_TREE, result,
2991 ffecom_2 (COMPONENT_REF, TREE_TYPE (result),
2992 multi_retval,
2993 ffecom_multi_fields_[bt][kt]));
2994 expand_expr_stmt (result);
2995 expand_null_return ();
2996 }
2997 else if (multi)
2998 {
2999 expand_expr_stmt (call);
3000 result
3001 = ffecom_modify (NULL_TREE, result,
3002 convert (TREE_TYPE (result),
3003 ffecom_2 (COMPONENT_REF,
3004 ffecom_tree_type[bt][kt],
3005 multi_retval,
3006 ffecom_multi_fields_[bt][kt])));
3007 expand_return (result);
3008 }
3009 else if (cmplxfunc)
3010 {
3011 result
3012 = ffecom_1 (INDIRECT_REF,
3013 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result))),
3014 result);
3015 result = ffecom_modify (NULL_TREE, result, call);
3016 expand_expr_stmt (result);
3017 expand_null_return ();
3018 }
3019 else
3020 {
3021 result = ffecom_modify (NULL_TREE,
3022 result,
3023 convert (TREE_TYPE (result),
3024 call));
3025 expand_return (result);
3026 }
3027
3028 clear_momentary ();
3029 }
3030
c7e4ee3a 3031 ffecom_end_compstmt ();
5ff904cd
JL
3032
3033 finish_function (0);
3034
44d2eabc
JL
3035 lineno = old_lineno;
3036 input_filename = old_input_filename;
3037
5ff904cd
JL
3038 ffecom_doing_entry_ = FALSE;
3039}
3040
3041#endif
3042/* Transform expr into gcc tree with possible destination
3043
3044 Recursive descent on expr while making corresponding tree nodes and
3045 attaching type info and such. If destination supplied and compatible
3046 with temporary that would be made in certain cases, temporary isn't
092a4ef8 3047 made, destination used instead, and dest_used flag set TRUE. */
5ff904cd
JL
3048
3049#if FFECOM_targetCURRENT == FFECOM_targetGCC
3050static tree
092a4ef8
RH
3051ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest,
3052 bool *dest_used, bool assignp, bool widenp)
5ff904cd
JL
3053{
3054 tree item;
3055 tree list;
3056 tree args;
3057 ffeinfoBasictype bt;
3058 ffeinfoKindtype kt;
3059 tree t;
5ff904cd 3060 tree dt; /* decl_tree for an ffesymbol. */
092a4ef8 3061 tree tree_type, tree_type_x;
af752698 3062 tree left, right;
5ff904cd
JL
3063 ffesymbol s;
3064 enum tree_code code;
3065
3066 assert (expr != NULL);
3067
3068 if (dest_used != NULL)
3069 *dest_used = FALSE;
3070
3071 bt = ffeinfo_basictype (ffebld_info (expr));
3072 kt = ffeinfo_kindtype (ffebld_info (expr));
af752698 3073 tree_type = ffecom_tree_type[bt][kt];
5ff904cd 3074
092a4ef8
RH
3075 /* Widen integral arithmetic as desired while preserving signedness. */
3076 tree_type_x = NULL_TREE;
3077 if (widenp && tree_type
3078 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
3079 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
3080 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
3081
5ff904cd
JL
3082 switch (ffebld_op (expr))
3083 {
3084 case FFEBLD_opACCTER:
5ff904cd
JL
3085 {
3086 ffebitCount i;
3087 ffebit bits = ffebld_accter_bits (expr);
3088 ffetargetOffset source_offset = 0;
a6fa6420 3089 ffetargetOffset dest_offset = ffebld_accter_pad (expr);
5ff904cd
JL
3090 tree purpose;
3091
a6fa6420
CB
3092 assert (dest_offset == 0
3093 || (bt == FFEINFO_basictypeCHARACTER
3094 && kt == FFEINFO_kindtypeCHARACTER1));
5ff904cd
JL
3095
3096 list = item = NULL;
3097 for (;;)
3098 {
3099 ffebldConstantUnion cu;
3100 ffebitCount length;
3101 bool value;
3102 ffebldConstantArray ca = ffebld_accter (expr);
3103
3104 ffebit_test (bits, source_offset, &value, &length);
3105 if (length == 0)
3106 break;
3107
3108 if (value)
3109 {
3110 for (i = 0; i < length; ++i)
3111 {
3112 cu = ffebld_constantarray_get (ca, bt, kt,
3113 source_offset + i);
3114
3115 t = ffecom_constantunion (&cu, bt, kt, tree_type);
3116
a6fa6420
CB
3117 if (i == 0
3118 && dest_offset != 0)
3119 purpose = build_int_2 (dest_offset, 0);
5ff904cd
JL
3120 else
3121 purpose = NULL_TREE;
3122
3123 if (list == NULL_TREE)
3124 list = item = build_tree_list (purpose, t);
3125 else
3126 {
3127 TREE_CHAIN (item) = build_tree_list (purpose, t);
3128 item = TREE_CHAIN (item);
3129 }
3130 }
3131 }
3132 source_offset += length;
a6fa6420 3133 dest_offset += length;
5ff904cd
JL
3134 }
3135 }
3136
a6fa6420
CB
3137 item = build_int_2 ((ffebld_accter_size (expr)
3138 + ffebld_accter_pad (expr)) - 1, 0);
5ff904cd
JL
3139 ffebit_kill (ffebld_accter_bits (expr));
3140 TREE_TYPE (item) = ffecom_integer_type_node;
3141 item
3142 = build_array_type
3143 (tree_type,
3144 build_range_type (ffecom_integer_type_node,
3145 ffecom_integer_zero_node,
3146 item));
3147 list = build (CONSTRUCTOR, item, NULL_TREE, list);
3148 TREE_CONSTANT (list) = 1;
3149 TREE_STATIC (list) = 1;
3150 return list;
3151
3152 case FFEBLD_opARRTER:
5ff904cd
JL
3153 {
3154 ffetargetOffset i;
3155
a6fa6420
CB
3156 list = NULL_TREE;
3157 if (ffebld_arrter_pad (expr) == 0)
3158 item = NULL_TREE;
3159 else
3160 {
3161 assert (bt == FFEINFO_basictypeCHARACTER
3162 && kt == FFEINFO_kindtypeCHARACTER1);
3163
3164 /* Becomes PURPOSE first time through loop. */
3165 item = build_int_2 (ffebld_arrter_pad (expr), 0);
3166 }
3167
5ff904cd
JL
3168 for (i = 0; i < ffebld_arrter_size (expr); ++i)
3169 {
3170 ffebldConstantUnion cu
3171 = ffebld_constantarray_get (ffebld_arrter (expr), bt, kt, i);
3172
3173 t = ffecom_constantunion (&cu, bt, kt, tree_type);
3174
3175 if (list == NULL_TREE)
a6fa6420
CB
3176 /* Assume item is PURPOSE first time through loop. */
3177 list = item = build_tree_list (item, t);
5ff904cd
JL
3178 else
3179 {
3180 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
3181 item = TREE_CHAIN (item);
3182 }
3183 }
3184 }
3185
a6fa6420
CB
3186 item = build_int_2 ((ffebld_arrter_size (expr)
3187 + ffebld_arrter_pad (expr)) - 1, 0);
5ff904cd
JL
3188 TREE_TYPE (item) = ffecom_integer_type_node;
3189 item
3190 = build_array_type
3191 (tree_type,
3192 build_range_type (ffecom_integer_type_node,
a6fa6420 3193 ffecom_integer_zero_node,
5ff904cd
JL
3194 item));
3195 list = build (CONSTRUCTOR, item, NULL_TREE, list);
3196 TREE_CONSTANT (list) = 1;
3197 TREE_STATIC (list) = 1;
3198 return list;
3199
3200 case FFEBLD_opCONTER:
c264f113 3201 assert (ffebld_conter_pad (expr) == 0);
5ff904cd
JL
3202 item
3203 = ffecom_constantunion (&ffebld_constant_union (ffebld_conter (expr)),
3204 bt, kt, tree_type);
3205 return item;
3206
3207 case FFEBLD_opSYMTER:
3208 if ((ffebld_symter_generic (expr) != FFEINTRIN_genNONE)
3209 || (ffebld_symter_specific (expr) != FFEINTRIN_specNONE))
3210 return ffecom_ptr_to_expr (expr); /* Same as %REF(intrinsic). */
3211 s = ffebld_symter (expr);
3212 t = ffesymbol_hook (s).decl_tree;
3213
3214 if (assignp)
3215 { /* ASSIGN'ed-label expr. */
3216 if (ffe_is_ugly_assign ())
3217 {
3218 /* User explicitly wants ASSIGN'ed variables to be at the same
3219 memory address as the variables when used in non-ASSIGN
3220 contexts. That can make old, arcane, non-standard code
3221 work, but don't try to do it when a pointer wouldn't fit
3222 in the normal variable (take other approach, and warn,
3223 instead). */
3224
3225 if (t == NULL_TREE)
3226 {
3227 s = ffecom_sym_transform_ (s);
3228 t = ffesymbol_hook (s).decl_tree;
3229 assert (t != NULL_TREE);
3230 }
3231
3232 if (t == error_mark_node)
3233 return t;
3234
3235 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (t)))
3236 >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
3237 {
3238 if (ffesymbol_hook (s).addr)
3239 t = ffecom_1 (INDIRECT_REF,
3240 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), t);
3241 return t;
3242 }
3243
3244 if (ffesymbol_hook (s).assign_tree == NULL_TREE)
3245 {
3246 ffebad_start_msg ("ASSIGN'ed label cannot fit into `%A' at %0 -- using wider sibling",
3247 FFEBAD_severityWARNING);
3248 ffebad_string (ffesymbol_text (s));
3249 ffebad_here (0, ffesymbol_where_line (s),
3250 ffesymbol_where_column (s));
3251 ffebad_finish ();
3252 }
3253 }
3254
3255 /* Don't use the normal variable's tree for ASSIGN, though mark
3256 it as in the system header (housekeeping). Use an explicit,
3257 specially created sibling that is known to be wide enough
3258 to hold pointers to labels. */
3259
3260 if (t != NULL_TREE
3261 && TREE_CODE (t) == VAR_DECL)
3262 DECL_IN_SYSTEM_HEADER (t) = 1; /* Don't let -Wunused complain. */
3263
3264 t = ffesymbol_hook (s).assign_tree;
3265 if (t == NULL_TREE)
3266 {
3267 s = ffecom_sym_transform_assign_ (s);
3268 t = ffesymbol_hook (s).assign_tree;
3269 assert (t != NULL_TREE);
3270 }
3271 }
3272 else
3273 {
3274 if (t == NULL_TREE)
3275 {
3276 s = ffecom_sym_transform_ (s);
3277 t = ffesymbol_hook (s).decl_tree;
3278 assert (t != NULL_TREE);
3279 }
3280 if (ffesymbol_hook (s).addr)
3281 t = ffecom_1 (INDIRECT_REF,
3282 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), t);
3283 }
3284 return t;
3285
3286 case FFEBLD_opARRAYREF:
ff852b44 3287 return ffecom_arrayref_ (NULL_TREE, expr, 0);
5ff904cd
JL
3288
3289 case FFEBLD_opUPLUS:
092a4ef8 3290 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
af752698 3291 return ffecom_1 (NOP_EXPR, tree_type, left);
5ff904cd 3292
c7e4ee3a
CB
3293 case FFEBLD_opPAREN:
3294 /* ~~~Make sure Fortran rules respected here */
092a4ef8 3295 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
af752698 3296 return ffecom_1 (NOP_EXPR, tree_type, left);
5ff904cd
JL
3297
3298 case FFEBLD_opUMINUS:
092a4ef8 3299 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
af752698
RH
3300 if (tree_type_x)
3301 {
3302 tree_type = tree_type_x;
3303 left = convert (tree_type, left);
3304 }
3305 return ffecom_1 (NEGATE_EXPR, tree_type, left);
5ff904cd
JL
3306
3307 case FFEBLD_opADD:
092a4ef8
RH
3308 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3309 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
af752698
RH
3310 if (tree_type_x)
3311 {
3312 tree_type = tree_type_x;
3313 left = convert (tree_type, left);
3314 right = convert (tree_type, right);
3315 }
3316 return ffecom_2 (PLUS_EXPR, tree_type, left, right);
5ff904cd
JL
3317
3318 case FFEBLD_opSUBTRACT:
092a4ef8
RH
3319 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3320 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
af752698
RH
3321 if (tree_type_x)
3322 {
3323 tree_type = tree_type_x;
3324 left = convert (tree_type, left);
3325 right = convert (tree_type, right);
3326 }
3327 return ffecom_2 (MINUS_EXPR, tree_type, left, right);
5ff904cd
JL
3328
3329 case FFEBLD_opMULTIPLY:
092a4ef8
RH
3330 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3331 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
af752698
RH
3332 if (tree_type_x)
3333 {
3334 tree_type = tree_type_x;
3335 left = convert (tree_type, left);
3336 right = convert (tree_type, right);
3337 }
3338 return ffecom_2 (MULT_EXPR, tree_type, left, right);
5ff904cd
JL
3339
3340 case FFEBLD_opDIVIDE:
092a4ef8
RH
3341 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3342 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
af752698
RH
3343 if (tree_type_x)
3344 {
3345 tree_type = tree_type_x;
3346 left = convert (tree_type, left);
3347 right = convert (tree_type, right);
3348 }
3349 return ffecom_tree_divide_ (tree_type, left, right,
c7e4ee3a
CB
3350 dest_tree, dest, dest_used,
3351 ffebld_nonter_hook (expr));
5ff904cd
JL
3352
3353 case FFEBLD_opPOWER:
5ff904cd
JL
3354 {
3355 ffebld left = ffebld_left (expr);
3356 ffebld right = ffebld_right (expr);
3357 ffecomGfrt code;
3358 ffeinfoKindtype rtkt;
270fc4e8 3359 ffeinfoKindtype ltkt;
5ff904cd
JL
3360
3361 switch (ffeinfo_basictype (ffebld_info (right)))
3362 {
3363 case FFEINFO_basictypeINTEGER:
3364 if (1 || optimize)
3365 {
c7e4ee3a 3366 item = ffecom_expr_power_integer_ (expr);
5ff904cd
JL
3367 if (item != NULL_TREE)
3368 return item;
3369 }
3370
3371 rtkt = FFEINFO_kindtypeINTEGER1;
3372 switch (ffeinfo_basictype (ffebld_info (left)))
3373 {
3374 case FFEINFO_basictypeINTEGER:
3375 if ((ffeinfo_kindtype (ffebld_info (left))
3376 == FFEINFO_kindtypeINTEGER4)
3377 || (ffeinfo_kindtype (ffebld_info (right))
3378 == FFEINFO_kindtypeINTEGER4))
3379 {
3380 code = FFECOM_gfrtPOW_QQ;
270fc4e8 3381 ltkt = FFEINFO_kindtypeINTEGER4;
5ff904cd
JL
3382 rtkt = FFEINFO_kindtypeINTEGER4;
3383 }
3384 else
6a047254
CB
3385 {
3386 code = FFECOM_gfrtPOW_II;
3387 ltkt = FFEINFO_kindtypeINTEGER1;
3388 }
5ff904cd
JL
3389 break;
3390
3391 case FFEINFO_basictypeREAL:
3392 if (ffeinfo_kindtype (ffebld_info (left))
3393 == FFEINFO_kindtypeREAL1)
6a047254
CB
3394 {
3395 code = FFECOM_gfrtPOW_RI;
3396 ltkt = FFEINFO_kindtypeREAL1;
3397 }
5ff904cd 3398 else
6a047254
CB
3399 {
3400 code = FFECOM_gfrtPOW_DI;
3401 ltkt = FFEINFO_kindtypeREAL2;
3402 }
5ff904cd
JL
3403 break;
3404
3405 case FFEINFO_basictypeCOMPLEX:
3406 if (ffeinfo_kindtype (ffebld_info (left))
3407 == FFEINFO_kindtypeREAL1)
6a047254
CB
3408 {
3409 code = FFECOM_gfrtPOW_CI; /* Overlapping result okay. */
3410 ltkt = FFEINFO_kindtypeREAL1;
3411 }
5ff904cd 3412 else
6a047254
CB
3413 {
3414 code = FFECOM_gfrtPOW_ZI; /* Overlapping result okay. */
3415 ltkt = FFEINFO_kindtypeREAL2;
3416 }
5ff904cd
JL
3417 break;
3418
3419 default:
3420 assert ("bad pow_*i" == NULL);
3421 code = FFECOM_gfrtPOW_CI; /* Overlapping result okay. */
6a047254 3422 ltkt = FFEINFO_kindtypeREAL1;
5ff904cd
JL
3423 break;
3424 }
270fc4e8 3425 if (ffeinfo_kindtype (ffebld_info (left)) != ltkt)
5ff904cd 3426 left = ffeexpr_convert (left, NULL, NULL,
6a047254 3427 ffeinfo_basictype (ffebld_info (left)),
270fc4e8 3428 ltkt, 0,
5ff904cd
JL
3429 FFETARGET_charactersizeNONE,
3430 FFEEXPR_contextLET);
3431 if (ffeinfo_kindtype (ffebld_info (right)) != rtkt)
3432 right = ffeexpr_convert (right, NULL, NULL,
3433 FFEINFO_basictypeINTEGER,
3434 rtkt, 0,
3435 FFETARGET_charactersizeNONE,
3436 FFEEXPR_contextLET);
3437 break;
3438
3439 case FFEINFO_basictypeREAL:
3440 if (ffeinfo_kindtype (ffebld_info (left)) == FFEINFO_kindtypeREAL1)
3441 left = ffeexpr_convert (left, NULL, NULL, FFEINFO_basictypeREAL,
3442 FFEINFO_kindtypeREALDOUBLE, 0,
3443 FFETARGET_charactersizeNONE,
3444 FFEEXPR_contextLET);
3445 if (ffeinfo_kindtype (ffebld_info (right))
3446 == FFEINFO_kindtypeREAL1)
3447 right = ffeexpr_convert (right, NULL, NULL,
3448 FFEINFO_basictypeREAL,
3449 FFEINFO_kindtypeREALDOUBLE, 0,
3450 FFETARGET_charactersizeNONE,
3451 FFEEXPR_contextLET);
3452 code = FFECOM_gfrtPOW_DD;
3453 break;
3454
3455 case FFEINFO_basictypeCOMPLEX:
3456 if (ffeinfo_kindtype (ffebld_info (left)) == FFEINFO_kindtypeREAL1)
3457 left = ffeexpr_convert (left, NULL, NULL,
3458 FFEINFO_basictypeCOMPLEX,
3459 FFEINFO_kindtypeREALDOUBLE, 0,
3460 FFETARGET_charactersizeNONE,
3461 FFEEXPR_contextLET);
3462 if (ffeinfo_kindtype (ffebld_info (right))
3463 == FFEINFO_kindtypeREAL1)
3464 right = ffeexpr_convert (right, NULL, NULL,
3465 FFEINFO_basictypeCOMPLEX,
3466 FFEINFO_kindtypeREALDOUBLE, 0,
3467 FFETARGET_charactersizeNONE,
3468 FFEEXPR_contextLET);
3469 code = FFECOM_gfrtPOW_ZZ; /* Overlapping result okay. */
3470 break;
3471
3472 default:
3473 assert ("bad pow_x*" == NULL);
3474 code = FFECOM_gfrtPOW_II;
3475 break;
3476 }
3477 return ffecom_call_binop_ (ffecom_gfrt_tree_ (code),
3478 ffecom_gfrt_kindtype (code),
3479 (ffe_is_f2c_library ()
3480 && ffecom_gfrt_complex_[code]),
3481 tree_type, left, right,
3482 dest_tree, dest, dest_used,
c7e4ee3a
CB
3483 NULL_TREE, FALSE,
3484 ffebld_nonter_hook (expr));
5ff904cd
JL
3485 }
3486
3487 case FFEBLD_opNOT:
5ff904cd
JL
3488 switch (bt)
3489 {
3490 case FFEINFO_basictypeLOGICAL:
83ffecd2 3491 item = ffecom_truth_value_invert (ffecom_expr (ffebld_left (expr)));
5ff904cd
JL
3492 return convert (tree_type, item);
3493
3494 case FFEINFO_basictypeINTEGER:
3495 return ffecom_1 (BIT_NOT_EXPR, tree_type,
3496 ffecom_expr (ffebld_left (expr)));
3497
3498 default:
3499 assert ("NOT bad basictype" == NULL);
3500 /* Fall through. */
3501 case FFEINFO_basictypeANY:
3502 return error_mark_node;
3503 }
3504 break;
3505
3506 case FFEBLD_opFUNCREF:
3507 assert (ffeinfo_basictype (ffebld_info (expr))
3508 != FFEINFO_basictypeCHARACTER);
3509 /* Fall through. */
3510 case FFEBLD_opSUBRREF:
5ff904cd
JL
3511 if (ffeinfo_where (ffebld_info (ffebld_left (expr)))
3512 == FFEINFO_whereINTRINSIC)
3513 { /* Invocation of an intrinsic. */
3514 item = ffecom_expr_intrinsic_ (expr, dest_tree, dest,
3515 dest_used);
3516 return item;
3517 }
3518 s = ffebld_symter (ffebld_left (expr));
3519 dt = ffesymbol_hook (s).decl_tree;
3520 if (dt == NULL_TREE)
3521 {
3522 s = ffecom_sym_transform_ (s);
3523 dt = ffesymbol_hook (s).decl_tree;
3524 }
3525 if (dt == error_mark_node)
3526 return dt;
3527
3528 if (ffesymbol_hook (s).addr)
3529 item = dt;
3530 else
3531 item = ffecom_1_fn (dt);
3532
5ff904cd
JL
3533 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT)
3534 args = ffecom_list_expr (ffebld_right (expr));
3535 else
3536 args = ffecom_list_ptr_to_expr (ffebld_right (expr));
5ff904cd 3537
702edf1d
CB
3538 if (args == error_mark_node)
3539 return error_mark_node;
3540
5ff904cd
JL
3541 item = ffecom_call_ (item, kt,
3542 ffesymbol_is_f2c (s)
3543 && (bt == FFEINFO_basictypeCOMPLEX)
3544 && (ffesymbol_where (s)
3545 != FFEINFO_whereCONSTANT),
3546 tree_type,
3547 args,
3548 dest_tree, dest, dest_used,
c7e4ee3a
CB
3549 error_mark_node, FALSE,
3550 ffebld_nonter_hook (expr));
5ff904cd
JL
3551 TREE_SIDE_EFFECTS (item) = 1;
3552 return item;
3553
3554 case FFEBLD_opAND:
5ff904cd
JL
3555 switch (bt)
3556 {
3557 case FFEINFO_basictypeLOGICAL:
3558 item
3559 = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
3560 ffecom_truth_value (ffecom_expr (ffebld_left (expr))),
3561 ffecom_truth_value (ffecom_expr (ffebld_right (expr))));
3562 return convert (tree_type, item);
3563
3564 case FFEINFO_basictypeINTEGER:
3565 return ffecom_2 (BIT_AND_EXPR, tree_type,
3566 ffecom_expr (ffebld_left (expr)),
3567 ffecom_expr (ffebld_right (expr)));
3568
3569 default:
3570 assert ("AND bad basictype" == NULL);
3571 /* Fall through. */
3572 case FFEINFO_basictypeANY:
3573 return error_mark_node;
3574 }
3575 break;
3576
3577 case FFEBLD_opOR:
5ff904cd
JL
3578 switch (bt)
3579 {
3580 case FFEINFO_basictypeLOGICAL:
3581 item
3582 = ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
3583 ffecom_truth_value (ffecom_expr (ffebld_left (expr))),
3584 ffecom_truth_value (ffecom_expr (ffebld_right (expr))));
3585 return convert (tree_type, item);
3586
3587 case FFEINFO_basictypeINTEGER:
3588 return ffecom_2 (BIT_IOR_EXPR, tree_type,
3589 ffecom_expr (ffebld_left (expr)),
3590 ffecom_expr (ffebld_right (expr)));
3591
3592 default:
3593 assert ("OR bad basictype" == NULL);
3594 /* Fall through. */
3595 case FFEINFO_basictypeANY:
3596 return error_mark_node;
3597 }
3598 break;
3599
3600 case FFEBLD_opXOR:
3601 case FFEBLD_opNEQV:
5ff904cd
JL
3602 switch (bt)
3603 {
3604 case FFEINFO_basictypeLOGICAL:
3605 item
3606 = ffecom_2 (NE_EXPR, integer_type_node,
3607 ffecom_expr (ffebld_left (expr)),
3608 ffecom_expr (ffebld_right (expr)));
3609 return convert (tree_type, ffecom_truth_value (item));
3610
3611 case FFEINFO_basictypeINTEGER:
3612 return ffecom_2 (BIT_XOR_EXPR, tree_type,
3613 ffecom_expr (ffebld_left (expr)),
3614 ffecom_expr (ffebld_right (expr)));
3615
3616 default:
3617 assert ("XOR/NEQV bad basictype" == NULL);
3618 /* Fall through. */
3619 case FFEINFO_basictypeANY:
3620 return error_mark_node;
3621 }
3622 break;
3623
3624 case FFEBLD_opEQV:
5ff904cd
JL
3625 switch (bt)
3626 {
3627 case FFEINFO_basictypeLOGICAL:
3628 item
3629 = ffecom_2 (EQ_EXPR, integer_type_node,
3630 ffecom_expr (ffebld_left (expr)),
3631 ffecom_expr (ffebld_right (expr)));
3632 return convert (tree_type, ffecom_truth_value (item));
3633
3634 case FFEINFO_basictypeINTEGER:
3635 return
3636 ffecom_1 (BIT_NOT_EXPR, tree_type,
3637 ffecom_2 (BIT_XOR_EXPR, tree_type,
3638 ffecom_expr (ffebld_left (expr)),
3639 ffecom_expr (ffebld_right (expr))));
3640
3641 default:
3642 assert ("EQV bad basictype" == NULL);
3643 /* Fall through. */
3644 case FFEINFO_basictypeANY:
3645 return error_mark_node;
3646 }
3647 break;
3648
3649 case FFEBLD_opCONVERT:
3650 if (ffebld_op (ffebld_left (expr)) == FFEBLD_opANY)
3651 return error_mark_node;
3652
5ff904cd
JL
3653 switch (bt)
3654 {
3655 case FFEINFO_basictypeLOGICAL:
3656 case FFEINFO_basictypeINTEGER:
3657 case FFEINFO_basictypeREAL:
3658 return convert (tree_type, ffecom_expr (ffebld_left (expr)));
3659
3660 case FFEINFO_basictypeCOMPLEX:
3661 switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr))))
3662 {
3663 case FFEINFO_basictypeINTEGER:
3664 case FFEINFO_basictypeLOGICAL:
3665 case FFEINFO_basictypeREAL:
3666 item = ffecom_expr (ffebld_left (expr));
3667 if (item == error_mark_node)
3668 return error_mark_node;
3669 /* convert() takes care of converting to the subtype first,
3670 at least in gcc-2.7.2. */
3671 item = convert (tree_type, item);
3672 return item;
3673
3674 case FFEINFO_basictypeCOMPLEX:
3675 return convert (tree_type, ffecom_expr (ffebld_left (expr)));
3676
3677 default:
3678 assert ("CONVERT COMPLEX bad basictype" == NULL);
3679 /* Fall through. */
3680 case FFEINFO_basictypeANY:
3681 return error_mark_node;
3682 }
3683 break;
3684
3685 default:
3686 assert ("CONVERT bad basictype" == NULL);
3687 /* Fall through. */
3688 case FFEINFO_basictypeANY:
3689 return error_mark_node;
3690 }
3691 break;
3692
3693 case FFEBLD_opLT:
3694 code = LT_EXPR;
3695 goto relational; /* :::::::::::::::::::: */
3696
3697 case FFEBLD_opLE:
3698 code = LE_EXPR;
3699 goto relational; /* :::::::::::::::::::: */
3700
3701 case FFEBLD_opEQ:
3702 code = EQ_EXPR;
3703 goto relational; /* :::::::::::::::::::: */
3704
3705 case FFEBLD_opNE:
3706 code = NE_EXPR;
3707 goto relational; /* :::::::::::::::::::: */
3708
3709 case FFEBLD_opGT:
3710 code = GT_EXPR;
3711 goto relational; /* :::::::::::::::::::: */
3712
3713 case FFEBLD_opGE:
3714 code = GE_EXPR;
3715
3716 relational: /* :::::::::::::::::::: */
5ff904cd
JL
3717 switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr))))
3718 {
3719 case FFEINFO_basictypeLOGICAL:
3720 case FFEINFO_basictypeINTEGER:
3721 case FFEINFO_basictypeREAL:
3722 item = ffecom_2 (code, integer_type_node,
3723 ffecom_expr (ffebld_left (expr)),
3724 ffecom_expr (ffebld_right (expr)));
3725 return convert (tree_type, item);
3726
3727 case FFEINFO_basictypeCOMPLEX:
3728 assert (code == EQ_EXPR || code == NE_EXPR);
3729 {
3730 tree real_type;
3731 tree arg1 = ffecom_expr (ffebld_left (expr));
3732 tree arg2 = ffecom_expr (ffebld_right (expr));
3733
3734 if (arg1 == error_mark_node || arg2 == error_mark_node)
3735 return error_mark_node;
3736
3737 arg1 = ffecom_save_tree (arg1);
3738 arg2 = ffecom_save_tree (arg2);
3739
3740 if (TREE_CODE (TREE_TYPE (arg1)) == COMPLEX_TYPE)
3741 {
3742 real_type = TREE_TYPE (TREE_TYPE (arg1));
3743 assert (real_type == TREE_TYPE (TREE_TYPE (arg2)));
3744 }
3745 else
3746 {
3747 real_type = TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg1)));
3748 assert (real_type == TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg2))));
3749 }
3750
3751 item
3752 = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
3753 ffecom_2 (EQ_EXPR, integer_type_node,
3754 ffecom_1 (REALPART_EXPR, real_type, arg1),
3755 ffecom_1 (REALPART_EXPR, real_type, arg2)),
3756 ffecom_2 (EQ_EXPR, integer_type_node,
3757 ffecom_1 (IMAGPART_EXPR, real_type, arg1),
3758 ffecom_1 (IMAGPART_EXPR, real_type,
3759 arg2)));
3760 if (code == EQ_EXPR)
3761 item = ffecom_truth_value (item);
3762 else
3763 item = ffecom_truth_value_invert (item);
3764 return convert (tree_type, item);
3765 }
3766
3767 case FFEINFO_basictypeCHARACTER:
5ff904cd
JL
3768 {
3769 ffebld left = ffebld_left (expr);
3770 ffebld right = ffebld_right (expr);
3771 tree left_tree;
3772 tree right_tree;
3773 tree left_length;
3774 tree right_length;
3775
3776 /* f2c run-time functions do the implicit blank-padding for us,
3777 so we don't usually have to implement blank-padding ourselves.
3778 (The exception is when we pass an argument to a separately
3779 compiled statement function -- if we know the arg is not the
3780 same length as the dummy, we must truncate or extend it. If
3781 we "inline" statement functions, that necessity goes away as
3782 well.)
3783
3784 Strip off the CONVERT operators that blank-pad. (Truncation by
3785 CONVERT shouldn't happen here, but it can happen in
3786 assignments.) */
3787
3788 while (ffebld_op (left) == FFEBLD_opCONVERT)
3789 left = ffebld_left (left);
3790 while (ffebld_op (right) == FFEBLD_opCONVERT)
3791 right = ffebld_left (right);
3792
3793 left_tree = ffecom_arg_ptr_to_expr (left, &left_length);
3794 right_tree = ffecom_arg_ptr_to_expr (right, &right_length);
3795
3796 if (left_tree == error_mark_node || left_length == error_mark_node
3797 || right_tree == error_mark_node
3798 || right_length == error_mark_node)
c7e4ee3a 3799 return error_mark_node;
5ff904cd
JL
3800
3801 if ((ffebld_size_known (left) == 1)
3802 && (ffebld_size_known (right) == 1))
3803 {
3804 left_tree
3805 = ffecom_1 (INDIRECT_REF,
3806 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree))),
3807 left_tree);
3808 right_tree
3809 = ffecom_1 (INDIRECT_REF,
3810 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree))),
3811 right_tree);
3812
3813 item
3814 = ffecom_2 (code, integer_type_node,
3815 ffecom_2 (ARRAY_REF,
3816 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree))),
3817 left_tree,
3818 integer_one_node),
3819 ffecom_2 (ARRAY_REF,
3820 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree))),
3821 right_tree,
3822 integer_one_node));
3823 }
3824 else
3825 {
3826 item = build_tree_list (NULL_TREE, left_tree);
3827 TREE_CHAIN (item) = build_tree_list (NULL_TREE, right_tree);
3828 TREE_CHAIN (TREE_CHAIN (item)) = build_tree_list (NULL_TREE,
3829 left_length);
3830 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item)))
3831 = build_tree_list (NULL_TREE, right_length);
c7e4ee3a 3832 item = ffecom_call_gfrt (FFECOM_gfrtCMP, item, NULL_TREE);
5ff904cd
JL
3833 item = ffecom_2 (code, integer_type_node,
3834 item,
3835 convert (TREE_TYPE (item),
3836 integer_zero_node));
3837 }
3838 item = convert (tree_type, item);
3839 }
3840
5ff904cd
JL
3841 return item;
3842
3843 default:
3844 assert ("relational bad basictype" == NULL);
3845 /* Fall through. */
3846 case FFEINFO_basictypeANY:
3847 return error_mark_node;
3848 }
3849 break;
3850
3851 case FFEBLD_opPERCENT_LOC:
5ff904cd
JL
3852 item = ffecom_arg_ptr_to_expr (ffebld_left (expr), &list);
3853 return convert (tree_type, item);
3854
3855 case FFEBLD_opITEM:
3856 case FFEBLD_opSTAR:
3857 case FFEBLD_opBOUNDS:
3858 case FFEBLD_opREPEAT:
3859 case FFEBLD_opLABTER:
3860 case FFEBLD_opLABTOK:
3861 case FFEBLD_opIMPDO:
3862 case FFEBLD_opCONCATENATE:
3863 case FFEBLD_opSUBSTR:
3864 default:
3865 assert ("bad op" == NULL);
3866 /* Fall through. */
3867 case FFEBLD_opANY:
3868 return error_mark_node;
3869 }
3870
3871#if 1
3872 assert ("didn't think anything got here anymore!!" == NULL);
3873#else
3874 switch (ffebld_arity (expr))
3875 {
3876 case 2:
3877 TREE_OPERAND (item, 0) = ffecom_expr (ffebld_left (expr));
3878 TREE_OPERAND (item, 1) = ffecom_expr (ffebld_right (expr));
3879 if (TREE_OPERAND (item, 0) == error_mark_node
3880 || TREE_OPERAND (item, 1) == error_mark_node)
3881 return error_mark_node;
3882 break;
3883
3884 case 1:
3885 TREE_OPERAND (item, 0) = ffecom_expr (ffebld_left (expr));
3886 if (TREE_OPERAND (item, 0) == error_mark_node)
3887 return error_mark_node;
3888 break;
3889
3890 default:
3891 break;
3892 }
3893
3894 return fold (item);
3895#endif
3896}
3897
3898#endif
3899/* Returns the tree that does the intrinsic invocation.
3900
3901 Note: this function applies only to intrinsics returning
3902 CHARACTER*1 or non-CHARACTER results, and to intrinsic
3903 subroutines. */
3904
3905#if FFECOM_targetCURRENT == FFECOM_targetGCC
3906static tree
3907ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree,
3908 ffebld dest, bool *dest_used)
3909{
3910 tree expr_tree;
3911 tree saved_expr1; /* For those who need it. */
3912 tree saved_expr2; /* For those who need it. */
3913 ffeinfoBasictype bt;
3914 ffeinfoKindtype kt;
3915 tree tree_type;
3916 tree arg1_type;
3917 tree real_type; /* REAL type corresponding to COMPLEX. */
3918 tree tempvar;
3919 ffebld list = ffebld_right (expr); /* List of (some) args. */
3920 ffebld arg1; /* For handy reference. */
3921 ffebld arg2;
3922 ffebld arg3;
3923 ffeintrinImp codegen_imp;
3924 ffecomGfrt gfrt;
3925
3926 assert (ffebld_op (ffebld_left (expr)) == FFEBLD_opSYMTER);
3927
3928 if (dest_used != NULL)
3929 *dest_used = FALSE;
3930
3931 bt = ffeinfo_basictype (ffebld_info (expr));
3932 kt = ffeinfo_kindtype (ffebld_info (expr));
3933 tree_type = ffecom_tree_type[bt][kt];
3934
3935 if (list != NULL)
3936 {
3937 arg1 = ffebld_head (list);
3938 if (arg1 != NULL && ffebld_op (arg1) == FFEBLD_opANY)
3939 return error_mark_node;
3940 if ((list = ffebld_trail (list)) != NULL)
3941 {
3942 arg2 = ffebld_head (list);
3943 if (arg2 != NULL && ffebld_op (arg2) == FFEBLD_opANY)
3944 return error_mark_node;
3945 if ((list = ffebld_trail (list)) != NULL)
3946 {
3947 arg3 = ffebld_head (list);
3948 if (arg3 != NULL && ffebld_op (arg3) == FFEBLD_opANY)
3949 return error_mark_node;
3950 }
3951 else
3952 arg3 = NULL;
3953 }
3954 else
3955 arg2 = arg3 = NULL;
3956 }
3957 else
3958 arg1 = arg2 = arg3 = NULL;
3959
3960 /* <list> ends up at the opITEM of the 3rd arg, or NULL if there are < 3
3961 args. This is used by the MAX/MIN expansions. */
3962
3963 if (arg1 != NULL)
3964 arg1_type = ffecom_tree_type
3965 [ffeinfo_basictype (ffebld_info (arg1))]
3966 [ffeinfo_kindtype (ffebld_info (arg1))];
3967 else
3968 arg1_type = NULL_TREE; /* Really not needed, but might catch bugs
3969 here. */
3970
3971 /* There are several ways for each of the cases in the following switch
3972 statements to exit (from simplest to use to most complicated):
3973
3974 break; (when expr_tree == NULL)
3975
3976 A standard call is made to the specific intrinsic just as if it had been
3977 passed in as a dummy procedure and called as any old procedure. This
3978 method can produce slower code but in some cases it's the easiest way for
3979 now. However, if a (presumably faster) direct call is available,
3980 that is used, so this is the easiest way in many more cases now.
3981
3982 gfrt = FFECOM_gfrtWHATEVER;
3983 break;
3984
3985 gfrt contains the gfrt index of a library function to call, passing the
3986 argument(s) by value rather than by reference. Used when a more
3987 careful choice of library function is needed than that provided
3988 by the vanilla `break;'.
3989
3990 return expr_tree;
3991
3992 The expr_tree has been completely set up and is ready to be returned
3993 as is. No further actions are taken. Use this when the tree is not
3994 in the simple form for one of the arity_n labels. */
3995
3996 /* For info on how the switch statement cases were written, see the files
3997 enclosed in comments below the switch statement. */
3998
3999 codegen_imp = ffebld_symter_implementation (ffebld_left (expr));
4000 gfrt = ffeintrin_gfrt_direct (codegen_imp);
4001 if (gfrt == FFECOM_gfrt)
4002 gfrt = ffeintrin_gfrt_indirect (codegen_imp);
4003
4004 switch (codegen_imp)
4005 {
4006 case FFEINTRIN_impABS:
4007 case FFEINTRIN_impCABS:
4008 case FFEINTRIN_impCDABS:
4009 case FFEINTRIN_impDABS:
4010 case FFEINTRIN_impIABS:
4011 if (ffeinfo_basictype (ffebld_info (arg1))
4012 == FFEINFO_basictypeCOMPLEX)
4013 {
4014 if (kt == FFEINFO_kindtypeREAL1)
4015 gfrt = FFECOM_gfrtCABS;
4016 else if (kt == FFEINFO_kindtypeREAL2)
4017 gfrt = FFECOM_gfrtCDABS;
4018 break;
4019 }
4020 return ffecom_1 (ABS_EXPR, tree_type,
4021 convert (tree_type, ffecom_expr (arg1)));
4022
4023 case FFEINTRIN_impACOS:
4024 case FFEINTRIN_impDACOS:
4025 break;
4026
4027 case FFEINTRIN_impAIMAG:
4028 case FFEINTRIN_impDIMAG:
4029 case FFEINTRIN_impIMAGPART:
4030 if (TREE_CODE (arg1_type) == COMPLEX_TYPE)
4031 arg1_type = TREE_TYPE (arg1_type);
4032 else
4033 arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type));
4034
4035 return
4036 convert (tree_type,
4037 ffecom_1 (IMAGPART_EXPR, arg1_type,
4038 ffecom_expr (arg1)));
4039
4040 case FFEINTRIN_impAINT:
4041 case FFEINTRIN_impDINT:
c7e4ee3a
CB
4042#if 0
4043 /* ~~Someday implement FIX_TRUNC_EXPR yielding same type as arg. */
5ff904cd
JL
4044 return ffecom_1 (FIX_TRUNC_EXPR, tree_type, ffecom_expr (arg1));
4045#else /* in the meantime, must use floor to avoid range problems with ints */
4046 /* r__1 = r1 >= 0 ? floor(r1) : -floor(-r1); */
4047 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
4048 return
4049 convert (tree_type,
4050 ffecom_3 (COND_EXPR, double_type_node,
4051 ffecom_truth_value
4052 (ffecom_2 (GE_EXPR, integer_type_node,
4053 saved_expr1,
4054 convert (arg1_type,
4055 ffecom_float_zero_))),
4056 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
4057 build_tree_list (NULL_TREE,
4058 convert (double_type_node,
c7e4ee3a
CB
4059 saved_expr1)),
4060 NULL_TREE),
5ff904cd
JL
4061 ffecom_1 (NEGATE_EXPR, double_type_node,
4062 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
4063 build_tree_list (NULL_TREE,
4064 convert (double_type_node,
4065 ffecom_1 (NEGATE_EXPR,
4066 arg1_type,
c7e4ee3a
CB
4067 saved_expr1))),
4068 NULL_TREE)
5ff904cd
JL
4069 ))
4070 );
4071#endif
4072
4073 case FFEINTRIN_impANINT:
4074 case FFEINTRIN_impDNINT:
4075#if 0 /* This way of doing it won't handle real
4076 numbers of large magnitudes. */
4077 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
4078 expr_tree = convert (tree_type,
4079 convert (integer_type_node,
4080 ffecom_3 (COND_EXPR, tree_type,
4081 ffecom_truth_value
4082 (ffecom_2 (GE_EXPR,
4083 integer_type_node,
4084 saved_expr1,
4085 ffecom_float_zero_)),
4086 ffecom_2 (PLUS_EXPR,
4087 tree_type,
4088 saved_expr1,
4089 ffecom_float_half_),
4090 ffecom_2 (MINUS_EXPR,
4091 tree_type,
4092 saved_expr1,
4093 ffecom_float_half_))));
4094 return expr_tree;
4095#else /* So we instead call floor. */
4096 /* r__1 = r1 >= 0 ? floor(r1 + .5) : -floor(.5 - r1) */
4097 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
4098 return
4099 convert (tree_type,
4100 ffecom_3 (COND_EXPR, double_type_node,
4101 ffecom_truth_value
4102 (ffecom_2 (GE_EXPR, integer_type_node,
4103 saved_expr1,
4104 convert (arg1_type,
4105 ffecom_float_zero_))),
4106 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
4107 build_tree_list (NULL_TREE,
4108 convert (double_type_node,
4109 ffecom_2 (PLUS_EXPR,
4110 arg1_type,
4111 saved_expr1,
4112 convert (arg1_type,
c7e4ee3a
CB
4113 ffecom_float_half_)))),
4114 NULL_TREE),
5ff904cd
JL
4115 ffecom_1 (NEGATE_EXPR, double_type_node,
4116 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
4117 build_tree_list (NULL_TREE,
4118 convert (double_type_node,
4119 ffecom_2 (MINUS_EXPR,
4120 arg1_type,
4121 convert (arg1_type,
4122 ffecom_float_half_),
c7e4ee3a
CB
4123 saved_expr1))),
4124 NULL_TREE))
5ff904cd
JL
4125 )
4126 );
4127#endif
4128
4129 case FFEINTRIN_impASIN:
4130 case FFEINTRIN_impDASIN:
4131 case FFEINTRIN_impATAN:
4132 case FFEINTRIN_impDATAN:
4133 case FFEINTRIN_impATAN2:
4134 case FFEINTRIN_impDATAN2:
4135 break;
4136
4137 case FFEINTRIN_impCHAR:
4138 case FFEINTRIN_impACHAR:
c7e4ee3a
CB
4139#ifdef HOHO
4140 tempvar = ffecom_make_tempvar (char_type_node, 1, -1);
4141#else
4142 tempvar = ffebld_nonter_hook (expr);
4143 assert (tempvar);
4144#endif
5ff904cd
JL
4145 {
4146 tree tmv = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (tempvar)));
4147
4148 expr_tree = ffecom_modify (tmv,
4149 ffecom_2 (ARRAY_REF, tmv, tempvar,
4150 integer_one_node),
4151 convert (tmv, ffecom_expr (arg1)));
4152 }
4153 expr_tree = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar),
4154 expr_tree,
4155 tempvar);
4156 expr_tree = ffecom_1 (ADDR_EXPR,
4157 build_pointer_type (TREE_TYPE (expr_tree)),
4158 expr_tree);
4159 return expr_tree;
4160
4161 case FFEINTRIN_impCMPLX:
4162 case FFEINTRIN_impDCMPLX:
4163 if (arg2 == NULL)
4164 return
4165 convert (tree_type, ffecom_expr (arg1));
4166
4167 real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
4168 return
4169 ffecom_2 (COMPLEX_EXPR, tree_type,
4170 convert (real_type, ffecom_expr (arg1)),
4171 convert (real_type,
4172 ffecom_expr (arg2)));
4173
4174 case FFEINTRIN_impCOMPLEX:
4175 return
4176 ffecom_2 (COMPLEX_EXPR, tree_type,
4177 ffecom_expr (arg1),
4178 ffecom_expr (arg2));
4179
4180 case FFEINTRIN_impCONJG:
4181 case FFEINTRIN_impDCONJG:
4182 {
4183 tree arg1_tree;
4184
4185 real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
4186 arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4187 return
4188 ffecom_2 (COMPLEX_EXPR, tree_type,
4189 ffecom_1 (REALPART_EXPR, real_type, arg1_tree),
4190 ffecom_1 (NEGATE_EXPR, real_type,
4191 ffecom_1 (IMAGPART_EXPR, real_type, arg1_tree)));
4192 }
4193
4194 case FFEINTRIN_impCOS:
4195 case FFEINTRIN_impCCOS:
4196 case FFEINTRIN_impCDCOS:
4197 case FFEINTRIN_impDCOS:
4198 if (bt == FFEINFO_basictypeCOMPLEX)
4199 {
4200 if (kt == FFEINFO_kindtypeREAL1)
4201 gfrt = FFECOM_gfrtCCOS; /* Overlapping result okay. */
4202 else if (kt == FFEINFO_kindtypeREAL2)
4203 gfrt = FFECOM_gfrtCDCOS; /* Overlapping result okay. */
4204 }
4205 break;
4206
4207 case FFEINTRIN_impCOSH:
4208 case FFEINTRIN_impDCOSH:
4209 break;
4210
4211 case FFEINTRIN_impDBLE:
4212 case FFEINTRIN_impDFLOAT:
4213 case FFEINTRIN_impDREAL:
4214 case FFEINTRIN_impFLOAT:
4215 case FFEINTRIN_impIDINT:
4216 case FFEINTRIN_impIFIX:
4217 case FFEINTRIN_impINT2:
4218 case FFEINTRIN_impINT8:
4219 case FFEINTRIN_impINT:
4220 case FFEINTRIN_impLONG:
4221 case FFEINTRIN_impREAL:
4222 case FFEINTRIN_impSHORT:
4223 case FFEINTRIN_impSNGL:
4224 return convert (tree_type, ffecom_expr (arg1));
4225
4226 case FFEINTRIN_impDIM:
4227 case FFEINTRIN_impDDIM:
4228 case FFEINTRIN_impIDIM:
4229 saved_expr1 = ffecom_save_tree (convert (tree_type,
4230 ffecom_expr (arg1)));
4231 saved_expr2 = ffecom_save_tree (convert (tree_type,
4232 ffecom_expr (arg2)));
4233 return
4234 ffecom_3 (COND_EXPR, tree_type,
4235 ffecom_truth_value
4236 (ffecom_2 (GT_EXPR, integer_type_node,
4237 saved_expr1,
4238 saved_expr2)),
4239 ffecom_2 (MINUS_EXPR, tree_type,
4240 saved_expr1,
4241 saved_expr2),
4242 convert (tree_type, ffecom_float_zero_));
4243
4244 case FFEINTRIN_impDPROD:
4245 return
4246 ffecom_2 (MULT_EXPR, tree_type,
4247 convert (tree_type, ffecom_expr (arg1)),
4248 convert (tree_type, ffecom_expr (arg2)));
4249
4250 case FFEINTRIN_impEXP:
4251 case FFEINTRIN_impCDEXP:
4252 case FFEINTRIN_impCEXP:
4253 case FFEINTRIN_impDEXP:
4254 if (bt == FFEINFO_basictypeCOMPLEX)
4255 {
4256 if (kt == FFEINFO_kindtypeREAL1)
4257 gfrt = FFECOM_gfrtCEXP; /* Overlapping result okay. */
4258 else if (kt == FFEINFO_kindtypeREAL2)
4259 gfrt = FFECOM_gfrtCDEXP; /* Overlapping result okay. */
4260 }
4261 break;
4262
4263 case FFEINTRIN_impICHAR:
4264 case FFEINTRIN_impIACHAR:
4265#if 0 /* The simple approach. */
4266 ffecom_char_args_ (&expr_tree, &saved_expr1 /* Ignored */ , arg1);
4267 expr_tree
4268 = ffecom_1 (INDIRECT_REF,
4269 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
4270 expr_tree);
4271 expr_tree
4272 = ffecom_2 (ARRAY_REF,
4273 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
4274 expr_tree,
4275 integer_one_node);
4276 return convert (tree_type, expr_tree);
4277#else /* The more interesting (and more optimal) approach. */
4278 expr_tree = ffecom_intrinsic_ichar_ (tree_type, arg1, &saved_expr1);
4279 expr_tree = ffecom_3 (COND_EXPR, tree_type,
4280 saved_expr1,
4281 expr_tree,
4282 convert (tree_type, integer_zero_node));
4283 return expr_tree;
4284#endif
4285
4286 case FFEINTRIN_impINDEX:
4287 break;
4288
4289 case FFEINTRIN_impLEN:
4290#if 0
4291 break; /* The simple approach. */
4292#else
4293 return ffecom_intrinsic_len_ (arg1); /* The more optimal approach. */
4294#endif
4295
4296 case FFEINTRIN_impLGE:
4297 case FFEINTRIN_impLGT:
4298 case FFEINTRIN_impLLE:
4299 case FFEINTRIN_impLLT:
4300 break;
4301
4302 case FFEINTRIN_impLOG:
4303 case FFEINTRIN_impALOG:
4304 case FFEINTRIN_impCDLOG:
4305 case FFEINTRIN_impCLOG:
4306 case FFEINTRIN_impDLOG:
4307 if (bt == FFEINFO_basictypeCOMPLEX)
4308 {
4309 if (kt == FFEINFO_kindtypeREAL1)
4310 gfrt = FFECOM_gfrtCLOG; /* Overlapping result okay. */
4311 else if (kt == FFEINFO_kindtypeREAL2)
4312 gfrt = FFECOM_gfrtCDLOG; /* Overlapping result okay. */
4313 }
4314 break;
4315
4316 case FFEINTRIN_impLOG10:
4317 case FFEINTRIN_impALOG10:
4318 case FFEINTRIN_impDLOG10:
4319 if (gfrt != FFECOM_gfrt)
4320 break; /* Already picked one, stick with it. */
4321
4322 if (kt == FFEINFO_kindtypeREAL1)
4323 gfrt = FFECOM_gfrtALOG10;
4324 else if (kt == FFEINFO_kindtypeREAL2)
4325 gfrt = FFECOM_gfrtDLOG10;
4326 break;
4327
4328 case FFEINTRIN_impMAX:
4329 case FFEINTRIN_impAMAX0:
4330 case FFEINTRIN_impAMAX1:
4331 case FFEINTRIN_impDMAX1:
4332 case FFEINTRIN_impMAX0:
4333 case FFEINTRIN_impMAX1:
4334 if (bt != ffeinfo_basictype (ffebld_info (arg1)))
4335 arg1_type = ffecom_widest_expr_type_ (ffebld_right (expr));
4336 else
4337 arg1_type = tree_type;
4338 expr_tree = ffecom_2 (MAX_EXPR, arg1_type,
4339 convert (arg1_type, ffecom_expr (arg1)),
4340 convert (arg1_type, ffecom_expr (arg2)));
4341 for (; list != NULL; list = ffebld_trail (list))
4342 {
4343 if ((ffebld_head (list) == NULL)
4344 || (ffebld_op (ffebld_head (list)) == FFEBLD_opANY))
4345 continue;
4346 expr_tree = ffecom_2 (MAX_EXPR, arg1_type,
4347 expr_tree,
4348 convert (arg1_type,
4349 ffecom_expr (ffebld_head (list))));
4350 }
4351 return convert (tree_type, expr_tree);
4352
4353 case FFEINTRIN_impMIN:
4354 case FFEINTRIN_impAMIN0:
4355 case FFEINTRIN_impAMIN1:
4356 case FFEINTRIN_impDMIN1:
4357 case FFEINTRIN_impMIN0:
4358 case FFEINTRIN_impMIN1:
4359 if (bt != ffeinfo_basictype (ffebld_info (arg1)))
4360 arg1_type = ffecom_widest_expr_type_ (ffebld_right (expr));
4361 else
4362 arg1_type = tree_type;
4363 expr_tree = ffecom_2 (MIN_EXPR, arg1_type,
4364 convert (arg1_type, ffecom_expr (arg1)),
4365 convert (arg1_type, ffecom_expr (arg2)));
4366 for (; list != NULL; list = ffebld_trail (list))
4367 {
4368 if ((ffebld_head (list) == NULL)
4369 || (ffebld_op (ffebld_head (list)) == FFEBLD_opANY))
4370 continue;
4371 expr_tree = ffecom_2 (MIN_EXPR, arg1_type,
4372 expr_tree,
4373 convert (arg1_type,
4374 ffecom_expr (ffebld_head (list))));
4375 }
4376 return convert (tree_type, expr_tree);
4377
4378 case FFEINTRIN_impMOD:
4379 case FFEINTRIN_impAMOD:
4380 case FFEINTRIN_impDMOD:
4381 if (bt != FFEINFO_basictypeREAL)
4382 return ffecom_2 (TRUNC_MOD_EXPR, tree_type,
4383 convert (tree_type, ffecom_expr (arg1)),
4384 convert (tree_type, ffecom_expr (arg2)));
4385
4386 if (kt == FFEINFO_kindtypeREAL1)
4387 gfrt = FFECOM_gfrtAMOD;
4388 else if (kt == FFEINFO_kindtypeREAL2)
4389 gfrt = FFECOM_gfrtDMOD;
4390 break;
4391
4392 case FFEINTRIN_impNINT:
4393 case FFEINTRIN_impIDNINT:
c7e4ee3a
CB
4394#if 0
4395 /* ~~Ideally FIX_ROUND_EXPR would be implemented, but it ain't yet. */
5ff904cd
JL
4396 return ffecom_1 (FIX_ROUND_EXPR, tree_type, ffecom_expr (arg1));
4397#else
4398 /* i__1 = r1 >= 0 ? floor(r1 + .5) : -floor(.5 - r1); */
4399 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
4400 return
4401 convert (ffecom_integer_type_node,
4402 ffecom_3 (COND_EXPR, arg1_type,
4403 ffecom_truth_value
4404 (ffecom_2 (GE_EXPR, integer_type_node,
4405 saved_expr1,
4406 convert (arg1_type,
4407 ffecom_float_zero_))),
4408 ffecom_2 (PLUS_EXPR, arg1_type,
4409 saved_expr1,
4410 convert (arg1_type,
4411 ffecom_float_half_)),
4412 ffecom_2 (MINUS_EXPR, arg1_type,
4413 saved_expr1,
4414 convert (arg1_type,
4415 ffecom_float_half_))));
4416#endif
4417
4418 case FFEINTRIN_impSIGN:
4419 case FFEINTRIN_impDSIGN:
4420 case FFEINTRIN_impISIGN:
4421 {
4422 tree arg2_tree = ffecom_expr (arg2);
4423
4424 saved_expr1
4425 = ffecom_save_tree
4426 (ffecom_1 (ABS_EXPR, tree_type,
4427 convert (tree_type,
4428 ffecom_expr (arg1))));
4429 expr_tree
4430 = ffecom_3 (COND_EXPR, tree_type,
4431 ffecom_truth_value
4432 (ffecom_2 (GE_EXPR, integer_type_node,
4433 arg2_tree,
4434 convert (TREE_TYPE (arg2_tree),
4435 integer_zero_node))),
4436 saved_expr1,
4437 ffecom_1 (NEGATE_EXPR, tree_type, saved_expr1));
4438 /* Make sure SAVE_EXPRs get referenced early enough. */
4439 expr_tree
4440 = ffecom_2 (COMPOUND_EXPR, tree_type,
4441 convert (void_type_node, saved_expr1),
4442 expr_tree);
4443 }
4444 return expr_tree;
4445
4446 case FFEINTRIN_impSIN:
4447 case FFEINTRIN_impCDSIN:
4448 case FFEINTRIN_impCSIN:
4449 case FFEINTRIN_impDSIN:
4450 if (bt == FFEINFO_basictypeCOMPLEX)
4451 {
4452 if (kt == FFEINFO_kindtypeREAL1)
4453 gfrt = FFECOM_gfrtCSIN; /* Overlapping result okay. */
4454 else if (kt == FFEINFO_kindtypeREAL2)
4455 gfrt = FFECOM_gfrtCDSIN; /* Overlapping result okay. */
4456 }
4457 break;
4458
4459 case FFEINTRIN_impSINH:
4460 case FFEINTRIN_impDSINH:
4461 break;
4462
4463 case FFEINTRIN_impSQRT:
4464 case FFEINTRIN_impCDSQRT:
4465 case FFEINTRIN_impCSQRT:
4466 case FFEINTRIN_impDSQRT:
4467 if (bt == FFEINFO_basictypeCOMPLEX)
4468 {
4469 if (kt == FFEINFO_kindtypeREAL1)
4470 gfrt = FFECOM_gfrtCSQRT; /* Overlapping result okay. */
4471 else if (kt == FFEINFO_kindtypeREAL2)
4472 gfrt = FFECOM_gfrtCDSQRT; /* Overlapping result okay. */
4473 }
4474 break;
4475
4476 case FFEINTRIN_impTAN:
4477 case FFEINTRIN_impDTAN:
4478 case FFEINTRIN_impTANH:
4479 case FFEINTRIN_impDTANH:
4480 break;
4481
4482 case FFEINTRIN_impREALPART:
4483 if (TREE_CODE (arg1_type) == COMPLEX_TYPE)
4484 arg1_type = TREE_TYPE (arg1_type);
4485 else
4486 arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type));
4487
4488 return
4489 convert (tree_type,
4490 ffecom_1 (REALPART_EXPR, arg1_type,
4491 ffecom_expr (arg1)));
4492
4493 case FFEINTRIN_impIAND:
4494 case FFEINTRIN_impAND:
4495 return ffecom_2 (BIT_AND_EXPR, tree_type,
4496 convert (tree_type,
4497 ffecom_expr (arg1)),
4498 convert (tree_type,
4499 ffecom_expr (arg2)));
4500
4501 case FFEINTRIN_impIOR:
4502 case FFEINTRIN_impOR:
4503 return ffecom_2 (BIT_IOR_EXPR, tree_type,
4504 convert (tree_type,
4505 ffecom_expr (arg1)),
4506 convert (tree_type,
4507 ffecom_expr (arg2)));
4508
4509 case FFEINTRIN_impIEOR:
4510 case FFEINTRIN_impXOR:
4511 return ffecom_2 (BIT_XOR_EXPR, tree_type,
4512 convert (tree_type,
4513 ffecom_expr (arg1)),
4514 convert (tree_type,
4515 ffecom_expr (arg2)));
4516
4517 case FFEINTRIN_impLSHIFT:
4518 return ffecom_2 (LSHIFT_EXPR, tree_type,
4519 ffecom_expr (arg1),
4520 convert (integer_type_node,
4521 ffecom_expr (arg2)));
4522
4523 case FFEINTRIN_impRSHIFT:
4524 return ffecom_2 (RSHIFT_EXPR, tree_type,
4525 ffecom_expr (arg1),
4526 convert (integer_type_node,
4527 ffecom_expr (arg2)));
4528
4529 case FFEINTRIN_impNOT:
4530 return ffecom_1 (BIT_NOT_EXPR, tree_type, ffecom_expr (arg1));
4531
4532 case FFEINTRIN_impBIT_SIZE:
4533 return convert (tree_type, TYPE_SIZE (arg1_type));
4534
4535 case FFEINTRIN_impBTEST:
4536 {
4537 ffetargetLogical1 true;
4538 ffetargetLogical1 false;
4539 tree true_tree;
4540 tree false_tree;
4541
4542 ffetarget_logical1 (&true, TRUE);
4543 ffetarget_logical1 (&false, FALSE);
4544 if (true == 1)
4545 true_tree = convert (tree_type, integer_one_node);
4546 else
4547 true_tree = convert (tree_type, build_int_2 (true, 0));
4548 if (false == 0)
4549 false_tree = convert (tree_type, integer_zero_node);
4550 else
4551 false_tree = convert (tree_type, build_int_2 (false, 0));
4552
4553 return
4554 ffecom_3 (COND_EXPR, tree_type,
4555 ffecom_truth_value
4556 (ffecom_2 (EQ_EXPR, integer_type_node,
4557 ffecom_2 (BIT_AND_EXPR, arg1_type,
4558 ffecom_expr (arg1),
4559 ffecom_2 (LSHIFT_EXPR, arg1_type,
4560 convert (arg1_type,
4561 integer_one_node),
4562 convert (integer_type_node,
4563 ffecom_expr (arg2)))),
4564 convert (arg1_type,
4565 integer_zero_node))),
4566 false_tree,
4567 true_tree);
4568 }
4569
4570 case FFEINTRIN_impIBCLR:
4571 return
4572 ffecom_2 (BIT_AND_EXPR, tree_type,
4573 ffecom_expr (arg1),
4574 ffecom_1 (BIT_NOT_EXPR, tree_type,
4575 ffecom_2 (LSHIFT_EXPR, tree_type,
4576 convert (tree_type,
4577 integer_one_node),
4578 convert (integer_type_node,
4579 ffecom_expr (arg2)))));
4580
4581 case FFEINTRIN_impIBITS:
4582 {
4583 tree arg3_tree = ffecom_save_tree (convert (integer_type_node,
4584 ffecom_expr (arg3)));
4585 tree uns_type
4586 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4587
4588 expr_tree
4589 = ffecom_2 (BIT_AND_EXPR, tree_type,
4590 ffecom_2 (RSHIFT_EXPR, tree_type,
4591 ffecom_expr (arg1),
4592 convert (integer_type_node,
4593 ffecom_expr (arg2))),
4594 convert (tree_type,
4595 ffecom_2 (RSHIFT_EXPR, uns_type,
4596 ffecom_1 (BIT_NOT_EXPR,
4597 uns_type,
4598 convert (uns_type,
4599 integer_zero_node)),
4600 ffecom_2 (MINUS_EXPR,
4601 integer_type_node,
4602 TYPE_SIZE (uns_type),
4603 arg3_tree))));
4604#if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4605 expr_tree
4606 = ffecom_3 (COND_EXPR, tree_type,
4607 ffecom_truth_value
4608 (ffecom_2 (NE_EXPR, integer_type_node,
4609 arg3_tree,
4610 integer_zero_node)),
4611 expr_tree,
4612 convert (tree_type, integer_zero_node));
4613#endif
4614 }
4615 return expr_tree;
4616
4617 case FFEINTRIN_impIBSET:
4618 return
4619 ffecom_2 (BIT_IOR_EXPR, tree_type,
4620 ffecom_expr (arg1),
4621 ffecom_2 (LSHIFT_EXPR, tree_type,
4622 convert (tree_type, integer_one_node),
4623 convert (integer_type_node,
4624 ffecom_expr (arg2))));
4625
4626 case FFEINTRIN_impISHFT:
4627 {
4628 tree arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4629 tree arg2_tree = ffecom_save_tree (convert (integer_type_node,
4630 ffecom_expr (arg2)));
4631 tree uns_type
4632 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4633
4634 expr_tree
4635 = ffecom_3 (COND_EXPR, tree_type,
4636 ffecom_truth_value
4637 (ffecom_2 (GE_EXPR, integer_type_node,
4638 arg2_tree,
4639 integer_zero_node)),
4640 ffecom_2 (LSHIFT_EXPR, tree_type,
4641 arg1_tree,
4642 arg2_tree),
4643 convert (tree_type,
4644 ffecom_2 (RSHIFT_EXPR, uns_type,
4645 convert (uns_type, arg1_tree),
4646 ffecom_1 (NEGATE_EXPR,
4647 integer_type_node,
4648 arg2_tree))));
4649#if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4650 expr_tree
4651 = ffecom_3 (COND_EXPR, tree_type,
4652 ffecom_truth_value
4653 (ffecom_2 (NE_EXPR, integer_type_node,
4654 arg2_tree,
4655 TYPE_SIZE (uns_type))),
4656 expr_tree,
4657 convert (tree_type, integer_zero_node));
4658#endif
4659 /* Make sure SAVE_EXPRs get referenced early enough. */
4660 expr_tree
4661 = ffecom_2 (COMPOUND_EXPR, tree_type,
4662 convert (void_type_node, arg1_tree),
4663 ffecom_2 (COMPOUND_EXPR, tree_type,
4664 convert (void_type_node, arg2_tree),
4665 expr_tree));
4666 }
4667 return expr_tree;
4668
4669 case FFEINTRIN_impISHFTC:
4670 {
4671 tree arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4672 tree arg2_tree = ffecom_save_tree (convert (integer_type_node,
4673 ffecom_expr (arg2)));
4674 tree arg3_tree = (arg3 == NULL) ? TYPE_SIZE (tree_type)
4675 : ffecom_save_tree (convert (integer_type_node, ffecom_expr (arg3)));
4676 tree shift_neg;
4677 tree shift_pos;
4678 tree mask_arg1;
4679 tree masked_arg1;
4680 tree uns_type
4681 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4682
4683 mask_arg1
4684 = ffecom_2 (LSHIFT_EXPR, tree_type,
4685 ffecom_1 (BIT_NOT_EXPR, tree_type,
4686 convert (tree_type, integer_zero_node)),
4687 arg3_tree);
4688#if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4689 mask_arg1
4690 = ffecom_3 (COND_EXPR, tree_type,
4691 ffecom_truth_value
4692 (ffecom_2 (NE_EXPR, integer_type_node,
4693 arg3_tree,
4694 TYPE_SIZE (uns_type))),
4695 mask_arg1,
4696 convert (tree_type, integer_zero_node));
4697#endif
4698 mask_arg1 = ffecom_save_tree (mask_arg1);
4699 masked_arg1
4700 = ffecom_2 (BIT_AND_EXPR, tree_type,
4701 arg1_tree,
4702 ffecom_1 (BIT_NOT_EXPR, tree_type,
4703 mask_arg1));
4704 masked_arg1 = ffecom_save_tree (masked_arg1);
4705 shift_neg
4706 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4707 convert (tree_type,
4708 ffecom_2 (RSHIFT_EXPR, uns_type,
4709 convert (uns_type, masked_arg1),
4710 ffecom_1 (NEGATE_EXPR,
4711 integer_type_node,
4712 arg2_tree))),
4713 ffecom_2 (LSHIFT_EXPR, tree_type,
4714 arg1_tree,
4715 ffecom_2 (PLUS_EXPR, integer_type_node,
4716 arg2_tree,
4717 arg3_tree)));
4718 shift_pos
4719 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4720 ffecom_2 (LSHIFT_EXPR, tree_type,
4721 arg1_tree,
4722 arg2_tree),
4723 convert (tree_type,
4724 ffecom_2 (RSHIFT_EXPR, uns_type,
4725 convert (uns_type, masked_arg1),
4726 ffecom_2 (MINUS_EXPR,
4727 integer_type_node,
4728 arg3_tree,
4729 arg2_tree))));
4730 expr_tree
4731 = ffecom_3 (COND_EXPR, tree_type,
4732 ffecom_truth_value
4733 (ffecom_2 (LT_EXPR, integer_type_node,
4734 arg2_tree,
4735 integer_zero_node)),
4736 shift_neg,
4737 shift_pos);
4738 expr_tree
4739 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4740 ffecom_2 (BIT_AND_EXPR, tree_type,
4741 mask_arg1,
4742 arg1_tree),
4743 ffecom_2 (BIT_AND_EXPR, tree_type,
4744 ffecom_1 (BIT_NOT_EXPR, tree_type,
4745 mask_arg1),
4746 expr_tree));
4747 expr_tree
4748 = ffecom_3 (COND_EXPR, tree_type,
4749 ffecom_truth_value
4750 (ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
4751 ffecom_2 (EQ_EXPR, integer_type_node,
4752 ffecom_1 (ABS_EXPR,
4753 integer_type_node,
4754 arg2_tree),
4755 arg3_tree),
4756 ffecom_2 (EQ_EXPR, integer_type_node,
4757 arg2_tree,
4758 integer_zero_node))),
4759 arg1_tree,
4760 expr_tree);
4761 /* Make sure SAVE_EXPRs get referenced early enough. */
4762 expr_tree
4763 = ffecom_2 (COMPOUND_EXPR, tree_type,
4764 convert (void_type_node, arg1_tree),
4765 ffecom_2 (COMPOUND_EXPR, tree_type,
4766 convert (void_type_node, arg2_tree),
4767 ffecom_2 (COMPOUND_EXPR, tree_type,
4768 convert (void_type_node,
4769 mask_arg1),
4770 ffecom_2 (COMPOUND_EXPR, tree_type,
4771 convert (void_type_node,
4772 masked_arg1),
4773 expr_tree))));
4774 expr_tree
4775 = ffecom_2 (COMPOUND_EXPR, tree_type,
4776 convert (void_type_node,
4777 arg3_tree),
4778 expr_tree);
4779 }
4780 return expr_tree;
4781
4782 case FFEINTRIN_impLOC:
4783 {
4784 tree arg1_tree = ffecom_expr (arg1);
4785
4786 expr_tree
4787 = convert (tree_type,
4788 ffecom_1 (ADDR_EXPR,
4789 build_pointer_type (TREE_TYPE (arg1_tree)),
4790 arg1_tree));
4791 }
4792 return expr_tree;
4793
4794 case FFEINTRIN_impMVBITS:
4795 {
4796 tree arg1_tree;
4797 tree arg2_tree;
4798 tree arg3_tree;
4799 ffebld arg4 = ffebld_head (ffebld_trail (list));
4800 tree arg4_tree;
4801 tree arg4_type;
4802 ffebld arg5 = ffebld_head (ffebld_trail (ffebld_trail (list)));
4803 tree arg5_tree;
4804 tree prep_arg1;
4805 tree prep_arg4;
4806 tree arg5_plus_arg3;
4807
5ff904cd
JL
4808 arg2_tree = convert (integer_type_node,
4809 ffecom_expr (arg2));
4810 arg3_tree = ffecom_save_tree (convert (integer_type_node,
4811 ffecom_expr (arg3)));
c7e4ee3a 4812 arg4_tree = ffecom_expr_rw (NULL_TREE, arg4);
5ff904cd
JL
4813 arg4_type = TREE_TYPE (arg4_tree);
4814
4815 arg1_tree = ffecom_save_tree (convert (arg4_type,
4816 ffecom_expr (arg1)));
4817
4818 arg5_tree = ffecom_save_tree (convert (integer_type_node,
4819 ffecom_expr (arg5)));
4820
5ff904cd
JL
4821 prep_arg1
4822 = ffecom_2 (LSHIFT_EXPR, arg4_type,
4823 ffecom_2 (BIT_AND_EXPR, arg4_type,
4824 ffecom_2 (RSHIFT_EXPR, arg4_type,
4825 arg1_tree,
4826 arg2_tree),
4827 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4828 ffecom_2 (LSHIFT_EXPR, arg4_type,
4829 ffecom_1 (BIT_NOT_EXPR,
4830 arg4_type,
4831 convert
4832 (arg4_type,
4833 integer_zero_node)),
4834 arg3_tree))),
4835 arg5_tree);
4836 arg5_plus_arg3
4837 = ffecom_save_tree (ffecom_2 (PLUS_EXPR, arg4_type,
4838 arg5_tree,
4839 arg3_tree));
4840 prep_arg4
4841 = ffecom_2 (LSHIFT_EXPR, arg4_type,
4842 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4843 convert (arg4_type,
4844 integer_zero_node)),
4845 arg5_plus_arg3);
4846#if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4847 prep_arg4
4848 = ffecom_3 (COND_EXPR, arg4_type,
4849 ffecom_truth_value
4850 (ffecom_2 (NE_EXPR, integer_type_node,
4851 arg5_plus_arg3,
4852 convert (TREE_TYPE (arg5_plus_arg3),
4853 TYPE_SIZE (arg4_type)))),
4854 prep_arg4,
4855 convert (arg4_type, integer_zero_node));
4856#endif
4857 prep_arg4
4858 = ffecom_2 (BIT_AND_EXPR, arg4_type,
4859 arg4_tree,
4860 ffecom_2 (BIT_IOR_EXPR, arg4_type,
4861 prep_arg4,
4862 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4863 ffecom_2 (LSHIFT_EXPR, arg4_type,
4864 ffecom_1 (BIT_NOT_EXPR,
4865 arg4_type,
4866 convert
4867 (arg4_type,
4868 integer_zero_node)),
4869 arg5_tree))));
4870 prep_arg1
4871 = ffecom_2 (BIT_IOR_EXPR, arg4_type,
4872 prep_arg1,
4873 prep_arg4);
4874#if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4875 prep_arg1
4876 = ffecom_3 (COND_EXPR, arg4_type,
4877 ffecom_truth_value
4878 (ffecom_2 (NE_EXPR, integer_type_node,
4879 arg3_tree,
4880 convert (TREE_TYPE (arg3_tree),
4881 integer_zero_node))),
4882 prep_arg1,
4883 arg4_tree);
4884 prep_arg1
4885 = ffecom_3 (COND_EXPR, arg4_type,
4886 ffecom_truth_value
4887 (ffecom_2 (NE_EXPR, integer_type_node,
4888 arg3_tree,
4889 convert (TREE_TYPE (arg3_tree),
4890 TYPE_SIZE (arg4_type)))),
4891 prep_arg1,
4892 arg1_tree);
4893#endif
4894 expr_tree
4895 = ffecom_2s (MODIFY_EXPR, void_type_node,
4896 arg4_tree,
4897 prep_arg1);
4898 /* Make sure SAVE_EXPRs get referenced early enough. */
4899 expr_tree
4900 = ffecom_2 (COMPOUND_EXPR, void_type_node,
4901 arg1_tree,
4902 ffecom_2 (COMPOUND_EXPR, void_type_node,
4903 arg3_tree,
4904 ffecom_2 (COMPOUND_EXPR, void_type_node,
4905 arg5_tree,
4906 ffecom_2 (COMPOUND_EXPR, void_type_node,
4907 arg5_plus_arg3,
4908 expr_tree))));
4909 expr_tree
4910 = ffecom_2 (COMPOUND_EXPR, void_type_node,
4911 arg4_tree,
4912 expr_tree);
4913
4914 }
4915 return expr_tree;
4916
4917 case FFEINTRIN_impDERF:
4918 case FFEINTRIN_impERF:
4919 case FFEINTRIN_impDERFC:
4920 case FFEINTRIN_impERFC:
4921 break;
4922
4923 case FFEINTRIN_impIARGC:
4924 /* extern int xargc; i__1 = xargc - 1; */
4925 expr_tree = ffecom_2 (MINUS_EXPR, TREE_TYPE (ffecom_tree_xargc_),
4926 ffecom_tree_xargc_,
4927 convert (TREE_TYPE (ffecom_tree_xargc_),
4928 integer_one_node));
4929 return expr_tree;
4930
4931 case FFEINTRIN_impSIGNAL_func:
4932 case FFEINTRIN_impSIGNAL_subr:
4933 {
4934 tree arg1_tree;
4935 tree arg2_tree;
4936 tree arg3_tree;
4937
5ff904cd
JL
4938 arg1_tree = convert (ffecom_f2c_integer_type_node,
4939 ffecom_expr (arg1));
4940 arg1_tree = ffecom_1 (ADDR_EXPR,
4941 build_pointer_type (TREE_TYPE (arg1_tree)),
4942 arg1_tree);
4943
4944 /* Pass procedure as a pointer to it, anything else by value. */
4945 if (ffeinfo_kind (ffebld_info (arg2)) == FFEINFO_kindENTITY)
4946 arg2_tree = convert (integer_type_node, ffecom_expr (arg2));
4947 else
4948 arg2_tree = ffecom_ptr_to_expr (arg2);
4949 arg2_tree = convert (TREE_TYPE (null_pointer_node),
4950 arg2_tree);
4951
4952 if (arg3 != NULL)
c7e4ee3a 4953 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
4954 else
4955 arg3_tree = NULL_TREE;
4956
5ff904cd
JL
4957 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4958 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
4959 TREE_CHAIN (arg1_tree) = arg2_tree;
4960
4961 expr_tree
4962 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4963 ffecom_gfrt_kindtype (gfrt),
4964 FALSE,
4965 ((codegen_imp == FFEINTRIN_impSIGNAL_subr) ?
4966 NULL_TREE :
4967 tree_type),
4968 arg1_tree,
c7e4ee3a
CB
4969 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4970 ffebld_nonter_hook (expr));
5ff904cd
JL
4971
4972 if (arg3_tree != NULL_TREE)
4973 expr_tree
4974 = ffecom_modify (NULL_TREE, arg3_tree,
4975 convert (TREE_TYPE (arg3_tree),
4976 expr_tree));
4977 }
4978 return expr_tree;
4979
4980 case FFEINTRIN_impALARM:
4981 {
4982 tree arg1_tree;
4983 tree arg2_tree;
4984 tree arg3_tree;
4985
5ff904cd
JL
4986 arg1_tree = convert (ffecom_f2c_integer_type_node,
4987 ffecom_expr (arg1));
4988 arg1_tree = ffecom_1 (ADDR_EXPR,
4989 build_pointer_type (TREE_TYPE (arg1_tree)),
4990 arg1_tree);
4991
4992 /* Pass procedure as a pointer to it, anything else by value. */
4993 if (ffeinfo_kind (ffebld_info (arg2)) == FFEINFO_kindENTITY)
4994 arg2_tree = convert (integer_type_node, ffecom_expr (arg2));
4995 else
4996 arg2_tree = ffecom_ptr_to_expr (arg2);
4997 arg2_tree = convert (TREE_TYPE (null_pointer_node),
4998 arg2_tree);
4999
5000 if (arg3 != NULL)
c7e4ee3a 5001 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
5002 else
5003 arg3_tree = NULL_TREE;
5004
5ff904cd
JL
5005 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5006 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5007 TREE_CHAIN (arg1_tree) = arg2_tree;
5008
5009 expr_tree
5010 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5011 ffecom_gfrt_kindtype (gfrt),
5012 FALSE,
5013 NULL_TREE,
5014 arg1_tree,
c7e4ee3a
CB
5015 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5016 ffebld_nonter_hook (expr));
5ff904cd
JL
5017
5018 if (arg3_tree != NULL_TREE)
5019 expr_tree
5020 = ffecom_modify (NULL_TREE, arg3_tree,
5021 convert (TREE_TYPE (arg3_tree),
5022 expr_tree));
5023 }
5024 return expr_tree;
5025
5026 case FFEINTRIN_impCHDIR_subr:
5027 case FFEINTRIN_impFDATE_subr:
5028 case FFEINTRIN_impFGET_subr:
5029 case FFEINTRIN_impFPUT_subr:
5030 case FFEINTRIN_impGETCWD_subr:
5031 case FFEINTRIN_impHOSTNM_subr:
5032 case FFEINTRIN_impSYSTEM_subr:
5033 case FFEINTRIN_impUNLINK_subr:
5034 {
5035 tree arg1_len = integer_zero_node;
5036 tree arg1_tree;
5037 tree arg2_tree;
5038
5ff904cd
JL
5039 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
5040
5041 if (arg2 != NULL)
c7e4ee3a 5042 arg2_tree = ffecom_expr_w (NULL_TREE, arg2);
5ff904cd
JL
5043 else
5044 arg2_tree = NULL_TREE;
5045
5ff904cd
JL
5046 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5047 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5048 TREE_CHAIN (arg1_tree) = arg1_len;
5049
5050 expr_tree
5051 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5052 ffecom_gfrt_kindtype (gfrt),
5053 FALSE,
5054 NULL_TREE,
5055 arg1_tree,
c7e4ee3a
CB
5056 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5057 ffebld_nonter_hook (expr));
5ff904cd
JL
5058
5059 if (arg2_tree != NULL_TREE)
5060 expr_tree
5061 = ffecom_modify (NULL_TREE, arg2_tree,
5062 convert (TREE_TYPE (arg2_tree),
5063 expr_tree));
5064 }
5065 return expr_tree;
5066
5067 case FFEINTRIN_impEXIT:
5068 if (arg1 != NULL)
5069 break;
5070
5071 expr_tree = build_tree_list (NULL_TREE,
5072 ffecom_1 (ADDR_EXPR,
5073 build_pointer_type
5074 (ffecom_integer_type_node),
5075 integer_zero_node));
5076
5077 return
5078 ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5079 ffecom_gfrt_kindtype (gfrt),
5080 FALSE,
5081 void_type_node,
5082 expr_tree,
c7e4ee3a
CB
5083 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5084 ffebld_nonter_hook (expr));
5ff904cd
JL
5085
5086 case FFEINTRIN_impFLUSH:
5087 if (arg1 == NULL)
5088 gfrt = FFECOM_gfrtFLUSH;
5089 else
5090 gfrt = FFECOM_gfrtFLUSH1;
5091 break;
5092
5093 case FFEINTRIN_impCHMOD_subr:
5094 case FFEINTRIN_impLINK_subr:
5095 case FFEINTRIN_impRENAME_subr:
5096 case FFEINTRIN_impSYMLNK_subr:
5097 {
5098 tree arg1_len = integer_zero_node;
5099 tree arg1_tree;
5100 tree arg2_len = integer_zero_node;
5101 tree arg2_tree;
5102 tree arg3_tree;
5103
5ff904cd
JL
5104 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
5105 arg2_tree = ffecom_arg_ptr_to_expr (arg2, &arg2_len);
5106 if (arg3 != NULL)
c7e4ee3a 5107 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
5108 else
5109 arg3_tree = NULL_TREE;
5110
5ff904cd
JL
5111 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5112 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5113 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5114 arg2_len = build_tree_list (NULL_TREE, arg2_len);
5115 TREE_CHAIN (arg1_tree) = arg2_tree;
5116 TREE_CHAIN (arg2_tree) = arg1_len;
5117 TREE_CHAIN (arg1_len) = arg2_len;
5118 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5119 ffecom_gfrt_kindtype (gfrt),
5120 FALSE,
5121 NULL_TREE,
5122 arg1_tree,
c7e4ee3a
CB
5123 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5124 ffebld_nonter_hook (expr));
5ff904cd
JL
5125 if (arg3_tree != NULL_TREE)
5126 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5127 convert (TREE_TYPE (arg3_tree),
5128 expr_tree));
5129 }
5130 return expr_tree;
5131
5132 case FFEINTRIN_impLSTAT_subr:
5133 case FFEINTRIN_impSTAT_subr:
5134 {
5135 tree arg1_len = integer_zero_node;
5136 tree arg1_tree;
5137 tree arg2_tree;
5138 tree arg3_tree;
5139
5ff904cd
JL
5140 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
5141
5142 arg2_tree = ffecom_ptr_to_expr (arg2);
5143
5144 if (arg3 != NULL)
c7e4ee3a 5145 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
5146 else
5147 arg3_tree = NULL_TREE;
5148
5ff904cd
JL
5149 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5150 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5151 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5152 TREE_CHAIN (arg1_tree) = arg2_tree;
5153 TREE_CHAIN (arg2_tree) = arg1_len;
5154 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5155 ffecom_gfrt_kindtype (gfrt),
5156 FALSE,
5157 NULL_TREE,
5158 arg1_tree,
c7e4ee3a
CB
5159 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5160 ffebld_nonter_hook (expr));
5ff904cd
JL
5161 if (arg3_tree != NULL_TREE)
5162 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5163 convert (TREE_TYPE (arg3_tree),
5164 expr_tree));
5165 }
5166 return expr_tree;
5167
5168 case FFEINTRIN_impFGETC_subr:
5169 case FFEINTRIN_impFPUTC_subr:
5170 {
5171 tree arg1_tree;
5172 tree arg2_tree;
5173 tree arg2_len = integer_zero_node;
5174 tree arg3_tree;
5175
5ff904cd
JL
5176 arg1_tree = convert (ffecom_f2c_integer_type_node,
5177 ffecom_expr (arg1));
5178 arg1_tree = ffecom_1 (ADDR_EXPR,
5179 build_pointer_type (TREE_TYPE (arg1_tree)),
5180 arg1_tree);
5181
5182 arg2_tree = ffecom_arg_ptr_to_expr (arg2, &arg2_len);
c7e4ee3a 5183 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
5184
5185 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5186 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5187 arg2_len = build_tree_list (NULL_TREE, arg2_len);
5188 TREE_CHAIN (arg1_tree) = arg2_tree;
5189 TREE_CHAIN (arg2_tree) = arg2_len;
5190
5191 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5192 ffecom_gfrt_kindtype (gfrt),
5193 FALSE,
5194 NULL_TREE,
5195 arg1_tree,
c7e4ee3a
CB
5196 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5197 ffebld_nonter_hook (expr));
5ff904cd
JL
5198 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5199 convert (TREE_TYPE (arg3_tree),
5200 expr_tree));
5201 }
5202 return expr_tree;
5203
5204 case FFEINTRIN_impFSTAT_subr:
5205 {
5206 tree arg1_tree;
5207 tree arg2_tree;
5208 tree arg3_tree;
5209
5ff904cd
JL
5210 arg1_tree = convert (ffecom_f2c_integer_type_node,
5211 ffecom_expr (arg1));
5212 arg1_tree = ffecom_1 (ADDR_EXPR,
5213 build_pointer_type (TREE_TYPE (arg1_tree)),
5214 arg1_tree);
5215
5216 arg2_tree = convert (ffecom_f2c_ptr_to_integer_type_node,
5217 ffecom_ptr_to_expr (arg2));
5218
5219 if (arg3 == NULL)
5220 arg3_tree = NULL_TREE;
5221 else
c7e4ee3a 5222 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
5223
5224 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5225 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5226 TREE_CHAIN (arg1_tree) = arg2_tree;
5227 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5228 ffecom_gfrt_kindtype (gfrt),
5229 FALSE,
5230 NULL_TREE,
5231 arg1_tree,
c7e4ee3a
CB
5232 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5233 ffebld_nonter_hook (expr));
5ff904cd
JL
5234 if (arg3_tree != NULL_TREE) {
5235 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5236 convert (TREE_TYPE (arg3_tree),
5237 expr_tree));
5238 }
5239 }
5240 return expr_tree;
5241
5242 case FFEINTRIN_impKILL_subr:
5243 {
5244 tree arg1_tree;
5245 tree arg2_tree;
5246 tree arg3_tree;
5247
5ff904cd
JL
5248 arg1_tree = convert (ffecom_f2c_integer_type_node,
5249 ffecom_expr (arg1));
5250 arg1_tree = ffecom_1 (ADDR_EXPR,
5251 build_pointer_type (TREE_TYPE (arg1_tree)),
5252 arg1_tree);
5253
5254 arg2_tree = convert (ffecom_f2c_integer_type_node,
5255 ffecom_expr (arg2));
5256 arg2_tree = ffecom_1 (ADDR_EXPR,
5257 build_pointer_type (TREE_TYPE (arg2_tree)),
5258 arg2_tree);
5259
5260 if (arg3 == NULL)
5261 arg3_tree = NULL_TREE;
5262 else
c7e4ee3a 5263 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
5264
5265 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5266 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5267 TREE_CHAIN (arg1_tree) = arg2_tree;
5268 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5269 ffecom_gfrt_kindtype (gfrt),
5270 FALSE,
5271 NULL_TREE,
5272 arg1_tree,
c7e4ee3a
CB
5273 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5274 ffebld_nonter_hook (expr));
5ff904cd
JL
5275 if (arg3_tree != NULL_TREE) {
5276 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5277 convert (TREE_TYPE (arg3_tree),
5278 expr_tree));
5279 }
5280 }
5281 return expr_tree;
5282
5283 case FFEINTRIN_impCTIME_subr:
5284 case FFEINTRIN_impTTYNAM_subr:
5285 {
5286 tree arg1_len = integer_zero_node;
5287 tree arg1_tree;
5288 tree arg2_tree;
5289
2b0bdd9a 5290 arg1_tree = ffecom_arg_ptr_to_expr (arg2, &arg1_len);
5ff904cd 5291
c56f65d6 5292 arg2_tree = convert (((codegen_imp == FFEINTRIN_impCTIME_subr) ?
5ff904cd
JL
5293 ffecom_f2c_longint_type_node :
5294 ffecom_f2c_integer_type_node),
2b0bdd9a 5295 ffecom_expr (arg1));
5ff904cd
JL
5296 arg2_tree = ffecom_1 (ADDR_EXPR,
5297 build_pointer_type (TREE_TYPE (arg2_tree)),
5298 arg2_tree);
5299
5ff904cd
JL
5300 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5301 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5302 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5303 TREE_CHAIN (arg1_len) = arg2_tree;
5304 TREE_CHAIN (arg1_tree) = arg1_len;
5305
5306 expr_tree
5307 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5308 ffecom_gfrt_kindtype (gfrt),
5309 FALSE,
5310 NULL_TREE,
5311 arg1_tree,
c7e4ee3a
CB
5312 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5313 ffebld_nonter_hook (expr));
2b0bdd9a 5314 TREE_SIDE_EFFECTS (expr_tree) = 1;
5ff904cd
JL
5315 }
5316 return expr_tree;
5317
5318 case FFEINTRIN_impIRAND:
5319 case FFEINTRIN_impRAND:
5320 /* Arg defaults to 0 (normal random case) */
5321 {
5322 tree arg1_tree;
5323
5324 if (arg1 == NULL)
5325 arg1_tree = ffecom_integer_zero_node;
5326 else
5327 arg1_tree = ffecom_expr (arg1);
5328 arg1_tree = convert (ffecom_f2c_integer_type_node,
5329 arg1_tree);
5330 arg1_tree = ffecom_1 (ADDR_EXPR,
5331 build_pointer_type (TREE_TYPE (arg1_tree)),
5332 arg1_tree);
5333 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5334
5335 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5336 ffecom_gfrt_kindtype (gfrt),
5337 FALSE,
5338 ((codegen_imp == FFEINTRIN_impIRAND) ?
5339 ffecom_f2c_integer_type_node :
de7f278a 5340 ffecom_f2c_real_type_node),
5ff904cd
JL
5341 arg1_tree,
5342 dest_tree, dest, dest_used,
c7e4ee3a
CB
5343 NULL_TREE, TRUE,
5344 ffebld_nonter_hook (expr));
5ff904cd
JL
5345 }
5346 return expr_tree;
5347
5348 case FFEINTRIN_impFTELL_subr:
5349 case FFEINTRIN_impUMASK_subr:
5350 {
5351 tree arg1_tree;
5352 tree arg2_tree;
5353
5ff904cd
JL
5354 arg1_tree = convert (ffecom_f2c_integer_type_node,
5355 ffecom_expr (arg1));
5356 arg1_tree = ffecom_1 (ADDR_EXPR,
5357 build_pointer_type (TREE_TYPE (arg1_tree)),
5358 arg1_tree);
5359
5360 if (arg2 == NULL)
5361 arg2_tree = NULL_TREE;
5362 else
c7e4ee3a 5363 arg2_tree = ffecom_expr_w (NULL_TREE, arg2);
5ff904cd
JL
5364
5365 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5366 ffecom_gfrt_kindtype (gfrt),
5367 FALSE,
5368 NULL_TREE,
5369 build_tree_list (NULL_TREE, arg1_tree),
5370 NULL_TREE, NULL, NULL, NULL_TREE,
c7e4ee3a
CB
5371 TRUE,
5372 ffebld_nonter_hook (expr));
5ff904cd
JL
5373 if (arg2_tree != NULL_TREE) {
5374 expr_tree = ffecom_modify (NULL_TREE, arg2_tree,
5375 convert (TREE_TYPE (arg2_tree),
5376 expr_tree));
5377 }
5378 }
5379 return expr_tree;
5380
5381 case FFEINTRIN_impCPU_TIME:
5382 case FFEINTRIN_impSECOND_subr:
5383 {
5384 tree arg1_tree;
5385
c7e4ee3a 5386 arg1_tree = ffecom_expr_w (NULL_TREE, arg1);
5ff904cd
JL
5387
5388 expr_tree
5389 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5390 ffecom_gfrt_kindtype (gfrt),
5391 FALSE,
5392 NULL_TREE,
5393 NULL_TREE,
c7e4ee3a
CB
5394 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5395 ffebld_nonter_hook (expr));
5ff904cd
JL
5396
5397 expr_tree
5398 = ffecom_modify (NULL_TREE, arg1_tree,
5399 convert (TREE_TYPE (arg1_tree),
5400 expr_tree));
5401 }
5402 return expr_tree;
5403
5404 case FFEINTRIN_impDTIME_subr:
5405 case FFEINTRIN_impETIME_subr:
5406 {
5407 tree arg1_tree;
2b0bdd9a 5408 tree result_tree;
5ff904cd 5409
2b0bdd9a 5410 result_tree = ffecom_expr_w (NULL_TREE, arg2);
5ff904cd 5411
2b0bdd9a 5412 arg1_tree = ffecom_ptr_to_expr (arg1);
5ff904cd 5413
5ff904cd
JL
5414 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5415 ffecom_gfrt_kindtype (gfrt),
5416 FALSE,
5417 NULL_TREE,
2b0bdd9a 5418 build_tree_list (NULL_TREE, arg1_tree),
5ff904cd 5419 NULL_TREE, NULL, NULL, NULL_TREE,
c7e4ee3a
CB
5420 TRUE,
5421 ffebld_nonter_hook (expr));
2b0bdd9a
CB
5422 expr_tree = ffecom_modify (NULL_TREE, result_tree,
5423 convert (TREE_TYPE (result_tree),
5ff904cd
JL
5424 expr_tree));
5425 }
5426 return expr_tree;
5427
c7e4ee3a 5428 /* Straightforward calls of libf2c routines: */
5ff904cd
JL
5429 case FFEINTRIN_impABORT:
5430 case FFEINTRIN_impACCESS:
5431 case FFEINTRIN_impBESJ0:
5432 case FFEINTRIN_impBESJ1:
5433 case FFEINTRIN_impBESJN:
5434 case FFEINTRIN_impBESY0:
5435 case FFEINTRIN_impBESY1:
5436 case FFEINTRIN_impBESYN:
5437 case FFEINTRIN_impCHDIR_func:
5438 case FFEINTRIN_impCHMOD_func:
5439 case FFEINTRIN_impDATE:
9e8e701d 5440 case FFEINTRIN_impDATE_AND_TIME:
5ff904cd
JL
5441 case FFEINTRIN_impDBESJ0:
5442 case FFEINTRIN_impDBESJ1:
5443 case FFEINTRIN_impDBESJN:
5444 case FFEINTRIN_impDBESY0:
5445 case FFEINTRIN_impDBESY1:
5446 case FFEINTRIN_impDBESYN:
5447 case FFEINTRIN_impDTIME_func:
5448 case FFEINTRIN_impETIME_func:
5449 case FFEINTRIN_impFGETC_func:
5450 case FFEINTRIN_impFGET_func:
5451 case FFEINTRIN_impFNUM:
5452 case FFEINTRIN_impFPUTC_func:
5453 case FFEINTRIN_impFPUT_func:
5454 case FFEINTRIN_impFSEEK:
5455 case FFEINTRIN_impFSTAT_func:
5456 case FFEINTRIN_impFTELL_func:
5457 case FFEINTRIN_impGERROR:
5458 case FFEINTRIN_impGETARG:
5459 case FFEINTRIN_impGETCWD_func:
5460 case FFEINTRIN_impGETENV:
5461 case FFEINTRIN_impGETGID:
5462 case FFEINTRIN_impGETLOG:
5463 case FFEINTRIN_impGETPID:
5464 case FFEINTRIN_impGETUID:
5465 case FFEINTRIN_impGMTIME:
5466 case FFEINTRIN_impHOSTNM_func:
5467 case FFEINTRIN_impIDATE_unix:
5468 case FFEINTRIN_impIDATE_vxt:
5469 case FFEINTRIN_impIERRNO:
5470 case FFEINTRIN_impISATTY:
5471 case FFEINTRIN_impITIME:
5472 case FFEINTRIN_impKILL_func:
5473 case FFEINTRIN_impLINK_func:
5474 case FFEINTRIN_impLNBLNK:
5475 case FFEINTRIN_impLSTAT_func:
5476 case FFEINTRIN_impLTIME:
5477 case FFEINTRIN_impMCLOCK8:
5478 case FFEINTRIN_impMCLOCK:
5479 case FFEINTRIN_impPERROR:
5480 case FFEINTRIN_impRENAME_func:
5481 case FFEINTRIN_impSECNDS:
5482 case FFEINTRIN_impSECOND_func:
5483 case FFEINTRIN_impSLEEP:
5484 case FFEINTRIN_impSRAND:
5485 case FFEINTRIN_impSTAT_func:
5486 case FFEINTRIN_impSYMLNK_func:
5487 case FFEINTRIN_impSYSTEM_CLOCK:
5488 case FFEINTRIN_impSYSTEM_func:
5489 case FFEINTRIN_impTIME8:
5490 case FFEINTRIN_impTIME_unix:
5491 case FFEINTRIN_impTIME_vxt:
5492 case FFEINTRIN_impUMASK_func:
5493 case FFEINTRIN_impUNLINK_func:
5494 break;
5495
5496 case FFEINTRIN_impCTIME_func: /* CHARACTER functions not handled here. */
5497 case FFEINTRIN_impFDATE_func: /* CHARACTER functions not handled here. */
5498 case FFEINTRIN_impTTYNAM_func: /* CHARACTER functions not handled here. */
5499 case FFEINTRIN_impNONE:
5500 case FFEINTRIN_imp: /* Hush up gcc warning. */
5501 fprintf (stderr, "No %s implementation.\n",
5502 ffeintrin_name_implementation (ffebld_symter_implementation (ffebld_left (expr))));
5503 assert ("unimplemented intrinsic" == NULL);
5504 return error_mark_node;
5505 }
5506
5507 assert (gfrt != FFECOM_gfrt); /* Must have an implementation! */
5508
5ff904cd
JL
5509 expr_tree = ffecom_arglist_expr_ (ffecom_gfrt_args_ (gfrt),
5510 ffebld_right (expr));
5ff904cd
JL
5511
5512 return ffecom_call_ (ffecom_gfrt_tree_ (gfrt), ffecom_gfrt_kindtype (gfrt),
5513 (ffe_is_f2c_library () && ffecom_gfrt_complex_[gfrt]),
5514 tree_type,
5515 expr_tree, dest_tree, dest, dest_used,
c7e4ee3a
CB
5516 NULL_TREE, TRUE,
5517 ffebld_nonter_hook (expr));
5ff904cd 5518
c7e4ee3a
CB
5519 /* See bottom of this file for f2c transforms used to determine
5520 many of the above implementations. The info seems to confuse
5521 Emacs's C mode indentation, which is why it's been moved to
5522 the bottom of this source file. */
5523}
5ff904cd 5524
c7e4ee3a
CB
5525#endif
5526/* For power (exponentiation) where right-hand operand is type INTEGER,
5527 generate in-line code to do it the fast way (which, if the operand
5528 is a constant, might just mean a series of multiplies). */
5ff904cd 5529
c7e4ee3a
CB
5530#if FFECOM_targetCURRENT == FFECOM_targetGCC
5531static tree
5532ffecom_expr_power_integer_ (ffebld expr)
5533{
5534 tree l = ffecom_expr (ffebld_left (expr));
5535 tree r = ffecom_expr (ffebld_right (expr));
5536 tree ltype = TREE_TYPE (l);
5537 tree rtype = TREE_TYPE (r);
5538 tree result = NULL_TREE;
5ff904cd 5539
c7e4ee3a
CB
5540 if (l == error_mark_node
5541 || r == error_mark_node)
5542 return error_mark_node;
5ff904cd 5543
c7e4ee3a
CB
5544 if (TREE_CODE (r) == INTEGER_CST)
5545 {
5546 int sgn = tree_int_cst_sgn (r);
5ff904cd 5547
c7e4ee3a
CB
5548 if (sgn == 0)
5549 return convert (ltype, integer_one_node);
5ff904cd 5550
c7e4ee3a
CB
5551 if ((TREE_CODE (ltype) == INTEGER_TYPE)
5552 && (sgn < 0))
5553 {
5554 /* Reciprocal of integer is either 0, -1, or 1, so after
5555 calculating that (which we leave to the back end to do
5556 or not do optimally), don't bother with any multiplying. */
5ff904cd 5557
c7e4ee3a
CB
5558 result = ffecom_tree_divide_ (ltype,
5559 convert (ltype, integer_one_node),
5560 l,
5561 NULL_TREE, NULL, NULL, NULL_TREE);
5562 r = ffecom_1 (NEGATE_EXPR,
5563 rtype,
5564 r);
5565 if ((TREE_INT_CST_LOW (r) & 1) == 0)
5566 result = ffecom_1 (ABS_EXPR, rtype,
5567 result);
5568 }
5ff904cd 5569
c7e4ee3a
CB
5570 /* Generate appropriate series of multiplies, preceded
5571 by divide if the exponent is negative. */
5ff904cd 5572
c7e4ee3a 5573 l = save_expr (l);
5ff904cd 5574
c7e4ee3a
CB
5575 if (sgn < 0)
5576 {
5577 l = ffecom_tree_divide_ (ltype,
5578 convert (ltype, integer_one_node),
5579 l,
5580 NULL_TREE, NULL, NULL,
5581 ffebld_nonter_hook (expr));
5582 r = ffecom_1 (NEGATE_EXPR, rtype, r);
5583 assert (TREE_CODE (r) == INTEGER_CST);
5ff904cd 5584
c7e4ee3a
CB
5585 if (tree_int_cst_sgn (r) < 0)
5586 { /* The "most negative" number. */
5587 r = ffecom_1 (NEGATE_EXPR, rtype,
5588 ffecom_2 (RSHIFT_EXPR, rtype,
5589 r,
5590 integer_one_node));
5591 l = save_expr (l);
5592 l = ffecom_2 (MULT_EXPR, ltype,
5593 l,
5594 l);
5595 }
5596 }
5ff904cd 5597
c7e4ee3a
CB
5598 for (;;)
5599 {
5600 if (TREE_INT_CST_LOW (r) & 1)
5601 {
5602 if (result == NULL_TREE)
5603 result = l;
5604 else
5605 result = ffecom_2 (MULT_EXPR, ltype,
5606 result,
5607 l);
5608 }
5ff904cd 5609
c7e4ee3a
CB
5610 r = ffecom_2 (RSHIFT_EXPR, rtype,
5611 r,
5612 integer_one_node);
5613 if (integer_zerop (r))
5614 break;
5615 assert (TREE_CODE (r) == INTEGER_CST);
5ff904cd 5616
c7e4ee3a
CB
5617 l = save_expr (l);
5618 l = ffecom_2 (MULT_EXPR, ltype,
5619 l,
5620 l);
5621 }
5622 return result;
5623 }
5ff904cd 5624
c7e4ee3a
CB
5625 /* Though rhs isn't a constant, in-line code cannot be expanded
5626 while transforming dummies
5627 because the back end cannot be easily convinced to generate
5628 stores (MODIFY_EXPR), handle temporaries, and so on before
5629 all the appropriate rtx's have been generated for things like
5630 dummy args referenced in rhs -- which doesn't happen until
5631 store_parm_decls() is called (expand_function_start, I believe,
5632 does the actual rtx-stuffing of PARM_DECLs).
5ff904cd 5633
c7e4ee3a
CB
5634 So, in this case, let the caller generate the call to the
5635 run-time-library function to evaluate the power for us. */
5ff904cd 5636
c7e4ee3a
CB
5637 if (ffecom_transform_only_dummies_)
5638 return NULL_TREE;
5ff904cd 5639
c7e4ee3a
CB
5640 /* Right-hand operand not a constant, expand in-line code to figure
5641 out how to do the multiplies, &c.
5ff904cd 5642
c7e4ee3a
CB
5643 The returned expression is expressed this way in GNU C, where l and
5644 r are the "inputs":
5ff904cd 5645
c7e4ee3a
CB
5646 ({ typeof (r) rtmp = r;
5647 typeof (l) ltmp = l;
5648 typeof (l) result;
5ff904cd 5649
c7e4ee3a
CB
5650 if (rtmp == 0)
5651 result = 1;
5652 else
5653 {
5654 if ((basetypeof (l) == basetypeof (int))
5655 && (rtmp < 0))
5656 {
5657 result = ((typeof (l)) 1) / ltmp;
5658 if ((ltmp < 0) && (((-rtmp) & 1) == 0))
5659 result = -result;
5660 }
5661 else
5662 {
5663 result = 1;
5664 if ((basetypeof (l) != basetypeof (int))
5665 && (rtmp < 0))
5666 {
5667 ltmp = ((typeof (l)) 1) / ltmp;
5668 rtmp = -rtmp;
5669 if (rtmp < 0)
5670 {
5671 rtmp = -(rtmp >> 1);
5672 ltmp *= ltmp;
5673 }
5674 }
5675 for (;;)
5676 {
5677 if (rtmp & 1)
5678 result *= ltmp;
5679 if ((rtmp >>= 1) == 0)
5680 break;
5681 ltmp *= ltmp;
5682 }
5683 }
5684 }
5685 result;
5686 })
5ff904cd 5687
c7e4ee3a
CB
5688 Note that some of the above is compile-time collapsable, such as
5689 the first part of the if statements that checks the base type of
5690 l against int. The if statements are phrased that way to suggest
5691 an easy way to generate the if/else constructs here, knowing that
5692 the back end should (and probably does) eliminate the resulting
5693 dead code (either the int case or the non-int case), something
5694 it couldn't do without the redundant phrasing, requiring explicit
5695 dead-code elimination here, which would be kind of difficult to
5696 read. */
5ff904cd 5697
c7e4ee3a
CB
5698 {
5699 tree rtmp;
5700 tree ltmp;
5701 tree divide;
5702 tree basetypeof_l_is_int;
5703 tree se;
5704 tree t;
5ff904cd 5705
c7e4ee3a
CB
5706 basetypeof_l_is_int
5707 = build_int_2 ((TREE_CODE (ltype) == INTEGER_TYPE), 0);
5ff904cd 5708
c7e4ee3a 5709 se = expand_start_stmt_expr ();
5ff904cd 5710
c7e4ee3a
CB
5711 ffecom_start_compstmt ();
5712
5713#ifndef HAHA
5714 rtmp = ffecom_make_tempvar ("power_r", rtype,
5715 FFETARGET_charactersizeNONE, -1);
5716 ltmp = ffecom_make_tempvar ("power_l", ltype,
5717 FFETARGET_charactersizeNONE, -1);
5718 result = ffecom_make_tempvar ("power_res", ltype,
5719 FFETARGET_charactersizeNONE, -1);
5720 if (TREE_CODE (ltype) == COMPLEX_TYPE
5721 || TREE_CODE (ltype) == RECORD_TYPE)
5722 divide = ffecom_make_tempvar ("power_div", ltype,
5723 FFETARGET_charactersizeNONE, -1);
5724 else
5725 divide = NULL_TREE;
5726#else /* HAHA */
5727 {
5728 tree hook;
5729
5730 hook = ffebld_nonter_hook (expr);
5731 assert (hook);
5732 assert (TREE_CODE (hook) == TREE_VEC);
5733 assert (TREE_VEC_LENGTH (hook) == 4);
5734 rtmp = TREE_VEC_ELT (hook, 0);
5735 ltmp = TREE_VEC_ELT (hook, 1);
5736 result = TREE_VEC_ELT (hook, 2);
5737 divide = TREE_VEC_ELT (hook, 3);
5738 if (TREE_CODE (ltype) == COMPLEX_TYPE
5739 || TREE_CODE (ltype) == RECORD_TYPE)
5740 assert (divide);
5741 else
5742 assert (! divide);
5743 }
5744#endif /* HAHA */
5ff904cd 5745
c7e4ee3a
CB
5746 expand_expr_stmt (ffecom_modify (void_type_node,
5747 rtmp,
5748 r));
5749 expand_expr_stmt (ffecom_modify (void_type_node,
5750 ltmp,
5751 l));
5752 expand_start_cond (ffecom_truth_value
5753 (ffecom_2 (EQ_EXPR, integer_type_node,
5754 rtmp,
5755 convert (rtype, integer_zero_node))),
5756 0);
5757 expand_expr_stmt (ffecom_modify (void_type_node,
5758 result,
5759 convert (ltype, integer_one_node)));
5760 expand_start_else ();
5761 if (! integer_zerop (basetypeof_l_is_int))
5762 {
5763 expand_start_cond (ffecom_2 (LT_EXPR, integer_type_node,
5764 rtmp,
5765 convert (rtype,
5766 integer_zero_node)),
5767 0);
5768 expand_expr_stmt (ffecom_modify (void_type_node,
5769 result,
5770 ffecom_tree_divide_
5771 (ltype,
5772 convert (ltype, integer_one_node),
5773 ltmp,
5774 NULL_TREE, NULL, NULL,
5775 divide)));
5776 expand_start_cond (ffecom_truth_value
5777 (ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
5778 ffecom_2 (LT_EXPR, integer_type_node,
5779 ltmp,
5780 convert (ltype,
5781 integer_zero_node)),
5782 ffecom_2 (EQ_EXPR, integer_type_node,
5783 ffecom_2 (BIT_AND_EXPR,
5784 rtype,
5785 ffecom_1 (NEGATE_EXPR,
5786 rtype,
5787 rtmp),
5788 convert (rtype,
5789 integer_one_node)),
5790 convert (rtype,
5791 integer_zero_node)))),
5792 0);
5793 expand_expr_stmt (ffecom_modify (void_type_node,
5794 result,
5795 ffecom_1 (NEGATE_EXPR,
5796 ltype,
5797 result)));
5798 expand_end_cond ();
5799 expand_start_else ();
5800 }
5801 expand_expr_stmt (ffecom_modify (void_type_node,
5802 result,
5803 convert (ltype, integer_one_node)));
5804 expand_start_cond (ffecom_truth_value
5805 (ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
5806 ffecom_truth_value_invert
5807 (basetypeof_l_is_int),
5808 ffecom_2 (LT_EXPR, integer_type_node,
5809 rtmp,
5810 convert (rtype,
5811 integer_zero_node)))),
5812 0);
5813 expand_expr_stmt (ffecom_modify (void_type_node,
5814 ltmp,
5815 ffecom_tree_divide_
5816 (ltype,
5817 convert (ltype, integer_one_node),
5818 ltmp,
5819 NULL_TREE, NULL, NULL,
5820 divide)));
5821 expand_expr_stmt (ffecom_modify (void_type_node,
5822 rtmp,
5823 ffecom_1 (NEGATE_EXPR, rtype,
5824 rtmp)));
5825 expand_start_cond (ffecom_truth_value
5826 (ffecom_2 (LT_EXPR, integer_type_node,
5827 rtmp,
5828 convert (rtype, integer_zero_node))),
5829 0);
5830 expand_expr_stmt (ffecom_modify (void_type_node,
5831 rtmp,
5832 ffecom_1 (NEGATE_EXPR, rtype,
5833 ffecom_2 (RSHIFT_EXPR,
5834 rtype,
5835 rtmp,
5836 integer_one_node))));
5837 expand_expr_stmt (ffecom_modify (void_type_node,
5838 ltmp,
5839 ffecom_2 (MULT_EXPR, ltype,
5840 ltmp,
5841 ltmp)));
5842 expand_end_cond ();
5843 expand_end_cond ();
5844 expand_start_loop (1);
5845 expand_start_cond (ffecom_truth_value
5846 (ffecom_2 (BIT_AND_EXPR, rtype,
5847 rtmp,
5848 convert (rtype, integer_one_node))),
5849 0);
5850 expand_expr_stmt (ffecom_modify (void_type_node,
5851 result,
5852 ffecom_2 (MULT_EXPR, ltype,
5853 result,
5854 ltmp)));
5855 expand_end_cond ();
5856 expand_exit_loop_if_false (NULL,
5857 ffecom_truth_value
5858 (ffecom_modify (rtype,
5859 rtmp,
5860 ffecom_2 (RSHIFT_EXPR,
5861 rtype,
5862 rtmp,
5863 integer_one_node))));
5864 expand_expr_stmt (ffecom_modify (void_type_node,
5865 ltmp,
5866 ffecom_2 (MULT_EXPR, ltype,
5867 ltmp,
5868 ltmp)));
5869 expand_end_loop ();
5870 expand_end_cond ();
5871 if (!integer_zerop (basetypeof_l_is_int))
5872 expand_end_cond ();
5873 expand_expr_stmt (result);
5ff904cd 5874
c7e4ee3a 5875 t = ffecom_end_compstmt ();
5ff904cd 5876
c7e4ee3a 5877 result = expand_end_stmt_expr (se);
5ff904cd 5878
c7e4ee3a 5879 /* This code comes from c-parse.in, after its expand_end_stmt_expr. */
5ff904cd 5880
c7e4ee3a
CB
5881 if (TREE_CODE (t) == BLOCK)
5882 {
5883 /* Make a BIND_EXPR for the BLOCK already made. */
5884 result = build (BIND_EXPR, TREE_TYPE (result),
5885 NULL_TREE, result, t);
5886 /* Remove the block from the tree at this point.
5887 It gets put back at the proper place
5888 when the BIND_EXPR is expanded. */
5889 delete_block (t);
5890 }
5891 else
5892 result = t;
5893 }
5ff904cd 5894
c7e4ee3a
CB
5895 return result;
5896}
5ff904cd 5897
c7e4ee3a
CB
5898#endif
5899/* ffecom_expr_transform_ -- Transform symbols in expr
5ff904cd 5900
c7e4ee3a
CB
5901 ffebld expr; // FFE expression.
5902 ffecom_expr_transform_ (expr);
5ff904cd 5903
c7e4ee3a 5904 Recursive descent on expr while transforming any untransformed SYMTERs. */
5ff904cd 5905
c7e4ee3a
CB
5906#if FFECOM_targetCURRENT == FFECOM_targetGCC
5907static void
5908ffecom_expr_transform_ (ffebld expr)
5909{
5910 tree t;
5911 ffesymbol s;
5ff904cd 5912
c7e4ee3a 5913tail_recurse: /* :::::::::::::::::::: */
5ff904cd 5914
c7e4ee3a
CB
5915 if (expr == NULL)
5916 return;
5ff904cd 5917
c7e4ee3a
CB
5918 switch (ffebld_op (expr))
5919 {
5920 case FFEBLD_opSYMTER:
5921 s = ffebld_symter (expr);
5922 t = ffesymbol_hook (s).decl_tree;
5923 if ((t == NULL_TREE)
5924 && ((ffesymbol_kind (s) != FFEINFO_kindNONE)
5925 || ((ffesymbol_where (s) != FFEINFO_whereNONE)
5926 && (ffesymbol_where (s) != FFEINFO_whereINTRINSIC))))
5927 {
5928 s = ffecom_sym_transform_ (s);
5929 t = ffesymbol_hook (s).decl_tree; /* Sfunc expr non-dummy,
5930 DIMENSION expr? */
5931 }
5932 break; /* Ok if (t == NULL) here. */
5ff904cd 5933
c7e4ee3a
CB
5934 case FFEBLD_opITEM:
5935 ffecom_expr_transform_ (ffebld_head (expr));
5936 expr = ffebld_trail (expr);
5937 goto tail_recurse; /* :::::::::::::::::::: */
5ff904cd 5938
c7e4ee3a
CB
5939 default:
5940 break;
5941 }
5ff904cd 5942
c7e4ee3a
CB
5943 switch (ffebld_arity (expr))
5944 {
5945 case 2:
5946 ffecom_expr_transform_ (ffebld_left (expr));
5947 expr = ffebld_right (expr);
5948 goto tail_recurse; /* :::::::::::::::::::: */
5ff904cd 5949
c7e4ee3a
CB
5950 case 1:
5951 expr = ffebld_left (expr);
5952 goto tail_recurse; /* :::::::::::::::::::: */
5ff904cd 5953
c7e4ee3a
CB
5954 default:
5955 break;
5956 }
5ff904cd 5957
c7e4ee3a
CB
5958 return;
5959}
5ff904cd 5960
c7e4ee3a
CB
5961#endif
5962/* Make a type based on info in live f2c.h file. */
5ff904cd 5963
c7e4ee3a
CB
5964#if FFECOM_targetCURRENT == FFECOM_targetGCC
5965static void
5966ffecom_f2c_make_type_ (tree *type, int tcode, const char *name)
5967{
5968 switch (tcode)
5969 {
5970 case FFECOM_f2ccodeCHAR:
5971 *type = make_signed_type (CHAR_TYPE_SIZE);
5972 break;
5ff904cd 5973
c7e4ee3a
CB
5974 case FFECOM_f2ccodeSHORT:
5975 *type = make_signed_type (SHORT_TYPE_SIZE);
5976 break;
5ff904cd 5977
c7e4ee3a
CB
5978 case FFECOM_f2ccodeINT:
5979 *type = make_signed_type (INT_TYPE_SIZE);
5980 break;
5ff904cd 5981
c7e4ee3a
CB
5982 case FFECOM_f2ccodeLONG:
5983 *type = make_signed_type (LONG_TYPE_SIZE);
5984 break;
5ff904cd 5985
c7e4ee3a
CB
5986 case FFECOM_f2ccodeLONGLONG:
5987 *type = make_signed_type (LONG_LONG_TYPE_SIZE);
5988 break;
5ff904cd 5989
c7e4ee3a
CB
5990 case FFECOM_f2ccodeCHARPTR:
5991 *type = build_pointer_type (DEFAULT_SIGNED_CHAR
5992 ? signed_char_type_node
5993 : unsigned_char_type_node);
5994 break;
5ff904cd 5995
c7e4ee3a
CB
5996 case FFECOM_f2ccodeFLOAT:
5997 *type = make_node (REAL_TYPE);
5998 TYPE_PRECISION (*type) = FLOAT_TYPE_SIZE;
5999 layout_type (*type);
6000 break;
6001
6002 case FFECOM_f2ccodeDOUBLE:
6003 *type = make_node (REAL_TYPE);
6004 TYPE_PRECISION (*type) = DOUBLE_TYPE_SIZE;
6005 layout_type (*type);
6006 break;
6007
6008 case FFECOM_f2ccodeLONGDOUBLE:
6009 *type = make_node (REAL_TYPE);
6010 TYPE_PRECISION (*type) = LONG_DOUBLE_TYPE_SIZE;
6011 layout_type (*type);
6012 break;
5ff904cd 6013
c7e4ee3a
CB
6014 case FFECOM_f2ccodeTWOREALS:
6015 *type = ffecom_make_complex_type_ (ffecom_f2c_real_type_node);
6016 break;
5ff904cd 6017
c7e4ee3a
CB
6018 case FFECOM_f2ccodeTWODOUBLEREALS:
6019 *type = ffecom_make_complex_type_ (ffecom_f2c_doublereal_type_node);
6020 break;
5ff904cd 6021
c7e4ee3a
CB
6022 default:
6023 assert ("unexpected FFECOM_f2ccodeXYZZY!" == NULL);
6024 *type = error_mark_node;
6025 return;
6026 }
5ff904cd 6027
c7e4ee3a 6028 pushdecl (build_decl (TYPE_DECL,
14657de8 6029 ffecom_get_invented_identifier ("__g77_f2c_%s", name),
c7e4ee3a
CB
6030 *type));
6031}
5ff904cd 6032
c7e4ee3a
CB
6033#endif
6034#if FFECOM_targetCURRENT == FFECOM_targetGCC
6035/* Set the f2c list-directed-I/O code for whatever (integral) type has the
6036 given size. */
5ff904cd 6037
c7e4ee3a
CB
6038static void
6039ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size,
6040 int code)
6041{
6042 int j;
6043 tree t;
5ff904cd 6044
c7e4ee3a 6045 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
05bccae2
RK
6046 if ((t = ffecom_tree_type[bt][j]) != NULL_TREE
6047 && compare_tree_int (TYPE_SIZE (t), size) == 0)
c7e4ee3a
CB
6048 {
6049 assert (code != -1);
6050 ffecom_f2c_typecode_[bt][j] = code;
6051 code = -1;
6052 }
6053}
5ff904cd 6054
c7e4ee3a
CB
6055#endif
6056/* Finish up globals after doing all program units in file
5ff904cd 6057
c7e4ee3a 6058 Need to handle only uninitialized COMMON areas. */
5ff904cd 6059
c7e4ee3a
CB
6060#if FFECOM_targetCURRENT == FFECOM_targetGCC
6061static ffeglobal
6062ffecom_finish_global_ (ffeglobal global)
6063{
6064 tree cbtype;
6065 tree cbt;
6066 tree size;
5ff904cd 6067
c7e4ee3a
CB
6068 if (ffeglobal_type (global) != FFEGLOBAL_typeCOMMON)
6069 return global;
5ff904cd 6070
c7e4ee3a
CB
6071 if (ffeglobal_common_init (global))
6072 return global;
5ff904cd 6073
c7e4ee3a
CB
6074 cbt = ffeglobal_hook (global);
6075 if ((cbt == NULL_TREE)
6076 || !ffeglobal_common_have_size (global))
6077 return global; /* No need to make common, never ref'd. */
5ff904cd 6078
c7e4ee3a 6079 suspend_momentary ();
5ff904cd 6080
c7e4ee3a 6081 DECL_EXTERNAL (cbt) = 0;
5ff904cd 6082
c7e4ee3a 6083 /* Give the array a size now. */
5ff904cd 6084
c7e4ee3a
CB
6085 size = build_int_2 ((ffeglobal_common_size (global)
6086 + ffeglobal_common_pad (global)) - 1,
6087 0);
5ff904cd 6088
c7e4ee3a
CB
6089 cbtype = TREE_TYPE (cbt);
6090 TYPE_DOMAIN (cbtype) = build_range_type (integer_type_node,
6091 integer_zero_node,
6092 size);
6093 if (!TREE_TYPE (size))
6094 TREE_TYPE (size) = TYPE_DOMAIN (cbtype);
6095 layout_type (cbtype);
5ff904cd 6096
c7e4ee3a
CB
6097 cbt = start_decl (cbt, FALSE);
6098 assert (cbt == ffeglobal_hook (global));
5ff904cd 6099
c7e4ee3a 6100 finish_decl (cbt, NULL_TREE, FALSE);
5ff904cd 6101
c7e4ee3a
CB
6102 return global;
6103}
5ff904cd 6104
c7e4ee3a
CB
6105#endif
6106/* Finish up any untransformed symbols. */
5ff904cd 6107
c7e4ee3a
CB
6108#if FFECOM_targetCURRENT == FFECOM_targetGCC
6109static ffesymbol
6110ffecom_finish_symbol_transform_ (ffesymbol s)
5ff904cd 6111{
c7e4ee3a
CB
6112 if ((s == NULL) || (TREE_CODE (current_function_decl) == ERROR_MARK))
6113 return s;
5ff904cd 6114
c7e4ee3a
CB
6115 /* It's easy to know to transform an untransformed symbol, to make sure
6116 we put out debugging info for it. But COMMON variables, unlike
6117 EQUIVALENCE ones, aren't given declarations in addition to the
6118 tree expressions that specify offsets, because COMMON variables
6119 can be referenced in the outer scope where only dummy arguments
6120 (PARM_DECLs) should really be seen. To be safe, just don't do any
6121 VAR_DECLs for COMMON variables when we transform them for real
6122 use, and therefore we do all the VAR_DECL creating here. */
5ff904cd 6123
c7e4ee3a
CB
6124 if (ffesymbol_hook (s).decl_tree == NULL_TREE)
6125 {
6126 if (ffesymbol_kind (s) != FFEINFO_kindNONE
6127 || (ffesymbol_where (s) != FFEINFO_whereNONE
6128 && ffesymbol_where (s) != FFEINFO_whereINTRINSIC
6129 && ffesymbol_where (s) != FFEINFO_whereDUMMY))
6130 /* Not transformed, and not CHARACTER*(*), and not a dummy
6131 argument, which can happen only if the entry point names
6132 it "rides in on" are all invalidated for other reasons. */
6133 s = ffecom_sym_transform_ (s);
6134 }
5ff904cd 6135
c7e4ee3a
CB
6136 if ((ffesymbol_where (s) == FFEINFO_whereCOMMON)
6137 && (ffesymbol_hook (s).decl_tree != error_mark_node))
6138 {
c7e4ee3a 6139 int yes = suspend_momentary ();
5ff904cd 6140
c7e4ee3a
CB
6141 /* This isn't working, at least for dbxout. The .s file looks
6142 okay to me (burley), but in gdb 4.9 at least, the variables
6143 appear to reside somewhere outside of the common area, so
6144 it doesn't make sense to mislead anyone by generating the info
6145 on those variables until this is fixed. NOTE: Same problem
6146 with EQUIVALENCE, sadly...see similar #if later. */
6147 ffecom_member_phase2_ (ffesymbol_storage (ffesymbol_common (s)),
6148 ffesymbol_storage (s));
5ff904cd 6149
c7e4ee3a 6150 resume_momentary (yes);
5ff904cd
JL
6151 }
6152
c7e4ee3a
CB
6153 return s;
6154}
5ff904cd 6155
c7e4ee3a
CB
6156#endif
6157/* Append underscore(s) to name before calling get_identifier. "us"
6158 is nonzero if the name already contains an underscore and thus
6159 needs two underscores appended. */
5ff904cd 6160
c7e4ee3a
CB
6161#if FFECOM_targetCURRENT == FFECOM_targetGCC
6162static tree
6163ffecom_get_appended_identifier_ (char us, const char *name)
6164{
6165 int i;
6166 char *newname;
6167 tree id;
5ff904cd 6168
c7e4ee3a
CB
6169 newname = xmalloc ((i = strlen (name)) + 1
6170 + ffe_is_underscoring ()
6171 + us);
6172 memcpy (newname, name, i);
6173 newname[i] = '_';
6174 newname[i + us] = '_';
6175 newname[i + 1 + us] = '\0';
6176 id = get_identifier (newname);
5ff904cd 6177
c7e4ee3a 6178 free (newname);
5ff904cd 6179
c7e4ee3a
CB
6180 return id;
6181}
5ff904cd 6182
c7e4ee3a
CB
6183#endif
6184/* Decide whether to append underscore to name before calling
6185 get_identifier. */
5ff904cd 6186
c7e4ee3a
CB
6187#if FFECOM_targetCURRENT == FFECOM_targetGCC
6188static tree
6189ffecom_get_external_identifier_ (ffesymbol s)
6190{
6191 char us;
6192 const char *name = ffesymbol_text (s);
5ff904cd 6193
c7e4ee3a 6194 /* If name is a built-in name, just return it as is. */
5ff904cd 6195
c7e4ee3a
CB
6196 if (!ffe_is_underscoring ()
6197 || (strcmp (name, FFETARGET_nameBLANK_COMMON) == 0)
6198#if FFETARGET_isENFORCED_MAIN_NAME
6199 || (strcmp (name, FFETARGET_nameENFORCED_NAME) == 0)
6200#else
6201 || (strcmp (name, FFETARGET_nameUNNAMED_MAIN) == 0)
6202#endif
6203 || (strcmp (name, FFETARGET_nameUNNAMED_BLOCK_DATA) == 0))
6204 return get_identifier (name);
5ff904cd 6205
c7e4ee3a
CB
6206 us = ffe_is_second_underscore ()
6207 ? (strchr (name, '_') != NULL)
6208 : 0;
5ff904cd 6209
c7e4ee3a
CB
6210 return ffecom_get_appended_identifier_ (us, name);
6211}
5ff904cd 6212
c7e4ee3a
CB
6213#endif
6214/* Decide whether to append underscore to internal name before calling
6215 get_identifier.
6216
6217 This is for non-external, top-function-context names only. Transform
6218 identifier so it doesn't conflict with the transformed result
6219 of using a _different_ external name. E.g. if "CALL FOO" is
6220 transformed into "FOO_();", then the variable in "FOO_ = 3"
6221 must be transformed into something that does not conflict, since
6222 these two things should be independent.
5ff904cd 6223
c7e4ee3a
CB
6224 The transformation is as follows. If the name does not contain
6225 an underscore, there is no possible conflict, so just return.
6226 If the name does contain an underscore, then transform it just
6227 like we transform an external identifier. */
5ff904cd 6228
c7e4ee3a
CB
6229#if FFECOM_targetCURRENT == FFECOM_targetGCC
6230static tree
6231ffecom_get_identifier_ (const char *name)
6232{
6233 /* If name does not contain an underscore, just return it as is. */
6234
6235 if (!ffe_is_underscoring ()
6236 || (strchr (name, '_') == NULL))
6237 return get_identifier (name);
6238
6239 return ffecom_get_appended_identifier_ (ffe_is_second_underscore (),
6240 name);
5ff904cd
JL
6241}
6242
6243#endif
c7e4ee3a 6244/* ffecom_gen_sfuncdef_ -- Generate definition of statement function
5ff904cd 6245
c7e4ee3a
CB
6246 tree t;
6247 ffesymbol s; // kindFUNCTION, whereIMMEDIATE.
6248 t = ffecom_gen_sfuncdef_(s,ffesymbol_basictype(s),
6249 ffesymbol_kindtype(s));
5ff904cd 6250
c7e4ee3a
CB
6251 Call after setting up containing function and getting trees for all
6252 other symbols. */
5ff904cd
JL
6253
6254#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
6255static tree
6256ffecom_gen_sfuncdef_ (ffesymbol s, ffeinfoBasictype bt, ffeinfoKindtype kt)
5ff904cd 6257{
c7e4ee3a
CB
6258 ffebld expr = ffesymbol_sfexpr (s);
6259 tree type;
6260 tree func;
6261 tree result;
6262 bool charfunc = (bt == FFEINFO_basictypeCHARACTER);
6263 static bool recurse = FALSE;
6264 int yes;
6265 int old_lineno = lineno;
6266 char *old_input_filename = input_filename;
5ff904cd 6267
c7e4ee3a 6268 ffecom_nested_entry_ = s;
5ff904cd 6269
c7e4ee3a
CB
6270 /* For now, we don't have a handy pointer to where the sfunc is actually
6271 defined, though that should be easy to add to an ffesymbol. (The
6272 token/where info available might well point to the place where the type
6273 of the sfunc is declared, especially if that precedes the place where
6274 the sfunc itself is defined, which is typically the case.) We should
6275 put out a null pointer rather than point somewhere wrong, but I want to
6276 see how it works at this point. */
5ff904cd 6277
c7e4ee3a
CB
6278 input_filename = ffesymbol_where_filename (s);
6279 lineno = ffesymbol_where_filelinenum (s);
5ff904cd 6280
c7e4ee3a
CB
6281 /* Pretransform the expression so any newly discovered things belong to the
6282 outer program unit, not to the statement function. */
5ff904cd 6283
c7e4ee3a 6284 ffecom_expr_transform_ (expr);
5ff904cd 6285
c7e4ee3a
CB
6286 /* Make sure no recursive invocation of this fn (a specific case of failing
6287 to pretransform an sfunc's expression, i.e. where its expression
6288 references another untransformed sfunc) happens. */
6289
6290 assert (!recurse);
6291 recurse = TRUE;
6292
6293 yes = suspend_momentary ();
6294
6295 push_f_function_context ();
6296
6297 if (charfunc)
6298 type = void_type_node;
6299 else
5ff904cd 6300 {
c7e4ee3a
CB
6301 type = ffecom_tree_type[bt][kt];
6302 if (type == NULL_TREE)
6303 type = integer_type_node; /* _sym_exec_transition reports
6304 error. */
6305 }
5ff904cd 6306
c7e4ee3a
CB
6307 start_function (ffecom_get_identifier_ (ffesymbol_text (s)),
6308 build_function_type (type, NULL_TREE),
6309 1, /* nested/inline */
6310 0); /* TREE_PUBLIC */
5ff904cd 6311
c7e4ee3a
CB
6312 /* We don't worry about COMPLEX return values here, because this is
6313 entirely internal to our code, and gcc has the ability to return COMPLEX
6314 directly as a value. */
6315
6316 yes = suspend_momentary ();
6317
6318 if (charfunc)
6319 { /* Prepend arg for where result goes. */
6320 tree type;
6321
6322 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
6323
14657de8 6324 result = ffecom_get_invented_identifier ("__g77_%s", "result");
c7e4ee3a
CB
6325
6326 ffecom_char_enhance_arg_ (&type, s); /* Ignore returned length. */
6327
6328 type = build_pointer_type (type);
6329 result = build_decl (PARM_DECL, result, type);
6330
6331 push_parm_decl (result);
5ff904cd 6332 }
c7e4ee3a
CB
6333 else
6334 result = NULL_TREE; /* Not ref'd if !charfunc. */
5ff904cd 6335
c7e4ee3a 6336 ffecom_push_dummy_decls_ (ffesymbol_dummyargs (s), TRUE);
5ff904cd 6337
c7e4ee3a 6338 resume_momentary (yes);
5ff904cd 6339
c7e4ee3a
CB
6340 store_parm_decls (0);
6341
6342 ffecom_start_compstmt ();
6343
6344 if (expr != NULL)
5ff904cd 6345 {
c7e4ee3a
CB
6346 if (charfunc)
6347 {
6348 ffetargetCharacterSize sz = ffesymbol_size (s);
6349 tree result_length;
5ff904cd 6350
c7e4ee3a
CB
6351 result_length = build_int_2 (sz, 0);
6352 TREE_TYPE (result_length) = ffecom_f2c_ftnlen_type_node;
5ff904cd 6353
c7e4ee3a 6354 ffecom_prepare_let_char_ (sz, expr);
5ff904cd 6355
c7e4ee3a 6356 ffecom_prepare_end ();
5ff904cd 6357
c7e4ee3a
CB
6358 ffecom_let_char_ (result, result_length, sz, expr);
6359 expand_null_return ();
6360 }
6361 else
6362 {
6363 ffecom_prepare_expr (expr);
5ff904cd 6364
c7e4ee3a 6365 ffecom_prepare_end ();
5ff904cd 6366
c7e4ee3a
CB
6367 expand_return (ffecom_modify (NULL_TREE,
6368 DECL_RESULT (current_function_decl),
6369 ffecom_expr (expr)));
6370 }
5ff904cd 6371
c7e4ee3a
CB
6372 clear_momentary ();
6373 }
5ff904cd 6374
c7e4ee3a 6375 ffecom_end_compstmt ();
5ff904cd 6376
c7e4ee3a
CB
6377 func = current_function_decl;
6378 finish_function (1);
5ff904cd 6379
c7e4ee3a 6380 pop_f_function_context ();
5ff904cd 6381
c7e4ee3a 6382 resume_momentary (yes);
5ff904cd 6383
c7e4ee3a
CB
6384 recurse = FALSE;
6385
6386 lineno = old_lineno;
6387 input_filename = old_input_filename;
6388
6389 ffecom_nested_entry_ = NULL;
6390
6391 return func;
5ff904cd
JL
6392}
6393
6394#endif
5ff904cd 6395
c7e4ee3a
CB
6396#if FFECOM_targetCURRENT == FFECOM_targetGCC
6397static const char *
6398ffecom_gfrt_args_ (ffecomGfrt ix)
5ff904cd 6399{
c7e4ee3a
CB
6400 return ffecom_gfrt_argstring_[ix];
6401}
5ff904cd 6402
c7e4ee3a
CB
6403#endif
6404#if FFECOM_targetCURRENT == FFECOM_targetGCC
6405static tree
6406ffecom_gfrt_tree_ (ffecomGfrt ix)
6407{
6408 if (ffecom_gfrt_[ix] == NULL_TREE)
6409 ffecom_make_gfrt_ (ix);
6410
6411 return ffecom_1 (ADDR_EXPR,
6412 build_pointer_type (TREE_TYPE (ffecom_gfrt_[ix])),
6413 ffecom_gfrt_[ix]);
5ff904cd
JL
6414}
6415
6416#endif
c7e4ee3a 6417/* Return initialize-to-zero expression for this VAR_DECL. */
5ff904cd
JL
6418
6419#if FFECOM_targetCURRENT == FFECOM_targetGCC
7189a4b0
GK
6420/* A somewhat evil way to prevent the garbage collector
6421 from collecting 'tree' structures. */
6422#define NUM_TRACKED_CHUNK 63
6423static struct tree_ggc_tracker
6424{
6425 struct tree_ggc_tracker *next;
6426 tree trees[NUM_TRACKED_CHUNK];
6427} *tracker_head = NULL;
6428
6429static void
54551044 6430mark_tracker_head (void *arg)
7189a4b0
GK
6431{
6432 struct tree_ggc_tracker *head;
6433 int i;
6434
6435 for (head = * (struct tree_ggc_tracker **) arg;
6436 head != NULL;
6437 head = head->next)
6438 {
6439 ggc_mark (head);
6440 for (i = 0; i < NUM_TRACKED_CHUNK; i++)
6441 ggc_mark_tree (head->trees[i]);
6442 }
6443}
6444
6445void
6446ffecom_save_tree_forever (tree t)
6447{
6448 int i;
6449 if (tracker_head != NULL)
6450 for (i = 0; i < NUM_TRACKED_CHUNK; i++)
6451 if (tracker_head->trees[i] == NULL)
6452 {
6453 tracker_head->trees[i] = t;
6454 return;
6455 }
6456
6457 {
6458 /* Need to allocate a new block. */
6459 struct tree_ggc_tracker *old_head = tracker_head;
6460
6461 tracker_head = ggc_alloc (sizeof (*tracker_head));
6462 tracker_head->next = old_head;
6463 tracker_head->trees[0] = t;
6464 for (i = 1; i < NUM_TRACKED_CHUNK; i++)
6465 tracker_head->trees[i] = NULL;
6466 }
6467}
6468
c7e4ee3a
CB
6469static tree
6470ffecom_init_zero_ (tree decl)
5ff904cd 6471{
c7e4ee3a
CB
6472 tree init;
6473 int incremental = TREE_STATIC (decl);
6474 tree type = TREE_TYPE (decl);
5ff904cd 6475
c7e4ee3a
CB
6476 if (incremental)
6477 {
c7e4ee3a
CB
6478 make_decl_rtl (decl, NULL, TREE_PUBLIC (decl) ? 1 : 0);
6479 assemble_variable (decl, TREE_PUBLIC (decl) ? 1 : 0, 0, 1);
c7e4ee3a 6480 }
5ff904cd 6481
c7e4ee3a 6482 push_momentary ();
5ff904cd 6483
c7e4ee3a
CB
6484 if ((TREE_CODE (type) != ARRAY_TYPE)
6485 && (TREE_CODE (type) != RECORD_TYPE)
6486 && (TREE_CODE (type) != UNION_TYPE)
6487 && !incremental)
6488 init = convert (type, integer_zero_node);
6489 else if (!incremental)
6490 {
6491 int momentary = suspend_momentary ();
5ff904cd 6492
c7e4ee3a
CB
6493 init = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
6494 TREE_CONSTANT (init) = 1;
6495 TREE_STATIC (init) = 1;
5ff904cd 6496
c7e4ee3a
CB
6497 resume_momentary (momentary);
6498 }
6499 else
6500 {
6501 int momentary = suspend_momentary ();
5ff904cd 6502
c7e4ee3a
CB
6503 assemble_zeros (int_size_in_bytes (type));
6504 init = error_mark_node;
5ff904cd 6505
c7e4ee3a
CB
6506 resume_momentary (momentary);
6507 }
5ff904cd 6508
c7e4ee3a 6509 pop_momentary_nofree ();
5ff904cd 6510
c7e4ee3a 6511 return init;
5ff904cd
JL
6512}
6513
6514#endif
5ff904cd 6515#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
6516static tree
6517ffecom_intrinsic_ichar_ (tree tree_type, ffebld arg,
6518 tree *maybe_tree)
5ff904cd 6519{
c7e4ee3a
CB
6520 tree expr_tree;
6521 tree length_tree;
5ff904cd 6522
c7e4ee3a 6523 switch (ffebld_op (arg))
6829256f 6524 {
c7e4ee3a
CB
6525 case FFEBLD_opCONTER: /* For F90, check 0-length. */
6526 if (ffetarget_length_character1
6527 (ffebld_constant_character1
6528 (ffebld_conter (arg))) == 0)
6529 {
6530 *maybe_tree = integer_zero_node;
6531 return convert (tree_type, integer_zero_node);
6532 }
5ff904cd 6533
c7e4ee3a
CB
6534 *maybe_tree = integer_one_node;
6535 expr_tree = build_int_2 (*ffetarget_text_character1
6536 (ffebld_constant_character1
6537 (ffebld_conter (arg))),
6538 0);
6539 TREE_TYPE (expr_tree) = tree_type;
6540 return expr_tree;
5ff904cd 6541
c7e4ee3a
CB
6542 case FFEBLD_opSYMTER:
6543 case FFEBLD_opARRAYREF:
6544 case FFEBLD_opFUNCREF:
6545 case FFEBLD_opSUBSTR:
6546 ffecom_char_args_ (&expr_tree, &length_tree, arg);
5ff904cd 6547
c7e4ee3a
CB
6548 if ((expr_tree == error_mark_node)
6549 || (length_tree == error_mark_node))
6550 {
6551 *maybe_tree = error_mark_node;
6552 return error_mark_node;
6553 }
5ff904cd 6554
c7e4ee3a
CB
6555 if (integer_zerop (length_tree))
6556 {
6557 *maybe_tree = integer_zero_node;
6558 return convert (tree_type, integer_zero_node);
6559 }
6560
6561 expr_tree
6562 = ffecom_1 (INDIRECT_REF,
6563 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
6564 expr_tree);
6565 expr_tree
6566 = ffecom_2 (ARRAY_REF,
6567 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
6568 expr_tree,
6569 integer_one_node);
6570 expr_tree = convert (tree_type, expr_tree);
6571
6572 if (TREE_CODE (length_tree) == INTEGER_CST)
6573 *maybe_tree = integer_one_node;
6574 else /* Must check length at run time. */
6575 *maybe_tree
6576 = ffecom_truth_value
6577 (ffecom_2 (GT_EXPR, integer_type_node,
6578 length_tree,
6579 ffecom_f2c_ftnlen_zero_node));
6580 return expr_tree;
6581
6582 case FFEBLD_opPAREN:
6583 case FFEBLD_opCONVERT:
6584 if (ffeinfo_size (ffebld_info (arg)) == 0)
6585 {
6586 *maybe_tree = integer_zero_node;
6587 return convert (tree_type, integer_zero_node);
6588 }
6589 return ffecom_intrinsic_ichar_ (tree_type, ffebld_left (arg),
6590 maybe_tree);
6591
6592 case FFEBLD_opCONCATENATE:
6593 {
6594 tree maybe_left;
6595 tree maybe_right;
6596 tree expr_left;
6597 tree expr_right;
6598
6599 expr_left = ffecom_intrinsic_ichar_ (tree_type, ffebld_left (arg),
6600 &maybe_left);
6601 expr_right = ffecom_intrinsic_ichar_ (tree_type, ffebld_right (arg),
6602 &maybe_right);
6603 *maybe_tree = ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
6604 maybe_left,
6605 maybe_right);
6606 expr_tree = ffecom_3 (COND_EXPR, tree_type,
6607 maybe_left,
6608 expr_left,
6609 expr_right);
6610 return expr_tree;
6611 }
6612
6613 default:
6614 assert ("bad op in ICHAR" == NULL);
6615 return error_mark_node;
6616 }
5ff904cd
JL
6617}
6618
6619#endif
c7e4ee3a
CB
6620/* ffecom_intrinsic_len_ -- Return length info for char arg (LEN())
6621
6622 tree length_arg;
6623 ffebld expr;
6624 length_arg = ffecom_intrinsic_len_ (expr);
6625
6626 Handles CHARACTER-type CONTER, SYMTER, SUBSTR, ARRAYREF, and FUNCREF
6627 subexpressions by constructing the appropriate tree for the
6628 length-of-character-text argument in a calling sequence. */
5ff904cd
JL
6629
6630#if FFECOM_targetCURRENT == FFECOM_targetGCC
6631static tree
c7e4ee3a 6632ffecom_intrinsic_len_ (ffebld expr)
5ff904cd 6633{
c7e4ee3a
CB
6634 ffetargetCharacter1 val;
6635 tree length;
6636
6637 switch (ffebld_op (expr))
6638 {
6639 case FFEBLD_opCONTER:
6640 val = ffebld_constant_character1 (ffebld_conter (expr));
6641 length = build_int_2 (ffetarget_length_character1 (val), 0);
6642 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6643 break;
6644
6645 case FFEBLD_opSYMTER:
6646 {
6647 ffesymbol s = ffebld_symter (expr);
6648 tree item;
6649
6650 item = ffesymbol_hook (s).decl_tree;
6651 if (item == NULL_TREE)
6652 {
6653 s = ffecom_sym_transform_ (s);
6654 item = ffesymbol_hook (s).decl_tree;
6655 }
6656 if (ffesymbol_kind (s) == FFEINFO_kindENTITY)
6657 {
6658 if (ffesymbol_size (s) == FFETARGET_charactersizeNONE)
6659 length = ffesymbol_hook (s).length_tree;
6660 else
6661 {
6662 length = build_int_2 (ffesymbol_size (s), 0);
6663 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6664 }
6665 }
6666 else if (item == error_mark_node)
6667 length = error_mark_node;
6668 else /* FFEINFO_kindFUNCTION: */
6669 length = NULL_TREE;
6670 }
6671 break;
5ff904cd 6672
c7e4ee3a
CB
6673 case FFEBLD_opARRAYREF:
6674 length = ffecom_intrinsic_len_ (ffebld_left (expr));
6675 break;
5ff904cd 6676
c7e4ee3a
CB
6677 case FFEBLD_opSUBSTR:
6678 {
6679 ffebld start;
6680 ffebld end;
6681 ffebld thing = ffebld_right (expr);
6682 tree start_tree;
6683 tree end_tree;
5ff904cd 6684
c7e4ee3a
CB
6685 assert (ffebld_op (thing) == FFEBLD_opITEM);
6686 start = ffebld_head (thing);
6687 thing = ffebld_trail (thing);
6688 assert (ffebld_trail (thing) == NULL);
6689 end = ffebld_head (thing);
5ff904cd 6690
c7e4ee3a 6691 length = ffecom_intrinsic_len_ (ffebld_left (expr));
5ff904cd 6692
c7e4ee3a
CB
6693 if (length == error_mark_node)
6694 break;
5ff904cd 6695
c7e4ee3a
CB
6696 if (start == NULL)
6697 {
6698 if (end == NULL)
6699 ;
6700 else
6701 {
6702 length = convert (ffecom_f2c_ftnlen_type_node,
6703 ffecom_expr (end));
6704 }
6705 }
6706 else
6707 {
6708 start_tree = convert (ffecom_f2c_ftnlen_type_node,
6709 ffecom_expr (start));
5ff904cd 6710
c7e4ee3a
CB
6711 if (start_tree == error_mark_node)
6712 {
6713 length = error_mark_node;
6714 break;
6715 }
5ff904cd 6716
c7e4ee3a
CB
6717 if (end == NULL)
6718 {
6719 length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6720 ffecom_f2c_ftnlen_one_node,
6721 ffecom_2 (MINUS_EXPR,
6722 ffecom_f2c_ftnlen_type_node,
6723 length,
6724 start_tree));
6725 }
6726 else
6727 {
6728 end_tree = convert (ffecom_f2c_ftnlen_type_node,
6729 ffecom_expr (end));
5ff904cd 6730
c7e4ee3a
CB
6731 if (end_tree == error_mark_node)
6732 {
6733 length = error_mark_node;
6734 break;
6735 }
5ff904cd 6736
c7e4ee3a
CB
6737 length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6738 ffecom_f2c_ftnlen_one_node,
6739 ffecom_2 (MINUS_EXPR,
6740 ffecom_f2c_ftnlen_type_node,
6741 end_tree, start_tree));
6742 }
6743 }
6744 }
6745 break;
5ff904cd 6746
c7e4ee3a
CB
6747 case FFEBLD_opCONCATENATE:
6748 length
6749 = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6750 ffecom_intrinsic_len_ (ffebld_left (expr)),
6751 ffecom_intrinsic_len_ (ffebld_right (expr)));
6752 break;
5ff904cd 6753
c7e4ee3a
CB
6754 case FFEBLD_opFUNCREF:
6755 case FFEBLD_opCONVERT:
6756 length = build_int_2 (ffebld_size (expr), 0);
6757 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6758 break;
5ff904cd 6759
c7e4ee3a
CB
6760 default:
6761 assert ("bad op for single char arg expr" == NULL);
6762 length = ffecom_f2c_ftnlen_zero_node;
6763 break;
6764 }
5ff904cd 6765
c7e4ee3a 6766 assert (length != NULL_TREE);
5ff904cd 6767
c7e4ee3a 6768 return length;
5ff904cd
JL
6769}
6770
6771#endif
c7e4ee3a 6772/* Handle CHARACTER assignments.
5ff904cd 6773
c7e4ee3a
CB
6774 Generates code to do the assignment. Used by ordinary assignment
6775 statement handler ffecom_let_stmt and by statement-function
6776 handler to generate code for a statement function. */
5ff904cd
JL
6777
6778#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
6779static void
6780ffecom_let_char_ (tree dest_tree, tree dest_length,
6781 ffetargetCharacterSize dest_size, ffebld source)
5ff904cd 6782{
c7e4ee3a
CB
6783 ffecomConcatList_ catlist;
6784 tree source_length;
6785 tree source_tree;
6786 tree expr_tree;
5ff904cd 6787
c7e4ee3a
CB
6788 if ((dest_tree == error_mark_node)
6789 || (dest_length == error_mark_node))
6790 return;
5ff904cd 6791
c7e4ee3a
CB
6792 assert (dest_tree != NULL_TREE);
6793 assert (dest_length != NULL_TREE);
5ff904cd 6794
c7e4ee3a
CB
6795 /* Source might be an opCONVERT, which just means it is a different size
6796 than the destination. Since the underlying implementation here handles
6797 that (directly or via the s_copy or s_cat run-time-library functions),
6798 we don't need the "convenience" of an opCONVERT that tells us to
6799 truncate or blank-pad, particularly since the resulting implementation
6800 would probably be slower than otherwise. */
5ff904cd 6801
c7e4ee3a
CB
6802 while (ffebld_op (source) == FFEBLD_opCONVERT)
6803 source = ffebld_left (source);
5ff904cd 6804
c7e4ee3a
CB
6805 catlist = ffecom_concat_list_new_ (source, dest_size);
6806 switch (ffecom_concat_list_count_ (catlist))
6807 {
6808 case 0: /* Shouldn't happen, but in case it does... */
6809 ffecom_concat_list_kill_ (catlist);
6810 source_tree = null_pointer_node;
6811 source_length = ffecom_f2c_ftnlen_zero_node;
6812 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6813 TREE_CHAIN (expr_tree) = build_tree_list (NULL_TREE, source_tree);
6814 TREE_CHAIN (TREE_CHAIN (expr_tree))
6815 = build_tree_list (NULL_TREE, dest_length);
6816 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6817 = build_tree_list (NULL_TREE, source_length);
5ff904cd 6818
c7e4ee3a
CB
6819 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCOPY, expr_tree, NULL_TREE);
6820 TREE_SIDE_EFFECTS (expr_tree) = 1;
5ff904cd 6821
c7e4ee3a 6822 expand_expr_stmt (expr_tree);
5ff904cd 6823
c7e4ee3a 6824 return;
5ff904cd 6825
c7e4ee3a
CB
6826 case 1: /* The (fairly) easy case. */
6827 ffecom_char_args_ (&source_tree, &source_length,
6828 ffecom_concat_list_expr_ (catlist, 0));
6829 ffecom_concat_list_kill_ (catlist);
6830 assert (source_tree != NULL_TREE);
6831 assert (source_length != NULL_TREE);
6832
6833 if ((source_tree == error_mark_node)
6834 || (source_length == error_mark_node))
6835 return;
6836
6837 if (dest_size == 1)
6838 {
6839 dest_tree
6840 = ffecom_1 (INDIRECT_REF,
6841 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6842 (dest_tree))),
6843 dest_tree);
6844 dest_tree
6845 = ffecom_2 (ARRAY_REF,
6846 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6847 (dest_tree))),
6848 dest_tree,
6849 integer_one_node);
6850 source_tree
6851 = ffecom_1 (INDIRECT_REF,
6852 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6853 (source_tree))),
6854 source_tree);
6855 source_tree
6856 = ffecom_2 (ARRAY_REF,
6857 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6858 (source_tree))),
6859 source_tree,
6860 integer_one_node);
5ff904cd 6861
c7e4ee3a 6862 expr_tree = ffecom_modify (void_type_node, dest_tree, source_tree);
5ff904cd 6863
c7e4ee3a 6864 expand_expr_stmt (expr_tree);
5ff904cd 6865
c7e4ee3a
CB
6866 return;
6867 }
5ff904cd 6868
c7e4ee3a
CB
6869 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6870 TREE_CHAIN (expr_tree) = build_tree_list (NULL_TREE, source_tree);
6871 TREE_CHAIN (TREE_CHAIN (expr_tree))
6872 = build_tree_list (NULL_TREE, dest_length);
6873 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6874 = build_tree_list (NULL_TREE, source_length);
5ff904cd 6875
c7e4ee3a
CB
6876 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCOPY, expr_tree, NULL_TREE);
6877 TREE_SIDE_EFFECTS (expr_tree) = 1;
5ff904cd 6878
c7e4ee3a 6879 expand_expr_stmt (expr_tree);
5ff904cd 6880
c7e4ee3a 6881 return;
5ff904cd 6882
c7e4ee3a
CB
6883 default: /* Must actually concatenate things. */
6884 break;
6885 }
5ff904cd 6886
c7e4ee3a 6887 /* Heavy-duty concatenation. */
5ff904cd 6888
c7e4ee3a
CB
6889 {
6890 int count = ffecom_concat_list_count_ (catlist);
6891 int i;
6892 tree lengths;
6893 tree items;
6894 tree length_array;
6895 tree item_array;
6896 tree citem;
6897 tree clength;
5ff904cd 6898
c7e4ee3a
CB
6899#ifdef HOHO
6900 length_array
6901 = lengths
6902 = ffecom_push_tempvar (ffecom_f2c_ftnlen_type_node,
6903 FFETARGET_charactersizeNONE, count, TRUE);
6904 item_array = items = ffecom_push_tempvar (ffecom_f2c_address_type_node,
6905 FFETARGET_charactersizeNONE,
6906 count, TRUE);
6907#else
6908 {
6909 tree hook;
6910
6911 hook = ffebld_nonter_hook (source);
6912 assert (hook);
6913 assert (TREE_CODE (hook) == TREE_VEC);
6914 assert (TREE_VEC_LENGTH (hook) == 2);
6915 length_array = lengths = TREE_VEC_ELT (hook, 0);
6916 item_array = items = TREE_VEC_ELT (hook, 1);
5ff904cd 6917 }
c7e4ee3a 6918#endif
5ff904cd 6919
c7e4ee3a
CB
6920 for (i = 0; i < count; ++i)
6921 {
6922 ffecom_char_args_ (&citem, &clength,
6923 ffecom_concat_list_expr_ (catlist, i));
6924 if ((citem == error_mark_node)
6925 || (clength == error_mark_node))
6926 {
6927 ffecom_concat_list_kill_ (catlist);
6928 return;
6929 }
5ff904cd 6930
c7e4ee3a
CB
6931 items
6932 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (items),
6933 ffecom_modify (void_type_node,
6934 ffecom_2 (ARRAY_REF,
6935 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array))),
6936 item_array,
6937 build_int_2 (i, 0)),
6938 citem),
6939 items);
6940 lengths
6941 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (lengths),
6942 ffecom_modify (void_type_node,
6943 ffecom_2 (ARRAY_REF,
6944 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array))),
6945 length_array,
6946 build_int_2 (i, 0)),
6947 clength),
6948 lengths);
6949 }
5ff904cd 6950
c7e4ee3a
CB
6951 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6952 TREE_CHAIN (expr_tree)
6953 = build_tree_list (NULL_TREE,
6954 ffecom_1 (ADDR_EXPR,
6955 build_pointer_type (TREE_TYPE (items)),
6956 items));
6957 TREE_CHAIN (TREE_CHAIN (expr_tree))
6958 = build_tree_list (NULL_TREE,
6959 ffecom_1 (ADDR_EXPR,
6960 build_pointer_type (TREE_TYPE (lengths)),
6961 lengths));
6962 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6963 = build_tree_list
6964 (NULL_TREE,
6965 ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
6966 convert (ffecom_f2c_ftnlen_type_node,
6967 build_int_2 (count, 0))));
6968 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree))))
6969 = build_tree_list (NULL_TREE, dest_length);
5ff904cd 6970
c7e4ee3a
CB
6971 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCAT, expr_tree, NULL_TREE);
6972 TREE_SIDE_EFFECTS (expr_tree) = 1;
5ff904cd 6973
c7e4ee3a
CB
6974 expand_expr_stmt (expr_tree);
6975 }
5ff904cd 6976
c7e4ee3a
CB
6977 ffecom_concat_list_kill_ (catlist);
6978}
5ff904cd 6979
c7e4ee3a
CB
6980#endif
6981/* ffecom_make_gfrt_ -- Make initial info for run-time routine
5ff904cd 6982
c7e4ee3a
CB
6983 ffecomGfrt ix;
6984 ffecom_make_gfrt_(ix);
5ff904cd 6985
c7e4ee3a
CB
6986 Assumes gfrt_[ix] is NULL_TREE, and replaces it with the FUNCTION_DECL
6987 for the indicated run-time routine (ix). */
5ff904cd 6988
c7e4ee3a
CB
6989#if FFECOM_targetCURRENT == FFECOM_targetGCC
6990static void
6991ffecom_make_gfrt_ (ffecomGfrt ix)
6992{
6993 tree t;
6994 tree ttype;
5ff904cd 6995
c7e4ee3a
CB
6996 switch (ffecom_gfrt_type_[ix])
6997 {
6998 case FFECOM_rttypeVOID_:
6999 ttype = void_type_node;
7000 break;
5ff904cd 7001
c7e4ee3a
CB
7002 case FFECOM_rttypeVOIDSTAR_:
7003 ttype = TREE_TYPE (null_pointer_node); /* `void *'. */
7004 break;
5ff904cd 7005
c7e4ee3a
CB
7006 case FFECOM_rttypeFTNINT_:
7007 ttype = ffecom_f2c_ftnint_type_node;
7008 break;
5ff904cd 7009
c7e4ee3a
CB
7010 case FFECOM_rttypeINTEGER_:
7011 ttype = ffecom_f2c_integer_type_node;
7012 break;
5ff904cd 7013
c7e4ee3a
CB
7014 case FFECOM_rttypeLONGINT_:
7015 ttype = ffecom_f2c_longint_type_node;
7016 break;
5ff904cd 7017
c7e4ee3a
CB
7018 case FFECOM_rttypeLOGICAL_:
7019 ttype = ffecom_f2c_logical_type_node;
7020 break;
5ff904cd 7021
c7e4ee3a
CB
7022 case FFECOM_rttypeREAL_F2C_:
7023 ttype = double_type_node;
7024 break;
5ff904cd 7025
c7e4ee3a
CB
7026 case FFECOM_rttypeREAL_GNU_:
7027 ttype = float_type_node;
7028 break;
5ff904cd 7029
c7e4ee3a
CB
7030 case FFECOM_rttypeCOMPLEX_F2C_:
7031 ttype = void_type_node;
7032 break;
5ff904cd 7033
c7e4ee3a
CB
7034 case FFECOM_rttypeCOMPLEX_GNU_:
7035 ttype = ffecom_f2c_complex_type_node;
7036 break;
5ff904cd 7037
c7e4ee3a
CB
7038 case FFECOM_rttypeDOUBLE_:
7039 ttype = double_type_node;
7040 break;
5ff904cd 7041
c7e4ee3a
CB
7042 case FFECOM_rttypeDOUBLEREAL_:
7043 ttype = ffecom_f2c_doublereal_type_node;
7044 break;
5ff904cd 7045
c7e4ee3a
CB
7046 case FFECOM_rttypeDBLCMPLX_F2C_:
7047 ttype = void_type_node;
7048 break;
5ff904cd 7049
c7e4ee3a
CB
7050 case FFECOM_rttypeDBLCMPLX_GNU_:
7051 ttype = ffecom_f2c_doublecomplex_type_node;
7052 break;
5ff904cd 7053
c7e4ee3a
CB
7054 case FFECOM_rttypeCHARACTER_:
7055 ttype = void_type_node;
7056 break;
7057
7058 default:
7059 ttype = NULL;
7060 assert ("bad rttype" == NULL);
7061 break;
5ff904cd 7062 }
5ff904cd 7063
c7e4ee3a
CB
7064 ttype = build_function_type (ttype, NULL_TREE);
7065 t = build_decl (FUNCTION_DECL,
7066 get_identifier (ffecom_gfrt_name_[ix]),
7067 ttype);
7068 DECL_EXTERNAL (t) = 1;
7069 TREE_PUBLIC (t) = 1;
7070 TREE_THIS_VOLATILE (t) = ffecom_gfrt_volatile_[ix] ? 1 : 0;
5ff904cd 7071
c7e4ee3a 7072 t = start_decl (t, TRUE);
5ff904cd 7073
c7e4ee3a 7074 finish_decl (t, NULL_TREE, TRUE);
5ff904cd 7075
c7e4ee3a 7076 ffecom_gfrt_[ix] = t;
5ff904cd
JL
7077}
7078
7079#endif
c7e4ee3a
CB
7080/* Phase 1 pass over each member of a COMMON/EQUIVALENCE group. */
7081
5ff904cd 7082#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
7083static void
7084ffecom_member_phase1_ (ffestorag mst UNUSED, ffestorag st)
5ff904cd 7085{
c7e4ee3a 7086 ffesymbol s = ffestorag_symbol (st);
5ff904cd 7087
c7e4ee3a
CB
7088 if (ffesymbol_namelisted (s))
7089 ffecom_member_namelisted_ = TRUE;
7090}
5ff904cd 7091
c7e4ee3a
CB
7092#endif
7093/* Phase 2 pass over each member of a COMMON/EQUIVALENCE group. Declare
7094 the member so debugger will see it. Otherwise nobody should be
7095 referencing the member. */
5ff904cd 7096
c7e4ee3a 7097#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
7098static void
7099ffecom_member_phase2_ (ffestorag mst, ffestorag st)
7100{
7101 ffesymbol s;
7102 tree t;
7103 tree mt;
7104 tree type;
5ff904cd 7105
c7e4ee3a
CB
7106 if ((mst == NULL)
7107 || ((mt = ffestorag_hook (mst)) == NULL)
7108 || (mt == error_mark_node))
7109 return;
5ff904cd 7110
c7e4ee3a
CB
7111 if ((st == NULL)
7112 || ((s = ffestorag_symbol (st)) == NULL))
7113 return;
5ff904cd 7114
c7e4ee3a
CB
7115 type = ffecom_type_localvar_ (s,
7116 ffesymbol_basictype (s),
7117 ffesymbol_kindtype (s));
7118 if (type == error_mark_node)
7119 return;
5ff904cd 7120
c7e4ee3a
CB
7121 t = build_decl (VAR_DECL,
7122 ffecom_get_identifier_ (ffesymbol_text (s)),
7123 type);
5ff904cd 7124
c7e4ee3a
CB
7125 TREE_STATIC (t) = TREE_STATIC (mt);
7126 DECL_INITIAL (t) = NULL_TREE;
7127 TREE_ASM_WRITTEN (t) = 1;
5ff904cd 7128
c7e4ee3a
CB
7129 DECL_RTL (t)
7130 = gen_rtx (MEM, TYPE_MODE (type),
7131 plus_constant (XEXP (DECL_RTL (mt), 0),
7132 ffestorag_modulo (mst)
7133 + ffestorag_offset (st)
7134 - ffestorag_offset (mst)));
5ff904cd 7135
c7e4ee3a 7136 t = start_decl (t, FALSE);
5ff904cd 7137
c7e4ee3a 7138 finish_decl (t, NULL_TREE, FALSE);
5ff904cd
JL
7139}
7140
c7e4ee3a
CB
7141#endif
7142/* Prepare source expression for assignment into a destination perhaps known
7143 to be of a specific size. */
5ff904cd 7144
c7e4ee3a
CB
7145static void
7146ffecom_prepare_let_char_ (ffetargetCharacterSize dest_size, ffebld source)
5ff904cd 7147{
c7e4ee3a
CB
7148 ffecomConcatList_ catlist;
7149 int count;
7150 int i;
7151 tree ltmp;
7152 tree itmp;
7153 tree tempvar = NULL_TREE;
5ff904cd 7154
c7e4ee3a
CB
7155 while (ffebld_op (source) == FFEBLD_opCONVERT)
7156 source = ffebld_left (source);
5ff904cd 7157
c7e4ee3a
CB
7158 catlist = ffecom_concat_list_new_ (source, dest_size);
7159 count = ffecom_concat_list_count_ (catlist);
5ff904cd 7160
c7e4ee3a
CB
7161 if (count >= 2)
7162 {
7163 ltmp
7164 = ffecom_make_tempvar ("let_char_len", ffecom_f2c_ftnlen_type_node,
7165 FFETARGET_charactersizeNONE, count);
7166 itmp
7167 = ffecom_make_tempvar ("let_char_item", ffecom_f2c_address_type_node,
7168 FFETARGET_charactersizeNONE, count);
7169
7170 tempvar = make_tree_vec (2);
7171 TREE_VEC_ELT (tempvar, 0) = ltmp;
7172 TREE_VEC_ELT (tempvar, 1) = itmp;
7173 }
5ff904cd 7174
c7e4ee3a
CB
7175 for (i = 0; i < count; ++i)
7176 ffecom_prepare_arg_ptr_to_expr (ffecom_concat_list_expr_ (catlist, i));
5ff904cd 7177
c7e4ee3a 7178 ffecom_concat_list_kill_ (catlist);
5ff904cd 7179
c7e4ee3a
CB
7180 if (tempvar)
7181 {
7182 ffebld_nonter_set_hook (source, tempvar);
7183 current_binding_level->prep_state = 1;
7184 }
7185}
5ff904cd 7186
c7e4ee3a 7187/* ffecom_push_dummy_decls_ -- Transform dummy args, push parm decls in order
5ff904cd 7188
c7e4ee3a
CB
7189 Ignores STAR (alternate-return) dummies. All other get exec-transitioned
7190 (which generates their trees) and then their trees get push_parm_decl'd.
5ff904cd 7191
c7e4ee3a
CB
7192 The second arg is TRUE if the dummies are for a statement function, in
7193 which case lengths are not pushed for character arguments (since they are
7194 always known by both the caller and the callee, though the code allows
7195 for someday permitting CHAR*(*) stmtfunc dummies). */
5ff904cd 7196
c7e4ee3a
CB
7197#if FFECOM_targetCURRENT == FFECOM_targetGCC
7198static void
7199ffecom_push_dummy_decls_ (ffebld dummy_list, bool stmtfunc)
7200{
7201 ffebld dummy;
7202 ffebld dumlist;
7203 ffesymbol s;
7204 tree parm;
5ff904cd 7205
c7e4ee3a 7206 ffecom_transform_only_dummies_ = TRUE;
5ff904cd 7207
c7e4ee3a 7208 /* First push the parms corresponding to actual dummy "contents". */
5ff904cd 7209
c7e4ee3a
CB
7210 for (dumlist = dummy_list; dumlist != NULL; dumlist = ffebld_trail (dumlist))
7211 {
7212 dummy = ffebld_head (dumlist);
7213 switch (ffebld_op (dummy))
7214 {
7215 case FFEBLD_opSTAR:
7216 case FFEBLD_opANY:
7217 continue; /* Forget alternate returns. */
5ff904cd 7218
c7e4ee3a
CB
7219 default:
7220 break;
7221 }
7222 assert (ffebld_op (dummy) == FFEBLD_opSYMTER);
7223 s = ffebld_symter (dummy);
7224 parm = ffesymbol_hook (s).decl_tree;
7225 if (parm == NULL_TREE)
7226 {
7227 s = ffecom_sym_transform_ (s);
7228 parm = ffesymbol_hook (s).decl_tree;
7229 assert (parm != NULL_TREE);
7230 }
7231 if (parm != error_mark_node)
7232 push_parm_decl (parm);
5ff904cd
JL
7233 }
7234
c7e4ee3a 7235 /* Then, for CHARACTER dummies, push the parms giving their lengths. */
5ff904cd 7236
c7e4ee3a
CB
7237 for (dumlist = dummy_list; dumlist != NULL; dumlist = ffebld_trail (dumlist))
7238 {
7239 dummy = ffebld_head (dumlist);
7240 switch (ffebld_op (dummy))
7241 {
7242 case FFEBLD_opSTAR:
7243 case FFEBLD_opANY:
7244 continue; /* Forget alternate returns, they mean
7245 NOTHING! */
7246
7247 default:
7248 break;
7249 }
7250 s = ffebld_symter (dummy);
7251 if (ffesymbol_basictype (s) != FFEINFO_basictypeCHARACTER)
7252 continue; /* Only looking for CHARACTER arguments. */
7253 if (stmtfunc && (ffesymbol_size (s) != FFETARGET_charactersizeNONE))
7254 continue; /* Stmtfunc arg with known size needs no
7255 length param. */
7256 if (ffesymbol_kind (s) != FFEINFO_kindENTITY)
7257 continue; /* Only looking for variables and arrays. */
7258 parm = ffesymbol_hook (s).length_tree;
7259 assert (parm != NULL_TREE);
7260 if (parm != error_mark_node)
7261 push_parm_decl (parm);
7262 }
7263
7264 ffecom_transform_only_dummies_ = FALSE;
5ff904cd
JL
7265}
7266
7267#endif
c7e4ee3a 7268/* ffecom_start_progunit_ -- Beginning of program unit
5ff904cd 7269
c7e4ee3a
CB
7270 Does GNU back end stuff necessary to teach it about the start of its
7271 equivalent of a Fortran program unit. */
5ff904cd
JL
7272
7273#if FFECOM_targetCURRENT == FFECOM_targetGCC
7274static void
c7e4ee3a 7275ffecom_start_progunit_ ()
5ff904cd 7276{
c7e4ee3a
CB
7277 ffesymbol fn = ffecom_primary_entry_;
7278 ffebld arglist;
7279 tree id; /* Identifier (name) of function. */
7280 tree type; /* Type of function. */
7281 tree result; /* Result of function. */
7282 ffeinfoBasictype bt;
7283 ffeinfoKindtype kt;
7284 ffeglobal g;
7285 ffeglobalType gt;
7286 ffeglobalType egt = FFEGLOBAL_type;
7287 bool charfunc;
7288 bool cmplxfunc;
7289 bool altentries = (ffecom_num_entrypoints_ != 0);
7290 bool multi
7291 = altentries
7292 && (ffecom_primary_entry_kind_ == FFEINFO_kindFUNCTION)
7293 && (ffecom_master_bt_ == FFEINFO_basictypeNONE);
7294 bool main_program = FALSE;
7295 int old_lineno = lineno;
7296 char *old_input_filename = input_filename;
7297 int yes;
5ff904cd 7298
c7e4ee3a
CB
7299 assert (fn != NULL);
7300 assert (ffesymbol_hook (fn).decl_tree == NULL_TREE);
5ff904cd 7301
c7e4ee3a
CB
7302 input_filename = ffesymbol_where_filename (fn);
7303 lineno = ffesymbol_where_filelinenum (fn);
5ff904cd 7304
c7e4ee3a
CB
7305 /* c-parse.y indeed does call suspend_momentary and not only ignores the
7306 return value, but also never calls resume_momentary, when starting an
7307 outer function (see "fndef:", "setspecs:", and so on). So g77 does the
7308 same thing. It shouldn't be a problem since start_function calls
7309 temporary_allocation, but it might be necessary. If it causes a problem
7310 here, then maybe there's a bug lurking in gcc. NOTE: This identical
7311 comment appears twice in thist file. */
7312
7313 suspend_momentary ();
7314
7315 switch (ffecom_primary_entry_kind_)
7316 {
7317 case FFEINFO_kindPROGRAM:
7318 main_program = TRUE;
7319 gt = FFEGLOBAL_typeMAIN;
7320 bt = FFEINFO_basictypeNONE;
7321 kt = FFEINFO_kindtypeNONE;
7322 type = ffecom_tree_fun_type_void;
7323 charfunc = FALSE;
7324 cmplxfunc = FALSE;
7325 break;
7326
7327 case FFEINFO_kindBLOCKDATA:
7328 gt = FFEGLOBAL_typeBDATA;
7329 bt = FFEINFO_basictypeNONE;
7330 kt = FFEINFO_kindtypeNONE;
7331 type = ffecom_tree_fun_type_void;
7332 charfunc = FALSE;
7333 cmplxfunc = FALSE;
7334 break;
7335
7336 case FFEINFO_kindFUNCTION:
7337 gt = FFEGLOBAL_typeFUNC;
7338 egt = FFEGLOBAL_typeEXT;
7339 bt = ffesymbol_basictype (fn);
7340 kt = ffesymbol_kindtype (fn);
7341 if (bt == FFEINFO_basictypeNONE)
7342 {
7343 ffeimplic_establish_symbol (fn);
7344 if (ffesymbol_funcresult (fn) != NULL)
7345 ffeimplic_establish_symbol (ffesymbol_funcresult (fn));
7346 bt = ffesymbol_basictype (fn);
7347 kt = ffesymbol_kindtype (fn);
7348 }
7349
7350 if (multi)
7351 charfunc = cmplxfunc = FALSE;
7352 else if (bt == FFEINFO_basictypeCHARACTER)
7353 charfunc = TRUE, cmplxfunc = FALSE;
7354 else if ((bt == FFEINFO_basictypeCOMPLEX)
7355 && ffesymbol_is_f2c (fn)
7356 && !altentries)
7357 charfunc = FALSE, cmplxfunc = TRUE;
7358 else
7359 charfunc = cmplxfunc = FALSE;
7360
7361 if (multi || charfunc)
7362 type = ffecom_tree_fun_type_void;
7363 else if (ffesymbol_is_f2c (fn) && !altentries)
7364 type = ffecom_tree_fun_type[bt][kt];
7365 else
7366 type = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
7367
7368 if ((type == NULL_TREE)
7369 || (TREE_TYPE (type) == NULL_TREE))
7370 type = ffecom_tree_fun_type_void; /* _sym_exec_transition. */
7371 break;
7372
7373 case FFEINFO_kindSUBROUTINE:
7374 gt = FFEGLOBAL_typeSUBR;
7375 egt = FFEGLOBAL_typeEXT;
7376 bt = FFEINFO_basictypeNONE;
7377 kt = FFEINFO_kindtypeNONE;
7378 if (ffecom_is_altreturning_)
7379 type = ffecom_tree_subr_type;
7380 else
7381 type = ffecom_tree_fun_type_void;
7382 charfunc = FALSE;
7383 cmplxfunc = FALSE;
7384 break;
5ff904cd 7385
c7e4ee3a
CB
7386 default:
7387 assert ("say what??" == NULL);
7388 /* Fall through. */
7389 case FFEINFO_kindANY:
7390 gt = FFEGLOBAL_typeANY;
7391 bt = FFEINFO_basictypeNONE;
7392 kt = FFEINFO_kindtypeNONE;
7393 type = error_mark_node;
7394 charfunc = FALSE;
7395 cmplxfunc = FALSE;
7396 break;
7397 }
5ff904cd 7398
c7e4ee3a 7399 if (altentries)
5ff904cd 7400 {
c7e4ee3a 7401 id = ffecom_get_invented_identifier ("__g77_masterfun_%s",
14657de8 7402 ffesymbol_text (fn));
c7e4ee3a
CB
7403 }
7404#if FFETARGET_isENFORCED_MAIN
7405 else if (main_program)
7406 id = get_identifier (FFETARGET_nameENFORCED_MAIN_NAME);
7407#endif
7408 else
7409 id = ffecom_get_external_identifier_ (fn);
5ff904cd 7410
c7e4ee3a
CB
7411 start_function (id,
7412 type,
7413 0, /* nested/inline */
7414 !altentries); /* TREE_PUBLIC */
5ff904cd 7415
c7e4ee3a 7416 TREE_USED (current_function_decl) = 1; /* Avoid spurious warning if altentries. */
5ff904cd 7417
c7e4ee3a
CB
7418 if (!altentries
7419 && ((g = ffesymbol_global (fn)) != NULL)
7420 && ((ffeglobal_type (g) == gt)
7421 || (ffeglobal_type (g) == egt)))
7422 {
7423 ffeglobal_set_hook (g, current_function_decl);
7424 }
5ff904cd 7425
c7e4ee3a 7426 yes = suspend_momentary ();
5ff904cd 7427
c7e4ee3a
CB
7428 /* Arg handling needs exec-transitioned ffesymbols to work with. But
7429 exec-transitioning needs current_function_decl to be filled in. So we
7430 do these things in two phases. */
5ff904cd 7431
c7e4ee3a
CB
7432 if (altentries)
7433 { /* 1st arg identifies which entrypoint. */
7434 ffecom_which_entrypoint_decl_
7435 = build_decl (PARM_DECL,
7436 ffecom_get_invented_identifier ("__g77_%s",
14657de8 7437 "which_entrypoint"),
c7e4ee3a
CB
7438 integer_type_node);
7439 push_parm_decl (ffecom_which_entrypoint_decl_);
7440 }
5ff904cd 7441
c7e4ee3a
CB
7442 if (charfunc
7443 || cmplxfunc
7444 || multi)
7445 { /* Arg for result (return value). */
7446 tree type;
7447 tree length;
5ff904cd 7448
c7e4ee3a
CB
7449 if (charfunc)
7450 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
7451 else if (cmplxfunc)
7452 type = ffecom_tree_type[FFEINFO_basictypeCOMPLEX][kt];
7453 else
7454 type = ffecom_multi_type_node_;
5ff904cd 7455
14657de8 7456 result = ffecom_get_invented_identifier ("__g77_%s", "result");
5ff904cd 7457
c7e4ee3a 7458 /* Make length arg _and_ enhance type info for CHAR arg itself. */
5ff904cd 7459
c7e4ee3a
CB
7460 if (charfunc)
7461 length = ffecom_char_enhance_arg_ (&type, fn);
7462 else
7463 length = NULL_TREE; /* Not ref'd if !charfunc. */
5ff904cd 7464
c7e4ee3a
CB
7465 type = build_pointer_type (type);
7466 result = build_decl (PARM_DECL, result, type);
5ff904cd 7467
c7e4ee3a
CB
7468 push_parm_decl (result);
7469 if (multi)
7470 ffecom_multi_retval_ = result;
7471 else
7472 ffecom_func_result_ = result;
5ff904cd 7473
c7e4ee3a
CB
7474 if (charfunc)
7475 {
7476 push_parm_decl (length);
7477 ffecom_func_length_ = length;
7478 }
5ff904cd
JL
7479 }
7480
c7e4ee3a
CB
7481 if (ffecom_primary_entry_is_proc_)
7482 {
7483 if (altentries)
7484 arglist = ffecom_master_arglist_;
7485 else
7486 arglist = ffesymbol_dummyargs (fn);
7487 ffecom_push_dummy_decls_ (arglist, FALSE);
7488 }
5ff904cd 7489
c7e4ee3a 7490 resume_momentary (yes);
5ff904cd 7491
c7e4ee3a
CB
7492 if (TREE_CODE (current_function_decl) != ERROR_MARK)
7493 store_parm_decls (main_program ? 1 : 0);
5ff904cd 7494
c7e4ee3a
CB
7495 ffecom_start_compstmt ();
7496 /* Disallow temp vars at this level. */
7497 current_binding_level->prep_state = 2;
5ff904cd 7498
c7e4ee3a
CB
7499 lineno = old_lineno;
7500 input_filename = old_input_filename;
5ff904cd 7501
c7e4ee3a
CB
7502 /* This handles any symbols still untransformed, in case -g specified.
7503 This used to be done in ffecom_finish_progunit, but it turns out to
7504 be necessary to do it here so that statement functions are
7505 expanded before code. But don't bother for BLOCK DATA. */
5ff904cd 7506
c7e4ee3a
CB
7507 if (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA)
7508 ffesymbol_drive (ffecom_finish_symbol_transform_);
5ff904cd
JL
7509}
7510
7511#endif
c7e4ee3a 7512/* ffecom_sym_transform_ -- Transform FFE sym into backend sym
5ff904cd 7513
c7e4ee3a
CB
7514 ffesymbol s;
7515 ffecom_sym_transform_(s);
7516
7517 The ffesymbol_hook info for s is updated with appropriate backend info
7518 on the symbol. */
7519
7520#if FFECOM_targetCURRENT == FFECOM_targetGCC
7521static ffesymbol
7522ffecom_sym_transform_ (ffesymbol s)
7523{
7524 tree t; /* Transformed thingy. */
7525 tree tlen; /* Length if CHAR*(*). */
7526 bool addr; /* Is t the address of the thingy? */
7527 ffeinfoBasictype bt;
7528 ffeinfoKindtype kt;
7529 ffeglobal g;
7530 int yes;
7531 int old_lineno = lineno;
7532 char *old_input_filename = input_filename;
5ff904cd 7533
c7e4ee3a
CB
7534 /* Must ensure special ASSIGN variables are declared at top of outermost
7535 block, else they'll end up in the innermost block when their first
7536 ASSIGN is seen, which leaves them out of scope when they're the
7537 subject of a GOTO or I/O statement.
5ff904cd 7538
c7e4ee3a
CB
7539 We make this variable even if -fugly-assign. Just let it go unused,
7540 in case it turns out there are cases where we really want to use this
7541 variable anyway (e.g. ASSIGN to INTEGER*2 variable). */
5ff904cd 7542
c7e4ee3a
CB
7543 if (! ffecom_transform_only_dummies_
7544 && ffesymbol_assigned (s)
7545 && ! ffesymbol_hook (s).assign_tree)
7546 s = ffecom_sym_transform_assign_ (s);
5ff904cd 7547
c7e4ee3a 7548 if (ffesymbol_sfdummyparent (s) == NULL)
5ff904cd 7549 {
c7e4ee3a
CB
7550 input_filename = ffesymbol_where_filename (s);
7551 lineno = ffesymbol_where_filelinenum (s);
7552 }
7553 else
7554 {
7555 ffesymbol sf = ffesymbol_sfdummyparent (s);
5ff904cd 7556
c7e4ee3a
CB
7557 input_filename = ffesymbol_where_filename (sf);
7558 lineno = ffesymbol_where_filelinenum (sf);
7559 }
6d433196 7560
c7e4ee3a
CB
7561 bt = ffeinfo_basictype (ffebld_info (s));
7562 kt = ffeinfo_kindtype (ffebld_info (s));
5ff904cd 7563
c7e4ee3a
CB
7564 t = NULL_TREE;
7565 tlen = NULL_TREE;
7566 addr = FALSE;
5ff904cd 7567
c7e4ee3a
CB
7568 switch (ffesymbol_kind (s))
7569 {
7570 case FFEINFO_kindNONE:
7571 switch (ffesymbol_where (s))
7572 {
7573 case FFEINFO_whereDUMMY: /* Subroutine or function. */
7574 assert (ffecom_transform_only_dummies_);
5ff904cd 7575
c7e4ee3a
CB
7576 /* Before 0.4, this could be ENTITY/DUMMY, but see
7577 ffestu_sym_end_transition -- no longer true (in particular, if
7578 it could be an ENTITY, it _will_ be made one, so that
7579 possibility won't come through here). So we never make length
7580 arg for CHARACTER type. */
5ff904cd 7581
c7e4ee3a
CB
7582 t = build_decl (PARM_DECL,
7583 ffecom_get_identifier_ (ffesymbol_text (s)),
7584 ffecom_tree_ptr_to_subr_type);
7585#if BUILT_FOR_270
7586 DECL_ARTIFICIAL (t) = 1;
7587#endif
7588 addr = TRUE;
7589 break;
5ff904cd 7590
c7e4ee3a
CB
7591 case FFEINFO_whereGLOBAL: /* Subroutine or function. */
7592 assert (!ffecom_transform_only_dummies_);
5ff904cd 7593
c7e4ee3a
CB
7594 if (((g = ffesymbol_global (s)) != NULL)
7595 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
7596 || (ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
7597 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
7598 && (ffeglobal_hook (g) != NULL_TREE)
7599 && ffe_is_globals ())
7600 {
7601 t = ffeglobal_hook (g);
7602 break;
7603 }
5ff904cd 7604
c7e4ee3a
CB
7605 t = build_decl (FUNCTION_DECL,
7606 ffecom_get_external_identifier_ (s),
7607 ffecom_tree_subr_type); /* Assume subr. */
7608 DECL_EXTERNAL (t) = 1;
7609 TREE_PUBLIC (t) = 1;
5ff904cd 7610
c7e4ee3a
CB
7611 t = start_decl (t, FALSE);
7612 finish_decl (t, NULL_TREE, FALSE);
795232f7 7613
c7e4ee3a
CB
7614 if ((g != NULL)
7615 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
7616 || (ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
7617 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
7618 ffeglobal_set_hook (g, t);
5ff904cd 7619
7189a4b0 7620 ffecom_save_tree_forever (t);
5ff904cd 7621
c7e4ee3a 7622 break;
5ff904cd 7623
c7e4ee3a
CB
7624 default:
7625 assert ("NONE where unexpected" == NULL);
7626 /* Fall through. */
7627 case FFEINFO_whereANY:
7628 break;
7629 }
5ff904cd 7630 break;
5ff904cd 7631
c7e4ee3a
CB
7632 case FFEINFO_kindENTITY:
7633 switch (ffeinfo_where (ffesymbol_info (s)))
7634 {
5ff904cd 7635
c7e4ee3a
CB
7636 case FFEINFO_whereCONSTANT:
7637 /* ~~Debugging info needed? */
7638 assert (!ffecom_transform_only_dummies_);
7639 t = error_mark_node; /* Shouldn't ever see this in expr. */
7640 break;
5ff904cd 7641
c7e4ee3a
CB
7642 case FFEINFO_whereLOCAL:
7643 assert (!ffecom_transform_only_dummies_);
5ff904cd 7644
c7e4ee3a
CB
7645 {
7646 ffestorag st = ffesymbol_storage (s);
7647 tree type;
5ff904cd 7648
c7e4ee3a
CB
7649 if ((st != NULL)
7650 && (ffestorag_size (st) == 0))
7651 {
7652 t = error_mark_node;
7653 break;
7654 }
5ff904cd 7655
c7e4ee3a
CB
7656 yes = suspend_momentary ();
7657 type = ffecom_type_localvar_ (s, bt, kt);
7658 resume_momentary (yes);
5ff904cd 7659
c7e4ee3a
CB
7660 if (type == error_mark_node)
7661 {
7662 t = error_mark_node;
7663 break;
7664 }
5ff904cd 7665
c7e4ee3a
CB
7666 if ((st != NULL)
7667 && (ffestorag_parent (st) != NULL))
7668 { /* Child of EQUIVALENCE parent. */
7669 ffestorag est;
7670 tree et;
7671 int yes;
7672 ffetargetOffset offset;
5ff904cd 7673
c7e4ee3a
CB
7674 est = ffestorag_parent (st);
7675 ffecom_transform_equiv_ (est);
5ff904cd 7676
c7e4ee3a
CB
7677 et = ffestorag_hook (est);
7678 assert (et != NULL_TREE);
5ff904cd 7679
c7e4ee3a
CB
7680 if (! TREE_STATIC (et))
7681 put_var_into_stack (et);
5ff904cd 7682
c7e4ee3a 7683 yes = suspend_momentary ();
5ff904cd 7684
c7e4ee3a
CB
7685 offset = ffestorag_modulo (est)
7686 + ffestorag_offset (ffesymbol_storage (s))
7687 - ffestorag_offset (est);
5ff904cd 7688
c7e4ee3a 7689 ffecom_debug_kludge_ (et, "EQUIVALENCE", s, type, offset);
5ff904cd 7690
c7e4ee3a 7691 /* (t_type *) (((char *) &et) + offset) */
5ff904cd 7692
c7e4ee3a
CB
7693 t = convert (string_type_node, /* (char *) */
7694 ffecom_1 (ADDR_EXPR,
7695 build_pointer_type (TREE_TYPE (et)),
7696 et));
7697 t = ffecom_2 (PLUS_EXPR, TREE_TYPE (t),
7698 t,
7699 build_int_2 (offset, 0));
7700 t = convert (build_pointer_type (type),
7701 t);
d50108c7 7702 TREE_CONSTANT (t) = staticp (et);
5ff904cd 7703
c7e4ee3a 7704 addr = TRUE;
5ff904cd 7705
c7e4ee3a
CB
7706 resume_momentary (yes);
7707 }
7708 else
7709 {
7710 tree initexpr;
7711 bool init = ffesymbol_is_init (s);
5ff904cd 7712
c7e4ee3a 7713 yes = suspend_momentary ();
5ff904cd 7714
c7e4ee3a
CB
7715 t = build_decl (VAR_DECL,
7716 ffecom_get_identifier_ (ffesymbol_text (s)),
7717 type);
5ff904cd 7718
c7e4ee3a
CB
7719 if (init
7720 || ffesymbol_namelisted (s)
7721#ifdef FFECOM_sizeMAXSTACKITEM
7722 || ((st != NULL)
7723 && (ffestorag_size (st) > FFECOM_sizeMAXSTACKITEM))
7724#endif
7725 || ((ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
7726 && (ffecom_primary_entry_kind_
7727 != FFEINFO_kindBLOCKDATA)
7728 && (ffesymbol_is_save (s) || ffe_is_saveall ())))
7729 TREE_STATIC (t) = !ffesymbol_attr (s, FFESYMBOL_attrADJUSTABLE);
7730 else
7731 TREE_STATIC (t) = 0; /* No need to make static. */
5ff904cd 7732
c7e4ee3a
CB
7733 if (init || ffe_is_init_local_zero ())
7734 DECL_INITIAL (t) = error_mark_node;
5ff904cd 7735
c7e4ee3a
CB
7736 /* Keep -Wunused from complaining about var if it
7737 is used as sfunc arg or DATA implied-DO. */
7738 if (ffesymbol_attrs (s) & FFESYMBOL_attrsSFARG)
7739 DECL_IN_SYSTEM_HEADER (t) = 1;
5ff904cd 7740
c7e4ee3a 7741 t = start_decl (t, FALSE);
5ff904cd 7742
c7e4ee3a
CB
7743 if (init)
7744 {
7745 if (ffesymbol_init (s) != NULL)
7746 initexpr = ffecom_expr (ffesymbol_init (s));
7747 else
7748 initexpr = ffecom_init_zero_ (t);
7749 }
7750 else if (ffe_is_init_local_zero ())
7751 initexpr = ffecom_init_zero_ (t);
7752 else
7753 initexpr = NULL_TREE; /* Not ref'd if !init. */
5ff904cd 7754
c7e4ee3a 7755 finish_decl (t, initexpr, FALSE);
5ff904cd 7756
06ceef4e 7757 if (st != NULL && DECL_SIZE (t) != error_mark_node)
c7e4ee3a 7758 {
06ceef4e 7759 assert (TREE_CODE (DECL_SIZE_UNIT (t)) == INTEGER_CST);
05bccae2
RK
7760 assert (0 == compare_tree_int (DECL_SIZE_UNIT (t),
7761 ffestorag_size (st)));
c7e4ee3a 7762 }
5ff904cd 7763
c7e4ee3a
CB
7764 resume_momentary (yes);
7765 }
7766 }
5ff904cd 7767 break;
5ff904cd 7768
c7e4ee3a
CB
7769 case FFEINFO_whereRESULT:
7770 assert (!ffecom_transform_only_dummies_);
5ff904cd 7771
c7e4ee3a
CB
7772 if (bt == FFEINFO_basictypeCHARACTER)
7773 { /* Result is already in list of dummies, use
7774 it (& length). */
7775 t = ffecom_func_result_;
7776 tlen = ffecom_func_length_;
7777 addr = TRUE;
7778 break;
7779 }
7780 if ((ffecom_num_entrypoints_ == 0)
7781 && (bt == FFEINFO_basictypeCOMPLEX)
7782 && (ffesymbol_is_f2c (ffecom_primary_entry_)))
7783 { /* Result is already in list of dummies, use
7784 it. */
7785 t = ffecom_func_result_;
7786 addr = TRUE;
7787 break;
7788 }
7789 if (ffecom_func_result_ != NULL_TREE)
7790 {
7791 t = ffecom_func_result_;
7792 break;
7793 }
7794 if ((ffecom_num_entrypoints_ != 0)
7795 && (ffecom_master_bt_ == FFEINFO_basictypeNONE))
7796 {
7797 yes = suspend_momentary ();
5ff904cd 7798
c7e4ee3a
CB
7799 assert (ffecom_multi_retval_ != NULL_TREE);
7800 t = ffecom_1 (INDIRECT_REF, ffecom_multi_type_node_,
7801 ffecom_multi_retval_);
7802 t = ffecom_2 (COMPONENT_REF, ffecom_tree_type[bt][kt],
7803 t, ffecom_multi_fields_[bt][kt]);
5ff904cd 7804
c7e4ee3a
CB
7805 resume_momentary (yes);
7806 break;
7807 }
5ff904cd 7808
c7e4ee3a 7809 yes = suspend_momentary ();
5ff904cd 7810
c7e4ee3a
CB
7811 t = build_decl (VAR_DECL,
7812 ffecom_get_identifier_ (ffesymbol_text (s)),
7813 ffecom_tree_type[bt][kt]);
7814 TREE_STATIC (t) = 0; /* Put result on stack. */
7815 t = start_decl (t, FALSE);
7816 finish_decl (t, NULL_TREE, FALSE);
5ff904cd 7817
c7e4ee3a 7818 ffecom_func_result_ = t;
5ff904cd 7819
c7e4ee3a
CB
7820 resume_momentary (yes);
7821 break;
5ff904cd 7822
c7e4ee3a
CB
7823 case FFEINFO_whereDUMMY:
7824 {
7825 tree type;
7826 ffebld dl;
7827 ffebld dim;
7828 tree low;
7829 tree high;
7830 tree old_sizes;
7831 bool adjustable = FALSE; /* Conditionally adjustable? */
5ff904cd 7832
c7e4ee3a
CB
7833 type = ffecom_tree_type[bt][kt];
7834 if (ffesymbol_sfdummyparent (s) != NULL)
7835 {
7836 if (current_function_decl == ffecom_outer_function_decl_)
7837 { /* Exec transition before sfunc
7838 context; get it later. */
7839 break;
7840 }
7841 t = ffecom_get_identifier_ (ffesymbol_text
7842 (ffesymbol_sfdummyparent (s)));
7843 }
7844 else
7845 t = ffecom_get_identifier_ (ffesymbol_text (s));
5ff904cd 7846
c7e4ee3a 7847 assert (ffecom_transform_only_dummies_);
5ff904cd 7848
c7e4ee3a
CB
7849 old_sizes = get_pending_sizes ();
7850 put_pending_sizes (old_sizes);
5ff904cd 7851
c7e4ee3a
CB
7852 if (bt == FFEINFO_basictypeCHARACTER)
7853 tlen = ffecom_char_enhance_arg_ (&type, s);
7854 type = ffecom_check_size_overflow_ (s, type, TRUE);
5ff904cd 7855
c7e4ee3a
CB
7856 for (dl = ffesymbol_dims (s); dl != NULL; dl = ffebld_trail (dl))
7857 {
7858 if (type == error_mark_node)
7859 break;
5ff904cd 7860
c7e4ee3a
CB
7861 dim = ffebld_head (dl);
7862 assert (ffebld_op (dim) == FFEBLD_opBOUNDS);
7863 if ((ffebld_left (dim) == NULL) || ffecom_doing_entry_)
7864 low = ffecom_integer_one_node;
7865 else
7866 low = ffecom_expr (ffebld_left (dim));
7867 assert (ffebld_right (dim) != NULL);
7868 if ((ffebld_op (ffebld_right (dim)) == FFEBLD_opSTAR)
7869 || ffecom_doing_entry_)
7870 {
7871 /* Used to just do high=low. But for ffecom_tree_
7872 canonize_ref_, it probably is important to correctly
7873 assess the size. E.g. given COMPLEX C(*),CFUNC and
7874 C(2)=CFUNC(C), overlap can happen, while it can't
7875 for, say, C(1)=CFUNC(C(2)). */
7876 /* Even more recently used to set to INT_MAX, but that
7877 broke when some overflow checking went into the back
7878 end. Now we just leave the upper bound unspecified. */
7879 high = NULL;
7880 }
7881 else
7882 high = ffecom_expr (ffebld_right (dim));
5ff904cd 7883
c7e4ee3a
CB
7884 /* Determine whether array is conditionally adjustable,
7885 to decide whether back-end magic is needed.
5ff904cd 7886
c7e4ee3a
CB
7887 Normally the front end uses the back-end function
7888 variable_size to wrap SAVE_EXPR's around expressions
7889 affecting the size/shape of an array so that the
7890 size/shape info doesn't change during execution
7891 of the compiled code even though variables and
7892 functions referenced in those expressions might.
5ff904cd 7893
c7e4ee3a
CB
7894 variable_size also makes sure those saved expressions
7895 get evaluated immediately upon entry to the
7896 compiled procedure -- the front end normally doesn't
7897 have to worry about that.
3cf0cea4 7898
c7e4ee3a
CB
7899 However, there is a problem with this that affects
7900 g77's implementation of entry points, and that is
7901 that it is _not_ true that each invocation of the
7902 compiled procedure is permitted to evaluate
7903 array size/shape info -- because it is possible
7904 that, for some invocations, that info is invalid (in
7905 which case it is "promised" -- i.e. a violation of
7906 the Fortran standard -- that the compiled code
7907 won't reference the array or its size/shape
7908 during that particular invocation).
5ff904cd 7909
c7e4ee3a 7910 To phrase this in C terms, consider this gcc function:
5ff904cd 7911
c7e4ee3a
CB
7912 void foo (int *n, float (*a)[*n])
7913 {
7914 // a is "pointer to array ...", fyi.
7915 }
5ff904cd 7916
c7e4ee3a
CB
7917 Suppose that, for some invocations, it is permitted
7918 for a caller of foo to do this:
5ff904cd 7919
c7e4ee3a 7920 foo (NULL, NULL);
5ff904cd 7921
c7e4ee3a
CB
7922 Now the _written_ code for foo can take such a call
7923 into account by either testing explicitly for whether
7924 (a == NULL) || (n == NULL) -- presumably it is
7925 not permitted to reference *a in various fashions
7926 if (n == NULL) I suppose -- or it can avoid it by
7927 looking at other info (other arguments, static/global
7928 data, etc.).
5ff904cd 7929
c7e4ee3a
CB
7930 However, this won't work in gcc 2.5.8 because it'll
7931 automatically emit the code to save the "*n"
7932 expression, which'll yield a NULL dereference for
7933 the "foo (NULL, NULL)" call, something the code
7934 for foo cannot prevent.
5ff904cd 7935
c7e4ee3a
CB
7936 g77 definitely needs to avoid executing such
7937 code anytime the pointer to the adjustable array
7938 is NULL, because even if its bounds expressions
7939 don't have any references to possible "absent"
7940 variables like "*n" -- say all variable references
7941 are to COMMON variables, i.e. global (though in C,
7942 local static could actually make sense) -- the
7943 expressions could yield other run-time problems
7944 for allowably "dead" values in those variables.
5ff904cd 7945
c7e4ee3a
CB
7946 For example, let's consider a more complicated
7947 version of foo:
5ff904cd 7948
c7e4ee3a
CB
7949 extern int i;
7950 extern int j;
5ff904cd 7951
c7e4ee3a
CB
7952 void foo (float (*a)[i/j])
7953 {
7954 ...
7955 }
5ff904cd 7956
c7e4ee3a
CB
7957 The above is (essentially) quite valid for Fortran
7958 but, again, for a call like "foo (NULL);", it is
7959 permitted for i and j to be undefined when the
7960 call is made. If j happened to be zero, for
7961 example, emitting the code to evaluate "i/j"
7962 could result in a run-time error.
5ff904cd 7963
c7e4ee3a
CB
7964 Offhand, though I don't have my F77 or F90
7965 standards handy, it might even be valid for a
7966 bounds expression to contain a function reference,
7967 in which case I doubt it is permitted for an
7968 implementation to invoke that function in the
7969 Fortran case involved here (invocation of an
7970 alternate ENTRY point that doesn't have the adjustable
7971 array as one of its arguments).
5ff904cd 7972
c7e4ee3a
CB
7973 So, the code that the compiler would normally emit
7974 to preevaluate the size/shape info for an
7975 adjustable array _must not_ be executed at run time
7976 in certain cases. Specifically, for Fortran,
7977 the case is when the pointer to the adjustable
7978 array == NULL. (For gnu-ish C, it might be nice
7979 for the source code itself to specify an expression
7980 that, if TRUE, inhibits execution of the code. Or
7981 reverse the sense for elegance.)
5ff904cd 7982
c7e4ee3a
CB
7983 (Note that g77 could use a different test than NULL,
7984 actually, since it happens to always pass an
7985 integer to the called function that specifies which
7986 entry point is being invoked. Hmm, this might
7987 solve the next problem.)
7988
7989 One way a user could, I suppose, write "foo" so
7990 it works is to insert COND_EXPR's for the
7991 size/shape info so the dangerous stuff isn't
7992 actually done, as in:
7993
7994 void foo (int *n, float (*a)[(a == NULL) ? 0 : *n])
7995 {
7996 ...
7997 }
5ff904cd 7998
c7e4ee3a
CB
7999 The next problem is that the front end needs to
8000 be able to tell the back end about the array's
8001 decl _before_ it tells it about the conditional
8002 expression to inhibit evaluation of size/shape info,
8003 as shown above.
5ff904cd 8004
c7e4ee3a
CB
8005 To solve this, the front end needs to be able
8006 to give the back end the expression to inhibit
8007 generation of the preevaluation code _after_
8008 it makes the decl for the adjustable array.
5ff904cd 8009
c7e4ee3a
CB
8010 Until then, the above example using the COND_EXPR
8011 doesn't pass muster with gcc because the "(a == NULL)"
8012 part has a reference to "a", which is still
8013 undefined at that point.
5ff904cd 8014
c7e4ee3a
CB
8015 g77 will therefore use a different mechanism in the
8016 meantime. */
5ff904cd 8017
c7e4ee3a
CB
8018 if (!adjustable
8019 && ((TREE_CODE (low) != INTEGER_CST)
8020 || (high && TREE_CODE (high) != INTEGER_CST)))
8021 adjustable = TRUE;
5ff904cd 8022
c7e4ee3a
CB
8023#if 0 /* Old approach -- see below. */
8024 if (TREE_CODE (low) != INTEGER_CST)
8025 low = ffecom_3 (COND_EXPR, integer_type_node,
8026 ffecom_adjarray_passed_ (s),
8027 low,
8028 ffecom_integer_zero_node);
5ff904cd 8029
c7e4ee3a
CB
8030 if (high && TREE_CODE (high) != INTEGER_CST)
8031 high = ffecom_3 (COND_EXPR, integer_type_node,
8032 ffecom_adjarray_passed_ (s),
8033 high,
8034 ffecom_integer_zero_node);
8035#endif
5ff904cd 8036
c7e4ee3a
CB
8037 /* ~~~gcc/stor-layout.c (layout_type) should do this,
8038 probably. Fixes 950302-1.f. */
5ff904cd 8039
c7e4ee3a
CB
8040 if (TREE_CODE (low) != INTEGER_CST)
8041 low = variable_size (low);
5ff904cd 8042
c7e4ee3a
CB
8043 /* ~~~Similarly, this fixes dumb0.f. The C front end
8044 does this, which is why dumb0.c would work. */
5ff904cd 8045
c7e4ee3a
CB
8046 if (high && TREE_CODE (high) != INTEGER_CST)
8047 high = variable_size (high);
5ff904cd 8048
c7e4ee3a
CB
8049 type
8050 = build_array_type
8051 (type,
8052 build_range_type (ffecom_integer_type_node,
8053 low, high));
8054 type = ffecom_check_size_overflow_ (s, type, TRUE);
8055 }
5ff904cd 8056
c7e4ee3a
CB
8057 if (type == error_mark_node)
8058 {
8059 t = error_mark_node;
8060 break;
8061 }
5ff904cd 8062
c7e4ee3a
CB
8063 if ((ffesymbol_sfdummyparent (s) == NULL)
8064 || (ffesymbol_basictype (s) == FFEINFO_basictypeCHARACTER))
8065 {
8066 type = build_pointer_type (type);
8067 addr = TRUE;
8068 }
5ff904cd 8069
c7e4ee3a 8070 t = build_decl (PARM_DECL, t, type);
5ff904cd 8071#if BUILT_FOR_270
c7e4ee3a 8072 DECL_ARTIFICIAL (t) = 1;
5ff904cd 8073#endif
5ff904cd 8074
c7e4ee3a
CB
8075 /* If this arg is present in every entry point's list of
8076 dummy args, then we're done. */
5ff904cd 8077
c7e4ee3a
CB
8078 if (ffesymbol_numentries (s)
8079 == (ffecom_num_entrypoints_ + 1))
5ff904cd 8080 break;
5ff904cd 8081
c7e4ee3a 8082#if 1
5ff904cd 8083
c7e4ee3a
CB
8084 /* If variable_size in stor-layout has been called during
8085 the above, then get_pending_sizes should have the
8086 yet-to-be-evaluated saved expressions pending.
8087 Make the whole lot of them get emitted, conditionally
8088 on whether the array decl ("t" above) is not NULL. */
5ff904cd 8089
c7e4ee3a
CB
8090 {
8091 tree sizes = get_pending_sizes ();
8092 tree tem;
5ff904cd 8093
c7e4ee3a
CB
8094 for (tem = sizes;
8095 tem != old_sizes;
8096 tem = TREE_CHAIN (tem))
8097 {
8098 tree temv = TREE_VALUE (tem);
5ff904cd 8099
c7e4ee3a
CB
8100 if (sizes == tem)
8101 sizes = temv;
8102 else
8103 sizes
8104 = ffecom_2 (COMPOUND_EXPR,
8105 TREE_TYPE (sizes),
8106 temv,
8107 sizes);
8108 }
5ff904cd 8109
c7e4ee3a
CB
8110 if (sizes != tem)
8111 {
8112 sizes
8113 = ffecom_3 (COND_EXPR,
8114 TREE_TYPE (sizes),
8115 ffecom_2 (NE_EXPR,
8116 integer_type_node,
8117 t,
8118 null_pointer_node),
8119 sizes,
8120 convert (TREE_TYPE (sizes),
8121 integer_zero_node));
8122 sizes = ffecom_save_tree (sizes);
5ff904cd 8123
c7e4ee3a
CB
8124 sizes
8125 = tree_cons (NULL_TREE, sizes, tem);
8126 }
5ff904cd 8127
c7e4ee3a
CB
8128 if (sizes)
8129 put_pending_sizes (sizes);
8130 }
5ff904cd 8131
c7e4ee3a
CB
8132#else
8133#if 0
8134 if (adjustable
8135 && (ffesymbol_numentries (s)
8136 != ffecom_num_entrypoints_ + 1))
8137 DECL_SOMETHING (t)
8138 = ffecom_2 (NE_EXPR, integer_type_node,
8139 t,
8140 null_pointer_node);
8141#else
8142#if 0
8143 if (adjustable
8144 && (ffesymbol_numentries (s)
8145 != ffecom_num_entrypoints_ + 1))
8146 {
8147 ffebad_start (FFEBAD_MISSING_ADJARRAY_UNSUPPORTED);
8148 ffebad_here (0, ffesymbol_where_line (s),
8149 ffesymbol_where_column (s));
8150 ffebad_string (ffesymbol_text (s));
8151 ffebad_finish ();
8152 }
8153#endif
8154#endif
8155#endif
8156 }
5ff904cd
JL
8157 break;
8158
c7e4ee3a 8159 case FFEINFO_whereCOMMON:
5ff904cd 8160 {
c7e4ee3a
CB
8161 ffesymbol cs;
8162 ffeglobal cg;
8163 tree ct;
5ff904cd
JL
8164 ffestorag st = ffesymbol_storage (s);
8165 tree type;
c7e4ee3a 8166 int yes;
5ff904cd 8167
c7e4ee3a
CB
8168 cs = ffesymbol_common (s); /* The COMMON area itself. */
8169 if (st != NULL) /* Else not laid out. */
5ff904cd 8170 {
c7e4ee3a
CB
8171 ffecom_transform_common_ (cs);
8172 st = ffesymbol_storage (s);
5ff904cd
JL
8173 }
8174
c7e4ee3a 8175 yes = suspend_momentary ();
5ff904cd 8176
c7e4ee3a 8177 type = ffecom_type_localvar_ (s, bt, kt);
5ff904cd 8178
c7e4ee3a
CB
8179 cg = ffesymbol_global (cs); /* The global COMMON info. */
8180 if ((cg == NULL)
8181 || (ffeglobal_type (cg) != FFEGLOBAL_typeCOMMON))
8182 ct = NULL_TREE;
8183 else
8184 ct = ffeglobal_hook (cg); /* The common area's tree. */
5ff904cd 8185
c7e4ee3a
CB
8186 if ((ct == NULL_TREE)
8187 || (st == NULL)
8188 || (type == error_mark_node))
8189 t = error_mark_node;
8190 else
8191 {
8192 ffetargetOffset offset;
8193 ffestorag cst;
5ff904cd 8194
c7e4ee3a
CB
8195 cst = ffestorag_parent (st);
8196 assert (cst == ffesymbol_storage (cs));
5ff904cd 8197
c7e4ee3a
CB
8198 offset = ffestorag_modulo (cst)
8199 + ffestorag_offset (st)
8200 - ffestorag_offset (cst);
5ff904cd 8201
c7e4ee3a 8202 ffecom_debug_kludge_ (ct, "COMMON", s, type, offset);
5ff904cd 8203
c7e4ee3a 8204 /* (t_type *) (((char *) &ct) + offset) */
5ff904cd
JL
8205
8206 t = convert (string_type_node, /* (char *) */
8207 ffecom_1 (ADDR_EXPR,
c7e4ee3a
CB
8208 build_pointer_type (TREE_TYPE (ct)),
8209 ct));
5ff904cd
JL
8210 t = ffecom_2 (PLUS_EXPR, TREE_TYPE (t),
8211 t,
8212 build_int_2 (offset, 0));
8213 t = convert (build_pointer_type (type),
8214 t);
d50108c7 8215 TREE_CONSTANT (t) = 1;
5ff904cd
JL
8216
8217 addr = TRUE;
5ff904cd 8218 }
5ff904cd 8219
c7e4ee3a
CB
8220 resume_momentary (yes);
8221 }
8222 break;
5ff904cd 8223
c7e4ee3a
CB
8224 case FFEINFO_whereIMMEDIATE:
8225 case FFEINFO_whereGLOBAL:
8226 case FFEINFO_whereFLEETING:
8227 case FFEINFO_whereFLEETING_CADDR:
8228 case FFEINFO_whereFLEETING_IADDR:
8229 case FFEINFO_whereINTRINSIC:
8230 case FFEINFO_whereCONSTANT_SUBOBJECT:
8231 default:
8232 assert ("ENTITY where unheard of" == NULL);
8233 /* Fall through. */
8234 case FFEINFO_whereANY:
8235 t = error_mark_node;
8236 break;
8237 }
8238 break;
5ff904cd 8239
c7e4ee3a
CB
8240 case FFEINFO_kindFUNCTION:
8241 switch (ffeinfo_where (ffesymbol_info (s)))
8242 {
8243 case FFEINFO_whereLOCAL: /* Me. */
8244 assert (!ffecom_transform_only_dummies_);
8245 t = current_function_decl;
5ff904cd
JL
8246 break;
8247
c7e4ee3a 8248 case FFEINFO_whereGLOBAL:
5ff904cd
JL
8249 assert (!ffecom_transform_only_dummies_);
8250
c7e4ee3a
CB
8251 if (((g = ffesymbol_global (s)) != NULL)
8252 && ((ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
8253 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
8254 && (ffeglobal_hook (g) != NULL_TREE)
8255 && ffe_is_globals ())
5ff904cd 8256 {
c7e4ee3a 8257 t = ffeglobal_hook (g);
5ff904cd
JL
8258 break;
8259 }
5ff904cd 8260
c7e4ee3a
CB
8261 if (ffesymbol_is_f2c (s)
8262 && (ffesymbol_where (s) != FFEINFO_whereCONSTANT))
8263 t = ffecom_tree_fun_type[bt][kt];
8264 else
8265 t = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
5ff904cd 8266
c7e4ee3a
CB
8267 t = build_decl (FUNCTION_DECL,
8268 ffecom_get_external_identifier_ (s),
8269 t);
8270 DECL_EXTERNAL (t) = 1;
8271 TREE_PUBLIC (t) = 1;
5ff904cd 8272
5ff904cd
JL
8273 t = start_decl (t, FALSE);
8274 finish_decl (t, NULL_TREE, FALSE);
8275
c7e4ee3a
CB
8276 if ((g != NULL)
8277 && ((ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
8278 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
8279 ffeglobal_set_hook (g, t);
8280
7189a4b0 8281 ffecom_save_tree_forever (t);
5ff904cd 8282
5ff904cd
JL
8283 break;
8284
8285 case FFEINFO_whereDUMMY:
c7e4ee3a 8286 assert (ffecom_transform_only_dummies_);
5ff904cd 8287
c7e4ee3a
CB
8288 if (ffesymbol_is_f2c (s)
8289 && (ffesymbol_where (s) != FFEINFO_whereCONSTANT))
8290 t = ffecom_tree_ptr_to_fun_type[bt][kt];
8291 else
8292 t = build_pointer_type
8293 (build_function_type (ffecom_tree_type[bt][kt], NULL_TREE));
8294
8295 t = build_decl (PARM_DECL,
8296 ffecom_get_identifier_ (ffesymbol_text (s)),
8297 t);
8298#if BUILT_FOR_270
8299 DECL_ARTIFICIAL (t) = 1;
8300#endif
8301 addr = TRUE;
8302 break;
8303
8304 case FFEINFO_whereCONSTANT: /* Statement function. */
8305 assert (!ffecom_transform_only_dummies_);
8306 t = ffecom_gen_sfuncdef_ (s, bt, kt);
8307 break;
8308
8309 case FFEINFO_whereINTRINSIC:
8310 assert (!ffecom_transform_only_dummies_);
8311 break; /* Let actual references generate their
8312 decls. */
8313
8314 default:
8315 assert ("FUNCTION where unheard of" == NULL);
8316 /* Fall through. */
8317 case FFEINFO_whereANY:
8318 t = error_mark_node;
8319 break;
8320 }
8321 break;
8322
8323 case FFEINFO_kindSUBROUTINE:
8324 switch (ffeinfo_where (ffesymbol_info (s)))
8325 {
8326 case FFEINFO_whereLOCAL: /* Me. */
8327 assert (!ffecom_transform_only_dummies_);
8328 t = current_function_decl;
8329 break;
5ff904cd 8330
c7e4ee3a
CB
8331 case FFEINFO_whereGLOBAL:
8332 assert (!ffecom_transform_only_dummies_);
5ff904cd 8333
c7e4ee3a
CB
8334 if (((g = ffesymbol_global (s)) != NULL)
8335 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
8336 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
8337 && (ffeglobal_hook (g) != NULL_TREE)
8338 && ffe_is_globals ())
8339 {
8340 t = ffeglobal_hook (g);
8341 break;
8342 }
5ff904cd 8343
c7e4ee3a
CB
8344 t = build_decl (FUNCTION_DECL,
8345 ffecom_get_external_identifier_ (s),
8346 ffecom_tree_subr_type);
8347 DECL_EXTERNAL (t) = 1;
8348 TREE_PUBLIC (t) = 1;
5ff904cd 8349
c7e4ee3a
CB
8350 t = start_decl (t, FALSE);
8351 finish_decl (t, NULL_TREE, FALSE);
5ff904cd 8352
c7e4ee3a
CB
8353 if ((g != NULL)
8354 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
8355 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
8356 ffeglobal_set_hook (g, t);
5ff904cd 8357
7189a4b0 8358 ffecom_save_tree_forever (t);
5ff904cd 8359
c7e4ee3a 8360 break;
5ff904cd 8361
c7e4ee3a
CB
8362 case FFEINFO_whereDUMMY:
8363 assert (ffecom_transform_only_dummies_);
5ff904cd 8364
c7e4ee3a
CB
8365 t = build_decl (PARM_DECL,
8366 ffecom_get_identifier_ (ffesymbol_text (s)),
8367 ffecom_tree_ptr_to_subr_type);
8368#if BUILT_FOR_270
8369 DECL_ARTIFICIAL (t) = 1;
8370#endif
8371 addr = TRUE;
8372 break;
5ff904cd 8373
c7e4ee3a
CB
8374 case FFEINFO_whereINTRINSIC:
8375 assert (!ffecom_transform_only_dummies_);
8376 break; /* Let actual references generate their
8377 decls. */
5ff904cd 8378
c7e4ee3a
CB
8379 default:
8380 assert ("SUBROUTINE where unheard of" == NULL);
8381 /* Fall through. */
8382 case FFEINFO_whereANY:
8383 t = error_mark_node;
8384 break;
8385 }
8386 break;
5ff904cd 8387
c7e4ee3a
CB
8388 case FFEINFO_kindPROGRAM:
8389 switch (ffeinfo_where (ffesymbol_info (s)))
8390 {
8391 case FFEINFO_whereLOCAL: /* Me. */
8392 assert (!ffecom_transform_only_dummies_);
8393 t = current_function_decl;
8394 break;
5ff904cd 8395
c7e4ee3a
CB
8396 case FFEINFO_whereCOMMON:
8397 case FFEINFO_whereDUMMY:
8398 case FFEINFO_whereGLOBAL:
8399 case FFEINFO_whereRESULT:
8400 case FFEINFO_whereFLEETING:
8401 case FFEINFO_whereFLEETING_CADDR:
8402 case FFEINFO_whereFLEETING_IADDR:
8403 case FFEINFO_whereIMMEDIATE:
8404 case FFEINFO_whereINTRINSIC:
8405 case FFEINFO_whereCONSTANT:
8406 case FFEINFO_whereCONSTANT_SUBOBJECT:
8407 default:
8408 assert ("PROGRAM where unheard of" == NULL);
8409 /* Fall through. */
8410 case FFEINFO_whereANY:
8411 t = error_mark_node;
8412 break;
8413 }
8414 break;
5ff904cd 8415
c7e4ee3a
CB
8416 case FFEINFO_kindBLOCKDATA:
8417 switch (ffeinfo_where (ffesymbol_info (s)))
8418 {
8419 case FFEINFO_whereLOCAL: /* Me. */
8420 assert (!ffecom_transform_only_dummies_);
8421 t = current_function_decl;
8422 break;
5ff904cd 8423
c7e4ee3a
CB
8424 case FFEINFO_whereGLOBAL:
8425 assert (!ffecom_transform_only_dummies_);
5ff904cd 8426
c7e4ee3a
CB
8427 t = build_decl (FUNCTION_DECL,
8428 ffecom_get_external_identifier_ (s),
8429 ffecom_tree_blockdata_type);
8430 DECL_EXTERNAL (t) = 1;
8431 TREE_PUBLIC (t) = 1;
5ff904cd 8432
c7e4ee3a
CB
8433 t = start_decl (t, FALSE);
8434 finish_decl (t, NULL_TREE, FALSE);
5ff904cd 8435
7189a4b0 8436 ffecom_save_tree_forever (t);
5ff904cd 8437
c7e4ee3a 8438 break;
5ff904cd 8439
c7e4ee3a
CB
8440 case FFEINFO_whereCOMMON:
8441 case FFEINFO_whereDUMMY:
8442 case FFEINFO_whereRESULT:
8443 case FFEINFO_whereFLEETING:
8444 case FFEINFO_whereFLEETING_CADDR:
8445 case FFEINFO_whereFLEETING_IADDR:
8446 case FFEINFO_whereIMMEDIATE:
8447 case FFEINFO_whereINTRINSIC:
8448 case FFEINFO_whereCONSTANT:
8449 case FFEINFO_whereCONSTANT_SUBOBJECT:
8450 default:
8451 assert ("BLOCKDATA where unheard of" == NULL);
8452 /* Fall through. */
8453 case FFEINFO_whereANY:
8454 t = error_mark_node;
8455 break;
8456 }
8457 break;
5ff904cd 8458
c7e4ee3a
CB
8459 case FFEINFO_kindCOMMON:
8460 switch (ffeinfo_where (ffesymbol_info (s)))
8461 {
8462 case FFEINFO_whereLOCAL:
8463 assert (!ffecom_transform_only_dummies_);
8464 ffecom_transform_common_ (s);
8465 break;
8466
8467 case FFEINFO_whereNONE:
8468 case FFEINFO_whereCOMMON:
8469 case FFEINFO_whereDUMMY:
8470 case FFEINFO_whereGLOBAL:
8471 case FFEINFO_whereRESULT:
8472 case FFEINFO_whereFLEETING:
8473 case FFEINFO_whereFLEETING_CADDR:
8474 case FFEINFO_whereFLEETING_IADDR:
8475 case FFEINFO_whereIMMEDIATE:
8476 case FFEINFO_whereINTRINSIC:
8477 case FFEINFO_whereCONSTANT:
8478 case FFEINFO_whereCONSTANT_SUBOBJECT:
8479 default:
8480 assert ("COMMON where unheard of" == NULL);
8481 /* Fall through. */
8482 case FFEINFO_whereANY:
8483 t = error_mark_node;
8484 break;
8485 }
8486 break;
5ff904cd 8487
c7e4ee3a
CB
8488 case FFEINFO_kindCONSTRUCT:
8489 switch (ffeinfo_where (ffesymbol_info (s)))
8490 {
8491 case FFEINFO_whereLOCAL:
8492 assert (!ffecom_transform_only_dummies_);
8493 break;
5ff904cd 8494
c7e4ee3a
CB
8495 case FFEINFO_whereNONE:
8496 case FFEINFO_whereCOMMON:
8497 case FFEINFO_whereDUMMY:
8498 case FFEINFO_whereGLOBAL:
8499 case FFEINFO_whereRESULT:
8500 case FFEINFO_whereFLEETING:
8501 case FFEINFO_whereFLEETING_CADDR:
8502 case FFEINFO_whereFLEETING_IADDR:
8503 case FFEINFO_whereIMMEDIATE:
8504 case FFEINFO_whereINTRINSIC:
8505 case FFEINFO_whereCONSTANT:
8506 case FFEINFO_whereCONSTANT_SUBOBJECT:
8507 default:
8508 assert ("CONSTRUCT where unheard of" == NULL);
8509 /* Fall through. */
8510 case FFEINFO_whereANY:
8511 t = error_mark_node;
8512 break;
8513 }
8514 break;
5ff904cd 8515
c7e4ee3a
CB
8516 case FFEINFO_kindNAMELIST:
8517 switch (ffeinfo_where (ffesymbol_info (s)))
8518 {
8519 case FFEINFO_whereLOCAL:
8520 assert (!ffecom_transform_only_dummies_);
8521 t = ffecom_transform_namelist_ (s);
8522 break;
5ff904cd 8523
c7e4ee3a
CB
8524 case FFEINFO_whereNONE:
8525 case FFEINFO_whereCOMMON:
8526 case FFEINFO_whereDUMMY:
8527 case FFEINFO_whereGLOBAL:
8528 case FFEINFO_whereRESULT:
8529 case FFEINFO_whereFLEETING:
8530 case FFEINFO_whereFLEETING_CADDR:
8531 case FFEINFO_whereFLEETING_IADDR:
8532 case FFEINFO_whereIMMEDIATE:
8533 case FFEINFO_whereINTRINSIC:
8534 case FFEINFO_whereCONSTANT:
8535 case FFEINFO_whereCONSTANT_SUBOBJECT:
8536 default:
8537 assert ("NAMELIST where unheard of" == NULL);
8538 /* Fall through. */
8539 case FFEINFO_whereANY:
8540 t = error_mark_node;
8541 break;
8542 }
8543 break;
5ff904cd 8544
c7e4ee3a
CB
8545 default:
8546 assert ("kind unheard of" == NULL);
8547 /* Fall through. */
8548 case FFEINFO_kindANY:
8549 t = error_mark_node;
8550 break;
8551 }
5ff904cd 8552
c7e4ee3a
CB
8553 ffesymbol_hook (s).decl_tree = t;
8554 ffesymbol_hook (s).length_tree = tlen;
8555 ffesymbol_hook (s).addr = addr;
5ff904cd 8556
c7e4ee3a
CB
8557 lineno = old_lineno;
8558 input_filename = old_input_filename;
5ff904cd 8559
c7e4ee3a
CB
8560 return s;
8561}
5ff904cd 8562
5ff904cd 8563#endif
c7e4ee3a 8564/* Transform into ASSIGNable symbol.
5ff904cd 8565
c7e4ee3a
CB
8566 Symbol has already been transformed, but for whatever reason, the
8567 resulting decl_tree has been deemed not usable for an ASSIGN target.
8568 (E.g. it isn't wide enough to hold a pointer.) So, here we invent
8569 another local symbol of type void * and stuff that in the assign_tree
8570 argument. The F77/F90 standards allow this implementation. */
5ff904cd 8571
c7e4ee3a
CB
8572#if FFECOM_targetCURRENT == FFECOM_targetGCC
8573static ffesymbol
8574ffecom_sym_transform_assign_ (ffesymbol s)
8575{
8576 tree t; /* Transformed thingy. */
8577 int yes;
8578 int old_lineno = lineno;
8579 char *old_input_filename = input_filename;
5ff904cd 8580
c7e4ee3a
CB
8581 if (ffesymbol_sfdummyparent (s) == NULL)
8582 {
8583 input_filename = ffesymbol_where_filename (s);
8584 lineno = ffesymbol_where_filelinenum (s);
8585 }
8586 else
8587 {
8588 ffesymbol sf = ffesymbol_sfdummyparent (s);
5ff904cd 8589
c7e4ee3a
CB
8590 input_filename = ffesymbol_where_filename (sf);
8591 lineno = ffesymbol_where_filelinenum (sf);
8592 }
5ff904cd 8593
c7e4ee3a 8594 assert (!ffecom_transform_only_dummies_);
5ff904cd 8595
c7e4ee3a 8596 yes = suspend_momentary ();
5ff904cd 8597
c7e4ee3a
CB
8598 t = build_decl (VAR_DECL,
8599 ffecom_get_invented_identifier ("__g77_ASSIGN_%s",
14657de8 8600 ffesymbol_text (s)),
c7e4ee3a 8601 TREE_TYPE (null_pointer_node));
5ff904cd 8602
c7e4ee3a
CB
8603 switch (ffesymbol_where (s))
8604 {
8605 case FFEINFO_whereLOCAL:
8606 /* Unlike for regular vars, SAVE status is easy to determine for
8607 ASSIGNed vars, since there's no initialization, there's no
8608 effective storage association (so "SAVE J" does not apply to
8609 K even given "EQUIVALENCE (J,K)"), there's no size issue
8610 to worry about, etc. */
8611 if ((ffesymbol_is_save (s) || ffe_is_saveall ())
8612 && (ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
8613 && (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA))
8614 TREE_STATIC (t) = 1; /* SAVEd in proc, make static. */
8615 else
8616 TREE_STATIC (t) = 0; /* No need to make static. */
8617 break;
5ff904cd 8618
c7e4ee3a
CB
8619 case FFEINFO_whereCOMMON:
8620 TREE_STATIC (t) = 1; /* Assume COMMONs always SAVEd. */
8621 break;
5ff904cd 8622
c7e4ee3a
CB
8623 case FFEINFO_whereDUMMY:
8624 /* Note that twinning a DUMMY means the caller won't see
8625 the ASSIGNed value. But both F77 and F90 allow implementations
8626 to do this, i.e. disallow Fortran code that would try and
8627 take advantage of actually putting a label into a variable
8628 via a dummy argument (or any other storage association, for
8629 that matter). */
8630 TREE_STATIC (t) = 0;
8631 break;
5ff904cd 8632
c7e4ee3a
CB
8633 default:
8634 TREE_STATIC (t) = 0;
8635 break;
8636 }
5ff904cd 8637
c7e4ee3a
CB
8638 t = start_decl (t, FALSE);
8639 finish_decl (t, NULL_TREE, FALSE);
5ff904cd 8640
c7e4ee3a 8641 resume_momentary (yes);
5ff904cd 8642
c7e4ee3a 8643 ffesymbol_hook (s).assign_tree = t;
5ff904cd 8644
c7e4ee3a
CB
8645 lineno = old_lineno;
8646 input_filename = old_input_filename;
5ff904cd 8647
c7e4ee3a
CB
8648 return s;
8649}
5ff904cd 8650
c7e4ee3a
CB
8651#endif
8652/* Implement COMMON area in back end.
5ff904cd 8653
c7e4ee3a
CB
8654 Because COMMON-based variables can be referenced in the dimension
8655 expressions of dummy (adjustable) arrays, and because dummies
8656 (in the gcc back end) need to be put in the outer binding level
8657 of a function (which has two binding levels, the outer holding
8658 the dummies and the inner holding the other vars), special care
8659 must be taken to handle COMMON areas.
5ff904cd 8660
c7e4ee3a
CB
8661 The current strategy is basically to always tell the back end about
8662 the COMMON area as a top-level external reference to just a block
8663 of storage of the master type of that area (e.g. integer, real,
8664 character, whatever -- not a structure). As a distinct action,
8665 if initial values are provided, tell the back end about the area
8666 as a top-level non-external (initialized) area and remember not to
8667 allow further initialization or expansion of the area. Meanwhile,
8668 if no initialization happens at all, tell the back end about
8669 the largest size we've seen declared so the space does get reserved.
8670 (This function doesn't handle all that stuff, but it does some
8671 of the important things.)
5ff904cd 8672
c7e4ee3a
CB
8673 Meanwhile, for COMMON variables themselves, just keep creating
8674 references like *((float *) (&common_area + offset)) each time
8675 we reference the variable. In other words, don't make a VAR_DECL
8676 or any kind of component reference (like we used to do before 0.4),
8677 though we might do that as well just for debugging purposes (and
8678 stuff the rtl with the appropriate offset expression). */
5ff904cd 8679
c7e4ee3a
CB
8680#if FFECOM_targetCURRENT == FFECOM_targetGCC
8681static void
8682ffecom_transform_common_ (ffesymbol s)
8683{
8684 ffestorag st = ffesymbol_storage (s);
8685 ffeglobal g = ffesymbol_global (s);
8686 tree cbt;
8687 tree cbtype;
8688 tree init;
8689 tree high;
8690 bool is_init = ffestorag_is_init (st);
5ff904cd 8691
c7e4ee3a 8692 assert (st != NULL);
5ff904cd 8693
c7e4ee3a
CB
8694 if ((g == NULL)
8695 || (ffeglobal_type (g) != FFEGLOBAL_typeCOMMON))
8696 return;
5ff904cd 8697
c7e4ee3a 8698 /* First update the size of the area in global terms. */
5ff904cd 8699
c7e4ee3a 8700 ffeglobal_size_common (s, ffestorag_size (st));
5ff904cd 8701
c7e4ee3a
CB
8702 if (!ffeglobal_common_init (g))
8703 is_init = FALSE; /* No explicit init, don't let erroneous joins init. */
5ff904cd 8704
c7e4ee3a 8705 cbt = ffeglobal_hook (g);
5ff904cd 8706
c7e4ee3a
CB
8707 /* If we already have declared this common block for a previous program
8708 unit, and either we already initialized it or we don't have new
8709 initialization for it, just return what we have without changing it. */
5ff904cd 8710
c7e4ee3a
CB
8711 if ((cbt != NULL_TREE)
8712 && (!is_init
8713 || !DECL_EXTERNAL (cbt)))
b7a80862
AV
8714 {
8715 if (st->hook == NULL) ffestorag_set_hook (st, cbt);
8716 return;
8717 }
5ff904cd 8718
c7e4ee3a 8719 /* Process inits. */
5ff904cd 8720
c7e4ee3a
CB
8721 if (is_init)
8722 {
8723 if (ffestorag_init (st) != NULL)
5ff904cd 8724 {
c7e4ee3a 8725 ffebld sexp;
5ff904cd 8726
c7e4ee3a
CB
8727 /* Set the padding for the expression, so ffecom_expr
8728 knows to insert that many zeros. */
8729 switch (ffebld_op (sexp = ffestorag_init (st)))
5ff904cd 8730 {
c7e4ee3a
CB
8731 case FFEBLD_opCONTER:
8732 ffebld_conter_set_pad (sexp, ffestorag_modulo (st));
5ff904cd 8733 break;
5ff904cd 8734
c7e4ee3a
CB
8735 case FFEBLD_opARRTER:
8736 ffebld_arrter_set_pad (sexp, ffestorag_modulo (st));
8737 break;
5ff904cd 8738
c7e4ee3a
CB
8739 case FFEBLD_opACCTER:
8740 ffebld_accter_set_pad (sexp, ffestorag_modulo (st));
8741 break;
5ff904cd 8742
c7e4ee3a
CB
8743 default:
8744 assert ("bad op for cmn init (pad)" == NULL);
8745 break;
8746 }
5ff904cd 8747
c7e4ee3a
CB
8748 init = ffecom_expr (sexp);
8749 if (init == error_mark_node)
8750 { /* Hopefully the back end complained! */
8751 init = NULL_TREE;
8752 if (cbt != NULL_TREE)
8753 return;
8754 }
8755 }
8756 else
8757 init = error_mark_node;
8758 }
8759 else
8760 init = NULL_TREE;
5ff904cd 8761
c7e4ee3a 8762 /* cbtype must be permanently allocated! */
5ff904cd 8763
c7e4ee3a
CB
8764 /* Allocate the MAX of the areas so far, seen filewide. */
8765 high = build_int_2 ((ffeglobal_common_size (g)
8766 + ffeglobal_common_pad (g)) - 1, 0);
8767 TREE_TYPE (high) = ffecom_integer_type_node;
5ff904cd 8768
c7e4ee3a
CB
8769 if (init)
8770 cbtype = build_array_type (char_type_node,
8771 build_range_type (integer_type_node,
8772 integer_zero_node,
8773 high));
8774 else
8775 cbtype = build_array_type (char_type_node, NULL_TREE);
5ff904cd 8776
c7e4ee3a
CB
8777 if (cbt == NULL_TREE)
8778 {
8779 cbt
8780 = build_decl (VAR_DECL,
8781 ffecom_get_external_identifier_ (s),
8782 cbtype);
8783 TREE_STATIC (cbt) = 1;
8784 TREE_PUBLIC (cbt) = 1;
8785 }
8786 else
8787 {
8788 assert (is_init);
8789 TREE_TYPE (cbt) = cbtype;
8790 }
8791 DECL_EXTERNAL (cbt) = init ? 0 : 1;
8792 DECL_INITIAL (cbt) = init ? error_mark_node : NULL_TREE;
5ff904cd 8793
c7e4ee3a
CB
8794 cbt = start_decl (cbt, TRUE);
8795 if (ffeglobal_hook (g) != NULL)
8796 assert (cbt == ffeglobal_hook (g));
5ff904cd 8797
c7e4ee3a 8798 assert (!init || !DECL_EXTERNAL (cbt));
5ff904cd 8799
c7e4ee3a
CB
8800 /* Make sure that any type can live in COMMON and be referenced
8801 without getting a bus error. We could pick the most restrictive
8802 alignment of all entities actually placed in the COMMON, but
8803 this seems easy enough. */
5ff904cd 8804
c7e4ee3a 8805 DECL_ALIGN (cbt) = BIGGEST_ALIGNMENT;
5ff904cd 8806
c7e4ee3a
CB
8807 if (is_init && (ffestorag_init (st) == NULL))
8808 init = ffecom_init_zero_ (cbt);
5ff904cd 8809
c7e4ee3a 8810 finish_decl (cbt, init, TRUE);
5ff904cd 8811
c7e4ee3a
CB
8812 if (is_init)
8813 ffestorag_set_init (st, ffebld_new_any ());
5ff904cd 8814
c7e4ee3a
CB
8815 if (init)
8816 {
06ceef4e
RK
8817 assert (DECL_SIZE_UNIT (cbt) != NULL_TREE);
8818 assert (TREE_CODE (DECL_SIZE_UNIT (cbt)) == INTEGER_CST);
05bccae2
RK
8819 assert (0 == compare_tree_int (DECL_SIZE_UNIT (cbt),
8820 (ffeglobal_common_size (g)
8821 + ffeglobal_common_pad (g))));
c7e4ee3a 8822 }
5ff904cd 8823
c7e4ee3a 8824 ffeglobal_set_hook (g, cbt);
5ff904cd 8825
c7e4ee3a 8826 ffestorag_set_hook (st, cbt);
5ff904cd 8827
7189a4b0 8828 ffecom_save_tree_forever (cbt);
c7e4ee3a 8829}
5ff904cd 8830
c7e4ee3a
CB
8831#endif
8832/* Make master area for local EQUIVALENCE. */
5ff904cd 8833
c7e4ee3a
CB
8834#if FFECOM_targetCURRENT == FFECOM_targetGCC
8835static void
8836ffecom_transform_equiv_ (ffestorag eqst)
8837{
8838 tree eqt;
8839 tree eqtype;
8840 tree init;
8841 tree high;
8842 bool is_init = ffestorag_is_init (eqst);
8843 int yes;
5ff904cd 8844
c7e4ee3a 8845 assert (eqst != NULL);
5ff904cd 8846
c7e4ee3a 8847 eqt = ffestorag_hook (eqst);
5ff904cd 8848
c7e4ee3a
CB
8849 if (eqt != NULL_TREE)
8850 return;
5ff904cd 8851
c7e4ee3a
CB
8852 /* Process inits. */
8853
8854 if (is_init)
8855 {
8856 if (ffestorag_init (eqst) != NULL)
5ff904cd 8857 {
c7e4ee3a 8858 ffebld sexp;
5ff904cd 8859
c7e4ee3a
CB
8860 /* Set the padding for the expression, so ffecom_expr
8861 knows to insert that many zeros. */
8862 switch (ffebld_op (sexp = ffestorag_init (eqst)))
8863 {
8864 case FFEBLD_opCONTER:
8865 ffebld_conter_set_pad (sexp, ffestorag_modulo (eqst));
8866 break;
5ff904cd 8867
c7e4ee3a
CB
8868 case FFEBLD_opARRTER:
8869 ffebld_arrter_set_pad (sexp, ffestorag_modulo (eqst));
8870 break;
5ff904cd 8871
c7e4ee3a
CB
8872 case FFEBLD_opACCTER:
8873 ffebld_accter_set_pad (sexp, ffestorag_modulo (eqst));
8874 break;
5ff904cd 8875
c7e4ee3a
CB
8876 default:
8877 assert ("bad op for eqv init (pad)" == NULL);
8878 break;
8879 }
5ff904cd 8880
c7e4ee3a
CB
8881 init = ffecom_expr (sexp);
8882 if (init == error_mark_node)
8883 init = NULL_TREE; /* Hopefully the back end complained! */
8884 }
8885 else
8886 init = error_mark_node;
8887 }
8888 else if (ffe_is_init_local_zero ())
8889 init = error_mark_node;
8890 else
8891 init = NULL_TREE;
5ff904cd 8892
c7e4ee3a
CB
8893 ffecom_member_namelisted_ = FALSE;
8894 ffestorag_drive (ffestorag_list_equivs (eqst),
8895 &ffecom_member_phase1_,
8896 eqst);
5ff904cd 8897
c7e4ee3a 8898 yes = suspend_momentary ();
5ff904cd 8899
c7e4ee3a
CB
8900 high = build_int_2 ((ffestorag_size (eqst)
8901 + ffestorag_modulo (eqst)) - 1, 0);
8902 TREE_TYPE (high) = ffecom_integer_type_node;
5ff904cd 8903
c7e4ee3a
CB
8904 eqtype = build_array_type (char_type_node,
8905 build_range_type (ffecom_integer_type_node,
8906 ffecom_integer_zero_node,
8907 high));
8908
8909 eqt = build_decl (VAR_DECL,
8910 ffecom_get_invented_identifier ("__g77_equiv_%s",
8911 ffesymbol_text
14657de8 8912 (ffestorag_symbol (eqst))),
c7e4ee3a
CB
8913 eqtype);
8914 DECL_EXTERNAL (eqt) = 0;
8915 if (is_init
8916 || ffecom_member_namelisted_
8917#ifdef FFECOM_sizeMAXSTACKITEM
8918 || (ffestorag_size (eqst) > FFECOM_sizeMAXSTACKITEM)
8919#endif
8920 || ((ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
8921 && (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA)
8922 && (ffestorag_is_save (eqst) || ffe_is_saveall ())))
8923 TREE_STATIC (eqt) = 1;
8924 else
8925 TREE_STATIC (eqt) = 0;
8926 TREE_PUBLIC (eqt) = 0;
8927 DECL_CONTEXT (eqt) = current_function_decl;
8928 if (init)
8929 DECL_INITIAL (eqt) = error_mark_node;
8930 else
8931 DECL_INITIAL (eqt) = NULL_TREE;
5ff904cd 8932
c7e4ee3a 8933 eqt = start_decl (eqt, FALSE);
5ff904cd 8934
c7e4ee3a
CB
8935 /* Make sure that any type can live in EQUIVALENCE and be referenced
8936 without getting a bus error. We could pick the most restrictive
8937 alignment of all entities actually placed in the EQUIVALENCE, but
8938 this seems easy enough. */
5ff904cd 8939
c7e4ee3a 8940 DECL_ALIGN (eqt) = BIGGEST_ALIGNMENT;
5ff904cd 8941
c7e4ee3a
CB
8942 if ((!is_init && ffe_is_init_local_zero ())
8943 || (is_init && (ffestorag_init (eqst) == NULL)))
8944 init = ffecom_init_zero_ (eqt);
5ff904cd 8945
c7e4ee3a 8946 finish_decl (eqt, init, FALSE);
5ff904cd 8947
c7e4ee3a
CB
8948 if (is_init)
8949 ffestorag_set_init (eqst, ffebld_new_any ());
5ff904cd 8950
c7e4ee3a 8951 {
06ceef4e 8952 assert (TREE_CODE (DECL_SIZE_UNIT (eqt)) == INTEGER_CST);
05bccae2
RK
8953 assert (0 == compare_tree_int (DECL_SIZE_UNIT (eqt),
8954 (ffestorag_size (eqst)
8955 + ffestorag_modulo (eqst))));
c7e4ee3a 8956 }
5ff904cd 8957
c7e4ee3a 8958 ffestorag_set_hook (eqst, eqt);
5ff904cd 8959
c7e4ee3a
CB
8960#ifdef SOMEONE_GETS_DEBUG_SUPPORT_WORKING
8961 ffestorag_drive (ffestorag_list_equivs (eqst),
8962 &ffecom_member_phase2_,
8963 eqst);
8964#endif
8965
8966 resume_momentary (yes);
5ff904cd
JL
8967}
8968
8969#endif
c7e4ee3a 8970/* Implement NAMELIST in back end. See f2c/format.c for more info. */
5ff904cd
JL
8971
8972#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
8973static tree
8974ffecom_transform_namelist_ (ffesymbol s)
5ff904cd 8975{
c7e4ee3a
CB
8976 tree nmlt;
8977 tree nmltype = ffecom_type_namelist_ ();
8978 tree nmlinits;
8979 tree nameinit;
8980 tree varsinit;
8981 tree nvarsinit;
8982 tree field;
8983 tree high;
5ff904cd 8984 int yes;
c7e4ee3a
CB
8985 int i;
8986 static int mynumber = 0;
5ff904cd 8987
c7e4ee3a 8988 yes = suspend_momentary ();
5ff904cd 8989
c7e4ee3a
CB
8990 nmlt = build_decl (VAR_DECL,
8991 ffecom_get_invented_identifier ("__g77_namelist_%d",
14657de8 8992 mynumber++),
c7e4ee3a
CB
8993 nmltype);
8994 TREE_STATIC (nmlt) = 1;
8995 DECL_INITIAL (nmlt) = error_mark_node;
5ff904cd 8996
c7e4ee3a 8997 nmlt = start_decl (nmlt, FALSE);
5ff904cd 8998
c7e4ee3a 8999 /* Process inits. */
5ff904cd 9000
c7e4ee3a 9001 i = strlen (ffesymbol_text (s));
5ff904cd 9002
c7e4ee3a
CB
9003 high = build_int_2 (i, 0);
9004 TREE_TYPE (high) = ffecom_f2c_ftnlen_type_node;
9005
9006 nameinit = ffecom_build_f2c_string_ (i + 1,
9007 ffesymbol_text (s));
9008 TREE_TYPE (nameinit)
9009 = build_type_variant
9010 (build_array_type
9011 (char_type_node,
9012 build_range_type (ffecom_f2c_ftnlen_type_node,
9013 ffecom_f2c_ftnlen_one_node,
9014 high)),
9015 1, 0);
9016 TREE_CONSTANT (nameinit) = 1;
9017 TREE_STATIC (nameinit) = 1;
9018 nameinit = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (nameinit)),
9019 nameinit);
9020
9021 varsinit = ffecom_vardesc_array_ (s);
9022 varsinit = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (varsinit)),
9023 varsinit);
9024 TREE_CONSTANT (varsinit) = 1;
9025 TREE_STATIC (varsinit) = 1;
9026
9027 {
9028 ffebld b;
9029
9030 for (i = 0, b = ffesymbol_namelist (s); b != NULL; b = ffebld_trail (b))
9031 ++i;
9032 }
9033 nvarsinit = build_int_2 (i, 0);
9034 TREE_TYPE (nvarsinit) = integer_type_node;
9035 TREE_CONSTANT (nvarsinit) = 1;
9036 TREE_STATIC (nvarsinit) = 1;
9037
9038 nmlinits = build_tree_list ((field = TYPE_FIELDS (nmltype)), nameinit);
9039 TREE_CHAIN (nmlinits) = build_tree_list ((field = TREE_CHAIN (field)),
9040 varsinit);
9041 TREE_CHAIN (TREE_CHAIN (nmlinits))
9042 = build_tree_list ((field = TREE_CHAIN (field)), nvarsinit);
9043
9044 nmlinits = build (CONSTRUCTOR, nmltype, NULL_TREE, nmlinits);
9045 TREE_CONSTANT (nmlinits) = 1;
9046 TREE_STATIC (nmlinits) = 1;
9047
9048 finish_decl (nmlt, nmlinits, FALSE);
9049
9050 nmlt = ffecom_1 (ADDR_EXPR, build_pointer_type (nmltype), nmlt);
9051
9052 resume_momentary (yes);
9053
9054 return nmlt;
9055}
9056
9057#endif
9058
9059/* A subroutine of ffecom_tree_canonize_ref_. The incoming tree is
9060 analyzed on the assumption it is calculating a pointer to be
9061 indirected through. It must return the proper decl and offset,
9062 taking into account different units of measurements for offsets. */
9063
9064#if FFECOM_targetCURRENT == FFECOM_targetGCC
9065static void
9066ffecom_tree_canonize_ptr_ (tree *decl, tree *offset,
9067 tree t)
9068{
9069 switch (TREE_CODE (t))
9070 {
9071 case NOP_EXPR:
9072 case CONVERT_EXPR:
9073 case NON_LVALUE_EXPR:
9074 ffecom_tree_canonize_ptr_ (decl, offset, TREE_OPERAND (t, 0));
5ff904cd
JL
9075 break;
9076
c7e4ee3a
CB
9077 case PLUS_EXPR:
9078 ffecom_tree_canonize_ptr_ (decl, offset, TREE_OPERAND (t, 0));
9079 if ((*decl == NULL_TREE)
9080 || (*decl == error_mark_node))
9081 break;
9082
9083 if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST)
9084 {
9085 /* An offset into COMMON. */
fed3cef0
RK
9086 *offset = fold (build (PLUS_EXPR, TREE_TYPE (*offset),
9087 *offset, TREE_OPERAND (t, 1)));
c7e4ee3a
CB
9088 /* Convert offset (presumably in bytes) into canonical units
9089 (presumably bits). */
fed3cef0
RK
9090 *offset = fold (build (MULT_EXPR, TREE_TYPE (*offset),
9091 TYPE_SIZE (TREE_TYPE (TREE_TYPE (t))),
9092 *offset));
c7e4ee3a
CB
9093 break;
9094 }
9095 /* Not a COMMON reference, so an unrecognized pattern. */
9096 *decl = error_mark_node;
5ff904cd
JL
9097 break;
9098
c7e4ee3a
CB
9099 case PARM_DECL:
9100 *decl = t;
06ceef4e 9101 *offset = bitsize_int (0);
5ff904cd
JL
9102 break;
9103
c7e4ee3a
CB
9104 case ADDR_EXPR:
9105 if (TREE_CODE (TREE_OPERAND (t, 0)) == VAR_DECL)
9106 {
9107 /* A reference to COMMON. */
9108 *decl = TREE_OPERAND (t, 0);
06ceef4e 9109 *offset = bitsize_int (0);
c7e4ee3a
CB
9110 break;
9111 }
9112 /* Fall through. */
5ff904cd 9113 default:
c7e4ee3a
CB
9114 /* Not a COMMON reference, so an unrecognized pattern. */
9115 *decl = error_mark_node;
5ff904cd
JL
9116 break;
9117 }
c7e4ee3a
CB
9118}
9119#endif
5ff904cd 9120
c7e4ee3a
CB
9121/* Given a tree that is possibly intended for use as an lvalue, return
9122 information representing a canonical view of that tree as a decl, an
9123 offset into that decl, and a size for the lvalue.
5ff904cd 9124
c7e4ee3a
CB
9125 If there's no applicable decl, NULL_TREE is returned for the decl,
9126 and the other fields are left undefined.
5ff904cd 9127
c7e4ee3a
CB
9128 If the tree doesn't fit the recognizable forms, an ERROR_MARK node
9129 is returned for the decl, and the other fields are left undefined.
5ff904cd 9130
c7e4ee3a
CB
9131 Otherwise, the decl returned currently is either a VAR_DECL or a
9132 PARM_DECL.
5ff904cd 9133
c7e4ee3a
CB
9134 The offset returned is always valid, but of course not necessarily
9135 a constant, and not necessarily converted into the appropriate
9136 type, leaving that up to the caller (so as to avoid that overhead
9137 if the decls being looked at are different anyway).
5ff904cd 9138
c7e4ee3a
CB
9139 If the size cannot be determined (e.g. an adjustable array),
9140 an ERROR_MARK node is returned for the size. Otherwise, the
9141 size returned is valid, not necessarily a constant, and not
9142 necessarily converted into the appropriate type as with the
9143 offset.
5ff904cd 9144
c7e4ee3a
CB
9145 Note that the offset and size expressions are expressed in the
9146 base storage units (usually bits) rather than in the units of
9147 the type of the decl, because two decls with different types
9148 might overlap but with apparently non-overlapping array offsets,
9149 whereas converting the array offsets to consistant offsets will
9150 reveal the overlap. */
5ff904cd
JL
9151
9152#if FFECOM_targetCURRENT == FFECOM_targetGCC
9153static void
c7e4ee3a
CB
9154ffecom_tree_canonize_ref_ (tree *decl, tree *offset,
9155 tree *size, tree t)
5ff904cd 9156{
c7e4ee3a
CB
9157 /* The default path is to report a nonexistant decl. */
9158 *decl = NULL_TREE;
5ff904cd 9159
c7e4ee3a 9160 if (t == NULL_TREE)
5ff904cd
JL
9161 return;
9162
c7e4ee3a
CB
9163 switch (TREE_CODE (t))
9164 {
9165 case ERROR_MARK:
9166 case IDENTIFIER_NODE:
9167 case INTEGER_CST:
9168 case REAL_CST:
9169 case COMPLEX_CST:
9170 case STRING_CST:
9171 case CONST_DECL:
9172 case PLUS_EXPR:
9173 case MINUS_EXPR:
9174 case MULT_EXPR:
9175 case TRUNC_DIV_EXPR:
9176 case CEIL_DIV_EXPR:
9177 case FLOOR_DIV_EXPR:
9178 case ROUND_DIV_EXPR:
9179 case TRUNC_MOD_EXPR:
9180 case CEIL_MOD_EXPR:
9181 case FLOOR_MOD_EXPR:
9182 case ROUND_MOD_EXPR:
9183 case RDIV_EXPR:
9184 case EXACT_DIV_EXPR:
9185 case FIX_TRUNC_EXPR:
9186 case FIX_CEIL_EXPR:
9187 case FIX_FLOOR_EXPR:
9188 case FIX_ROUND_EXPR:
9189 case FLOAT_EXPR:
9190 case EXPON_EXPR:
9191 case NEGATE_EXPR:
9192 case MIN_EXPR:
9193 case MAX_EXPR:
9194 case ABS_EXPR:
9195 case FFS_EXPR:
9196 case LSHIFT_EXPR:
9197 case RSHIFT_EXPR:
9198 case LROTATE_EXPR:
9199 case RROTATE_EXPR:
9200 case BIT_IOR_EXPR:
9201 case BIT_XOR_EXPR:
9202 case BIT_AND_EXPR:
9203 case BIT_ANDTC_EXPR:
9204 case BIT_NOT_EXPR:
9205 case TRUTH_ANDIF_EXPR:
9206 case TRUTH_ORIF_EXPR:
9207 case TRUTH_AND_EXPR:
9208 case TRUTH_OR_EXPR:
9209 case TRUTH_XOR_EXPR:
9210 case TRUTH_NOT_EXPR:
9211 case LT_EXPR:
9212 case LE_EXPR:
9213 case GT_EXPR:
9214 case GE_EXPR:
9215 case EQ_EXPR:
9216 case NE_EXPR:
9217 case COMPLEX_EXPR:
9218 case CONJ_EXPR:
9219 case REALPART_EXPR:
9220 case IMAGPART_EXPR:
9221 case LABEL_EXPR:
9222 case COMPONENT_REF:
9223 case COMPOUND_EXPR:
9224 case ADDR_EXPR:
9225 return;
5ff904cd 9226
c7e4ee3a
CB
9227 case VAR_DECL:
9228 case PARM_DECL:
9229 *decl = t;
06ceef4e 9230 *offset = bitsize_int (0);
c7e4ee3a
CB
9231 *size = TYPE_SIZE (TREE_TYPE (t));
9232 return;
5ff904cd 9233
c7e4ee3a
CB
9234 case ARRAY_REF:
9235 {
9236 tree array = TREE_OPERAND (t, 0);
9237 tree element = TREE_OPERAND (t, 1);
9238 tree init_offset;
9239
9240 if ((array == NULL_TREE)
9241 || (element == NULL_TREE))
9242 {
9243 *decl = error_mark_node;
9244 return;
9245 }
9246
9247 ffecom_tree_canonize_ref_ (decl, &init_offset, size,
9248 array);
9249 if ((*decl == NULL_TREE)
9250 || (*decl == error_mark_node))
9251 return;
9252
fed3cef0
RK
9253 *offset
9254 = size_binop (MULT_EXPR,
9255 TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))),
9256 convert (sizetype,
9257 fold (build (MINUS_EXPR, TREE_TYPE (element),
9258 element,
9259 TYPE_MIN_VALUE
9260 (TYPE_DOMAIN
9261 (TREE_TYPE (array)))))));;
9262
9263 *offset = size_binop (PLUS_EXPR, convert (sizetype, init_offset),
c7e4ee3a
CB
9264 *offset);
9265
9266 *size = TYPE_SIZE (TREE_TYPE (t));
9267 return;
9268 }
9269
9270 case INDIRECT_REF:
9271
9272 /* Most of this code is to handle references to COMMON. And so
9273 far that is useful only for calling library functions, since
9274 external (user) functions might reference common areas. But
9275 even calling an external function, it's worthwhile to decode
9276 COMMON references because if not storing into COMMON, we don't
9277 want COMMON-based arguments to gratuitously force use of a
9278 temporary. */
9279
9280 *size = TYPE_SIZE (TREE_TYPE (t));
5ff904cd 9281
c7e4ee3a
CB
9282 ffecom_tree_canonize_ptr_ (decl, offset,
9283 TREE_OPERAND (t, 0));
5ff904cd 9284
c7e4ee3a 9285 return;
5ff904cd 9286
c7e4ee3a
CB
9287 case CONVERT_EXPR:
9288 case NOP_EXPR:
9289 case MODIFY_EXPR:
9290 case NON_LVALUE_EXPR:
9291 case RESULT_DECL:
9292 case FIELD_DECL:
9293 case COND_EXPR: /* More cases than we can handle. */
9294 case SAVE_EXPR:
9295 case REFERENCE_EXPR:
9296 case PREDECREMENT_EXPR:
9297 case PREINCREMENT_EXPR:
9298 case POSTDECREMENT_EXPR:
9299 case POSTINCREMENT_EXPR:
9300 case CALL_EXPR:
9301 default:
9302 *decl = error_mark_node;
9303 return;
9304 }
9305}
9306#endif
5ff904cd 9307
c7e4ee3a 9308/* Do divide operation appropriate to type of operands. */
5ff904cd 9309
c7e4ee3a
CB
9310#if FFECOM_targetCURRENT == FFECOM_targetGCC
9311static tree
9312ffecom_tree_divide_ (tree tree_type, tree left, tree right,
9313 tree dest_tree, ffebld dest, bool *dest_used,
9314 tree hook)
9315{
9316 if ((left == error_mark_node)
9317 || (right == error_mark_node))
9318 return error_mark_node;
a6fa6420 9319
c7e4ee3a
CB
9320 switch (TREE_CODE (tree_type))
9321 {
9322 case INTEGER_TYPE:
9323 return ffecom_2 (TRUNC_DIV_EXPR, tree_type,
9324 left,
9325 right);
a6fa6420 9326
c7e4ee3a 9327 case COMPLEX_TYPE:
c64f913e
CB
9328 if (! optimize_size)
9329 return ffecom_2 (RDIV_EXPR, tree_type,
9330 left,
9331 right);
c7e4ee3a
CB
9332 {
9333 ffecomGfrt ix;
a6fa6420 9334
c7e4ee3a
CB
9335 if (TREE_TYPE (tree_type)
9336 == ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1])
9337 ix = FFECOM_gfrtDIV_CC; /* Overlapping result okay. */
9338 else
9339 ix = FFECOM_gfrtDIV_ZZ; /* Overlapping result okay. */
a6fa6420 9340
c7e4ee3a
CB
9341 left = ffecom_1 (ADDR_EXPR,
9342 build_pointer_type (TREE_TYPE (left)),
9343 left);
9344 left = build_tree_list (NULL_TREE, left);
9345 right = ffecom_1 (ADDR_EXPR,
9346 build_pointer_type (TREE_TYPE (right)),
9347 right);
9348 right = build_tree_list (NULL_TREE, right);
9349 TREE_CHAIN (left) = right;
a6fa6420 9350
c7e4ee3a
CB
9351 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
9352 ffecom_gfrt_kindtype (ix),
9353 ffe_is_f2c_library (),
9354 tree_type,
9355 left,
9356 dest_tree, dest, dest_used,
9357 NULL_TREE, TRUE, hook);
9358 }
9359 break;
5ff904cd 9360
c7e4ee3a
CB
9361 case RECORD_TYPE:
9362 {
9363 ffecomGfrt ix;
5ff904cd 9364
c7e4ee3a
CB
9365 if (TREE_TYPE (TYPE_FIELDS (tree_type))
9366 == ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1])
9367 ix = FFECOM_gfrtDIV_CC; /* Overlapping result okay. */
9368 else
9369 ix = FFECOM_gfrtDIV_ZZ; /* Overlapping result okay. */
5ff904cd 9370
c7e4ee3a
CB
9371 left = ffecom_1 (ADDR_EXPR,
9372 build_pointer_type (TREE_TYPE (left)),
9373 left);
9374 left = build_tree_list (NULL_TREE, left);
9375 right = ffecom_1 (ADDR_EXPR,
9376 build_pointer_type (TREE_TYPE (right)),
9377 right);
9378 right = build_tree_list (NULL_TREE, right);
9379 TREE_CHAIN (left) = right;
a6fa6420 9380
c7e4ee3a
CB
9381 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
9382 ffecom_gfrt_kindtype (ix),
9383 ffe_is_f2c_library (),
9384 tree_type,
9385 left,
9386 dest_tree, dest, dest_used,
9387 NULL_TREE, TRUE, hook);
9388 }
9389 break;
5ff904cd 9390
c7e4ee3a
CB
9391 default:
9392 return ffecom_2 (RDIV_EXPR, tree_type,
9393 left,
9394 right);
5ff904cd 9395 }
c7e4ee3a 9396}
5ff904cd 9397
c7e4ee3a
CB
9398#endif
9399/* Build type info for non-dummy variable. */
5ff904cd 9400
c7e4ee3a
CB
9401#if FFECOM_targetCURRENT == FFECOM_targetGCC
9402static tree
9403ffecom_type_localvar_ (ffesymbol s, ffeinfoBasictype bt,
9404 ffeinfoKindtype kt)
9405{
9406 tree type;
9407 ffebld dl;
9408 ffebld dim;
9409 tree lowt;
9410 tree hight;
5ff904cd 9411
c7e4ee3a
CB
9412 type = ffecom_tree_type[bt][kt];
9413 if (bt == FFEINFO_basictypeCHARACTER)
9414 {
9415 hight = build_int_2 (ffesymbol_size (s), 0);
9416 TREE_TYPE (hight) = ffecom_f2c_ftnlen_type_node;
5ff904cd 9417
c7e4ee3a
CB
9418 type
9419 = build_array_type
9420 (type,
9421 build_range_type (ffecom_f2c_ftnlen_type_node,
9422 ffecom_f2c_ftnlen_one_node,
9423 hight));
9424 type = ffecom_check_size_overflow_ (s, type, FALSE);
9425 }
5ff904cd 9426
c7e4ee3a
CB
9427 for (dl = ffesymbol_dims (s); dl != NULL; dl = ffebld_trail (dl))
9428 {
9429 if (type == error_mark_node)
9430 break;
5ff904cd 9431
c7e4ee3a
CB
9432 dim = ffebld_head (dl);
9433 assert (ffebld_op (dim) == FFEBLD_opBOUNDS);
5ff904cd 9434
c7e4ee3a
CB
9435 if (ffebld_left (dim) == NULL)
9436 lowt = integer_one_node;
9437 else
9438 lowt = ffecom_expr (ffebld_left (dim));
5ff904cd 9439
c7e4ee3a
CB
9440 if (TREE_CODE (lowt) != INTEGER_CST)
9441 lowt = variable_size (lowt);
5ff904cd 9442
c7e4ee3a
CB
9443 assert (ffebld_right (dim) != NULL);
9444 hight = ffecom_expr (ffebld_right (dim));
5ff904cd 9445
c7e4ee3a
CB
9446 if (TREE_CODE (hight) != INTEGER_CST)
9447 hight = variable_size (hight);
5ff904cd 9448
c7e4ee3a
CB
9449 type = build_array_type (type,
9450 build_range_type (ffecom_integer_type_node,
9451 lowt, hight));
9452 type = ffecom_check_size_overflow_ (s, type, FALSE);
9453 }
5ff904cd 9454
c7e4ee3a 9455 return type;
5ff904cd
JL
9456}
9457
9458#endif
c7e4ee3a 9459/* Build Namelist type. */
5ff904cd 9460
c7e4ee3a
CB
9461#if FFECOM_targetCURRENT == FFECOM_targetGCC
9462static tree
9463ffecom_type_namelist_ ()
9464{
9465 static tree type = NULL_TREE;
5ff904cd 9466
c7e4ee3a
CB
9467 if (type == NULL_TREE)
9468 {
9469 static tree namefield, varsfield, nvarsfield;
9470 tree vardesctype;
5ff904cd 9471
c7e4ee3a 9472 vardesctype = ffecom_type_vardesc_ ();
5ff904cd 9473
c7e4ee3a 9474 type = make_node (RECORD_TYPE);
a6fa6420 9475
c7e4ee3a 9476 vardesctype = build_pointer_type (build_pointer_type (vardesctype));
a6fa6420 9477
c7e4ee3a
CB
9478 namefield = ffecom_decl_field (type, NULL_TREE, "name",
9479 string_type_node);
9480 varsfield = ffecom_decl_field (type, namefield, "vars", vardesctype);
9481 nvarsfield = ffecom_decl_field (type, varsfield, "nvars",
9482 integer_type_node);
a6fa6420 9483
c7e4ee3a
CB
9484 TYPE_FIELDS (type) = namefield;
9485 layout_type (type);
a6fa6420 9486
7189a4b0 9487 ggc_add_tree_root (&type, 1);
5ff904cd 9488 }
5ff904cd 9489
c7e4ee3a
CB
9490 return type;
9491}
5ff904cd 9492
c7e4ee3a 9493#endif
5ff904cd 9494
c7e4ee3a 9495/* Build Vardesc type. */
5ff904cd 9496
c7e4ee3a
CB
9497#if FFECOM_targetCURRENT == FFECOM_targetGCC
9498static tree
9499ffecom_type_vardesc_ ()
9500{
9501 static tree type = NULL_TREE;
9502 static tree namefield, addrfield, dimsfield, typefield;
5ff904cd 9503
c7e4ee3a
CB
9504 if (type == NULL_TREE)
9505 {
c7e4ee3a 9506 type = make_node (RECORD_TYPE);
5ff904cd 9507
c7e4ee3a
CB
9508 namefield = ffecom_decl_field (type, NULL_TREE, "name",
9509 string_type_node);
9510 addrfield = ffecom_decl_field (type, namefield, "addr",
9511 string_type_node);
9512 dimsfield = ffecom_decl_field (type, addrfield, "dims",
9513 ffecom_f2c_ptr_to_ftnlen_type_node);
9514 typefield = ffecom_decl_field (type, dimsfield, "type",
9515 integer_type_node);
5ff904cd 9516
c7e4ee3a
CB
9517 TYPE_FIELDS (type) = namefield;
9518 layout_type (type);
9519
7189a4b0 9520 ggc_add_tree_root (&type, 1);
c7e4ee3a
CB
9521 }
9522
9523 return type;
5ff904cd
JL
9524}
9525
9526#endif
5ff904cd
JL
9527
9528#if FFECOM_targetCURRENT == FFECOM_targetGCC
9529static tree
c7e4ee3a 9530ffecom_vardesc_ (ffebld expr)
5ff904cd 9531{
c7e4ee3a 9532 ffesymbol s;
5ff904cd 9533
c7e4ee3a
CB
9534 assert (ffebld_op (expr) == FFEBLD_opSYMTER);
9535 s = ffebld_symter (expr);
5ff904cd 9536
c7e4ee3a
CB
9537 if (ffesymbol_hook (s).vardesc_tree == NULL_TREE)
9538 {
9539 int i;
9540 tree vardesctype = ffecom_type_vardesc_ ();
9541 tree var;
9542 tree nameinit;
9543 tree dimsinit;
9544 tree addrinit;
9545 tree typeinit;
9546 tree field;
9547 tree varinits;
9548 int yes;
9549 static int mynumber = 0;
5ff904cd 9550
c7e4ee3a 9551 yes = suspend_momentary ();
5ff904cd 9552
c7e4ee3a
CB
9553 var = build_decl (VAR_DECL,
9554 ffecom_get_invented_identifier ("__g77_vardesc_%d",
14657de8 9555 mynumber++),
c7e4ee3a
CB
9556 vardesctype);
9557 TREE_STATIC (var) = 1;
9558 DECL_INITIAL (var) = error_mark_node;
5ff904cd 9559
c7e4ee3a 9560 var = start_decl (var, FALSE);
5ff904cd 9561
c7e4ee3a 9562 /* Process inits. */
5ff904cd 9563
c7e4ee3a
CB
9564 nameinit = ffecom_build_f2c_string_ ((i = strlen (ffesymbol_text (s)))
9565 + 1,
9566 ffesymbol_text (s));
9567 TREE_TYPE (nameinit)
9568 = build_type_variant
9569 (build_array_type
9570 (char_type_node,
9571 build_range_type (integer_type_node,
9572 integer_one_node,
9573 build_int_2 (i, 0))),
9574 1, 0);
9575 TREE_CONSTANT (nameinit) = 1;
9576 TREE_STATIC (nameinit) = 1;
9577 nameinit = ffecom_1 (ADDR_EXPR,
9578 build_pointer_type (TREE_TYPE (nameinit)),
9579 nameinit);
5ff904cd 9580
c7e4ee3a 9581 addrinit = ffecom_arg_ptr_to_expr (expr, &typeinit);
5ff904cd 9582
c7e4ee3a 9583 dimsinit = ffecom_vardesc_dims_ (s);
5ff904cd 9584
c7e4ee3a
CB
9585 if (typeinit == NULL_TREE)
9586 {
9587 ffeinfoBasictype bt = ffesymbol_basictype (s);
9588 ffeinfoKindtype kt = ffesymbol_kindtype (s);
9589 int tc = ffecom_f2c_typecode (bt, kt);
5ff904cd 9590
c7e4ee3a
CB
9591 assert (tc != -1);
9592 typeinit = build_int_2 (tc, (tc < 0) ? -1 : 0);
9593 }
9594 else
9595 typeinit = ffecom_1 (NEGATE_EXPR, TREE_TYPE (typeinit), typeinit);
5ff904cd 9596
c7e4ee3a
CB
9597 varinits = build_tree_list ((field = TYPE_FIELDS (vardesctype)),
9598 nameinit);
9599 TREE_CHAIN (varinits) = build_tree_list ((field = TREE_CHAIN (field)),
9600 addrinit);
9601 TREE_CHAIN (TREE_CHAIN (varinits))
9602 = build_tree_list ((field = TREE_CHAIN (field)), dimsinit);
9603 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (varinits)))
9604 = build_tree_list ((field = TREE_CHAIN (field)), typeinit);
5ff904cd 9605
c7e4ee3a
CB
9606 varinits = build (CONSTRUCTOR, vardesctype, NULL_TREE, varinits);
9607 TREE_CONSTANT (varinits) = 1;
9608 TREE_STATIC (varinits) = 1;
5ff904cd 9609
c7e4ee3a 9610 finish_decl (var, varinits, FALSE);
5ff904cd 9611
c7e4ee3a 9612 var = ffecom_1 (ADDR_EXPR, build_pointer_type (vardesctype), var);
5ff904cd 9613
c7e4ee3a 9614 resume_momentary (yes);
5ff904cd 9615
c7e4ee3a
CB
9616 ffesymbol_hook (s).vardesc_tree = var;
9617 }
5ff904cd 9618
c7e4ee3a
CB
9619 return ffesymbol_hook (s).vardesc_tree;
9620}
5ff904cd 9621
c7e4ee3a 9622#endif
5ff904cd 9623#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
9624static tree
9625ffecom_vardesc_array_ (ffesymbol s)
5ff904cd 9626{
c7e4ee3a
CB
9627 ffebld b;
9628 tree list;
9629 tree item = NULL_TREE;
9630 tree var;
9631 int i;
9632 int yes;
9633 static int mynumber = 0;
5ff904cd 9634
c7e4ee3a
CB
9635 for (i = 0, list = NULL_TREE, b = ffesymbol_namelist (s);
9636 b != NULL;
9637 b = ffebld_trail (b), ++i)
9638 {
9639 tree t;
5ff904cd 9640
c7e4ee3a 9641 t = ffecom_vardesc_ (ffebld_head (b));
5ff904cd 9642
c7e4ee3a
CB
9643 if (list == NULL_TREE)
9644 list = item = build_tree_list (NULL_TREE, t);
9645 else
5ff904cd 9646 {
c7e4ee3a
CB
9647 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
9648 item = TREE_CHAIN (item);
5ff904cd 9649 }
5ff904cd 9650 }
5ff904cd 9651
c7e4ee3a 9652 yes = suspend_momentary ();
5ff904cd 9653
c7e4ee3a
CB
9654 item = build_array_type (build_pointer_type (ffecom_type_vardesc_ ()),
9655 build_range_type (integer_type_node,
9656 integer_one_node,
9657 build_int_2 (i, 0)));
9658 list = build (CONSTRUCTOR, item, NULL_TREE, list);
9659 TREE_CONSTANT (list) = 1;
9660 TREE_STATIC (list) = 1;
5ff904cd 9661
14657de8 9662 var = ffecom_get_invented_identifier ("__g77_vardesc_array_%d", mynumber++);
c7e4ee3a
CB
9663 var = build_decl (VAR_DECL, var, item);
9664 TREE_STATIC (var) = 1;
9665 DECL_INITIAL (var) = error_mark_node;
9666 var = start_decl (var, FALSE);
9667 finish_decl (var, list, FALSE);
5ff904cd 9668
c7e4ee3a 9669 resume_momentary (yes);
5ff904cd 9670
c7e4ee3a
CB
9671 return var;
9672}
5ff904cd 9673
c7e4ee3a
CB
9674#endif
9675#if FFECOM_targetCURRENT == FFECOM_targetGCC
9676static tree
9677ffecom_vardesc_dims_ (ffesymbol s)
9678{
9679 if (ffesymbol_dims (s) == NULL)
9680 return convert (ffecom_f2c_ptr_to_ftnlen_type_node,
9681 integer_zero_node);
5ff904cd 9682
c7e4ee3a
CB
9683 {
9684 ffebld b;
9685 ffebld e;
9686 tree list;
9687 tree backlist;
9688 tree item = NULL_TREE;
9689 tree var;
9690 int yes;
9691 tree numdim;
9692 tree numelem;
9693 tree baseoff = NULL_TREE;
9694 static int mynumber = 0;
9695
9696 numdim = build_int_2 ((int) ffesymbol_rank (s), 0);
9697 TREE_TYPE (numdim) = ffecom_f2c_ftnlen_type_node;
9698
9699 numelem = ffecom_expr (ffesymbol_arraysize (s));
9700 TREE_TYPE (numelem) = ffecom_f2c_ftnlen_type_node;
9701
9702 list = NULL_TREE;
9703 backlist = NULL_TREE;
9704 for (b = ffesymbol_dims (s), e = ffesymbol_extents (s);
9705 b != NULL;
9706 b = ffebld_trail (b), e = ffebld_trail (e))
5ff904cd 9707 {
c7e4ee3a
CB
9708 tree t;
9709 tree low;
9710 tree back;
5ff904cd 9711
c7e4ee3a
CB
9712 if (ffebld_trail (b) == NULL)
9713 t = NULL_TREE;
9714 else
5ff904cd 9715 {
c7e4ee3a
CB
9716 t = convert (ffecom_f2c_ftnlen_type_node,
9717 ffecom_expr (ffebld_head (e)));
5ff904cd 9718
c7e4ee3a
CB
9719 if (list == NULL_TREE)
9720 list = item = build_tree_list (NULL_TREE, t);
9721 else
9722 {
9723 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
9724 item = TREE_CHAIN (item);
9725 }
9726 }
5ff904cd 9727
c7e4ee3a
CB
9728 if (ffebld_left (ffebld_head (b)) == NULL)
9729 low = ffecom_integer_one_node;
9730 else
9731 low = ffecom_expr (ffebld_left (ffebld_head (b)));
9732 low = convert (ffecom_f2c_ftnlen_type_node, low);
5ff904cd 9733
c7e4ee3a
CB
9734 back = build_tree_list (low, t);
9735 TREE_CHAIN (back) = backlist;
9736 backlist = back;
9737 }
5ff904cd 9738
c7e4ee3a
CB
9739 for (item = backlist; item != NULL_TREE; item = TREE_CHAIN (item))
9740 {
9741 if (TREE_VALUE (item) == NULL_TREE)
9742 baseoff = TREE_PURPOSE (item);
9743 else
9744 baseoff = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
9745 TREE_PURPOSE (item),
9746 ffecom_2 (MULT_EXPR,
9747 ffecom_f2c_ftnlen_type_node,
9748 TREE_VALUE (item),
9749 baseoff));
5ff904cd
JL
9750 }
9751
c7e4ee3a 9752 /* backlist now dead, along with all TREE_PURPOSEs on it. */
5ff904cd 9753
c7e4ee3a
CB
9754 baseoff = build_tree_list (NULL_TREE, baseoff);
9755 TREE_CHAIN (baseoff) = list;
5ff904cd 9756
c7e4ee3a
CB
9757 numelem = build_tree_list (NULL_TREE, numelem);
9758 TREE_CHAIN (numelem) = baseoff;
5ff904cd 9759
c7e4ee3a
CB
9760 numdim = build_tree_list (NULL_TREE, numdim);
9761 TREE_CHAIN (numdim) = numelem;
5ff904cd 9762
c7e4ee3a 9763 yes = suspend_momentary ();
5ff904cd 9764
c7e4ee3a
CB
9765 item = build_array_type (ffecom_f2c_ftnlen_type_node,
9766 build_range_type (integer_type_node,
9767 integer_zero_node,
9768 build_int_2
9769 ((int) ffesymbol_rank (s)
9770 + 2, 0)));
9771 list = build (CONSTRUCTOR, item, NULL_TREE, numdim);
9772 TREE_CONSTANT (list) = 1;
9773 TREE_STATIC (list) = 1;
9774
14657de8 9775 var = ffecom_get_invented_identifier ("__g77_dims_%d", mynumber++);
c7e4ee3a
CB
9776 var = build_decl (VAR_DECL, var, item);
9777 TREE_STATIC (var) = 1;
9778 DECL_INITIAL (var) = error_mark_node;
9779 var = start_decl (var, FALSE);
9780 finish_decl (var, list, FALSE);
9781
9782 var = ffecom_1 (ADDR_EXPR, build_pointer_type (item), var);
9783
9784 resume_momentary (yes);
9785
9786 return var;
9787 }
5ff904cd 9788}
c7e4ee3a 9789
5ff904cd 9790#endif
c7e4ee3a
CB
9791/* Essentially does a "fold (build1 (code, type, node))" while checking
9792 for certain housekeeping things.
5ff904cd 9793
c7e4ee3a
CB
9794 NOTE: for building an ADDR_EXPR around a FUNCTION_DECL, use
9795 ffecom_1_fn instead. */
5ff904cd
JL
9796
9797#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
9798tree
9799ffecom_1 (enum tree_code code, tree type, tree node)
5ff904cd 9800{
c7e4ee3a
CB
9801 tree item;
9802
9803 if ((node == error_mark_node)
9804 || (type == error_mark_node))
5ff904cd
JL
9805 return error_mark_node;
9806
c7e4ee3a 9807 if (code == ADDR_EXPR)
5ff904cd 9808 {
c7e4ee3a
CB
9809 if (!mark_addressable (node))
9810 assert ("can't mark_addressable this node!" == NULL);
9811 }
5ff904cd 9812
c7e4ee3a
CB
9813 switch (ffe_is_emulate_complex () ? code : NOP_EXPR)
9814 {
9815 tree realtype;
5ff904cd 9816
c7e4ee3a
CB
9817 case REALPART_EXPR:
9818 item = build (COMPONENT_REF, type, node, TYPE_FIELDS (TREE_TYPE (node)));
5ff904cd
JL
9819 break;
9820
c7e4ee3a
CB
9821 case IMAGPART_EXPR:
9822 item = build (COMPONENT_REF, type, node, TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (node))));
9823 break;
5ff904cd 9824
5ff904cd 9825
c7e4ee3a
CB
9826 case NEGATE_EXPR:
9827 if (TREE_CODE (type) != RECORD_TYPE)
9828 {
9829 item = build1 (code, type, node);
9830 break;
9831 }
9832 node = ffecom_stabilize_aggregate_ (node);
9833 realtype = TREE_TYPE (TYPE_FIELDS (type));
9834 item =
9835 ffecom_2 (COMPLEX_EXPR, type,
9836 ffecom_1 (NEGATE_EXPR, realtype,
9837 ffecom_1 (REALPART_EXPR, realtype,
9838 node)),
9839 ffecom_1 (NEGATE_EXPR, realtype,
9840 ffecom_1 (IMAGPART_EXPR, realtype,
9841 node)));
5ff904cd
JL
9842 break;
9843
9844 default:
c7e4ee3a
CB
9845 item = build1 (code, type, node);
9846 break;
5ff904cd 9847 }
5ff904cd 9848
c7e4ee3a
CB
9849 if (TREE_SIDE_EFFECTS (node))
9850 TREE_SIDE_EFFECTS (item) = 1;
9851 if ((code == ADDR_EXPR) && staticp (node))
9852 TREE_CONSTANT (item) = 1;
9853 return fold (item);
9854}
5ff904cd 9855#endif
5ff904cd 9856
c7e4ee3a
CB
9857/* Like ffecom_1 (ADDR_EXPR, TREE_TYPE (node), node), except
9858 handles TREE_CODE (node) == FUNCTION_DECL. In particular,
9859 does not set TREE_ADDRESSABLE (because calling an inline
9860 function does not mean the function needs to be separately
9861 compiled). */
5ff904cd
JL
9862
9863#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
9864tree
9865ffecom_1_fn (tree node)
5ff904cd 9866{
c7e4ee3a 9867 tree item;
5ff904cd 9868 tree type;
5ff904cd 9869
c7e4ee3a
CB
9870 if (node == error_mark_node)
9871 return error_mark_node;
5ff904cd 9872
c7e4ee3a
CB
9873 type = build_type_variant (TREE_TYPE (node),
9874 TREE_READONLY (node),
9875 TREE_THIS_VOLATILE (node));
9876 item = build1 (ADDR_EXPR,
9877 build_pointer_type (type), node);
9878 if (TREE_SIDE_EFFECTS (node))
9879 TREE_SIDE_EFFECTS (item) = 1;
9880 if (staticp (node))
9881 TREE_CONSTANT (item) = 1;
9882 return fold (item);
5ff904cd 9883}
5ff904cd 9884#endif
c7e4ee3a
CB
9885
9886/* Essentially does a "fold (build (code, type, node1, node2))" while
9887 checking for certain housekeeping things. */
5ff904cd
JL
9888
9889#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
9890tree
9891ffecom_2 (enum tree_code code, tree type, tree node1,
9892 tree node2)
5ff904cd 9893{
c7e4ee3a 9894 tree item;
5ff904cd 9895
c7e4ee3a
CB
9896 if ((node1 == error_mark_node)
9897 || (node2 == error_mark_node)
9898 || (type == error_mark_node))
9899 return error_mark_node;
9900
9901 switch (ffe_is_emulate_complex () ? code : NOP_EXPR)
5ff904cd 9902 {
c7e4ee3a 9903 tree a, b, c, d, realtype;
5ff904cd 9904
c7e4ee3a
CB
9905 case CONJ_EXPR:
9906 assert ("no CONJ_EXPR support yet" == NULL);
9907 return error_mark_node;
5ff904cd 9908
c7e4ee3a
CB
9909 case COMPLEX_EXPR:
9910 item = build_tree_list (TYPE_FIELDS (type), node1);
9911 TREE_CHAIN (item) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), node2);
9912 item = build (CONSTRUCTOR, type, NULL_TREE, item);
9913 break;
5ff904cd 9914
c7e4ee3a
CB
9915 case PLUS_EXPR:
9916 if (TREE_CODE (type) != RECORD_TYPE)
9917 {
9918 item = build (code, type, node1, node2);
9919 break;
9920 }
9921 node1 = ffecom_stabilize_aggregate_ (node1);
9922 node2 = ffecom_stabilize_aggregate_ (node2);
9923 realtype = TREE_TYPE (TYPE_FIELDS (type));
9924 item =
9925 ffecom_2 (COMPLEX_EXPR, type,
9926 ffecom_2 (PLUS_EXPR, realtype,
9927 ffecom_1 (REALPART_EXPR, realtype,
9928 node1),
9929 ffecom_1 (REALPART_EXPR, realtype,
9930 node2)),
9931 ffecom_2 (PLUS_EXPR, realtype,
9932 ffecom_1 (IMAGPART_EXPR, realtype,
9933 node1),
9934 ffecom_1 (IMAGPART_EXPR, realtype,
9935 node2)));
9936 break;
5ff904cd 9937
c7e4ee3a
CB
9938 case MINUS_EXPR:
9939 if (TREE_CODE (type) != RECORD_TYPE)
9940 {
9941 item = build (code, type, node1, node2);
9942 break;
9943 }
9944 node1 = ffecom_stabilize_aggregate_ (node1);
9945 node2 = ffecom_stabilize_aggregate_ (node2);
9946 realtype = TREE_TYPE (TYPE_FIELDS (type));
9947 item =
9948 ffecom_2 (COMPLEX_EXPR, type,
9949 ffecom_2 (MINUS_EXPR, realtype,
9950 ffecom_1 (REALPART_EXPR, realtype,
9951 node1),
9952 ffecom_1 (REALPART_EXPR, realtype,
9953 node2)),
9954 ffecom_2 (MINUS_EXPR, realtype,
9955 ffecom_1 (IMAGPART_EXPR, realtype,
9956 node1),
9957 ffecom_1 (IMAGPART_EXPR, realtype,
9958 node2)));
9959 break;
5ff904cd 9960
c7e4ee3a
CB
9961 case MULT_EXPR:
9962 if (TREE_CODE (type) != RECORD_TYPE)
9963 {
9964 item = build (code, type, node1, node2);
9965 break;
9966 }
9967 node1 = ffecom_stabilize_aggregate_ (node1);
9968 node2 = ffecom_stabilize_aggregate_ (node2);
9969 realtype = TREE_TYPE (TYPE_FIELDS (type));
9970 a = save_expr (ffecom_1 (REALPART_EXPR, realtype,
9971 node1));
9972 b = save_expr (ffecom_1 (IMAGPART_EXPR, realtype,
9973 node1));
9974 c = save_expr (ffecom_1 (REALPART_EXPR, realtype,
9975 node2));
9976 d = save_expr (ffecom_1 (IMAGPART_EXPR, realtype,
9977 node2));
9978 item =
9979 ffecom_2 (COMPLEX_EXPR, type,
9980 ffecom_2 (MINUS_EXPR, realtype,
9981 ffecom_2 (MULT_EXPR, realtype,
9982 a,
9983 c),
9984 ffecom_2 (MULT_EXPR, realtype,
9985 b,
9986 d)),
9987 ffecom_2 (PLUS_EXPR, realtype,
9988 ffecom_2 (MULT_EXPR, realtype,
9989 a,
9990 d),
9991 ffecom_2 (MULT_EXPR, realtype,
9992 c,
9993 b)));
9994 break;
5ff904cd 9995
c7e4ee3a
CB
9996 case EQ_EXPR:
9997 if ((TREE_CODE (node1) != RECORD_TYPE)
9998 && (TREE_CODE (node2) != RECORD_TYPE))
9999 {
10000 item = build (code, type, node1, node2);
10001 break;
10002 }
10003 assert (TREE_CODE (node1) == RECORD_TYPE);
10004 assert (TREE_CODE (node2) == RECORD_TYPE);
10005 node1 = ffecom_stabilize_aggregate_ (node1);
10006 node2 = ffecom_stabilize_aggregate_ (node2);
10007 realtype = TREE_TYPE (TYPE_FIELDS (type));
10008 item =
10009 ffecom_2 (TRUTH_ANDIF_EXPR, type,
10010 ffecom_2 (code, type,
10011 ffecom_1 (REALPART_EXPR, realtype,
10012 node1),
10013 ffecom_1 (REALPART_EXPR, realtype,
10014 node2)),
10015 ffecom_2 (code, type,
10016 ffecom_1 (IMAGPART_EXPR, realtype,
10017 node1),
10018 ffecom_1 (IMAGPART_EXPR, realtype,
10019 node2)));
10020 break;
10021
10022 case NE_EXPR:
10023 if ((TREE_CODE (node1) != RECORD_TYPE)
10024 && (TREE_CODE (node2) != RECORD_TYPE))
10025 {
10026 item = build (code, type, node1, node2);
10027 break;
10028 }
10029 assert (TREE_CODE (node1) == RECORD_TYPE);
10030 assert (TREE_CODE (node2) == RECORD_TYPE);
10031 node1 = ffecom_stabilize_aggregate_ (node1);
10032 node2 = ffecom_stabilize_aggregate_ (node2);
10033 realtype = TREE_TYPE (TYPE_FIELDS (type));
10034 item =
10035 ffecom_2 (TRUTH_ORIF_EXPR, type,
10036 ffecom_2 (code, type,
10037 ffecom_1 (REALPART_EXPR, realtype,
10038 node1),
10039 ffecom_1 (REALPART_EXPR, realtype,
10040 node2)),
10041 ffecom_2 (code, type,
10042 ffecom_1 (IMAGPART_EXPR, realtype,
10043 node1),
10044 ffecom_1 (IMAGPART_EXPR, realtype,
10045 node2)));
10046 break;
5ff904cd 10047
c7e4ee3a
CB
10048 default:
10049 item = build (code, type, node1, node2);
10050 break;
5ff904cd
JL
10051 }
10052
c7e4ee3a
CB
10053 if (TREE_SIDE_EFFECTS (node1) || TREE_SIDE_EFFECTS (node2))
10054 TREE_SIDE_EFFECTS (item) = 1;
10055 return fold (item);
5ff904cd
JL
10056}
10057
10058#endif
c7e4ee3a 10059/* ffecom_2pass_advise_entrypoint -- Advise that there's this entrypoint
5ff904cd 10060
c7e4ee3a
CB
10061 ffesymbol s; // the ENTRY point itself
10062 if (ffecom_2pass_advise_entrypoint(s))
10063 // the ENTRY point has been accepted
5ff904cd 10064
c7e4ee3a
CB
10065 Does whatever compiler needs to do when it learns about the entrypoint,
10066 like determine the return type of the master function, count the
10067 number of entrypoints, etc. Returns FALSE if the return type is
10068 not compatible with the return type(s) of other entrypoint(s).
5ff904cd 10069
c7e4ee3a
CB
10070 NOTE: for every call to this fn that returns TRUE, _do_entrypoint must
10071 later (after _finish_progunit) be called with the same entrypoint(s)
10072 as passed to this fn for which TRUE was returned.
5ff904cd 10073
c7e4ee3a
CB
10074 03-Jan-92 JCB 2.0
10075 Return FALSE if the return type conflicts with previous entrypoints. */
5ff904cd
JL
10076
10077#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
10078bool
10079ffecom_2pass_advise_entrypoint (ffesymbol entry)
5ff904cd 10080{
c7e4ee3a
CB
10081 ffebld list; /* opITEM. */
10082 ffebld mlist; /* opITEM. */
10083 ffebld plist; /* opITEM. */
10084 ffebld arg; /* ffebld_head(opITEM). */
10085 ffebld item; /* opITEM. */
10086 ffesymbol s; /* ffebld_symter(arg). */
10087 ffeinfoBasictype bt = ffesymbol_basictype (entry);
10088 ffeinfoKindtype kt = ffesymbol_kindtype (entry);
10089 ffetargetCharacterSize size = ffesymbol_size (entry);
10090 bool ok;
5ff904cd 10091
c7e4ee3a
CB
10092 if (ffecom_num_entrypoints_ == 0)
10093 { /* First entrypoint, make list of main
10094 arglist's dummies. */
10095 assert (ffecom_primary_entry_ != NULL);
5ff904cd 10096
c7e4ee3a
CB
10097 ffecom_master_bt_ = ffesymbol_basictype (ffecom_primary_entry_);
10098 ffecom_master_kt_ = ffesymbol_kindtype (ffecom_primary_entry_);
10099 ffecom_master_size_ = ffesymbol_size (ffecom_primary_entry_);
5ff904cd 10100
c7e4ee3a
CB
10101 for (plist = NULL, list = ffesymbol_dummyargs (ffecom_primary_entry_);
10102 list != NULL;
10103 list = ffebld_trail (list))
10104 {
10105 arg = ffebld_head (list);
10106 if (ffebld_op (arg) != FFEBLD_opSYMTER)
10107 continue; /* Alternate return or some such thing. */
10108 item = ffebld_new_item (arg, NULL);
10109 if (plist == NULL)
10110 ffecom_master_arglist_ = item;
10111 else
10112 ffebld_set_trail (plist, item);
10113 plist = item;
10114 }
5ff904cd
JL
10115 }
10116
c7e4ee3a
CB
10117 /* If necessary, scan entry arglist for alternate returns. Do this scan
10118 apparently redundantly (it's done below to UNIONize the arglists) so
10119 that we don't complain about RETURN 1 if an offending ENTRY is the only
10120 one with an alternate return. */
5ff904cd 10121
c7e4ee3a 10122 if (!ffecom_is_altreturning_)
5ff904cd 10123 {
c7e4ee3a
CB
10124 for (list = ffesymbol_dummyargs (entry);
10125 list != NULL;
10126 list = ffebld_trail (list))
10127 {
10128 arg = ffebld_head (list);
10129 if (ffebld_op (arg) == FFEBLD_opSTAR)
10130 {
10131 ffecom_is_altreturning_ = TRUE;
10132 break;
10133 }
10134 }
10135 }
5ff904cd 10136
c7e4ee3a 10137 /* Now check type compatibility. */
5ff904cd 10138
c7e4ee3a
CB
10139 switch (ffecom_master_bt_)
10140 {
10141 case FFEINFO_basictypeNONE:
10142 ok = (bt != FFEINFO_basictypeCHARACTER);
10143 break;
5ff904cd 10144
c7e4ee3a
CB
10145 case FFEINFO_basictypeCHARACTER:
10146 ok
10147 = (bt == FFEINFO_basictypeCHARACTER)
10148 && (kt == ffecom_master_kt_)
10149 && (size == ffecom_master_size_);
10150 break;
5ff904cd 10151
c7e4ee3a
CB
10152 case FFEINFO_basictypeANY:
10153 return FALSE; /* Just don't bother. */
5ff904cd 10154
c7e4ee3a
CB
10155 default:
10156 if (bt == FFEINFO_basictypeCHARACTER)
5ff904cd 10157 {
c7e4ee3a
CB
10158 ok = FALSE;
10159 break;
5ff904cd 10160 }
c7e4ee3a
CB
10161 ok = TRUE;
10162 if ((bt != ffecom_master_bt_) || (kt != ffecom_master_kt_))
10163 {
10164 ffecom_master_bt_ = FFEINFO_basictypeNONE;
10165 ffecom_master_kt_ = FFEINFO_kindtypeNONE;
10166 }
10167 break;
10168 }
5ff904cd 10169
c7e4ee3a
CB
10170 if (!ok)
10171 {
10172 ffebad_start (FFEBAD_ENTRY_CONFLICTS);
10173 ffest_ffebad_here_current_stmt (0);
10174 ffebad_finish ();
10175 return FALSE; /* Can't handle entrypoint. */
10176 }
5ff904cd 10177
c7e4ee3a 10178 /* Entrypoint type compatible with previous types. */
5ff904cd 10179
c7e4ee3a 10180 ++ffecom_num_entrypoints_;
5ff904cd 10181
c7e4ee3a
CB
10182 /* Master-arg-list = UNION(Master-arg-list,entry-arg-list). */
10183
10184 for (list = ffesymbol_dummyargs (entry);
10185 list != NULL;
10186 list = ffebld_trail (list))
10187 {
10188 arg = ffebld_head (list);
10189 if (ffebld_op (arg) != FFEBLD_opSYMTER)
10190 continue; /* Alternate return or some such thing. */
10191 s = ffebld_symter (arg);
10192 for (plist = NULL, mlist = ffecom_master_arglist_;
10193 mlist != NULL;
10194 plist = mlist, mlist = ffebld_trail (mlist))
10195 { /* plist points to previous item for easy
10196 appending of arg. */
10197 if (ffebld_symter (ffebld_head (mlist)) == s)
10198 break; /* Already have this arg in the master list. */
10199 }
10200 if (mlist != NULL)
10201 continue; /* Already have this arg in the master list. */
5ff904cd 10202
c7e4ee3a 10203 /* Append this arg to the master list. */
5ff904cd 10204
c7e4ee3a
CB
10205 item = ffebld_new_item (arg, NULL);
10206 if (plist == NULL)
10207 ffecom_master_arglist_ = item;
10208 else
10209 ffebld_set_trail (plist, item);
5ff904cd
JL
10210 }
10211
c7e4ee3a 10212 return TRUE;
5ff904cd
JL
10213}
10214
10215#endif
c7e4ee3a
CB
10216/* ffecom_2pass_do_entrypoint -- Do compilation of entrypoint
10217
10218 ffesymbol s; // the ENTRY point itself
10219 ffecom_2pass_do_entrypoint(s);
10220
10221 Does whatever compiler needs to do to make the entrypoint actually
10222 happen. Must be called for each entrypoint after
10223 ffecom_finish_progunit is called. */
10224
5ff904cd 10225#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
10226void
10227ffecom_2pass_do_entrypoint (ffesymbol entry)
5ff904cd 10228{
c7e4ee3a
CB
10229 static int mfn_num = 0;
10230 static int ent_num;
5ff904cd 10231
c7e4ee3a
CB
10232 if (mfn_num != ffecom_num_fns_)
10233 { /* First entrypoint for this program unit. */
10234 ent_num = 1;
10235 mfn_num = ffecom_num_fns_;
10236 ffecom_do_entry_ (ffecom_primary_entry_, 0);
10237 }
10238 else
10239 ++ent_num;
5ff904cd 10240
c7e4ee3a 10241 --ffecom_num_entrypoints_;
5ff904cd 10242
c7e4ee3a
CB
10243 ffecom_do_entry_ (entry, ent_num);
10244}
5ff904cd 10245
c7e4ee3a 10246#endif
5ff904cd 10247
c7e4ee3a
CB
10248/* Essentially does a "fold (build (code, type, node1, node2))" while
10249 checking for certain housekeeping things. Always sets
10250 TREE_SIDE_EFFECTS. */
5ff904cd 10251
c7e4ee3a
CB
10252#if FFECOM_targetCURRENT == FFECOM_targetGCC
10253tree
10254ffecom_2s (enum tree_code code, tree type, tree node1,
10255 tree node2)
10256{
10257 tree item;
5ff904cd 10258
c7e4ee3a
CB
10259 if ((node1 == error_mark_node)
10260 || (node2 == error_mark_node)
10261 || (type == error_mark_node))
10262 return error_mark_node;
5ff904cd 10263
c7e4ee3a
CB
10264 item = build (code, type, node1, node2);
10265 TREE_SIDE_EFFECTS (item) = 1;
10266 return fold (item);
5ff904cd
JL
10267}
10268
10269#endif
c7e4ee3a
CB
10270/* Essentially does a "fold (build (code, type, node1, node2, node3))" while
10271 checking for certain housekeeping things. */
10272
5ff904cd 10273#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
10274tree
10275ffecom_3 (enum tree_code code, tree type, tree node1,
10276 tree node2, tree node3)
5ff904cd 10277{
c7e4ee3a 10278 tree item;
5ff904cd 10279
c7e4ee3a
CB
10280 if ((node1 == error_mark_node)
10281 || (node2 == error_mark_node)
10282 || (node3 == error_mark_node)
10283 || (type == error_mark_node))
10284 return error_mark_node;
5ff904cd 10285
c7e4ee3a
CB
10286 item = build (code, type, node1, node2, node3);
10287 if (TREE_SIDE_EFFECTS (node1) || TREE_SIDE_EFFECTS (node2)
10288 || (node3 != NULL_TREE && TREE_SIDE_EFFECTS (node3)))
10289 TREE_SIDE_EFFECTS (item) = 1;
10290 return fold (item);
10291}
5ff904cd 10292
c7e4ee3a
CB
10293#endif
10294/* Essentially does a "fold (build (code, type, node1, node2, node3))" while
10295 checking for certain housekeeping things. Always sets
10296 TREE_SIDE_EFFECTS. */
5ff904cd 10297
c7e4ee3a
CB
10298#if FFECOM_targetCURRENT == FFECOM_targetGCC
10299tree
10300ffecom_3s (enum tree_code code, tree type, tree node1,
10301 tree node2, tree node3)
10302{
10303 tree item;
5ff904cd 10304
c7e4ee3a
CB
10305 if ((node1 == error_mark_node)
10306 || (node2 == error_mark_node)
10307 || (node3 == error_mark_node)
10308 || (type == error_mark_node))
10309 return error_mark_node;
5ff904cd 10310
c7e4ee3a
CB
10311 item = build (code, type, node1, node2, node3);
10312 TREE_SIDE_EFFECTS (item) = 1;
10313 return fold (item);
10314}
5ff904cd 10315
c7e4ee3a 10316#endif
5ff904cd 10317
c7e4ee3a 10318/* ffecom_arg_expr -- Transform argument expr into gcc tree
5ff904cd 10319
c7e4ee3a 10320 See use by ffecom_list_expr.
5ff904cd 10321
c7e4ee3a
CB
10322 If expression is NULL, returns an integer zero tree. If it is not
10323 a CHARACTER expression, returns whatever ffecom_expr
10324 returns and sets the length return value to NULL_TREE. Otherwise
10325 generates code to evaluate the character expression, returns the proper
10326 pointer to the result, but does NOT set the length return value to a tree
10327 that specifies the length of the result. (In other words, the length
10328 variable is always set to NULL_TREE, because a length is never passed.)
5ff904cd 10329
c7e4ee3a
CB
10330 21-Dec-91 JCB 1.1
10331 Don't set returned length, since nobody needs it (yet; someday if
10332 we allow CHARACTER*(*) dummies to statement functions, we'll need
10333 it). */
5ff904cd 10334
c7e4ee3a
CB
10335#if FFECOM_targetCURRENT == FFECOM_targetGCC
10336tree
10337ffecom_arg_expr (ffebld expr, tree *length)
10338{
10339 tree ign;
5ff904cd 10340
c7e4ee3a 10341 *length = NULL_TREE;
5ff904cd 10342
c7e4ee3a
CB
10343 if (expr == NULL)
10344 return integer_zero_node;
5ff904cd 10345
c7e4ee3a
CB
10346 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10347 return ffecom_expr (expr);
5ff904cd 10348
c7e4ee3a
CB
10349 return ffecom_arg_ptr_to_expr (expr, &ign);
10350}
10351
10352#endif
10353/* Transform expression into constant argument-pointer-to-expression tree.
10354
10355 If the expression can be transformed into a argument-pointer-to-expression
10356 tree that is constant, that is done, and the tree returned. Else
10357 NULL_TREE is returned.
5ff904cd 10358
c7e4ee3a
CB
10359 That way, a caller can attempt to provide compile-time initialization
10360 of a variable and, if that fails, *then* choose to start a new block
10361 and resort to using temporaries, as appropriate. */
5ff904cd 10362
c7e4ee3a
CB
10363tree
10364ffecom_arg_ptr_to_const_expr (ffebld expr, tree *length)
10365{
10366 if (! expr)
10367 return integer_zero_node;
5ff904cd 10368
c7e4ee3a
CB
10369 if (ffebld_op (expr) == FFEBLD_opANY)
10370 {
10371 if (length)
10372 *length = error_mark_node;
10373 return error_mark_node;
10374 }
10375
10376 if (ffebld_arity (expr) == 0
10377 && (ffebld_op (expr) != FFEBLD_opSYMTER
10378 || ffebld_where (expr) == FFEINFO_whereCOMMON
10379 || ffebld_where (expr) == FFEINFO_whereGLOBAL
10380 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
10381 {
10382 tree t;
10383
10384 t = ffecom_arg_ptr_to_expr (expr, length);
10385 assert (TREE_CONSTANT (t));
10386 assert (! length || TREE_CONSTANT (*length));
10387 return t;
10388 }
10389
10390 if (length
10391 && ffebld_size (expr) != FFETARGET_charactersizeNONE)
10392 *length = build_int_2 (ffebld_size (expr), 0);
10393 else if (length)
10394 *length = NULL_TREE;
10395 return NULL_TREE;
5ff904cd
JL
10396}
10397
c7e4ee3a 10398/* ffecom_arg_ptr_to_expr -- Transform argument expr into gcc tree
5ff904cd 10399
c7e4ee3a
CB
10400 See use by ffecom_list_ptr_to_expr.
10401
10402 If expression is NULL, returns an integer zero tree. If it is not
10403 a CHARACTER expression, returns whatever ffecom_ptr_to_expr
10404 returns and sets the length return value to NULL_TREE. Otherwise
10405 generates code to evaluate the character expression, returns the proper
10406 pointer to the result, AND sets the length return value to a tree that
10407 specifies the length of the result.
10408
10409 If the length argument is NULL, this is a slightly special
10410 case of building a FORMAT expression, that is, an expression that
10411 will be used at run time without regard to length. For the current
10412 implementation, which uses the libf2c library, this means it is nice
10413 to append a null byte to the end of the expression, where feasible,
10414 to make sure any diagnostic about the FORMAT string terminates at
10415 some useful point.
10416
10417 For now, treat %REF(char-expr) as the same as char-expr with a NULL
10418 length argument. This might even be seen as a feature, if a null
10419 byte can always be appended. */
5ff904cd
JL
10420
10421#if FFECOM_targetCURRENT == FFECOM_targetGCC
10422tree
c7e4ee3a 10423ffecom_arg_ptr_to_expr (ffebld expr, tree *length)
5ff904cd
JL
10424{
10425 tree item;
c7e4ee3a
CB
10426 tree ign_length;
10427 ffecomConcatList_ catlist;
5ff904cd 10428
c7e4ee3a
CB
10429 if (length != NULL)
10430 *length = NULL_TREE;
5ff904cd 10431
c7e4ee3a
CB
10432 if (expr == NULL)
10433 return integer_zero_node;
5ff904cd 10434
c7e4ee3a 10435 switch (ffebld_op (expr))
5ff904cd 10436 {
c7e4ee3a
CB
10437 case FFEBLD_opPERCENT_VAL:
10438 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10439 return ffecom_expr (ffebld_left (expr));
10440 {
10441 tree temp_exp;
10442 tree temp_length;
5ff904cd 10443
c7e4ee3a
CB
10444 temp_exp = ffecom_arg_ptr_to_expr (ffebld_left (expr), &temp_length);
10445 if (temp_exp == error_mark_node)
10446 return error_mark_node;
5ff904cd 10447
c7e4ee3a
CB
10448 return ffecom_1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (temp_exp)),
10449 temp_exp);
10450 }
5ff904cd 10451
c7e4ee3a
CB
10452 case FFEBLD_opPERCENT_REF:
10453 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10454 return ffecom_ptr_to_expr (ffebld_left (expr));
10455 if (length != NULL)
10456 {
10457 ign_length = NULL_TREE;
10458 length = &ign_length;
10459 }
10460 expr = ffebld_left (expr);
10461 break;
5ff904cd 10462
c7e4ee3a
CB
10463 case FFEBLD_opPERCENT_DESCR:
10464 switch (ffeinfo_basictype (ffebld_info (expr)))
5ff904cd 10465 {
c7e4ee3a
CB
10466#ifdef PASS_HOLLERITH_BY_DESCRIPTOR
10467 case FFEINFO_basictypeHOLLERITH:
10468#endif
10469 case FFEINFO_basictypeCHARACTER:
10470 break; /* Passed by descriptor anyway. */
10471
10472 default:
10473 item = ffecom_ptr_to_expr (expr);
10474 if (item != error_mark_node)
10475 *length = TYPE_SIZE (TREE_TYPE (TREE_TYPE (item)));
5ff904cd
JL
10476 break;
10477 }
5ff904cd
JL
10478 break;
10479
10480 default:
5ff904cd
JL
10481 break;
10482 }
10483
c7e4ee3a
CB
10484#ifdef PASS_HOLLERITH_BY_DESCRIPTOR
10485 if ((ffeinfo_basictype (ffebld_info (expr)) == FFEINFO_basictypeHOLLERITH)
10486 && (length != NULL))
10487 { /* Pass Hollerith by descriptor. */
10488 ffetargetHollerith h;
10489
10490 assert (ffebld_op (expr) == FFEBLD_opCONTER);
10491 h = ffebld_cu_val_hollerith (ffebld_constant_union
10492 (ffebld_conter (expr)));
10493 *length
10494 = build_int_2 (h.length, 0);
10495 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
10496 }
10497#endif
10498
10499 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10500 return ffecom_ptr_to_expr (expr);
10501
10502 assert (ffeinfo_kindtype (ffebld_info (expr))
10503 == FFEINFO_kindtypeCHARACTER1);
10504
47d98fa2
CB
10505 while (ffebld_op (expr) == FFEBLD_opPAREN)
10506 expr = ffebld_left (expr);
10507
c7e4ee3a
CB
10508 catlist = ffecom_concat_list_new_ (expr, FFETARGET_charactersizeNONE);
10509 switch (ffecom_concat_list_count_ (catlist))
10510 {
10511 case 0: /* Shouldn't happen, but in case it does... */
10512 if (length != NULL)
10513 {
10514 *length = ffecom_f2c_ftnlen_zero_node;
10515 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
10516 }
10517 ffecom_concat_list_kill_ (catlist);
10518 return null_pointer_node;
10519
10520 case 1: /* The (fairly) easy case. */
10521 if (length == NULL)
10522 ffecom_char_args_with_null_ (&item, &ign_length,
10523 ffecom_concat_list_expr_ (catlist, 0));
10524 else
10525 ffecom_char_args_ (&item, length,
10526 ffecom_concat_list_expr_ (catlist, 0));
10527 ffecom_concat_list_kill_ (catlist);
10528 assert (item != NULL_TREE);
10529 return item;
10530
10531 default: /* Must actually concatenate things. */
10532 break;
10533 }
10534
10535 {
10536 int count = ffecom_concat_list_count_ (catlist);
10537 int i;
10538 tree lengths;
10539 tree items;
10540 tree length_array;
10541 tree item_array;
10542 tree citem;
10543 tree clength;
10544 tree temporary;
10545 tree num;
10546 tree known_length;
10547 ffetargetCharacterSize sz;
10548
10549 sz = ffecom_concat_list_maxlen_ (catlist);
10550 /* ~~Kludge! */
10551 assert (sz != FFETARGET_charactersizeNONE);
10552
10553#ifdef HOHO
10554 length_array
10555 = lengths
10556 = ffecom_push_tempvar (ffecom_f2c_ftnlen_type_node,
10557 FFETARGET_charactersizeNONE, count, TRUE);
10558 item_array
10559 = items
10560 = ffecom_push_tempvar (ffecom_f2c_address_type_node,
10561 FFETARGET_charactersizeNONE, count, TRUE);
10562 temporary = ffecom_push_tempvar (char_type_node,
10563 sz, -1, TRUE);
10564#else
10565 {
10566 tree hook;
10567
10568 hook = ffebld_nonter_hook (expr);
10569 assert (hook);
10570 assert (TREE_CODE (hook) == TREE_VEC);
10571 assert (TREE_VEC_LENGTH (hook) == 3);
10572 length_array = lengths = TREE_VEC_ELT (hook, 0);
10573 item_array = items = TREE_VEC_ELT (hook, 1);
10574 temporary = TREE_VEC_ELT (hook, 2);
10575 }
10576#endif
10577
10578 known_length = ffecom_f2c_ftnlen_zero_node;
10579
10580 for (i = 0; i < count; ++i)
10581 {
10582 if ((i == count)
10583 && (length == NULL))
10584 ffecom_char_args_with_null_ (&citem, &clength,
10585 ffecom_concat_list_expr_ (catlist, i));
10586 else
10587 ffecom_char_args_ (&citem, &clength,
10588 ffecom_concat_list_expr_ (catlist, i));
10589 if ((citem == error_mark_node)
10590 || (clength == error_mark_node))
10591 {
10592 ffecom_concat_list_kill_ (catlist);
10593 *length = error_mark_node;
10594 return error_mark_node;
10595 }
10596
10597 items
10598 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (items),
10599 ffecom_modify (void_type_node,
10600 ffecom_2 (ARRAY_REF,
10601 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array))),
10602 item_array,
10603 build_int_2 (i, 0)),
10604 citem),
10605 items);
10606 clength = ffecom_save_tree (clength);
10607 if (length != NULL)
10608 known_length
10609 = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
10610 known_length,
10611 clength);
10612 lengths
10613 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (lengths),
10614 ffecom_modify (void_type_node,
10615 ffecom_2 (ARRAY_REF,
10616 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array))),
10617 length_array,
10618 build_int_2 (i, 0)),
10619 clength),
10620 lengths);
10621 }
10622
10623 temporary = ffecom_1 (ADDR_EXPR,
10624 build_pointer_type (TREE_TYPE (temporary)),
10625 temporary);
10626
10627 item = build_tree_list (NULL_TREE, temporary);
10628 TREE_CHAIN (item)
10629 = build_tree_list (NULL_TREE,
10630 ffecom_1 (ADDR_EXPR,
10631 build_pointer_type (TREE_TYPE (items)),
10632 items));
10633 TREE_CHAIN (TREE_CHAIN (item))
10634 = build_tree_list (NULL_TREE,
10635 ffecom_1 (ADDR_EXPR,
10636 build_pointer_type (TREE_TYPE (lengths)),
10637 lengths));
10638 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item)))
10639 = build_tree_list
10640 (NULL_TREE,
10641 ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
10642 convert (ffecom_f2c_ftnlen_type_node,
10643 build_int_2 (count, 0))));
10644 num = build_int_2 (sz, 0);
10645 TREE_TYPE (num) = ffecom_f2c_ftnlen_type_node;
10646 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item))))
10647 = build_tree_list (NULL_TREE, num);
10648
10649 item = ffecom_call_gfrt (FFECOM_gfrtCAT, item, NULL_TREE);
5ff904cd 10650 TREE_SIDE_EFFECTS (item) = 1;
c7e4ee3a
CB
10651 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (temporary),
10652 item,
10653 temporary);
10654
10655 if (length != NULL)
10656 *length = known_length;
10657 }
10658
10659 ffecom_concat_list_kill_ (catlist);
10660 assert (item != NULL_TREE);
10661 return item;
5ff904cd 10662}
c7e4ee3a 10663
5ff904cd 10664#endif
c7e4ee3a 10665/* Generate call to run-time function.
5ff904cd 10666
c7e4ee3a
CB
10667 The first arg is the GNU Fortran Run-Time function index, the second
10668 arg is the list of arguments to pass to it. Returned is the expression
10669 (WITHOUT TREE_SIDE_EFFECTS set!) that makes the call and returns the
10670 result (which may be void). */
5ff904cd
JL
10671
10672#if FFECOM_targetCURRENT == FFECOM_targetGCC
10673tree
c7e4ee3a 10674ffecom_call_gfrt (ffecomGfrt ix, tree args, tree hook)
5ff904cd 10675{
c7e4ee3a
CB
10676 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
10677 ffecom_gfrt_kindtype (ix),
10678 ffe_is_f2c_library () && ffecom_gfrt_complex_[ix],
10679 NULL_TREE, args, NULL_TREE, NULL,
10680 NULL, NULL_TREE, TRUE, hook);
5ff904cd
JL
10681}
10682#endif
10683
c7e4ee3a 10684/* Transform constant-union to tree. */
5ff904cd
JL
10685
10686#if FFECOM_targetCURRENT == FFECOM_targetGCC
10687tree
c7e4ee3a
CB
10688ffecom_constantunion (ffebldConstantUnion *cu, ffeinfoBasictype bt,
10689 ffeinfoKindtype kt, tree tree_type)
5ff904cd
JL
10690{
10691 tree item;
10692
c7e4ee3a 10693 switch (bt)
5ff904cd 10694 {
c7e4ee3a
CB
10695 case FFEINFO_basictypeINTEGER:
10696 {
10697 int val;
5ff904cd 10698
c7e4ee3a
CB
10699 switch (kt)
10700 {
10701#if FFETARGET_okINTEGER1
10702 case FFEINFO_kindtypeINTEGER1:
10703 val = ffebld_cu_val_integer1 (*cu);
10704 break;
10705#endif
5ff904cd 10706
c7e4ee3a
CB
10707#if FFETARGET_okINTEGER2
10708 case FFEINFO_kindtypeINTEGER2:
10709 val = ffebld_cu_val_integer2 (*cu);
10710 break;
10711#endif
5ff904cd 10712
c7e4ee3a
CB
10713#if FFETARGET_okINTEGER3
10714 case FFEINFO_kindtypeINTEGER3:
10715 val = ffebld_cu_val_integer3 (*cu);
10716 break;
10717#endif
5ff904cd 10718
c7e4ee3a
CB
10719#if FFETARGET_okINTEGER4
10720 case FFEINFO_kindtypeINTEGER4:
10721 val = ffebld_cu_val_integer4 (*cu);
10722 break;
10723#endif
5ff904cd 10724
c7e4ee3a
CB
10725 default:
10726 assert ("bad INTEGER constant kind type" == NULL);
10727 /* Fall through. */
10728 case FFEINFO_kindtypeANY:
10729 return error_mark_node;
10730 }
10731 item = build_int_2 (val, (val < 0) ? -1 : 0);
10732 TREE_TYPE (item) = tree_type;
10733 }
5ff904cd 10734 break;
5ff904cd 10735
c7e4ee3a
CB
10736 case FFEINFO_basictypeLOGICAL:
10737 {
10738 int val;
5ff904cd 10739
c7e4ee3a
CB
10740 switch (kt)
10741 {
10742#if FFETARGET_okLOGICAL1
10743 case FFEINFO_kindtypeLOGICAL1:
10744 val = ffebld_cu_val_logical1 (*cu);
10745 break;
5ff904cd 10746#endif
5ff904cd 10747
c7e4ee3a
CB
10748#if FFETARGET_okLOGICAL2
10749 case FFEINFO_kindtypeLOGICAL2:
10750 val = ffebld_cu_val_logical2 (*cu);
10751 break;
10752#endif
5ff904cd 10753
c7e4ee3a
CB
10754#if FFETARGET_okLOGICAL3
10755 case FFEINFO_kindtypeLOGICAL3:
10756 val = ffebld_cu_val_logical3 (*cu);
10757 break;
10758#endif
5ff904cd 10759
c7e4ee3a
CB
10760#if FFETARGET_okLOGICAL4
10761 case FFEINFO_kindtypeLOGICAL4:
10762 val = ffebld_cu_val_logical4 (*cu);
10763 break;
10764#endif
5ff904cd 10765
c7e4ee3a
CB
10766 default:
10767 assert ("bad LOGICAL constant kind type" == NULL);
10768 /* Fall through. */
10769 case FFEINFO_kindtypeANY:
10770 return error_mark_node;
10771 }
10772 item = build_int_2 (val, (val < 0) ? -1 : 0);
10773 TREE_TYPE (item) = tree_type;
10774 }
10775 break;
5ff904cd 10776
c7e4ee3a
CB
10777 case FFEINFO_basictypeREAL:
10778 {
10779 REAL_VALUE_TYPE val;
5ff904cd 10780
c7e4ee3a
CB
10781 switch (kt)
10782 {
10783#if FFETARGET_okREAL1
10784 case FFEINFO_kindtypeREAL1:
10785 val = ffetarget_value_real1 (ffebld_cu_val_real1 (*cu));
10786 break;
10787#endif
5ff904cd 10788
c7e4ee3a
CB
10789#if FFETARGET_okREAL2
10790 case FFEINFO_kindtypeREAL2:
10791 val = ffetarget_value_real2 (ffebld_cu_val_real2 (*cu));
10792 break;
10793#endif
5ff904cd 10794
c7e4ee3a
CB
10795#if FFETARGET_okREAL3
10796 case FFEINFO_kindtypeREAL3:
10797 val = ffetarget_value_real3 (ffebld_cu_val_real3 (*cu));
10798 break;
10799#endif
5ff904cd 10800
c7e4ee3a
CB
10801#if FFETARGET_okREAL4
10802 case FFEINFO_kindtypeREAL4:
10803 val = ffetarget_value_real4 (ffebld_cu_val_real4 (*cu));
10804 break;
10805#endif
5ff904cd 10806
c7e4ee3a
CB
10807 default:
10808 assert ("bad REAL constant kind type" == NULL);
10809 /* Fall through. */
10810 case FFEINFO_kindtypeANY:
10811 return error_mark_node;
10812 }
10813 item = build_real (tree_type, val);
10814 }
5ff904cd
JL
10815 break;
10816
c7e4ee3a
CB
10817 case FFEINFO_basictypeCOMPLEX:
10818 {
10819 REAL_VALUE_TYPE real;
10820 REAL_VALUE_TYPE imag;
10821 tree el_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
5ff904cd 10822
c7e4ee3a
CB
10823 switch (kt)
10824 {
10825#if FFETARGET_okCOMPLEX1
10826 case FFEINFO_kindtypeREAL1:
10827 real = ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu).real);
10828 imag = ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu).imaginary);
10829 break;
10830#endif
5ff904cd 10831
c7e4ee3a
CB
10832#if FFETARGET_okCOMPLEX2
10833 case FFEINFO_kindtypeREAL2:
10834 real = ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu).real);
10835 imag = ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu).imaginary);
10836 break;
10837#endif
5ff904cd 10838
c7e4ee3a
CB
10839#if FFETARGET_okCOMPLEX3
10840 case FFEINFO_kindtypeREAL3:
10841 real = ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu).real);
10842 imag = ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu).imaginary);
10843 break;
10844#endif
5ff904cd 10845
c7e4ee3a
CB
10846#if FFETARGET_okCOMPLEX4
10847 case FFEINFO_kindtypeREAL4:
10848 real = ffetarget_value_real4 (ffebld_cu_val_complex4 (*cu).real);
10849 imag = ffetarget_value_real4 (ffebld_cu_val_complex4 (*cu).imaginary);
10850 break;
10851#endif
5ff904cd 10852
c7e4ee3a
CB
10853 default:
10854 assert ("bad REAL constant kind type" == NULL);
10855 /* Fall through. */
10856 case FFEINFO_kindtypeANY:
10857 return error_mark_node;
10858 }
10859 item = ffecom_build_complex_constant_ (tree_type,
10860 build_real (el_type, real),
10861 build_real (el_type, imag));
10862 }
10863 break;
5ff904cd 10864
c7e4ee3a
CB
10865 case FFEINFO_basictypeCHARACTER:
10866 { /* Happens only in DATA and similar contexts. */
10867 ffetargetCharacter1 val;
5ff904cd 10868
c7e4ee3a
CB
10869 switch (kt)
10870 {
10871#if FFETARGET_okCHARACTER1
10872 case FFEINFO_kindtypeLOGICAL1:
10873 val = ffebld_cu_val_character1 (*cu);
10874 break;
10875#endif
10876
10877 default:
10878 assert ("bad CHARACTER constant kind type" == NULL);
10879 /* Fall through. */
10880 case FFEINFO_kindtypeANY:
10881 return error_mark_node;
10882 }
10883 item = build_string (ffetarget_length_character1 (val),
10884 ffetarget_text_character1 (val));
10885 TREE_TYPE (item)
10886 = build_type_variant (build_array_type (char_type_node,
10887 build_range_type
10888 (integer_type_node,
10889 integer_one_node,
10890 build_int_2
10891 (ffetarget_length_character1
10892 (val), 0))),
10893 1, 0);
10894 }
10895 break;
5ff904cd 10896
c7e4ee3a
CB
10897 case FFEINFO_basictypeHOLLERITH:
10898 {
10899 ffetargetHollerith h;
5ff904cd 10900
c7e4ee3a 10901 h = ffebld_cu_val_hollerith (*cu);
5ff904cd 10902
c7e4ee3a
CB
10903 /* If not at least as wide as default INTEGER, widen it. */
10904 if (h.length >= FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE)
10905 item = build_string (h.length, h.text);
10906 else
10907 {
10908 char str[FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE];
5ff904cd 10909
c7e4ee3a
CB
10910 memcpy (str, h.text, h.length);
10911 memset (&str[h.length], ' ',
10912 FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE
10913 - h.length);
10914 item = build_string (FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE,
10915 str);
10916 }
10917 TREE_TYPE (item)
10918 = build_type_variant (build_array_type (char_type_node,
10919 build_range_type
10920 (integer_type_node,
10921 integer_one_node,
10922 build_int_2
10923 (h.length, 0))),
10924 1, 0);
10925 }
10926 break;
5ff904cd 10927
c7e4ee3a
CB
10928 case FFEINFO_basictypeTYPELESS:
10929 {
10930 ffetargetInteger1 ival;
10931 ffetargetTypeless tless;
10932 ffebad error;
5ff904cd 10933
c7e4ee3a
CB
10934 tless = ffebld_cu_val_typeless (*cu);
10935 error = ffetarget_convert_integer1_typeless (&ival, tless);
10936 assert (error == FFEBAD);
5ff904cd 10937
c7e4ee3a
CB
10938 item = build_int_2 ((int) ival, 0);
10939 }
10940 break;
5ff904cd 10941
c7e4ee3a
CB
10942 default:
10943 assert ("not yet on constant type" == NULL);
10944 /* Fall through. */
10945 case FFEINFO_basictypeANY:
10946 return error_mark_node;
5ff904cd 10947 }
5ff904cd 10948
c7e4ee3a 10949 TREE_CONSTANT (item) = 1;
5ff904cd 10950
c7e4ee3a 10951 return item;
5ff904cd
JL
10952}
10953
10954#endif
10955
c7e4ee3a
CB
10956/* Transform expression into constant tree.
10957
10958 If the expression can be transformed into a tree that is constant,
10959 that is done, and the tree returned. Else NULL_TREE is returned.
10960
10961 That way, a caller can attempt to provide compile-time initialization
10962 of a variable and, if that fails, *then* choose to start a new block
10963 and resort to using temporaries, as appropriate. */
5ff904cd 10964
5ff904cd 10965tree
c7e4ee3a 10966ffecom_const_expr (ffebld expr)
5ff904cd 10967{
c7e4ee3a
CB
10968 if (! expr)
10969 return integer_zero_node;
5ff904cd 10970
c7e4ee3a 10971 if (ffebld_op (expr) == FFEBLD_opANY)
5ff904cd
JL
10972 return error_mark_node;
10973
c7e4ee3a
CB
10974 if (ffebld_arity (expr) == 0
10975 && (ffebld_op (expr) != FFEBLD_opSYMTER
10976#if NEWCOMMON
10977 /* ~~Enable once common/equivalence is handled properly? */
10978 || ffebld_where (expr) == FFEINFO_whereCOMMON
5ff904cd 10979#endif
c7e4ee3a
CB
10980 || ffebld_where (expr) == FFEINFO_whereGLOBAL
10981 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
10982 {
10983 tree t;
5ff904cd 10984
c7e4ee3a
CB
10985 t = ffecom_expr (expr);
10986 assert (TREE_CONSTANT (t));
10987 return t;
10988 }
5ff904cd 10989
c7e4ee3a 10990 return NULL_TREE;
5ff904cd
JL
10991}
10992
c7e4ee3a 10993/* Handy way to make a field in a struct/union. */
5ff904cd
JL
10994
10995#if FFECOM_targetCURRENT == FFECOM_targetGCC
10996tree
c7e4ee3a
CB
10997ffecom_decl_field (tree context, tree prevfield,
10998 const char *name, tree type)
5ff904cd 10999{
c7e4ee3a 11000 tree field;
5ff904cd 11001
c7e4ee3a
CB
11002 field = build_decl (FIELD_DECL, get_identifier (name), type);
11003 DECL_CONTEXT (field) = context;
11004 DECL_FRAME_SIZE (field) = 0;
11005 if (prevfield != NULL_TREE)
11006 TREE_CHAIN (prevfield) = field;
5ff904cd 11007
c7e4ee3a 11008 return field;
5ff904cd
JL
11009}
11010
11011#endif
5ff904cd 11012
c7e4ee3a
CB
11013void
11014ffecom_close_include (FILE *f)
11015{
11016#if FFECOM_GCC_INCLUDE
11017 ffecom_close_include_ (f);
11018#endif
11019}
5ff904cd 11020
c7e4ee3a
CB
11021int
11022ffecom_decode_include_option (char *spec)
11023{
11024#if FFECOM_GCC_INCLUDE
11025 return ffecom_decode_include_option_ (spec);
11026#else
11027 return 1;
11028#endif
11029}
5ff904cd 11030
c7e4ee3a 11031/* End a compound statement (block). */
5ff904cd
JL
11032
11033#if FFECOM_targetCURRENT == FFECOM_targetGCC
11034tree
c7e4ee3a 11035ffecom_end_compstmt (void)
5ff904cd 11036{
c7e4ee3a
CB
11037 return bison_rule_compstmt_ ();
11038}
11039#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
5ff904cd 11040
c7e4ee3a 11041/* ffecom_end_transition -- Perform end transition on all symbols
5ff904cd 11042
c7e4ee3a 11043 ffecom_end_transition();
5ff904cd 11044
c7e4ee3a 11045 Calls ffecom_sym_end_transition for each global and local symbol. */
5ff904cd 11046
c7e4ee3a
CB
11047void
11048ffecom_end_transition ()
11049{
11050#if FFECOM_targetCURRENT == FFECOM_targetGCC
11051 ffebld item;
5ff904cd 11052#endif
5ff904cd 11053
c7e4ee3a
CB
11054 if (ffe_is_ffedebug ())
11055 fprintf (dmpout, "; end_stmt_transition\n");
86fc7a6c 11056
c7e4ee3a
CB
11057#if FFECOM_targetCURRENT == FFECOM_targetGCC
11058 ffecom_list_blockdata_ = NULL;
11059 ffecom_list_common_ = NULL;
11060#endif
86fc7a6c 11061
c7e4ee3a
CB
11062 ffesymbol_drive (ffecom_sym_end_transition);
11063 if (ffe_is_ffedebug ())
11064 {
11065 ffestorag_report ();
11066#if FFECOM_targetCURRENT == FFECOM_targetFFE
11067 ffesymbol_report_all ();
11068#endif
11069 }
5ff904cd
JL
11070
11071#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
11072 ffecom_start_progunit_ ();
11073
11074 for (item = ffecom_list_blockdata_;
11075 item != NULL;
11076 item = ffebld_trail (item))
11077 {
11078 ffebld callee;
11079 ffesymbol s;
11080 tree dt;
11081 tree t;
11082 tree var;
11083 int yes;
11084 static int number = 0;
11085
11086 callee = ffebld_head (item);
11087 s = ffebld_symter (callee);
11088 t = ffesymbol_hook (s).decl_tree;
11089 if (t == NULL_TREE)
11090 {
11091 s = ffecom_sym_transform_ (s);
11092 t = ffesymbol_hook (s).decl_tree;
11093 }
5ff904cd 11094
c7e4ee3a 11095 yes = suspend_momentary ();
5ff904cd 11096
c7e4ee3a 11097 dt = build_pointer_type (TREE_TYPE (t));
5ff904cd 11098
c7e4ee3a
CB
11099 var = build_decl (VAR_DECL,
11100 ffecom_get_invented_identifier ("__g77_forceload_%d",
14657de8 11101 number++),
c7e4ee3a
CB
11102 dt);
11103 DECL_EXTERNAL (var) = 0;
11104 TREE_STATIC (var) = 1;
11105 TREE_PUBLIC (var) = 0;
11106 DECL_INITIAL (var) = error_mark_node;
11107 TREE_USED (var) = 1;
5ff904cd 11108
c7e4ee3a 11109 var = start_decl (var, FALSE);
702edf1d 11110
c7e4ee3a 11111 t = ffecom_1 (ADDR_EXPR, dt, t);
5ff904cd 11112
c7e4ee3a 11113 finish_decl (var, t, FALSE);
5ff904cd 11114
c7e4ee3a
CB
11115 resume_momentary (yes);
11116 }
11117
11118 /* This handles any COMMON areas that weren't referenced but have, for
11119 example, important initial data. */
11120
11121 for (item = ffecom_list_common_;
11122 item != NULL;
11123 item = ffebld_trail (item))
11124 ffecom_transform_common_ (ffebld_symter (ffebld_head (item)));
11125
11126 ffecom_list_common_ = NULL;
5ff904cd 11127#endif
c7e4ee3a 11128}
5ff904cd 11129
c7e4ee3a 11130/* ffecom_exec_transition -- Perform exec transition on all symbols
5ff904cd 11131
c7e4ee3a 11132 ffecom_exec_transition();
5ff904cd 11133
c7e4ee3a
CB
11134 Calls ffecom_sym_exec_transition for each global and local symbol.
11135 Make sure error updating not inhibited. */
5ff904cd 11136
c7e4ee3a
CB
11137void
11138ffecom_exec_transition ()
11139{
11140 bool inhibited;
5ff904cd 11141
c7e4ee3a
CB
11142 if (ffe_is_ffedebug ())
11143 fprintf (dmpout, "; exec_stmt_transition\n");
5ff904cd 11144
c7e4ee3a
CB
11145 inhibited = ffebad_inhibit ();
11146 ffebad_set_inhibit (FALSE);
5ff904cd 11147
c7e4ee3a
CB
11148 ffesymbol_drive (ffecom_sym_exec_transition); /* Don't retract! */
11149 ffeequiv_exec_transition (); /* Handle all pending EQUIVALENCEs. */
11150 if (ffe_is_ffedebug ())
5ff904cd 11151 {
c7e4ee3a
CB
11152 ffestorag_report ();
11153#if FFECOM_targetCURRENT == FFECOM_targetFFE
11154 ffesymbol_report_all ();
11155#endif
11156 }
5ff904cd 11157
c7e4ee3a
CB
11158 if (inhibited)
11159 ffebad_set_inhibit (TRUE);
11160}
5ff904cd 11161
c7e4ee3a 11162/* Handle assignment statement.
5ff904cd 11163
c7e4ee3a
CB
11164 Convert dest and source using ffecom_expr, then join them
11165 with an ASSIGN op and pass the whole thing to expand_expr_stmt. */
5ff904cd 11166
c7e4ee3a
CB
11167#if FFECOM_targetCURRENT == FFECOM_targetGCC
11168void
11169ffecom_expand_let_stmt (ffebld dest, ffebld source)
11170{
11171 tree dest_tree;
11172 tree dest_length;
11173 tree source_tree;
11174 tree expr_tree;
5ff904cd 11175
c7e4ee3a
CB
11176 if (ffeinfo_basictype (ffebld_info (dest)) != FFEINFO_basictypeCHARACTER)
11177 {
11178 bool dest_used;
d6cd84e0 11179 tree assign_temp;
5ff904cd 11180
c7e4ee3a
CB
11181 /* This attempts to replicate the test below, but must not be
11182 true when the test below is false. (Always err on the side
11183 of creating unused temporaries, to avoid ICEs.) */
11184 if (ffebld_op (dest) != FFEBLD_opSYMTER
11185 || ((dest_tree = ffesymbol_hook (ffebld_symter (dest)).decl_tree)
11186 && (TREE_CODE (dest_tree) != VAR_DECL
11187 || TREE_ADDRESSABLE (dest_tree))))
11188 {
11189 ffecom_prepare_expr_ (source, dest);
11190 dest_used = TRUE;
11191 }
11192 else
11193 {
11194 ffecom_prepare_expr_ (source, NULL);
11195 dest_used = FALSE;
11196 }
5ff904cd 11197
c7e4ee3a 11198 ffecom_prepare_expr_w (NULL_TREE, dest);
5ff904cd 11199
d6cd84e0
CB
11200 /* For COMPLEX assignment like C1=C2, if partial overlap is possible,
11201 create a temporary through which the assignment is to take place,
11202 since MODIFY_EXPR doesn't handle partial overlap properly. */
11203 if (ffebld_basictype (dest) == FFEINFO_basictypeCOMPLEX
11204 && ffecom_possible_partial_overlap_ (dest, source))
11205 {
11206 assign_temp = ffecom_make_tempvar ("complex_let",
11207 ffecom_tree_type
11208 [ffebld_basictype (dest)]
11209 [ffebld_kindtype (dest)],
11210 FFETARGET_charactersizeNONE,
11211 -1);
11212 }
11213 else
11214 assign_temp = NULL_TREE;
11215
c7e4ee3a 11216 ffecom_prepare_end ();
5ff904cd 11217
c7e4ee3a
CB
11218 dest_tree = ffecom_expr_w (NULL_TREE, dest);
11219 if (dest_tree == error_mark_node)
11220 return;
5ff904cd 11221
c7e4ee3a
CB
11222 if ((TREE_CODE (dest_tree) != VAR_DECL)
11223 || TREE_ADDRESSABLE (dest_tree))
11224 source_tree = ffecom_expr_ (source, dest_tree, dest, &dest_used,
11225 FALSE, FALSE);
11226 else
11227 {
11228 assert (! dest_used);
11229 dest_used = FALSE;
11230 source_tree = ffecom_expr (source);
11231 }
11232 if (source_tree == error_mark_node)
11233 return;
5ff904cd 11234
c7e4ee3a
CB
11235 if (dest_used)
11236 expr_tree = source_tree;
d6cd84e0
CB
11237 else if (assign_temp)
11238 {
11239#ifdef MOVE_EXPR
11240 /* The back end understands a conceptual move (evaluate source;
11241 store into dest), so use that, in case it can determine
11242 that it is going to use, say, two registers as temporaries
11243 anyway. So don't use the temp (and someday avoid generating
11244 it, once this code starts triggering regularly). */
11245 expr_tree = ffecom_2s (MOVE_EXPR, void_type_node,
11246 dest_tree,
11247 source_tree);
11248#else
11249 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
11250 assign_temp,
11251 source_tree);
11252 expand_expr_stmt (expr_tree);
11253 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
11254 dest_tree,
11255 assign_temp);
11256#endif
11257 }
c7e4ee3a
CB
11258 else
11259 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
11260 dest_tree,
11261 source_tree);
5ff904cd 11262
c7e4ee3a
CB
11263 expand_expr_stmt (expr_tree);
11264 return;
11265 }
5ff904cd 11266
c7e4ee3a
CB
11267 ffecom_prepare_let_char_ (ffebld_size_known (dest), source);
11268 ffecom_prepare_expr_w (NULL_TREE, dest);
11269
11270 ffecom_prepare_end ();
11271
11272 ffecom_char_args_ (&dest_tree, &dest_length, dest);
11273 ffecom_let_char_ (dest_tree, dest_length, ffebld_size_known (dest),
11274 source);
5ff904cd
JL
11275}
11276
11277#endif
c7e4ee3a 11278/* ffecom_expr -- Transform expr into gcc tree
5ff904cd 11279
c7e4ee3a
CB
11280 tree t;
11281 ffebld expr; // FFE expression.
11282 tree = ffecom_expr(expr);
5ff904cd 11283
c7e4ee3a
CB
11284 Recursive descent on expr while making corresponding tree nodes and
11285 attaching type info and such. */
5ff904cd
JL
11286
11287#if FFECOM_targetCURRENT == FFECOM_targetGCC
11288tree
c7e4ee3a 11289ffecom_expr (ffebld expr)
5ff904cd 11290{
c7e4ee3a 11291 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, FALSE, FALSE);
5ff904cd 11292}
c7e4ee3a 11293
5ff904cd 11294#endif
c7e4ee3a 11295/* Like ffecom_expr, but return tree usable for assigned GOTO or FORMAT. */
5ff904cd 11296
c7e4ee3a
CB
11297#if FFECOM_targetCURRENT == FFECOM_targetGCC
11298tree
11299ffecom_expr_assign (ffebld expr)
11300{
11301 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, TRUE, FALSE);
11302}
5ff904cd 11303
c7e4ee3a
CB
11304#endif
11305/* Like ffecom_expr_rw, but return tree usable for ASSIGN. */
5ff904cd
JL
11306
11307#if FFECOM_targetCURRENT == FFECOM_targetGCC
11308tree
c7e4ee3a 11309ffecom_expr_assign_w (ffebld expr)
5ff904cd 11310{
c7e4ee3a
CB
11311 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, TRUE, FALSE);
11312}
5ff904cd 11313
5ff904cd 11314#endif
c7e4ee3a
CB
11315/* Transform expr for use as into read/write tree and stabilize the
11316 reference. Not for use on CHARACTER expressions.
5ff904cd 11317
c7e4ee3a
CB
11318 Recursive descent on expr while making corresponding tree nodes and
11319 attaching type info and such. */
5ff904cd 11320
c7e4ee3a
CB
11321#if FFECOM_targetCURRENT == FFECOM_targetGCC
11322tree
11323ffecom_expr_rw (tree type, ffebld expr)
11324{
11325 assert (expr != NULL);
11326 /* Different target types not yet supported. */
11327 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
11328
11329 return stabilize_reference (ffecom_expr (expr));
11330}
5ff904cd 11331
5ff904cd 11332#endif
c7e4ee3a
CB
11333/* Transform expr for use as into write tree and stabilize the
11334 reference. Not for use on CHARACTER expressions.
5ff904cd 11335
c7e4ee3a
CB
11336 Recursive descent on expr while making corresponding tree nodes and
11337 attaching type info and such. */
5ff904cd 11338
c7e4ee3a
CB
11339#if FFECOM_targetCURRENT == FFECOM_targetGCC
11340tree
11341ffecom_expr_w (tree type, ffebld expr)
11342{
11343 assert (expr != NULL);
11344 /* Different target types not yet supported. */
11345 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
11346
11347 return stabilize_reference (ffecom_expr (expr));
11348}
5ff904cd 11349
5ff904cd 11350#endif
c7e4ee3a
CB
11351/* Do global stuff. */
11352
11353#if FFECOM_targetCURRENT == FFECOM_targetGCC
11354void
11355ffecom_finish_compile ()
11356{
11357 assert (ffecom_outer_function_decl_ == NULL_TREE);
11358 assert (current_function_decl == NULL_TREE);
11359
11360 ffeglobal_drive (ffecom_finish_global_);
11361}
5ff904cd 11362
5ff904cd 11363#endif
c7e4ee3a
CB
11364/* Public entry point for front end to access finish_decl. */
11365
11366#if FFECOM_targetCURRENT == FFECOM_targetGCC
11367void
11368ffecom_finish_decl (tree decl, tree init, bool is_top_level)
11369{
11370 assert (!is_top_level);
11371 finish_decl (decl, init, FALSE);
11372}
5ff904cd 11373
5ff904cd 11374#endif
c7e4ee3a
CB
11375/* Finish a program unit. */
11376
11377#if FFECOM_targetCURRENT == FFECOM_targetGCC
11378void
11379ffecom_finish_progunit ()
11380{
11381 ffecom_end_compstmt ();
11382
11383 ffecom_previous_function_decl_ = current_function_decl;
11384 ffecom_which_entrypoint_decl_ = NULL_TREE;
11385
11386 finish_function (0);
11387}
5ff904cd 11388
5ff904cd 11389#endif
14657de8
KG
11390
11391/* Wrapper for get_identifier. pattern is sprintf-like. */
c7e4ee3a
CB
11392
11393#if FFECOM_targetCURRENT == FFECOM_targetGCC
11394tree
14657de8 11395ffecom_get_invented_identifier (const char *pattern, ...)
c7e4ee3a
CB
11396{
11397 tree decl;
11398 char *nam;
14657de8 11399 va_list ap;
c7e4ee3a 11400
14657de8
KG
11401 va_start (ap, pattern);
11402 if (vasprintf (&nam, pattern, ap) == 0)
11403 abort ();
11404 va_end (ap);
c7e4ee3a 11405 decl = get_identifier (nam);
14657de8 11406 free (nam);
c7e4ee3a 11407 IDENTIFIER_INVENTED (decl) = 1;
c7e4ee3a
CB
11408 return decl;
11409}
11410
11411ffeinfoBasictype
11412ffecom_gfrt_basictype (ffecomGfrt gfrt)
11413{
11414 assert (gfrt < FFECOM_gfrt);
11415
11416 switch (ffecom_gfrt_type_[gfrt])
11417 {
11418 case FFECOM_rttypeVOID_:
11419 case FFECOM_rttypeVOIDSTAR_:
11420 return FFEINFO_basictypeNONE;
11421
11422 case FFECOM_rttypeFTNINT_:
11423 return FFEINFO_basictypeINTEGER;
11424
11425 case FFECOM_rttypeINTEGER_:
11426 return FFEINFO_basictypeINTEGER;
11427
11428 case FFECOM_rttypeLONGINT_:
11429 return FFEINFO_basictypeINTEGER;
11430
11431 case FFECOM_rttypeLOGICAL_:
11432 return FFEINFO_basictypeLOGICAL;
11433
11434 case FFECOM_rttypeREAL_F2C_:
11435 case FFECOM_rttypeREAL_GNU_:
11436 return FFEINFO_basictypeREAL;
11437
11438 case FFECOM_rttypeCOMPLEX_F2C_:
11439 case FFECOM_rttypeCOMPLEX_GNU_:
11440 return FFEINFO_basictypeCOMPLEX;
11441
11442 case FFECOM_rttypeDOUBLE_:
11443 case FFECOM_rttypeDOUBLEREAL_:
11444 return FFEINFO_basictypeREAL;
11445
11446 case FFECOM_rttypeDBLCMPLX_F2C_:
11447 case FFECOM_rttypeDBLCMPLX_GNU_:
11448 return FFEINFO_basictypeCOMPLEX;
11449
11450 case FFECOM_rttypeCHARACTER_:
11451 return FFEINFO_basictypeCHARACTER;
11452
11453 default:
11454 return FFEINFO_basictypeANY;
11455 }
11456}
11457
11458ffeinfoKindtype
11459ffecom_gfrt_kindtype (ffecomGfrt gfrt)
11460{
11461 assert (gfrt < FFECOM_gfrt);
11462
11463 switch (ffecom_gfrt_type_[gfrt])
11464 {
11465 case FFECOM_rttypeVOID_:
11466 case FFECOM_rttypeVOIDSTAR_:
11467 return FFEINFO_kindtypeNONE;
5ff904cd 11468
c7e4ee3a
CB
11469 case FFECOM_rttypeFTNINT_:
11470 return FFEINFO_kindtypeINTEGER1;
5ff904cd 11471
c7e4ee3a
CB
11472 case FFECOM_rttypeINTEGER_:
11473 return FFEINFO_kindtypeINTEGER1;
5ff904cd 11474
c7e4ee3a
CB
11475 case FFECOM_rttypeLONGINT_:
11476 return FFEINFO_kindtypeINTEGER4;
5ff904cd 11477
c7e4ee3a
CB
11478 case FFECOM_rttypeLOGICAL_:
11479 return FFEINFO_kindtypeLOGICAL1;
5ff904cd 11480
c7e4ee3a
CB
11481 case FFECOM_rttypeREAL_F2C_:
11482 case FFECOM_rttypeREAL_GNU_:
11483 return FFEINFO_kindtypeREAL1;
5ff904cd 11484
c7e4ee3a
CB
11485 case FFECOM_rttypeCOMPLEX_F2C_:
11486 case FFECOM_rttypeCOMPLEX_GNU_:
11487 return FFEINFO_kindtypeREAL1;
5ff904cd 11488
c7e4ee3a
CB
11489 case FFECOM_rttypeDOUBLE_:
11490 case FFECOM_rttypeDOUBLEREAL_:
11491 return FFEINFO_kindtypeREAL2;
5ff904cd 11492
c7e4ee3a
CB
11493 case FFECOM_rttypeDBLCMPLX_F2C_:
11494 case FFECOM_rttypeDBLCMPLX_GNU_:
11495 return FFEINFO_kindtypeREAL2;
5ff904cd 11496
c7e4ee3a
CB
11497 case FFECOM_rttypeCHARACTER_:
11498 return FFEINFO_kindtypeCHARACTER1;
5ff904cd 11499
c7e4ee3a
CB
11500 default:
11501 return FFEINFO_kindtypeANY;
11502 }
11503}
5ff904cd 11504
c7e4ee3a
CB
11505void
11506ffecom_init_0 ()
11507{
11508 tree endlink;
11509 int i;
11510 int j;
11511 tree t;
11512 tree field;
11513 ffetype type;
11514 ffetype base_type;
7189a4b0
GK
11515 tree double_ftype_double;
11516 tree float_ftype_float;
11517 tree ldouble_ftype_ldouble;
11518 tree ffecom_tree_ptr_to_fun_type_void;
5ff904cd 11519
c7e4ee3a
CB
11520 /* This block of code comes from the now-obsolete cktyps.c. It checks
11521 whether the compiler environment is buggy in known ways, some of which
11522 would, if not explicitly checked here, result in subtle bugs in g77. */
5ff904cd 11523
c7e4ee3a
CB
11524 if (ffe_is_do_internal_checks ())
11525 {
11526 static char names[][12]
11527 =
11528 {"bar", "bletch", "foo", "foobar"};
11529 char *name;
11530 unsigned long ul;
11531 double fl;
5ff904cd 11532
c7e4ee3a 11533 name = bsearch ("foo", &names[0], ARRAY_SIZE (names), sizeof (names[0]),
b0791fa9 11534 (int (*)(const void *, const void *)) strcmp);
c7e4ee3a
CB
11535 if (name != (char *) &names[2])
11536 {
11537 assert ("bsearch doesn't work, #define FFEPROJ_BSEARCH 0 in proj.h"
11538 == NULL);
11539 abort ();
11540 }
5ff904cd 11541
c7e4ee3a
CB
11542 ul = strtoul ("123456789", NULL, 10);
11543 if (ul != 123456789L)
11544 {
11545 assert ("strtoul doesn't have enough range, #define FFEPROJ_STRTOUL 0\
11546 in proj.h" == NULL);
11547 abort ();
11548 }
5ff904cd 11549
c7e4ee3a
CB
11550 fl = atof ("56.789");
11551 if ((fl < 56.788) || (fl > 56.79))
11552 {
11553 assert ("atof not type double, fix your #include <stdio.h>"
11554 == NULL);
11555 abort ();
11556 }
11557 }
5ff904cd 11558
c7e4ee3a
CB
11559#if FFECOM_GCC_INCLUDE
11560 ffecom_initialize_char_syntax_ ();
11561#endif
5ff904cd 11562
c7e4ee3a
CB
11563 ffecom_outer_function_decl_ = NULL_TREE;
11564 current_function_decl = NULL_TREE;
11565 named_labels = NULL_TREE;
11566 current_binding_level = NULL_BINDING_LEVEL;
11567 free_binding_level = NULL_BINDING_LEVEL;
11568 /* Make the binding_level structure for global names. */
11569 pushlevel (0);
11570 global_binding_level = current_binding_level;
11571 current_binding_level->prep_state = 2;
5ff904cd 11572
81b3411c 11573 build_common_tree_nodes (1);
5ff904cd 11574
81b3411c 11575 /* Define `int' and `char' first so that dbx will output them first. */
c7e4ee3a
CB
11576 pushdecl (build_decl (TYPE_DECL, get_identifier ("int"),
11577 integer_type_node));
c7e4ee3a
CB
11578 pushdecl (build_decl (TYPE_DECL, get_identifier ("char"),
11579 char_type_node));
c7e4ee3a
CB
11580 pushdecl (build_decl (TYPE_DECL, get_identifier ("long int"),
11581 long_integer_type_node));
c7e4ee3a
CB
11582 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned int"),
11583 unsigned_type_node));
c7e4ee3a
CB
11584 pushdecl (build_decl (TYPE_DECL, get_identifier ("long unsigned int"),
11585 long_unsigned_type_node));
c7e4ee3a
CB
11586 pushdecl (build_decl (TYPE_DECL, get_identifier ("long long int"),
11587 long_long_integer_type_node));
c7e4ee3a
CB
11588 pushdecl (build_decl (TYPE_DECL, get_identifier ("long long unsigned int"),
11589 long_long_unsigned_type_node));
c7e4ee3a
CB
11590 pushdecl (build_decl (TYPE_DECL, get_identifier ("short int"),
11591 short_integer_type_node));
c7e4ee3a
CB
11592 pushdecl (build_decl (TYPE_DECL, get_identifier ("short unsigned int"),
11593 short_unsigned_type_node));
5ff904cd 11594
ff852b44
CB
11595 /* Set the sizetype before we make other types. This *should* be the
11596 first type we create. */
11597
11598 set_sizetype
11599 (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE))));
11600 ffecom_typesize_pointer_
11601 = TREE_INT_CST_LOW (TYPE_SIZE (sizetype)) / BITS_PER_UNIT;
11602
81b3411c 11603 build_common_tree_nodes_2 (0);
ff852b44 11604
c7e4ee3a 11605 /* Define both `signed char' and `unsigned char'. */
c7e4ee3a
CB
11606 pushdecl (build_decl (TYPE_DECL, get_identifier ("signed char"),
11607 signed_char_type_node));
5ff904cd 11608
c7e4ee3a
CB
11609 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned char"),
11610 unsigned_char_type_node));
5ff904cd 11611
c7e4ee3a
CB
11612 pushdecl (build_decl (TYPE_DECL, get_identifier ("float"),
11613 float_type_node));
c7e4ee3a
CB
11614 pushdecl (build_decl (TYPE_DECL, get_identifier ("double"),
11615 double_type_node));
c7e4ee3a
CB
11616 pushdecl (build_decl (TYPE_DECL, get_identifier ("long double"),
11617 long_double_type_node));
5ff904cd 11618
81b3411c 11619 /* For now, override what build_common_tree_nodes has done. */
c7e4ee3a 11620 complex_integer_type_node = ffecom_make_complex_type_ (integer_type_node);
81b3411c
BS
11621 complex_float_type_node = ffecom_make_complex_type_ (float_type_node);
11622 complex_double_type_node = ffecom_make_complex_type_ (double_type_node);
11623 complex_long_double_type_node
11624 = ffecom_make_complex_type_ (long_double_type_node);
11625
c7e4ee3a
CB
11626 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex int"),
11627 complex_integer_type_node));
c7e4ee3a
CB
11628 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex float"),
11629 complex_float_type_node));
c7e4ee3a
CB
11630 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex double"),
11631 complex_double_type_node));
c7e4ee3a
CB
11632 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex long double"),
11633 complex_long_double_type_node));
5ff904cd 11634
c7e4ee3a
CB
11635 pushdecl (build_decl (TYPE_DECL, get_identifier ("void"),
11636 void_type_node));
c7e4ee3a
CB
11637 /* We are not going to have real types in C with less than byte alignment,
11638 so we might as well not have any types that claim to have it. */
11639 TYPE_ALIGN (void_type_node) = BITS_PER_UNIT;
5ff904cd 11640
c7e4ee3a 11641 string_type_node = build_pointer_type (char_type_node);
5ff904cd 11642
c7e4ee3a
CB
11643 ffecom_tree_fun_type_void
11644 = build_function_type (void_type_node, NULL_TREE);
5ff904cd 11645
c7e4ee3a
CB
11646 ffecom_tree_ptr_to_fun_type_void
11647 = build_pointer_type (ffecom_tree_fun_type_void);
5ff904cd 11648
c7e4ee3a 11649 endlink = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
5ff904cd 11650
c7e4ee3a
CB
11651 float_ftype_float
11652 = build_function_type (float_type_node,
11653 tree_cons (NULL_TREE, float_type_node, endlink));
5ff904cd 11654
c7e4ee3a
CB
11655 double_ftype_double
11656 = build_function_type (double_type_node,
11657 tree_cons (NULL_TREE, double_type_node, endlink));
5ff904cd 11658
c7e4ee3a
CB
11659 ldouble_ftype_ldouble
11660 = build_function_type (long_double_type_node,
11661 tree_cons (NULL_TREE, long_double_type_node,
11662 endlink));
5ff904cd 11663
c7e4ee3a
CB
11664 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11665 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11666 {
11667 ffecom_tree_type[i][j] = NULL_TREE;
11668 ffecom_tree_fun_type[i][j] = NULL_TREE;
11669 ffecom_tree_ptr_to_fun_type[i][j] = NULL_TREE;
11670 ffecom_f2c_typecode_[i][j] = -1;
11671 }
5ff904cd 11672
c7e4ee3a
CB
11673 /* Set up standard g77 types. Note that INTEGER and LOGICAL are set
11674 to size FLOAT_TYPE_SIZE because they have to be the same size as
11675 REAL, which also is FLOAT_TYPE_SIZE, according to the standard.
11676 Compiler options and other such stuff that change the ways these
11677 types are set should not affect this particular setup. */
5ff904cd 11678
c7e4ee3a
CB
11679 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER1]
11680 = t = make_signed_type (FLOAT_TYPE_SIZE);
11681 pushdecl (build_decl (TYPE_DECL, get_identifier ("integer"),
11682 t));
11683 type = ffetype_new ();
11684 base_type = type;
11685 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER1,
11686 type);
11687 ffetype_set_ams (type,
11688 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11689 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11690 ffetype_set_star (base_type,
11691 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11692 type);
11693 ffetype_set_kind (base_type, 1, type);
ff852b44 11694 ffecom_typesize_integer1_ = ffetype_size (type);
c7e4ee3a 11695 assert (ffetype_size (type) == sizeof (ffetargetInteger1));
5ff904cd 11696
c7e4ee3a
CB
11697 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER1]
11698 = t = make_unsigned_type (FLOAT_TYPE_SIZE); /* HOLLERITH means unsigned. */
11699 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned"),
11700 t));
5ff904cd 11701
c7e4ee3a
CB
11702 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER2]
11703 = t = make_signed_type (CHAR_TYPE_SIZE);
11704 pushdecl (build_decl (TYPE_DECL, get_identifier ("byte"),
11705 t));
11706 type = ffetype_new ();
11707 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER2,
11708 type);
11709 ffetype_set_ams (type,
11710 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11711 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11712 ffetype_set_star (base_type,
11713 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11714 type);
11715 ffetype_set_kind (base_type, 3, type);
11716 assert (ffetype_size (type) == sizeof (ffetargetInteger2));
5ff904cd 11717
c7e4ee3a
CB
11718 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER2]
11719 = t = make_unsigned_type (CHAR_TYPE_SIZE);
11720 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned byte"),
11721 t));
11722
11723 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER3]
11724 = t = make_signed_type (CHAR_TYPE_SIZE * 2);
11725 pushdecl (build_decl (TYPE_DECL, get_identifier ("word"),
11726 t));
11727 type = ffetype_new ();
11728 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER3,
11729 type);
11730 ffetype_set_ams (type,
11731 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11732 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11733 ffetype_set_star (base_type,
11734 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11735 type);
11736 ffetype_set_kind (base_type, 6, type);
11737 assert (ffetype_size (type) == sizeof (ffetargetInteger3));
5ff904cd 11738
c7e4ee3a
CB
11739 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER3]
11740 = t = make_unsigned_type (CHAR_TYPE_SIZE * 2);
11741 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned word"),
11742 t));
5ff904cd 11743
c7e4ee3a
CB
11744 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER4]
11745 = t = make_signed_type (FLOAT_TYPE_SIZE * 2);
11746 pushdecl (build_decl (TYPE_DECL, get_identifier ("integer4"),
11747 t));
11748 type = ffetype_new ();
11749 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER4,
11750 type);
11751 ffetype_set_ams (type,
11752 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11753 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11754 ffetype_set_star (base_type,
11755 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11756 type);
11757 ffetype_set_kind (base_type, 2, type);
11758 assert (ffetype_size (type) == sizeof (ffetargetInteger4));
5ff904cd 11759
c7e4ee3a
CB
11760 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER4]
11761 = t = make_unsigned_type (FLOAT_TYPE_SIZE * 2);
11762 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned4"),
11763 t));
5ff904cd 11764
c7e4ee3a
CB
11765#if 0
11766 if (ffe_is_do_internal_checks ()
11767 && LONG_TYPE_SIZE != FLOAT_TYPE_SIZE
11768 && LONG_TYPE_SIZE != CHAR_TYPE_SIZE
11769 && LONG_TYPE_SIZE != SHORT_TYPE_SIZE
11770 && LONG_TYPE_SIZE != LONG_LONG_TYPE_SIZE)
5ff904cd 11771 {
c7e4ee3a
CB
11772 fprintf (stderr, "Sorry, no g77 support for LONG_TYPE_SIZE (%d bits) yet.\n",
11773 LONG_TYPE_SIZE);
5ff904cd 11774 }
c7e4ee3a 11775#endif
5ff904cd 11776
c7e4ee3a
CB
11777 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL1]
11778 = t = make_signed_type (FLOAT_TYPE_SIZE);
11779 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical"),
11780 t));
11781 type = ffetype_new ();
11782 base_type = type;
11783 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL1,
11784 type);
11785 ffetype_set_ams (type,
11786 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11787 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11788 ffetype_set_star (base_type,
11789 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11790 type);
11791 ffetype_set_kind (base_type, 1, type);
11792 assert (ffetype_size (type) == sizeof (ffetargetLogical1));
5ff904cd 11793
c7e4ee3a
CB
11794 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL2]
11795 = t = make_signed_type (CHAR_TYPE_SIZE);
11796 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical2"),
11797 t));
11798 type = ffetype_new ();
11799 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL2,
11800 type);
11801 ffetype_set_ams (type,
11802 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11803 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11804 ffetype_set_star (base_type,
11805 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11806 type);
11807 ffetype_set_kind (base_type, 3, type);
11808 assert (ffetype_size (type) == sizeof (ffetargetLogical2));
5ff904cd 11809
c7e4ee3a
CB
11810 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL3]
11811 = t = make_signed_type (CHAR_TYPE_SIZE * 2);
11812 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical3"),
11813 t));
11814 type = ffetype_new ();
11815 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL3,
11816 type);
11817 ffetype_set_ams (type,
11818 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11819 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11820 ffetype_set_star (base_type,
11821 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11822 type);
11823 ffetype_set_kind (base_type, 6, type);
11824 assert (ffetype_size (type) == sizeof (ffetargetLogical3));
5ff904cd 11825
c7e4ee3a
CB
11826 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL4]
11827 = t = make_signed_type (FLOAT_TYPE_SIZE * 2);
11828 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical4"),
11829 t));
11830 type = ffetype_new ();
11831 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL4,
11832 type);
11833 ffetype_set_ams (type,
11834 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11835 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11836 ffetype_set_star (base_type,
11837 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11838 type);
11839 ffetype_set_kind (base_type, 2, type);
11840 assert (ffetype_size (type) == sizeof (ffetargetLogical4));
5ff904cd 11841
c7e4ee3a
CB
11842 ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]
11843 = t = make_node (REAL_TYPE);
11844 TYPE_PRECISION (t) = FLOAT_TYPE_SIZE;
11845 pushdecl (build_decl (TYPE_DECL, get_identifier ("real"),
11846 t));
11847 layout_type (t);
11848 type = ffetype_new ();
11849 base_type = type;
11850 ffeinfo_set_type (FFEINFO_basictypeREAL, FFEINFO_kindtypeREAL1,
11851 type);
11852 ffetype_set_ams (type,
11853 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11854 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11855 ffetype_set_star (base_type,
11856 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11857 type);
11858 ffetype_set_kind (base_type, 1, type);
11859 ffecom_f2c_typecode_[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]
11860 = FFETARGET_f2cTYREAL;
11861 assert (ffetype_size (type) == sizeof (ffetargetReal1));
5ff904cd 11862
c7e4ee3a
CB
11863 ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREALDOUBLE]
11864 = t = make_node (REAL_TYPE);
11865 TYPE_PRECISION (t) = FLOAT_TYPE_SIZE * 2; /* Always twice REAL. */
11866 pushdecl (build_decl (TYPE_DECL, get_identifier ("double precision"),
11867 t));
11868 layout_type (t);
11869 type = ffetype_new ();
11870 ffeinfo_set_type (FFEINFO_basictypeREAL, FFEINFO_kindtypeREALDOUBLE,
11871 type);
11872 ffetype_set_ams (type,
11873 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11874 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11875 ffetype_set_star (base_type,
11876 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11877 type);
11878 ffetype_set_kind (base_type, 2, type);
11879 ffecom_f2c_typecode_[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2]
11880 = FFETARGET_f2cTYDREAL;
11881 assert (ffetype_size (type) == sizeof (ffetargetReal2));
5ff904cd 11882
c7e4ee3a
CB
11883 ffecom_tree_type[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL1]
11884 = t = ffecom_make_complex_type_ (ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]);
11885 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex"),
11886 t));
11887 type = ffetype_new ();
11888 base_type = type;
11889 ffeinfo_set_type (FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREAL1,
11890 type);
11891 ffetype_set_ams (type,
11892 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11893 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11894 ffetype_set_star (base_type,
11895 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11896 type);
11897 ffetype_set_kind (base_type, 1, type);
11898 ffecom_f2c_typecode_[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL1]
11899 = FFETARGET_f2cTYCOMPLEX;
11900 assert (ffetype_size (type) == sizeof (ffetargetComplex1));
5ff904cd 11901
c7e4ee3a
CB
11902 ffecom_tree_type[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREALDOUBLE]
11903 = t = ffecom_make_complex_type_ (ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2]);
11904 pushdecl (build_decl (TYPE_DECL, get_identifier ("double complex"),
11905 t));
11906 type = ffetype_new ();
11907 ffeinfo_set_type (FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREALDOUBLE,
11908 type);
11909 ffetype_set_ams (type,
11910 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11911 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11912 ffetype_set_star (base_type,
11913 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11914 type);
11915 ffetype_set_kind (base_type, 2,
11916 type);
11917 ffecom_f2c_typecode_[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL2]
11918 = FFETARGET_f2cTYDCOMPLEX;
11919 assert (ffetype_size (type) == sizeof (ffetargetComplex2));
5ff904cd 11920
c7e4ee3a 11921 /* Make function and ptr-to-function types for non-CHARACTER types. */
5ff904cd 11922
c7e4ee3a
CB
11923 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11924 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11925 {
11926 if ((t = ffecom_tree_type[i][j]) != NULL_TREE)
11927 {
11928 if (i == FFEINFO_basictypeINTEGER)
11929 {
11930 /* Figure out the smallest INTEGER type that can hold
11931 a pointer on this machine. */
11932 if (GET_MODE_SIZE (TYPE_MODE (t))
11933 >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
11934 {
11935 if ((ffecom_pointer_kind_ == FFEINFO_kindtypeNONE)
11936 || (GET_MODE_SIZE (TYPE_MODE (ffecom_tree_type[i][ffecom_pointer_kind_]))
11937 > GET_MODE_SIZE (TYPE_MODE (t))))
11938 ffecom_pointer_kind_ = j;
11939 }
11940 }
11941 else if (i == FFEINFO_basictypeCOMPLEX)
11942 t = void_type_node;
11943 /* For f2c compatibility, REAL functions are really
11944 implemented as DOUBLE PRECISION. */
11945 else if ((i == FFEINFO_basictypeREAL)
11946 && (j == FFEINFO_kindtypeREAL1))
11947 t = ffecom_tree_type
11948 [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2];
5ff904cd 11949
c7e4ee3a
CB
11950 t = ffecom_tree_fun_type[i][j] = build_function_type (t,
11951 NULL_TREE);
11952 ffecom_tree_ptr_to_fun_type[i][j] = build_pointer_type (t);
11953 }
11954 }
5ff904cd 11955
c7e4ee3a 11956 /* Set up pointer types. */
5ff904cd 11957
c7e4ee3a
CB
11958 if (ffecom_pointer_kind_ == FFEINFO_basictypeNONE)
11959 fatal ("no INTEGER type can hold a pointer on this configuration");
11960 else if (0 && ffe_is_do_internal_checks ())
11961 fprintf (stderr, "Pointer type kt=%d\n", ffecom_pointer_kind_);
11962 ffetype_set_kind (ffeinfo_type (FFEINFO_basictypeINTEGER,
11963 FFEINFO_kindtypeINTEGERDEFAULT),
11964 7,
11965 ffeinfo_type (FFEINFO_basictypeINTEGER,
11966 ffecom_pointer_kind_));
5ff904cd 11967
c7e4ee3a
CB
11968 if (ffe_is_ugly_assign ())
11969 ffecom_label_kind_ = ffecom_pointer_kind_; /* Require ASSIGN etc to this. */
11970 else
11971 ffecom_label_kind_ = FFEINFO_kindtypeINTEGERDEFAULT;
11972 if (0 && ffe_is_do_internal_checks ())
11973 fprintf (stderr, "Label type kt=%d\n", ffecom_label_kind_);
5ff904cd 11974
c7e4ee3a
CB
11975 ffecom_integer_type_node
11976 = ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER1];
11977 ffecom_integer_zero_node = convert (ffecom_integer_type_node,
11978 integer_zero_node);
11979 ffecom_integer_one_node = convert (ffecom_integer_type_node,
11980 integer_one_node);
5ff904cd 11981
c7e4ee3a
CB
11982 /* Yes, the "FLOAT_TYPE_SIZE" references below are intentional.
11983 Turns out that by TYLONG, runtime/libI77/lio.h really means
11984 "whatever size an ftnint is". For consistency and sanity,
11985 com.h and runtime/f2c.h.in agree that flag, ftnint, and ftlen
11986 all are INTEGER, which we also make out of whatever back-end
11987 integer type is FLOAT_TYPE_SIZE bits wide. This change, from
11988 LONG_TYPE_SIZE, for TYLONG and TYLOGICAL, was necessary to
11989 accommodate machines like the Alpha. Note that this suggests
11990 f2c and libf2c are missing a distinction perhaps needed on
11991 some machines between "int" and "long int". -- burley 0.5.5 950215 */
5ff904cd 11992
c7e4ee3a
CB
11993 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, FLOAT_TYPE_SIZE,
11994 FFETARGET_f2cTYLONG);
11995 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, SHORT_TYPE_SIZE,
11996 FFETARGET_f2cTYSHORT);
11997 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, CHAR_TYPE_SIZE,
11998 FFETARGET_f2cTYINT1);
11999 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, LONG_LONG_TYPE_SIZE,
12000 FFETARGET_f2cTYQUAD);
12001 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, FLOAT_TYPE_SIZE,
12002 FFETARGET_f2cTYLOGICAL);
12003 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, SHORT_TYPE_SIZE,
12004 FFETARGET_f2cTYLOGICAL2);
12005 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, CHAR_TYPE_SIZE,
12006 FFETARGET_f2cTYLOGICAL1);
12007 /* ~~~Not really such a type in libf2c, e.g. I/O support? */
12008 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, LONG_LONG_TYPE_SIZE,
12009 FFETARGET_f2cTYQUAD);
5ff904cd 12010
c7e4ee3a
CB
12011 /* CHARACTER stuff is all special-cased, so it is not handled in the above
12012 loop. CHARACTER items are built as arrays of unsigned char. */
5ff904cd 12013
c7e4ee3a
CB
12014 ffecom_tree_type[FFEINFO_basictypeCHARACTER]
12015 [FFEINFO_kindtypeCHARACTER1] = t = char_type_node;
12016 type = ffetype_new ();
12017 base_type = type;
12018 ffeinfo_set_type (FFEINFO_basictypeCHARACTER,
12019 FFEINFO_kindtypeCHARACTER1,
12020 type);
12021 ffetype_set_ams (type,
12022 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
12023 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
12024 ffetype_set_kind (base_type, 1, type);
12025 assert (ffetype_size (type)
12026 == sizeof (((ffetargetCharacter1) { 0, NULL }).text[0]));
5ff904cd 12027
c7e4ee3a
CB
12028 ffecom_tree_fun_type[FFEINFO_basictypeCHARACTER]
12029 [FFEINFO_kindtypeCHARACTER1] = ffecom_tree_fun_type_void;
12030 ffecom_tree_ptr_to_fun_type[FFEINFO_basictypeCHARACTER]
12031 [FFEINFO_kindtypeCHARACTER1]
12032 = ffecom_tree_ptr_to_fun_type_void;
12033 ffecom_f2c_typecode_[FFEINFO_basictypeCHARACTER][FFEINFO_kindtypeCHARACTER1]
12034 = FFETARGET_f2cTYCHAR;
5ff904cd 12035
c7e4ee3a
CB
12036 ffecom_f2c_typecode_[FFEINFO_basictypeANY][FFEINFO_kindtypeANY]
12037 = 0;
5ff904cd 12038
c7e4ee3a 12039 /* Make multi-return-value type and fields. */
5ff904cd 12040
c7e4ee3a 12041 ffecom_multi_type_node_ = make_node (UNION_TYPE);
5ff904cd 12042
c7e4ee3a 12043 field = NULL_TREE;
5ff904cd 12044
c7e4ee3a
CB
12045 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
12046 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
12047 {
12048 char name[30];
5ff904cd 12049
c7e4ee3a
CB
12050 if (ffecom_tree_type[i][j] == NULL_TREE)
12051 continue; /* Not supported. */
12052 sprintf (&name[0], "bt_%s_kt_%s",
12053 ffeinfo_basictype_string ((ffeinfoBasictype) i),
12054 ffeinfo_kindtype_string ((ffeinfoKindtype) j));
12055 ffecom_multi_fields_[i][j] = build_decl (FIELD_DECL,
12056 get_identifier (name),
12057 ffecom_tree_type[i][j]);
12058 DECL_CONTEXT (ffecom_multi_fields_[i][j])
12059 = ffecom_multi_type_node_;
12060 DECL_FRAME_SIZE (ffecom_multi_fields_[i][j]) = 0;
12061 TREE_CHAIN (ffecom_multi_fields_[i][j]) = field;
12062 field = ffecom_multi_fields_[i][j];
12063 }
5ff904cd 12064
c7e4ee3a
CB
12065 TYPE_FIELDS (ffecom_multi_type_node_) = field;
12066 layout_type (ffecom_multi_type_node_);
5ff904cd 12067
c7e4ee3a
CB
12068 /* Subroutines usually return integer because they might have alternate
12069 returns. */
5ff904cd 12070
c7e4ee3a
CB
12071 ffecom_tree_subr_type
12072 = build_function_type (integer_type_node, NULL_TREE);
12073 ffecom_tree_ptr_to_subr_type
12074 = build_pointer_type (ffecom_tree_subr_type);
12075 ffecom_tree_blockdata_type
12076 = build_function_type (void_type_node, NULL_TREE);
5ff904cd 12077
c7e4ee3a 12078 builtin_function ("__builtin_sqrtf", float_ftype_float,
26db82d8 12079 BUILT_IN_FSQRT, BUILT_IN_NORMAL, "sqrtf");
c7e4ee3a 12080 builtin_function ("__builtin_fsqrt", double_ftype_double,
26db82d8 12081 BUILT_IN_FSQRT, BUILT_IN_NORMAL, "sqrt");
c7e4ee3a 12082 builtin_function ("__builtin_sqrtl", ldouble_ftype_ldouble,
26db82d8 12083 BUILT_IN_FSQRT, BUILT_IN_NORMAL, "sqrtl");
c7e4ee3a 12084 builtin_function ("__builtin_sinf", float_ftype_float,
26db82d8 12085 BUILT_IN_SIN, BUILT_IN_NORMAL, "sinf");
c7e4ee3a 12086 builtin_function ("__builtin_sin", double_ftype_double,
26db82d8 12087 BUILT_IN_SIN, BUILT_IN_NORMAL, "sin");
c7e4ee3a 12088 builtin_function ("__builtin_sinl", ldouble_ftype_ldouble,
26db82d8 12089 BUILT_IN_SIN, BUILT_IN_NORMAL, "sinl");
c7e4ee3a 12090 builtin_function ("__builtin_cosf", float_ftype_float,
26db82d8 12091 BUILT_IN_COS, BUILT_IN_NORMAL, "cosf");
c7e4ee3a 12092 builtin_function ("__builtin_cos", double_ftype_double,
26db82d8 12093 BUILT_IN_COS, BUILT_IN_NORMAL, "cos");
c7e4ee3a 12094 builtin_function ("__builtin_cosl", ldouble_ftype_ldouble,
26db82d8 12095 BUILT_IN_COS, BUILT_IN_NORMAL, "cosl");
5ff904cd 12096
c7e4ee3a
CB
12097#if BUILT_FOR_270
12098 pedantic_lvalues = FALSE;
5ff904cd 12099#endif
5ff904cd 12100
c7e4ee3a
CB
12101 ffecom_f2c_make_type_ (&ffecom_f2c_integer_type_node,
12102 FFECOM_f2cINTEGER,
12103 "integer");
12104 ffecom_f2c_make_type_ (&ffecom_f2c_address_type_node,
12105 FFECOM_f2cADDRESS,
12106 "address");
12107 ffecom_f2c_make_type_ (&ffecom_f2c_real_type_node,
12108 FFECOM_f2cREAL,
12109 "real");
12110 ffecom_f2c_make_type_ (&ffecom_f2c_doublereal_type_node,
12111 FFECOM_f2cDOUBLEREAL,
12112 "doublereal");
12113 ffecom_f2c_make_type_ (&ffecom_f2c_complex_type_node,
12114 FFECOM_f2cCOMPLEX,
12115 "complex");
12116 ffecom_f2c_make_type_ (&ffecom_f2c_doublecomplex_type_node,
12117 FFECOM_f2cDOUBLECOMPLEX,
12118 "doublecomplex");
12119 ffecom_f2c_make_type_ (&ffecom_f2c_longint_type_node,
12120 FFECOM_f2cLONGINT,
12121 "longint");
12122 ffecom_f2c_make_type_ (&ffecom_f2c_logical_type_node,
12123 FFECOM_f2cLOGICAL,
12124 "logical");
12125 ffecom_f2c_make_type_ (&ffecom_f2c_flag_type_node,
12126 FFECOM_f2cFLAG,
12127 "flag");
12128 ffecom_f2c_make_type_ (&ffecom_f2c_ftnlen_type_node,
12129 FFECOM_f2cFTNLEN,
12130 "ftnlen");
12131 ffecom_f2c_make_type_ (&ffecom_f2c_ftnint_type_node,
12132 FFECOM_f2cFTNINT,
12133 "ftnint");
5ff904cd 12134
c7e4ee3a
CB
12135 ffecom_f2c_ftnlen_zero_node
12136 = convert (ffecom_f2c_ftnlen_type_node, integer_zero_node);
5ff904cd 12137
c7e4ee3a
CB
12138 ffecom_f2c_ftnlen_one_node
12139 = convert (ffecom_f2c_ftnlen_type_node, integer_one_node);
5ff904cd 12140
c7e4ee3a
CB
12141 ffecom_f2c_ftnlen_two_node = build_int_2 (2, 0);
12142 TREE_TYPE (ffecom_f2c_ftnlen_two_node) = ffecom_integer_type_node;
5ff904cd 12143
c7e4ee3a
CB
12144 ffecom_f2c_ptr_to_ftnlen_type_node
12145 = build_pointer_type (ffecom_f2c_ftnlen_type_node);
5ff904cd 12146
c7e4ee3a
CB
12147 ffecom_f2c_ptr_to_ftnint_type_node
12148 = build_pointer_type (ffecom_f2c_ftnint_type_node);
5ff904cd 12149
c7e4ee3a
CB
12150 ffecom_f2c_ptr_to_integer_type_node
12151 = build_pointer_type (ffecom_f2c_integer_type_node);
5ff904cd 12152
c7e4ee3a
CB
12153 ffecom_f2c_ptr_to_real_type_node
12154 = build_pointer_type (ffecom_f2c_real_type_node);
5ff904cd 12155
c7e4ee3a
CB
12156 ffecom_float_zero_ = build_real (float_type_node, dconst0);
12157 ffecom_double_zero_ = build_real (double_type_node, dconst0);
12158 {
12159 REAL_VALUE_TYPE point_5;
5ff904cd 12160
c7e4ee3a
CB
12161#ifdef REAL_ARITHMETIC
12162 REAL_ARITHMETIC (point_5, RDIV_EXPR, dconst1, dconst2);
12163#else
12164 point_5 = .5;
12165#endif
12166 ffecom_float_half_ = build_real (float_type_node, point_5);
12167 ffecom_double_half_ = build_real (double_type_node, point_5);
12168 }
5ff904cd 12169
c7e4ee3a 12170 /* Do "extern int xargc;". */
5ff904cd 12171
c7e4ee3a
CB
12172 ffecom_tree_xargc_ = build_decl (VAR_DECL,
12173 get_identifier ("f__xargc"),
12174 integer_type_node);
12175 DECL_EXTERNAL (ffecom_tree_xargc_) = 1;
12176 TREE_STATIC (ffecom_tree_xargc_) = 1;
12177 TREE_PUBLIC (ffecom_tree_xargc_) = 1;
12178 ffecom_tree_xargc_ = start_decl (ffecom_tree_xargc_, FALSE);
12179 finish_decl (ffecom_tree_xargc_, NULL_TREE, FALSE);
5ff904cd 12180
c7e4ee3a
CB
12181#if 0 /* This is being fixed, and seems to be working now. */
12182 if ((FLOAT_TYPE_SIZE != 32)
12183 || (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node))) != 32))
5ff904cd 12184 {
c7e4ee3a
CB
12185 warning ("configuration: REAL, INTEGER, and LOGICAL are %d bits wide,",
12186 (int) FLOAT_TYPE_SIZE);
12187 warning ("and pointers are %d bits wide, but g77 doesn't yet work",
12188 (int) TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node))));
12189 warning ("properly unless they all are 32 bits wide.");
12190 warning ("Please keep this in mind before you report bugs. g77 should");
12191 warning ("support non-32-bit machines better as of version 0.6.");
12192 }
12193#endif
5ff904cd 12194
c7e4ee3a
CB
12195#if 0 /* Code in ste.c that would crash has been commented out. */
12196 if (TYPE_PRECISION (ffecom_f2c_ftnlen_type_node)
12197 < TYPE_PRECISION (string_type_node))
12198 /* I/O will probably crash. */
12199 warning ("configuration: char * holds %d bits, but ftnlen only %d",
12200 TYPE_PRECISION (string_type_node),
12201 TYPE_PRECISION (ffecom_f2c_ftnlen_type_node));
12202#endif
5ff904cd 12203
c7e4ee3a
CB
12204#if 0 /* ASSIGN-related stuff has been changed to accommodate this. */
12205 if (TYPE_PRECISION (ffecom_integer_type_node)
12206 < TYPE_PRECISION (string_type_node))
12207 /* ASSIGN 10 TO I will crash. */
12208 warning ("configuration: char * holds %d bits, but INTEGER only %d --\n\
12209 ASSIGN statement might fail",
12210 TYPE_PRECISION (string_type_node),
12211 TYPE_PRECISION (ffecom_integer_type_node));
12212#endif
12213}
5ff904cd 12214
c7e4ee3a
CB
12215#endif
12216/* ffecom_init_2 -- Initialize
5ff904cd 12217
c7e4ee3a 12218 ffecom_init_2(); */
5ff904cd 12219
c7e4ee3a
CB
12220#if FFECOM_targetCURRENT == FFECOM_targetGCC
12221void
12222ffecom_init_2 ()
12223{
12224 assert (ffecom_outer_function_decl_ == NULL_TREE);
12225 assert (current_function_decl == NULL_TREE);
12226 assert (ffecom_which_entrypoint_decl_ == NULL_TREE);
5ff904cd 12227
c7e4ee3a
CB
12228 ffecom_master_arglist_ = NULL;
12229 ++ffecom_num_fns_;
12230 ffecom_primary_entry_ = NULL;
12231 ffecom_is_altreturning_ = FALSE;
12232 ffecom_func_result_ = NULL_TREE;
12233 ffecom_multi_retval_ = NULL_TREE;
12234}
5ff904cd 12235
c7e4ee3a
CB
12236#endif
12237/* ffecom_list_expr -- Transform list of exprs into gcc tree
5ff904cd 12238
c7e4ee3a
CB
12239 tree t;
12240 ffebld expr; // FFE opITEM list.
12241 tree = ffecom_list_expr(expr);
5ff904cd 12242
c7e4ee3a 12243 List of actual args is transformed into corresponding gcc backend list. */
5ff904cd 12244
c7e4ee3a
CB
12245#if FFECOM_targetCURRENT == FFECOM_targetGCC
12246tree
12247ffecom_list_expr (ffebld expr)
5ff904cd 12248{
c7e4ee3a
CB
12249 tree list;
12250 tree *plist = &list;
12251 tree trail = NULL_TREE; /* Append char length args here. */
12252 tree *ptrail = &trail;
12253 tree length;
5ff904cd 12254
c7e4ee3a 12255 while (expr != NULL)
5ff904cd 12256 {
c7e4ee3a 12257 tree texpr = ffecom_arg_expr (ffebld_head (expr), &length);
5ff904cd 12258
c7e4ee3a
CB
12259 if (texpr == error_mark_node)
12260 return error_mark_node;
5ff904cd 12261
c7e4ee3a
CB
12262 *plist = build_tree_list (NULL_TREE, texpr);
12263 plist = &TREE_CHAIN (*plist);
12264 expr = ffebld_trail (expr);
12265 if (length != NULL_TREE)
5ff904cd 12266 {
c7e4ee3a
CB
12267 *ptrail = build_tree_list (NULL_TREE, length);
12268 ptrail = &TREE_CHAIN (*ptrail);
5ff904cd
JL
12269 }
12270 }
12271
c7e4ee3a 12272 *plist = trail;
5ff904cd 12273
c7e4ee3a
CB
12274 return list;
12275}
5ff904cd 12276
c7e4ee3a
CB
12277#endif
12278/* ffecom_list_ptr_to_expr -- Transform list of exprs into gcc tree
5ff904cd 12279
c7e4ee3a
CB
12280 tree t;
12281 ffebld expr; // FFE opITEM list.
12282 tree = ffecom_list_ptr_to_expr(expr);
5ff904cd 12283
c7e4ee3a
CB
12284 List of actual args is transformed into corresponding gcc backend list for
12285 use in calling an external procedure (vs. a statement function). */
5ff904cd 12286
c7e4ee3a
CB
12287#if FFECOM_targetCURRENT == FFECOM_targetGCC
12288tree
12289ffecom_list_ptr_to_expr (ffebld expr)
12290{
12291 tree list;
12292 tree *plist = &list;
12293 tree trail = NULL_TREE; /* Append char length args here. */
12294 tree *ptrail = &trail;
12295 tree length;
5ff904cd 12296
c7e4ee3a
CB
12297 while (expr != NULL)
12298 {
12299 tree texpr = ffecom_arg_ptr_to_expr (ffebld_head (expr), &length);
5ff904cd 12300
c7e4ee3a
CB
12301 if (texpr == error_mark_node)
12302 return error_mark_node;
5ff904cd 12303
c7e4ee3a
CB
12304 *plist = build_tree_list (NULL_TREE, texpr);
12305 plist = &TREE_CHAIN (*plist);
12306 expr = ffebld_trail (expr);
12307 if (length != NULL_TREE)
12308 {
12309 *ptrail = build_tree_list (NULL_TREE, length);
12310 ptrail = &TREE_CHAIN (*ptrail);
12311 }
12312 }
5ff904cd 12313
c7e4ee3a 12314 *plist = trail;
5ff904cd 12315
c7e4ee3a
CB
12316 return list;
12317}
5ff904cd 12318
c7e4ee3a
CB
12319#endif
12320/* Obtain gcc's LABEL_DECL tree for label. */
5ff904cd 12321
c7e4ee3a
CB
12322#if FFECOM_targetCURRENT == FFECOM_targetGCC
12323tree
12324ffecom_lookup_label (ffelab label)
12325{
12326 tree glabel;
5ff904cd 12327
c7e4ee3a
CB
12328 if (ffelab_hook (label) == NULL_TREE)
12329 {
12330 char labelname[16];
5ff904cd 12331
c7e4ee3a
CB
12332 switch (ffelab_type (label))
12333 {
12334 case FFELAB_typeLOOPEND:
12335 case FFELAB_typeNOTLOOP:
12336 case FFELAB_typeENDIF:
12337 sprintf (labelname, "%" ffelabValue_f "u", ffelab_value (label));
12338 glabel = build_decl (LABEL_DECL, get_identifier (labelname),
12339 void_type_node);
12340 DECL_CONTEXT (glabel) = current_function_decl;
12341 DECL_MODE (glabel) = VOIDmode;
12342 break;
5ff904cd 12343
c7e4ee3a 12344 case FFELAB_typeFORMAT:
c7e4ee3a
CB
12345 glabel = build_decl (VAR_DECL,
12346 ffecom_get_invented_identifier
14657de8 12347 ("__g77_format_%d", (int) ffelab_value (label)),
c7e4ee3a
CB
12348 build_type_variant (build_array_type
12349 (char_type_node,
12350 NULL_TREE),
12351 1, 0));
12352 TREE_CONSTANT (glabel) = 1;
12353 TREE_STATIC (glabel) = 1;
12354 DECL_CONTEXT (glabel) = 0;
12355 DECL_INITIAL (glabel) = NULL;
12356 make_decl_rtl (glabel, NULL, 0);
12357 expand_decl (glabel);
5ff904cd 12358
7189a4b0 12359 ffecom_save_tree_forever (glabel);
5ff904cd 12360
c7e4ee3a 12361 break;
5ff904cd 12362
c7e4ee3a
CB
12363 case FFELAB_typeANY:
12364 glabel = error_mark_node;
12365 break;
5ff904cd 12366
c7e4ee3a
CB
12367 default:
12368 assert ("bad label type" == NULL);
12369 glabel = NULL;
12370 break;
12371 }
12372 ffelab_set_hook (label, glabel);
12373 }
12374 else
12375 {
12376 glabel = ffelab_hook (label);
12377 }
5ff904cd 12378
c7e4ee3a
CB
12379 return glabel;
12380}
5ff904cd 12381
c7e4ee3a
CB
12382#endif
12383/* Stabilizes the arguments. Don't use this if the lhs and rhs come from
12384 a single source specification (as in the fourth argument of MVBITS).
12385 If the type is NULL_TREE, the type of lhs is used to make the type of
12386 the MODIFY_EXPR. */
5ff904cd 12387
c7e4ee3a
CB
12388#if FFECOM_targetCURRENT == FFECOM_targetGCC
12389tree
12390ffecom_modify (tree newtype, tree lhs,
12391 tree rhs)
12392{
12393 if (lhs == error_mark_node || rhs == error_mark_node)
12394 return error_mark_node;
5ff904cd 12395
c7e4ee3a
CB
12396 if (newtype == NULL_TREE)
12397 newtype = TREE_TYPE (lhs);
5ff904cd 12398
c7e4ee3a
CB
12399 if (TREE_SIDE_EFFECTS (lhs))
12400 lhs = stabilize_reference (lhs);
5ff904cd 12401
c7e4ee3a
CB
12402 return ffecom_2s (MODIFY_EXPR, newtype, lhs, rhs);
12403}
5ff904cd 12404
c7e4ee3a 12405#endif
5ff904cd 12406
c7e4ee3a 12407/* Register source file name. */
5ff904cd 12408
c7e4ee3a 12409void
b0791fa9 12410ffecom_file (const char *name)
c7e4ee3a
CB
12411{
12412#if FFECOM_GCC_INCLUDE
12413 ffecom_file_ (name);
12414#endif
12415}
5ff904cd 12416
c7e4ee3a 12417/* ffecom_notify_init_storage -- An aggregate storage is now fully init'ed
5ff904cd 12418
c7e4ee3a
CB
12419 ffestorag st;
12420 ffecom_notify_init_storage(st);
5ff904cd 12421
c7e4ee3a
CB
12422 Gets called when all possible units in an aggregate storage area (a LOCAL
12423 with equivalences or a COMMON) have been initialized. The initialization
12424 info either is in ffestorag_init or, if that is NULL,
12425 ffestorag_accretion:
5ff904cd 12426
c7e4ee3a
CB
12427 ffestorag_init may contain an opCONTER or opARRTER. opCONTER may occur
12428 even for an array if the array is one element in length!
5ff904cd 12429
c7e4ee3a
CB
12430 ffestorag_accretion will contain an opACCTER. It is much like an
12431 opARRTER except it has an ffebit object in it instead of just a size.
12432 The back end can use the info in the ffebit object, if it wants, to
12433 reduce the amount of actual initialization, but in any case it should
12434 kill the ffebit object when done. Also, set accretion to NULL but
12435 init to a non-NULL value.
5ff904cd 12436
c7e4ee3a
CB
12437 After performing initialization, DO NOT set init to NULL, because that'll
12438 tell the front end it is ok for more initialization to happen. Instead,
12439 set init to an opANY expression or some such thing that you can use to
12440 tell that you've already initialized the object.
5ff904cd 12441
c7e4ee3a
CB
12442 27-Oct-91 JCB 1.1
12443 Support two-pass FFE. */
5ff904cd 12444
c7e4ee3a
CB
12445void
12446ffecom_notify_init_storage (ffestorag st)
12447{
12448 ffebld init; /* The initialization expression. */
12449#if 0 && FFECOM_targetCURRENT == FFECOM_targetGCC
12450 ffetargetOffset size; /* The size of the entity. */
12451 ffetargetAlign pad; /* Its initial padding. */
12452#endif
12453
12454 if (ffestorag_init (st) == NULL)
5ff904cd 12455 {
c7e4ee3a
CB
12456 init = ffestorag_accretion (st);
12457 assert (init != NULL);
12458 ffestorag_set_accretion (st, NULL);
12459 ffestorag_set_accretes (st, 0);
12460
12461#if 0 && FFECOM_targetCURRENT == FFECOM_targetGCC
12462 /* For GNU backend, just turn ACCTER into ARRTER and proceed. */
12463 size = ffebld_accter_size (init);
12464 pad = ffebld_accter_pad (init);
12465 ffebit_kill (ffebld_accter_bits (init));
12466 ffebld_set_op (init, FFEBLD_opARRTER);
12467 ffebld_set_arrter (init, ffebld_accter (init));
12468 ffebld_arrter_set_size (init, size);
12469 ffebld_arrter_set_pad (init, size);
12470#endif
12471
12472#if FFECOM_TWOPASS
12473 ffestorag_set_init (st, init);
12474#endif
5ff904cd 12475 }
c7e4ee3a
CB
12476#if FFECOM_ONEPASS
12477 else
12478 init = ffestorag_init (st);
5ff904cd
JL
12479#endif
12480
c7e4ee3a
CB
12481#if FFECOM_ONEPASS /* Process the inits, wipe 'em out. */
12482 ffestorag_set_init (st, ffebld_new_any ());
5ff904cd 12483
c7e4ee3a
CB
12484 if (ffebld_op (init) == FFEBLD_opANY)
12485 return; /* Oh, we already did this! */
5ff904cd 12486
c7e4ee3a
CB
12487#if FFECOM_targetCURRENT == FFECOM_targetFFE
12488 {
12489 ffesymbol s;
5ff904cd 12490
c7e4ee3a
CB
12491 if (ffestorag_symbol (st) != NULL)
12492 s = ffestorag_symbol (st);
12493 else
12494 s = ffestorag_typesymbol (st);
5ff904cd 12495
c7e4ee3a
CB
12496 fprintf (dmpout, "= initialize_storage \"%s\" ",
12497 (s != NULL) ? ffesymbol_text (s) : "(unnamed)");
12498 ffebld_dump (init);
12499 fputc ('\n', dmpout);
12500 }
12501#endif
5ff904cd 12502
c7e4ee3a
CB
12503#endif /* if FFECOM_ONEPASS */
12504}
5ff904cd 12505
c7e4ee3a 12506/* ffecom_notify_init_symbol -- A symbol is now fully init'ed
5ff904cd 12507
c7e4ee3a
CB
12508 ffesymbol s;
12509 ffecom_notify_init_symbol(s);
5ff904cd 12510
c7e4ee3a
CB
12511 Gets called when all possible units in a symbol (not placed in COMMON
12512 or involved in EQUIVALENCE, unless it as yet has no ffestorag object)
12513 have been initialized. The initialization info either is in
12514 ffesymbol_init or, if that is NULL, ffesymbol_accretion:
5ff904cd 12515
c7e4ee3a
CB
12516 ffesymbol_init may contain an opCONTER or opARRTER. opCONTER may occur
12517 even for an array if the array is one element in length!
5ff904cd 12518
c7e4ee3a
CB
12519 ffesymbol_accretion will contain an opACCTER. It is much like an
12520 opARRTER except it has an ffebit object in it instead of just a size.
12521 The back end can use the info in the ffebit object, if it wants, to
12522 reduce the amount of actual initialization, but in any case it should
12523 kill the ffebit object when done. Also, set accretion to NULL but
12524 init to a non-NULL value.
5ff904cd 12525
c7e4ee3a
CB
12526 After performing initialization, DO NOT set init to NULL, because that'll
12527 tell the front end it is ok for more initialization to happen. Instead,
12528 set init to an opANY expression or some such thing that you can use to
12529 tell that you've already initialized the object.
5ff904cd 12530
c7e4ee3a
CB
12531 27-Oct-91 JCB 1.1
12532 Support two-pass FFE. */
5ff904cd 12533
c7e4ee3a
CB
12534void
12535ffecom_notify_init_symbol (ffesymbol s)
12536{
12537 ffebld init; /* The initialization expression. */
12538#if 0 && FFECOM_targetCURRENT == FFECOM_targetGCC
12539 ffetargetOffset size; /* The size of the entity. */
12540 ffetargetAlign pad; /* Its initial padding. */
12541#endif
5ff904cd 12542
c7e4ee3a
CB
12543 if (ffesymbol_storage (s) == NULL)
12544 return; /* Do nothing until COMMON/EQUIVALENCE
12545 possibilities checked. */
5ff904cd 12546
c7e4ee3a
CB
12547 if ((ffesymbol_init (s) == NULL)
12548 && ((init = ffesymbol_accretion (s)) != NULL))
12549 {
12550 ffesymbol_set_accretion (s, NULL);
12551 ffesymbol_set_accretes (s, 0);
5ff904cd 12552
c7e4ee3a
CB
12553#if 0 && FFECOM_targetCURRENT == FFECOM_targetGCC
12554 /* For GNU backend, just turn ACCTER into ARRTER and proceed. */
12555 size = ffebld_accter_size (init);
12556 pad = ffebld_accter_pad (init);
12557 ffebit_kill (ffebld_accter_bits (init));
12558 ffebld_set_op (init, FFEBLD_opARRTER);
12559 ffebld_set_arrter (init, ffebld_accter (init));
12560 ffebld_arrter_set_size (init, size);
12561 ffebld_arrter_set_pad (init, size);
12562#endif
5ff904cd 12563
c7e4ee3a
CB
12564#if FFECOM_TWOPASS
12565 ffesymbol_set_init (s, init);
12566#endif
12567 }
12568#if FFECOM_ONEPASS
12569 else
12570 init = ffesymbol_init (s);
12571#endif
5ff904cd 12572
c7e4ee3a
CB
12573#if FFECOM_ONEPASS
12574 ffesymbol_set_init (s, ffebld_new_any ());
5ff904cd 12575
c7e4ee3a
CB
12576 if (ffebld_op (init) == FFEBLD_opANY)
12577 return; /* Oh, we already did this! */
5ff904cd 12578
c7e4ee3a
CB
12579#if FFECOM_targetCURRENT == FFECOM_targetFFE
12580 fprintf (dmpout, "= initialize_symbol \"%s\" ", ffesymbol_text (s));
12581 ffebld_dump (init);
12582 fputc ('\n', dmpout);
12583#endif
5ff904cd 12584
c7e4ee3a
CB
12585#endif /* if FFECOM_ONEPASS */
12586}
5ff904cd 12587
c7e4ee3a 12588/* ffecom_notify_primary_entry -- Learn which is the primary entry point
5ff904cd 12589
c7e4ee3a
CB
12590 ffesymbol s;
12591 ffecom_notify_primary_entry(s);
5ff904cd 12592
c7e4ee3a
CB
12593 Gets called when implicit or explicit PROGRAM statement seen or when
12594 FUNCTION, SUBROUTINE, or BLOCK DATA statement seen, with the primary
12595 global symbol that serves as the entry point. */
5ff904cd 12596
c7e4ee3a
CB
12597void
12598ffecom_notify_primary_entry (ffesymbol s)
12599{
12600 ffecom_primary_entry_ = s;
12601 ffecom_primary_entry_kind_ = ffesymbol_kind (s);
5ff904cd 12602
c7e4ee3a
CB
12603 if ((ffecom_primary_entry_kind_ == FFEINFO_kindFUNCTION)
12604 || (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE))
12605 ffecom_primary_entry_is_proc_ = TRUE;
12606 else
12607 ffecom_primary_entry_is_proc_ = FALSE;
5ff904cd 12608
c7e4ee3a
CB
12609 if (!ffe_is_silent ())
12610 {
12611 if (ffecom_primary_entry_kind_ == FFEINFO_kindPROGRAM)
12612 fprintf (stderr, "%s:\n", ffesymbol_text (s));
12613 else
12614 fprintf (stderr, " %s:\n", ffesymbol_text (s));
12615 }
5ff904cd 12616
c7e4ee3a
CB
12617#if FFECOM_targetCURRENT == FFECOM_targetGCC
12618 if (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE)
12619 {
12620 ffebld list;
12621 ffebld arg;
5ff904cd 12622
c7e4ee3a
CB
12623 for (list = ffesymbol_dummyargs (s);
12624 list != NULL;
12625 list = ffebld_trail (list))
12626 {
12627 arg = ffebld_head (list);
12628 if (ffebld_op (arg) == FFEBLD_opSTAR)
12629 {
12630 ffecom_is_altreturning_ = TRUE;
12631 break;
12632 }
12633 }
12634 }
12635#endif
12636}
5ff904cd 12637
c7e4ee3a
CB
12638FILE *
12639ffecom_open_include (char *name, ffewhereLine l, ffewhereColumn c)
12640{
12641#if FFECOM_GCC_INCLUDE
12642 return ffecom_open_include_ (name, l, c);
12643#else
12644 return fopen (name, "r");
5ff904cd 12645#endif
c7e4ee3a 12646}
5ff904cd 12647
c7e4ee3a 12648/* ffecom_ptr_to_expr -- Transform expr into gcc tree with & in front
5ff904cd 12649
c7e4ee3a
CB
12650 tree t;
12651 ffebld expr; // FFE expression.
12652 tree = ffecom_ptr_to_expr(expr);
5ff904cd 12653
c7e4ee3a 12654 Like ffecom_expr, but sticks address-of in front of most things. */
5ff904cd 12655
c7e4ee3a
CB
12656#if FFECOM_targetCURRENT == FFECOM_targetGCC
12657tree
12658ffecom_ptr_to_expr (ffebld expr)
12659{
12660 tree item;
12661 ffeinfoBasictype bt;
12662 ffeinfoKindtype kt;
12663 ffesymbol s;
5ff904cd 12664
c7e4ee3a 12665 assert (expr != NULL);
5ff904cd 12666
c7e4ee3a
CB
12667 switch (ffebld_op (expr))
12668 {
12669 case FFEBLD_opSYMTER:
12670 s = ffebld_symter (expr);
12671 if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC)
12672 {
12673 ffecomGfrt ix;
5ff904cd 12674
c7e4ee3a
CB
12675 ix = ffeintrin_gfrt_indirect (ffebld_symter_implementation (expr));
12676 assert (ix != FFECOM_gfrt);
12677 if ((item = ffecom_gfrt_[ix]) == NULL_TREE)
12678 {
12679 ffecom_make_gfrt_ (ix);
12680 item = ffecom_gfrt_[ix];
12681 }
12682 }
12683 else
12684 {
12685 item = ffesymbol_hook (s).decl_tree;
12686 if (item == NULL_TREE)
12687 {
12688 s = ffecom_sym_transform_ (s);
12689 item = ffesymbol_hook (s).decl_tree;
12690 }
12691 }
12692 assert (item != NULL);
12693 if (item == error_mark_node)
12694 return item;
12695 if (!ffesymbol_hook (s).addr)
12696 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12697 item);
12698 return item;
5ff904cd 12699
c7e4ee3a 12700 case FFEBLD_opARRAYREF:
ff852b44 12701 return ffecom_arrayref_ (NULL_TREE, expr, 1);
5ff904cd 12702
c7e4ee3a 12703 case FFEBLD_opCONTER:
5ff904cd 12704
c7e4ee3a
CB
12705 bt = ffeinfo_basictype (ffebld_info (expr));
12706 kt = ffeinfo_kindtype (ffebld_info (expr));
5ff904cd 12707
c7e4ee3a
CB
12708 item = ffecom_constantunion (&ffebld_constant_union
12709 (ffebld_conter (expr)), bt, kt,
12710 ffecom_tree_type[bt][kt]);
12711 if (item == error_mark_node)
12712 return error_mark_node;
12713 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12714 item);
12715 return item;
5ff904cd 12716
c7e4ee3a
CB
12717 case FFEBLD_opANY:
12718 return error_mark_node;
5ff904cd 12719
c7e4ee3a
CB
12720 default:
12721 bt = ffeinfo_basictype (ffebld_info (expr));
12722 kt = ffeinfo_kindtype (ffebld_info (expr));
12723
12724 item = ffecom_expr (expr);
12725 if (item == error_mark_node)
12726 return error_mark_node;
12727
12728 /* The back end currently optimizes a bit too zealously for us, in that
12729 we fail JCB001 if the following block of code is omitted. It checks
12730 to see if the transformed expression is a symbol or array reference,
12731 and encloses it in a SAVE_EXPR if that is the case. */
12732
12733 STRIP_NOPS (item);
12734 if ((TREE_CODE (item) == VAR_DECL)
12735 || (TREE_CODE (item) == PARM_DECL)
12736 || (TREE_CODE (item) == RESULT_DECL)
12737 || (TREE_CODE (item) == INDIRECT_REF)
12738 || (TREE_CODE (item) == ARRAY_REF)
12739 || (TREE_CODE (item) == COMPONENT_REF)
12740#ifdef OFFSET_REF
12741 || (TREE_CODE (item) == OFFSET_REF)
12742#endif
12743 || (TREE_CODE (item) == BUFFER_REF)
12744 || (TREE_CODE (item) == REALPART_EXPR)
12745 || (TREE_CODE (item) == IMAGPART_EXPR))
12746 {
12747 item = ffecom_save_tree (item);
12748 }
12749
12750 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12751 item);
12752 return item;
12753 }
12754
12755 assert ("fall-through error" == NULL);
12756 return error_mark_node;
5ff904cd
JL
12757}
12758
12759#endif
c7e4ee3a 12760/* Obtain a temp var with given data type.
5ff904cd 12761
c7e4ee3a
CB
12762 size is FFETARGET_charactersizeNONE for a non-CHARACTER type
12763 or >= 0 for a CHARACTER type.
5ff904cd 12764
c7e4ee3a 12765 elements is -1 for a scalar or > 0 for an array of type. */
5ff904cd
JL
12766
12767#if FFECOM_targetCURRENT == FFECOM_targetGCC
12768tree
c7e4ee3a
CB
12769ffecom_make_tempvar (const char *commentary, tree type,
12770 ffetargetCharacterSize size, int elements)
5ff904cd 12771{
c7e4ee3a
CB
12772 int yes;
12773 tree t;
12774 static int mynumber;
5ff904cd 12775
c7e4ee3a 12776 assert (current_binding_level->prep_state < 2);
702edf1d 12777
c7e4ee3a
CB
12778 if (type == error_mark_node)
12779 return error_mark_node;
702edf1d 12780
c7e4ee3a 12781 yes = suspend_momentary ();
5ff904cd 12782
c7e4ee3a
CB
12783 if (size != FFETARGET_charactersizeNONE)
12784 type = build_array_type (type,
12785 build_range_type (ffecom_f2c_ftnlen_type_node,
12786 ffecom_f2c_ftnlen_one_node,
12787 build_int_2 (size, 0)));
12788 if (elements != -1)
12789 type = build_array_type (type,
12790 build_range_type (integer_type_node,
12791 integer_zero_node,
12792 build_int_2 (elements - 1,
12793 0)));
12794 t = build_decl (VAR_DECL,
12795 ffecom_get_invented_identifier ("__g77_%s_%d",
12796 commentary,
12797 mynumber++),
12798 type);
5ff904cd 12799
c7e4ee3a
CB
12800 t = start_decl (t, FALSE);
12801 finish_decl (t, NULL_TREE, FALSE);
12802
12803 resume_momentary (yes);
5ff904cd 12804
c7e4ee3a
CB
12805 return t;
12806}
5ff904cd 12807#endif
5ff904cd 12808
c7e4ee3a 12809/* Prepare argument pointer to expression.
5ff904cd 12810
c7e4ee3a
CB
12811 Like ffecom_prepare_expr, except for expressions to be evaluated
12812 via ffecom_arg_ptr_to_expr. */
5ff904cd 12813
c7e4ee3a
CB
12814void
12815ffecom_prepare_arg_ptr_to_expr (ffebld expr)
5ff904cd 12816{
c7e4ee3a
CB
12817 /* ~~For now, it seems to be the same thing. */
12818 ffecom_prepare_expr (expr);
12819 return;
12820}
702edf1d 12821
c7e4ee3a 12822/* End of preparations. */
702edf1d 12823
c7e4ee3a
CB
12824bool
12825ffecom_prepare_end (void)
12826{
12827 int prep_state = current_binding_level->prep_state;
5ff904cd 12828
c7e4ee3a
CB
12829 assert (prep_state < 2);
12830 current_binding_level->prep_state = 2;
5ff904cd 12831
c7e4ee3a 12832 return (prep_state == 1) ? TRUE : FALSE;
5ff904cd
JL
12833}
12834
c7e4ee3a 12835/* Prepare expression.
5ff904cd 12836
c7e4ee3a
CB
12837 This is called before any code is generated for the current block.
12838 It scans the expression, declares any temporaries that might be needed
12839 during evaluation of the expression, and stores those temporaries in
12840 the appropriate "hook" fields of the expression. `dest', if not NULL,
12841 specifies the destination that ffecom_expr_ will see, in case that
12842 helps avoid generating unused temporaries.
12843
12844 ~~Improve to avoid allocating unused temporaries by taking `dest'
12845 into account vis-a-vis aliasing requirements of complex/character
12846 functions. */
12847
12848void
12849ffecom_prepare_expr_ (ffebld expr, ffebld dest UNUSED)
5ff904cd 12850{
c7e4ee3a
CB
12851 ffeinfoBasictype bt;
12852 ffeinfoKindtype kt;
12853 ffetargetCharacterSize sz;
12854 tree tempvar = NULL_TREE;
5ff904cd 12855
c7e4ee3a
CB
12856 assert (current_binding_level->prep_state < 2);
12857
12858 if (! expr)
12859 return;
12860
12861 bt = ffeinfo_basictype (ffebld_info (expr));
12862 kt = ffeinfo_kindtype (ffebld_info (expr));
12863 sz = ffeinfo_size (ffebld_info (expr));
12864
12865 /* Generate whatever temporaries are needed to represent the result
12866 of the expression. */
12867
47d98fa2
CB
12868 if (bt == FFEINFO_basictypeCHARACTER)
12869 {
12870 while (ffebld_op (expr) == FFEBLD_opPAREN)
12871 expr = ffebld_left (expr);
12872 }
12873
c7e4ee3a 12874 switch (ffebld_op (expr))
5ff904cd 12875 {
c7e4ee3a
CB
12876 default:
12877 /* Don't make temps for SYMTER, CONTER, etc. */
12878 if (ffebld_arity (expr) == 0)
12879 break;
5ff904cd 12880
c7e4ee3a 12881 switch (bt)
5ff904cd 12882 {
c7e4ee3a
CB
12883 case FFEINFO_basictypeCOMPLEX:
12884 if (ffebld_op (expr) == FFEBLD_opFUNCREF)
12885 {
12886 ffesymbol s;
5ff904cd 12887
c7e4ee3a
CB
12888 if (ffebld_op (ffebld_left (expr)) != FFEBLD_opSYMTER)
12889 break;
5ff904cd 12890
c7e4ee3a
CB
12891 s = ffebld_symter (ffebld_left (expr));
12892 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT
68779408
CB
12893 || (ffesymbol_where (s) != FFEINFO_whereINTRINSIC
12894 && ! ffesymbol_is_f2c (s))
12895 || (ffesymbol_where (s) == FFEINFO_whereINTRINSIC
12896 && ! ffe_is_f2c_library ()))
c7e4ee3a
CB
12897 break;
12898 }
12899 else if (ffebld_op (expr) == FFEBLD_opPOWER)
12900 {
12901 /* Requires special treatment. There's no POW_CC function
12902 in libg2c, so POW_ZZ is used, which means we always
12903 need a double-complex temp, not a single-complex. */
12904 kt = FFEINFO_kindtypeREAL2;
12905 }
12906 else if (ffebld_op (expr) != FFEBLD_opDIVIDE)
12907 /* The other ops don't need temps for complex operands. */
12908 break;
5ff904cd 12909
c7e4ee3a
CB
12910 /* ~~~Avoid making temps for some intrinsics, such as AIMAG(C),
12911 REAL(C). See 19990325-0.f, routine `check', for cases. */
12912 tempvar = ffecom_make_tempvar ("complex",
12913 ffecom_tree_type
12914 [FFEINFO_basictypeCOMPLEX][kt],
12915 FFETARGET_charactersizeNONE,
12916 -1);
5ff904cd
JL
12917 break;
12918
c7e4ee3a
CB
12919 case FFEINFO_basictypeCHARACTER:
12920 if (ffebld_op (expr) != FFEBLD_opFUNCREF)
12921 break;
12922
12923 if (sz == FFETARGET_charactersizeNONE)
12924 /* ~~Kludge alert! This should someday be fixed. */
12925 sz = 24;
12926
12927 tempvar = ffecom_make_tempvar ("char", char_type_node, sz, -1);
5ff904cd
JL
12928 break;
12929
12930 default:
5ff904cd
JL
12931 break;
12932 }
c7e4ee3a 12933 break;
5ff904cd 12934
c7e4ee3a
CB
12935#ifdef HAHA
12936 case FFEBLD_opPOWER:
12937 {
12938 tree rtype, ltype;
12939 tree rtmp, ltmp, result;
5ff904cd 12940
c7e4ee3a
CB
12941 ltype = ffecom_type_expr (ffebld_left (expr));
12942 rtype = ffecom_type_expr (ffebld_right (expr));
5ff904cd 12943
c7e4ee3a
CB
12944 rtmp = ffecom_make_tempvar (rtype, FFETARGET_charactersizeNONE, -1);
12945 ltmp = ffecom_make_tempvar (ltype, FFETARGET_charactersizeNONE, -1);
12946 result = ffecom_make_tempvar (ltype, FFETARGET_charactersizeNONE, -1);
5ff904cd 12947
c7e4ee3a
CB
12948 tempvar = make_tree_vec (3);
12949 TREE_VEC_ELT (tempvar, 0) = rtmp;
12950 TREE_VEC_ELT (tempvar, 1) = ltmp;
12951 TREE_VEC_ELT (tempvar, 2) = result;
12952 }
12953 break;
12954#endif /* HAHA */
5ff904cd 12955
c7e4ee3a
CB
12956 case FFEBLD_opCONCATENATE:
12957 {
12958 /* This gets special handling, because only one set of temps
12959 is needed for a tree of these -- the tree is treated as
12960 a flattened list of concatenations when generating code. */
5ff904cd 12961
c7e4ee3a
CB
12962 ffecomConcatList_ catlist;
12963 tree ltmp, itmp, result;
12964 int count;
12965 int i;
5ff904cd 12966
c7e4ee3a
CB
12967 catlist = ffecom_concat_list_new_ (expr, FFETARGET_charactersizeNONE);
12968 count = ffecom_concat_list_count_ (catlist);
5ff904cd 12969
c7e4ee3a
CB
12970 if (count >= 2)
12971 {
12972 ltmp
12973 = ffecom_make_tempvar ("concat_len",
12974 ffecom_f2c_ftnlen_type_node,
12975 FFETARGET_charactersizeNONE, count);
12976 itmp
12977 = ffecom_make_tempvar ("concat_item",
12978 ffecom_f2c_address_type_node,
12979 FFETARGET_charactersizeNONE, count);
12980 result
12981 = ffecom_make_tempvar ("concat_res",
12982 char_type_node,
12983 ffecom_concat_list_maxlen_ (catlist),
12984 -1);
12985
12986 tempvar = make_tree_vec (3);
12987 TREE_VEC_ELT (tempvar, 0) = ltmp;
12988 TREE_VEC_ELT (tempvar, 1) = itmp;
12989 TREE_VEC_ELT (tempvar, 2) = result;
12990 }
5ff904cd 12991
c7e4ee3a
CB
12992 for (i = 0; i < count; ++i)
12993 ffecom_prepare_arg_ptr_to_expr (ffecom_concat_list_expr_ (catlist,
12994 i));
5ff904cd 12995
c7e4ee3a 12996 ffecom_concat_list_kill_ (catlist);
5ff904cd 12997
c7e4ee3a
CB
12998 if (tempvar)
12999 {
13000 ffebld_nonter_set_hook (expr, tempvar);
13001 current_binding_level->prep_state = 1;
13002 }
13003 }
13004 return;
5ff904cd 13005
c7e4ee3a
CB
13006 case FFEBLD_opCONVERT:
13007 if (bt == FFEINFO_basictypeCHARACTER
13008 && ((ffebld_size_known (ffebld_left (expr))
13009 == FFETARGET_charactersizeNONE)
13010 || (ffebld_size_known (ffebld_left (expr)) >= sz)))
13011 tempvar = ffecom_make_tempvar ("convert", char_type_node, sz, -1);
13012 break;
13013 }
5ff904cd 13014
c7e4ee3a
CB
13015 if (tempvar)
13016 {
13017 ffebld_nonter_set_hook (expr, tempvar);
13018 current_binding_level->prep_state = 1;
13019 }
5ff904cd 13020
c7e4ee3a 13021 /* Prepare subexpressions for this expr. */
5ff904cd 13022
c7e4ee3a 13023 switch (ffebld_op (expr))
5ff904cd 13024 {
c7e4ee3a
CB
13025 case FFEBLD_opPERCENT_LOC:
13026 ffecom_prepare_ptr_to_expr (ffebld_left (expr));
13027 break;
5ff904cd 13028
c7e4ee3a
CB
13029 case FFEBLD_opPERCENT_VAL:
13030 case FFEBLD_opPERCENT_REF:
13031 ffecom_prepare_expr (ffebld_left (expr));
13032 break;
5ff904cd 13033
c7e4ee3a
CB
13034 case FFEBLD_opPERCENT_DESCR:
13035 ffecom_prepare_arg_ptr_to_expr (ffebld_left (expr));
13036 break;
5ff904cd 13037
c7e4ee3a
CB
13038 case FFEBLD_opITEM:
13039 {
13040 ffebld item;
5ff904cd 13041
c7e4ee3a
CB
13042 for (item = expr;
13043 item != NULL;
13044 item = ffebld_trail (item))
13045 if (ffebld_head (item) != NULL)
13046 ffecom_prepare_expr (ffebld_head (item));
13047 }
13048 break;
5ff904cd 13049
c7e4ee3a
CB
13050 default:
13051 /* Need to handle character conversion specially. */
13052 switch (ffebld_arity (expr))
13053 {
13054 case 2:
13055 ffecom_prepare_expr (ffebld_left (expr));
13056 ffecom_prepare_expr (ffebld_right (expr));
13057 break;
5ff904cd 13058
c7e4ee3a
CB
13059 case 1:
13060 ffecom_prepare_expr (ffebld_left (expr));
13061 break;
5ff904cd 13062
c7e4ee3a
CB
13063 default:
13064 break;
13065 }
13066 }
5ff904cd 13067
c7e4ee3a 13068 return;
5ff904cd
JL
13069}
13070
c7e4ee3a 13071/* Prepare expression for reading and writing.
5ff904cd 13072
c7e4ee3a
CB
13073 Like ffecom_prepare_expr, except for expressions to be evaluated
13074 via ffecom_expr_rw. */
5ff904cd 13075
c7e4ee3a
CB
13076void
13077ffecom_prepare_expr_rw (tree type, ffebld expr)
13078{
13079 /* This is all we support for now. */
13080 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
5ff904cd 13081
c7e4ee3a
CB
13082 /* ~~For now, it seems to be the same thing. */
13083 ffecom_prepare_expr (expr);
13084 return;
13085}
5ff904cd 13086
c7e4ee3a 13087/* Prepare expression for writing.
5ff904cd 13088
c7e4ee3a
CB
13089 Like ffecom_prepare_expr, except for expressions to be evaluated
13090 via ffecom_expr_w. */
5ff904cd
JL
13091
13092void
c7e4ee3a 13093ffecom_prepare_expr_w (tree type, ffebld expr)
5ff904cd 13094{
c7e4ee3a
CB
13095 /* This is all we support for now. */
13096 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
5ff904cd 13097
c7e4ee3a
CB
13098 /* ~~For now, it seems to be the same thing. */
13099 ffecom_prepare_expr (expr);
13100 return;
13101}
5ff904cd 13102
c7e4ee3a 13103/* Prepare expression for returning.
5ff904cd 13104
c7e4ee3a
CB
13105 Like ffecom_prepare_expr, except for expressions to be evaluated
13106 via ffecom_return_expr. */
5ff904cd 13107
c7e4ee3a
CB
13108void
13109ffecom_prepare_return_expr (ffebld expr)
13110{
13111 assert (current_binding_level->prep_state < 2);
5ff904cd 13112
c7e4ee3a
CB
13113 if (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE
13114 && ffecom_is_altreturning_
13115 && expr != NULL)
13116 ffecom_prepare_expr (expr);
13117}
5ff904cd 13118
c7e4ee3a 13119/* Prepare pointer to expression.
5ff904cd 13120
c7e4ee3a
CB
13121 Like ffecom_prepare_expr, except for expressions to be evaluated
13122 via ffecom_ptr_to_expr. */
5ff904cd 13123
c7e4ee3a
CB
13124void
13125ffecom_prepare_ptr_to_expr (ffebld expr)
13126{
13127 /* ~~For now, it seems to be the same thing. */
13128 ffecom_prepare_expr (expr);
13129 return;
5ff904cd
JL
13130}
13131
c7e4ee3a 13132/* Transform expression into constant pointer-to-expression tree.
5ff904cd 13133
c7e4ee3a
CB
13134 If the expression can be transformed into a pointer-to-expression tree
13135 that is constant, that is done, and the tree returned. Else NULL_TREE
13136 is returned.
5ff904cd 13137
c7e4ee3a
CB
13138 That way, a caller can attempt to provide compile-time initialization
13139 of a variable and, if that fails, *then* choose to start a new block
13140 and resort to using temporaries, as appropriate. */
5ff904cd 13141
c7e4ee3a
CB
13142tree
13143ffecom_ptr_to_const_expr (ffebld expr)
5ff904cd 13144{
c7e4ee3a
CB
13145 if (! expr)
13146 return integer_zero_node;
5ff904cd 13147
c7e4ee3a
CB
13148 if (ffebld_op (expr) == FFEBLD_opANY)
13149 return error_mark_node;
5ff904cd 13150
c7e4ee3a
CB
13151 if (ffebld_arity (expr) == 0
13152 && (ffebld_op (expr) != FFEBLD_opSYMTER
13153 || ffebld_where (expr) == FFEINFO_whereCOMMON
13154 || ffebld_where (expr) == FFEINFO_whereGLOBAL
13155 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
5ff904cd 13156 {
c7e4ee3a
CB
13157 tree t;
13158
13159 t = ffecom_ptr_to_expr (expr);
13160 assert (TREE_CONSTANT (t));
13161 return t;
5ff904cd
JL
13162 }
13163
c7e4ee3a
CB
13164 return NULL_TREE;
13165}
13166
13167/* ffecom_return_expr -- Returns return-value expr given alt return expr
13168
13169 tree rtn; // NULL_TREE means use expand_null_return()
13170 ffebld expr; // NULL if no alt return expr to RETURN stmt
13171 rtn = ffecom_return_expr(expr);
13172
13173 Based on the program unit type and other info (like return function
13174 type, return master function type when alternate ENTRY points,
13175 whether subroutine has any alternate RETURN points, etc), returns the
13176 appropriate expression to be returned to the caller, or NULL_TREE
13177 meaning no return value or the caller expects it to be returned somewhere
13178 else (which is handled by other parts of this module). */
13179
5ff904cd 13180#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
13181tree
13182ffecom_return_expr (ffebld expr)
13183{
13184 tree rtn;
13185
13186 switch (ffecom_primary_entry_kind_)
5ff904cd 13187 {
c7e4ee3a
CB
13188 case FFEINFO_kindPROGRAM:
13189 case FFEINFO_kindBLOCKDATA:
13190 rtn = NULL_TREE;
13191 break;
5ff904cd 13192
c7e4ee3a
CB
13193 case FFEINFO_kindSUBROUTINE:
13194 if (!ffecom_is_altreturning_)
13195 rtn = NULL_TREE; /* No alt returns, never an expr. */
13196 else if (expr == NULL)
13197 rtn = integer_zero_node;
13198 else
13199 rtn = ffecom_expr (expr);
13200 break;
13201
13202 case FFEINFO_kindFUNCTION:
13203 if ((ffecom_multi_retval_ != NULL_TREE)
13204 || (ffesymbol_basictype (ffecom_primary_entry_)
13205 == FFEINFO_basictypeCHARACTER)
13206 || ((ffesymbol_basictype (ffecom_primary_entry_)
13207 == FFEINFO_basictypeCOMPLEX)
13208 && (ffecom_num_entrypoints_ == 0)
13209 && ffesymbol_is_f2c (ffecom_primary_entry_)))
13210 { /* Value is returned by direct assignment
13211 into (implicit) dummy. */
13212 rtn = NULL_TREE;
13213 break;
5ff904cd 13214 }
c7e4ee3a
CB
13215 rtn = ffecom_func_result_;
13216#if 0
13217 /* Spurious error if RETURN happens before first reference! So elide
13218 this code. In particular, for debugging registry, rtn should always
13219 be non-null after all, but TREE_USED won't be set until we encounter
13220 a reference in the code. Perfectly okay (but weird) code that,
13221 e.g., has "GOTO 20;10 RETURN;20 RTN=0;GOTO 10", would result in
13222 this diagnostic for no reason. Have people use -O -Wuninitialized
13223 and leave it to the back end to find obviously weird cases. */
5ff904cd 13224
c7e4ee3a
CB
13225 /* Used to "assert(rtn != NULL_TREE);" here, but it's kind of a valid
13226 situation; if the return value has never been referenced, it won't
13227 have a tree under 2pass mode. */
13228 if ((rtn == NULL_TREE)
13229 || !TREE_USED (rtn))
13230 {
13231 ffebad_start (FFEBAD_RETURN_VALUE_UNSET);
13232 ffebad_here (0, ffesymbol_where_line (ffecom_primary_entry_),
13233 ffesymbol_where_column (ffecom_primary_entry_));
13234 ffebad_string (ffesymbol_text (ffesymbol_funcresult
13235 (ffecom_primary_entry_)));
13236 ffebad_finish ();
13237 }
5ff904cd 13238#endif
c7e4ee3a 13239 break;
5ff904cd 13240
c7e4ee3a
CB
13241 default:
13242 assert ("bad unit kind" == NULL);
13243 case FFEINFO_kindANY:
13244 rtn = error_mark_node;
13245 break;
13246 }
5ff904cd 13247
c7e4ee3a
CB
13248 return rtn;
13249}
5ff904cd 13250
c7e4ee3a
CB
13251#endif
13252/* Do save_expr only if tree is not error_mark_node. */
5ff904cd
JL
13253
13254#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
13255tree
13256ffecom_save_tree (tree t)
5ff904cd 13257{
c7e4ee3a 13258 return save_expr (t);
5ff904cd 13259}
5ff904cd 13260#endif
c7e4ee3a
CB
13261
13262/* Start a compound statement (block). */
5ff904cd
JL
13263
13264#if FFECOM_targetCURRENT == FFECOM_targetGCC
13265void
c7e4ee3a 13266ffecom_start_compstmt (void)
5ff904cd 13267{
c7e4ee3a 13268 bison_rule_pushlevel_ ();
5ff904cd 13269}
c7e4ee3a 13270#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
5ff904cd 13271
c7e4ee3a 13272/* Public entry point for front end to access start_decl. */
5ff904cd
JL
13273
13274#if FFECOM_targetCURRENT == FFECOM_targetGCC
13275tree
c7e4ee3a 13276ffecom_start_decl (tree decl, bool is_initialized)
5ff904cd 13277{
c7e4ee3a
CB
13278 DECL_INITIAL (decl) = is_initialized ? error_mark_node : NULL_TREE;
13279 return start_decl (decl, FALSE);
13280}
5ff904cd 13281
c7e4ee3a
CB
13282#endif
13283/* ffecom_sym_commit -- Symbol's state being committed to reality
5ff904cd 13284
c7e4ee3a
CB
13285 ffesymbol s;
13286 ffecom_sym_commit(s);
5ff904cd 13287
c7e4ee3a
CB
13288 Does whatever the backend needs when a symbol is committed after having
13289 been backtrackable for a period of time. */
5ff904cd 13290
c7e4ee3a
CB
13291#if FFECOM_targetCURRENT == FFECOM_targetGCC
13292void
13293ffecom_sym_commit (ffesymbol s UNUSED)
13294{
13295 assert (!ffesymbol_retractable ());
13296}
5ff904cd 13297
c7e4ee3a
CB
13298#endif
13299/* ffecom_sym_end_transition -- Perform end transition on all symbols
5ff904cd 13300
c7e4ee3a 13301 ffecom_sym_end_transition();
5ff904cd 13302
c7e4ee3a
CB
13303 Does backend-specific stuff and also calls ffest_sym_end_transition
13304 to do the necessary FFE stuff.
5ff904cd 13305
c7e4ee3a
CB
13306 Backtracking is never enabled when this fn is called, so don't worry
13307 about it. */
5ff904cd 13308
c7e4ee3a
CB
13309ffesymbol
13310ffecom_sym_end_transition (ffesymbol s)
13311{
13312 ffestorag st;
5ff904cd 13313
c7e4ee3a 13314 assert (!ffesymbol_retractable ());
5ff904cd 13315
c7e4ee3a 13316 s = ffest_sym_end_transition (s);
5ff904cd 13317
c7e4ee3a
CB
13318#if FFECOM_targetCURRENT == FFECOM_targetGCC
13319 if ((ffesymbol_kind (s) == FFEINFO_kindBLOCKDATA)
13320 && (ffesymbol_where (s) == FFEINFO_whereGLOBAL))
13321 {
13322 ffecom_list_blockdata_
13323 = ffebld_new_item (ffebld_new_symter (s, FFEINTRIN_genNONE,
13324 FFEINTRIN_specNONE,
13325 FFEINTRIN_impNONE),
13326 ffecom_list_blockdata_);
5ff904cd 13327 }
5ff904cd 13328#endif
5ff904cd 13329
c7e4ee3a
CB
13330 /* This is where we finally notice that a symbol has partial initialization
13331 and finalize it. */
5ff904cd 13332
c7e4ee3a
CB
13333 if (ffesymbol_accretion (s) != NULL)
13334 {
13335 assert (ffesymbol_init (s) == NULL);
13336 ffecom_notify_init_symbol (s);
13337 }
13338 else if (((st = ffesymbol_storage (s)) != NULL)
13339 && ((st = ffestorag_parent (st)) != NULL)
13340 && (ffestorag_accretion (st) != NULL))
13341 {
13342 assert (ffestorag_init (st) == NULL);
13343 ffecom_notify_init_storage (st);
13344 }
5ff904cd
JL
13345
13346#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
13347 if ((ffesymbol_kind (s) == FFEINFO_kindCOMMON)
13348 && (ffesymbol_where (s) == FFEINFO_whereLOCAL)
13349 && (ffesymbol_storage (s) != NULL))
13350 {
13351 ffecom_list_common_
13352 = ffebld_new_item (ffebld_new_symter (s, FFEINTRIN_genNONE,
13353 FFEINTRIN_specNONE,
13354 FFEINTRIN_impNONE),
13355 ffecom_list_common_);
13356 }
13357#endif
5ff904cd 13358
c7e4ee3a
CB
13359 return s;
13360}
5ff904cd 13361
c7e4ee3a 13362/* ffecom_sym_exec_transition -- Perform exec transition on all symbols
5ff904cd 13363
c7e4ee3a 13364 ffecom_sym_exec_transition();
5ff904cd 13365
c7e4ee3a
CB
13366 Does backend-specific stuff and also calls ffest_sym_exec_transition
13367 to do the necessary FFE stuff.
5ff904cd 13368
c7e4ee3a
CB
13369 See the long-winded description in ffecom_sym_learned for info
13370 on handling the situation where backtracking is inhibited. */
5ff904cd 13371
c7e4ee3a
CB
13372ffesymbol
13373ffecom_sym_exec_transition (ffesymbol s)
13374{
13375 s = ffest_sym_exec_transition (s);
5ff904cd 13376
c7e4ee3a
CB
13377 return s;
13378}
5ff904cd 13379
c7e4ee3a 13380/* ffecom_sym_learned -- Initial or more info gained on symbol after exec
5ff904cd 13381
c7e4ee3a
CB
13382 ffesymbol s;
13383 s = ffecom_sym_learned(s);
5ff904cd 13384
c7e4ee3a
CB
13385 Called when a new symbol is seen after the exec transition or when more
13386 info (perhaps) is gained for an UNCERTAIN symbol. The symbol state when
13387 it arrives here is that all its latest info is updated already, so its
13388 state may be UNCERTAIN or UNDERSTOOD, it might already have the hook
13389 field filled in if its gone through here or exec_transition first, and
13390 so on.
5ff904cd 13391
c7e4ee3a
CB
13392 The backend probably wants to check ffesymbol_retractable() to see if
13393 backtracking is in effect. If so, the FFE's changes to the symbol may
13394 be retracted (undone) or committed (ratified), at which time the
13395 appropriate ffecom_sym_retract or _commit function will be called
13396 for that function.
5ff904cd 13397
c7e4ee3a
CB
13398 If the backend has its own backtracking mechanism, great, use it so that
13399 committal is a simple operation. Though it doesn't make much difference,
13400 I suppose: the reason for tentative symbol evolution in the FFE is to
13401 enable error detection in weird incorrect statements early and to disable
13402 incorrect error detection on a correct statement. The backend is not
13403 likely to introduce any information that'll get involved in these
13404 considerations, so it is probably just fine that the implementation
13405 model for this fn and for _exec_transition is to not do anything
13406 (besides the required FFE stuff) if ffesymbol_retractable() returns TRUE
13407 and instead wait until ffecom_sym_commit is called (which it never
13408 will be as long as we're using ambiguity-detecting statement analysis in
13409 the FFE, which we are initially to shake out the code, but don't depend
13410 on this), otherwise go ahead and do whatever is needed.
5ff904cd 13411
c7e4ee3a
CB
13412 In essence, then, when this fn and _exec_transition get called while
13413 backtracking is enabled, a general mechanism would be to flag which (or
13414 both) of these were called (and in what order? neat question as to what
13415 might happen that I'm too lame to think through right now) and then when
13416 _commit is called reproduce the original calling sequence, if any, for
13417 the two fns (at which point backtracking will, of course, be disabled). */
5ff904cd 13418
c7e4ee3a
CB
13419ffesymbol
13420ffecom_sym_learned (ffesymbol s)
13421{
13422 ffestorag_exec_layout (s);
5ff904cd 13423
c7e4ee3a 13424 return s;
5ff904cd
JL
13425}
13426
c7e4ee3a 13427/* ffecom_sym_retract -- Symbol's state being retracted from reality
5ff904cd 13428
c7e4ee3a
CB
13429 ffesymbol s;
13430 ffecom_sym_retract(s);
5ff904cd 13431
c7e4ee3a
CB
13432 Does whatever the backend needs when a symbol is retracted after having
13433 been backtrackable for a period of time. */
5ff904cd
JL
13434
13435#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
13436void
13437ffecom_sym_retract (ffesymbol s UNUSED)
5ff904cd 13438{
c7e4ee3a 13439 assert (!ffesymbol_retractable ());
5ff904cd 13440
c7e4ee3a
CB
13441#if 0 /* GCC doesn't commit any backtrackable sins,
13442 so nothing needed here. */
13443 switch (ffesymbol_hook (s).state)
5ff904cd 13444 {
c7e4ee3a 13445 case 0: /* nothing happened yet. */
5ff904cd
JL
13446 break;
13447
c7e4ee3a 13448 case 1: /* exec transition happened. */
5ff904cd
JL
13449 break;
13450
c7e4ee3a
CB
13451 case 2: /* learned happened. */
13452 break;
5ff904cd 13453
c7e4ee3a
CB
13454 case 3: /* learned then exec. */
13455 break;
13456
13457 case 4: /* exec then learned. */
5ff904cd
JL
13458 break;
13459
13460 default:
c7e4ee3a 13461 assert ("bad hook state" == NULL);
5ff904cd
JL
13462 break;
13463 }
c7e4ee3a
CB
13464#endif
13465}
5ff904cd 13466
c7e4ee3a
CB
13467#endif
13468/* Create temporary gcc label. */
13469
13470#if FFECOM_targetCURRENT == FFECOM_targetGCC
13471tree
13472ffecom_temp_label ()
13473{
13474 tree glabel;
13475 static int mynumber = 0;
13476
13477 glabel = build_decl (LABEL_DECL,
13478 ffecom_get_invented_identifier ("__g77_label_%d",
c7e4ee3a
CB
13479 mynumber++),
13480 void_type_node);
13481 DECL_CONTEXT (glabel) = current_function_decl;
13482 DECL_MODE (glabel) = VOIDmode;
13483
13484 return glabel;
5ff904cd
JL
13485}
13486
13487#endif
c7e4ee3a
CB
13488/* Return an expression that is usable as an arg in a conditional context
13489 (IF, DO WHILE, .NOT., and so on).
13490
13491 Use the one provided for the back end as of >2.6.0. */
5ff904cd
JL
13492
13493#if FFECOM_targetCURRENT == FFECOM_targetGCC
a2977d2d 13494tree
c7e4ee3a 13495ffecom_truth_value (tree expr)
5ff904cd 13496{
c7e4ee3a 13497 return truthvalue_conversion (expr);
5ff904cd 13498}
c7e4ee3a 13499
5ff904cd 13500#endif
c7e4ee3a
CB
13501/* Return the inversion of a truth value (the inversion of what
13502 ffecom_truth_value builds).
5ff904cd 13503
c7e4ee3a
CB
13504 Apparently invert_truthvalue, which is properly in the back end, is
13505 enough for now, so just use it. */
5ff904cd
JL
13506
13507#if FFECOM_targetCURRENT == FFECOM_targetGCC
13508tree
c7e4ee3a 13509ffecom_truth_value_invert (tree expr)
5ff904cd 13510{
c7e4ee3a 13511 return invert_truthvalue (ffecom_truth_value (expr));
5ff904cd
JL
13512}
13513
13514#endif
5ff904cd 13515
c7e4ee3a
CB
13516/* Return the tree that is the type of the expression, as would be
13517 returned in TREE_TYPE(ffecom_expr(expr)), without otherwise
13518 transforming the expression, generating temporaries, etc. */
5ff904cd 13519
c7e4ee3a
CB
13520tree
13521ffecom_type_expr (ffebld expr)
13522{
13523 ffeinfoBasictype bt;
13524 ffeinfoKindtype kt;
13525 tree tree_type;
13526
13527 assert (expr != NULL);
13528
13529 bt = ffeinfo_basictype (ffebld_info (expr));
13530 kt = ffeinfo_kindtype (ffebld_info (expr));
13531 tree_type = ffecom_tree_type[bt][kt];
13532
13533 switch (ffebld_op (expr))
13534 {
13535 case FFEBLD_opCONTER:
13536 case FFEBLD_opSYMTER:
13537 case FFEBLD_opARRAYREF:
13538 case FFEBLD_opUPLUS:
13539 case FFEBLD_opPAREN:
13540 case FFEBLD_opUMINUS:
13541 case FFEBLD_opADD:
13542 case FFEBLD_opSUBTRACT:
13543 case FFEBLD_opMULTIPLY:
13544 case FFEBLD_opDIVIDE:
13545 case FFEBLD_opPOWER:
13546 case FFEBLD_opNOT:
13547 case FFEBLD_opFUNCREF:
13548 case FFEBLD_opSUBRREF:
13549 case FFEBLD_opAND:
13550 case FFEBLD_opOR:
13551 case FFEBLD_opXOR:
13552 case FFEBLD_opNEQV:
13553 case FFEBLD_opEQV:
13554 case FFEBLD_opCONVERT:
13555 case FFEBLD_opLT:
13556 case FFEBLD_opLE:
13557 case FFEBLD_opEQ:
13558 case FFEBLD_opNE:
13559 case FFEBLD_opGT:
13560 case FFEBLD_opGE:
13561 case FFEBLD_opPERCENT_LOC:
13562 return tree_type;
13563
13564 case FFEBLD_opACCTER:
13565 case FFEBLD_opARRTER:
13566 case FFEBLD_opITEM:
13567 case FFEBLD_opSTAR:
13568 case FFEBLD_opBOUNDS:
13569 case FFEBLD_opREPEAT:
13570 case FFEBLD_opLABTER:
13571 case FFEBLD_opLABTOK:
13572 case FFEBLD_opIMPDO:
13573 case FFEBLD_opCONCATENATE:
13574 case FFEBLD_opSUBSTR:
13575 default:
13576 assert ("bad op for ffecom_type_expr" == NULL);
13577 /* Fall through. */
13578 case FFEBLD_opANY:
13579 return error_mark_node;
13580 }
13581}
13582
13583/* Return PARM_DECL for arg#1 of master fn containing alternate ENTRY points
13584
13585 If the PARM_DECL already exists, return it, else create it. It's an
13586 integer_type_node argument for the master function that implements a
13587 subroutine or function with more than one entrypoint and is bound at
13588 run time with the entrypoint number (0 for SUBROUTINE/FUNCTION, 1 for
13589 first ENTRY statement, and so on). */
5ff904cd
JL
13590
13591#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
13592tree
13593ffecom_which_entrypoint_decl ()
5ff904cd 13594{
c7e4ee3a
CB
13595 assert (ffecom_which_entrypoint_decl_ != NULL_TREE);
13596
13597 return ffecom_which_entrypoint_decl_;
5ff904cd
JL
13598}
13599
13600#endif
c7e4ee3a
CB
13601\f
13602/* The following sections consists of private and public functions
13603 that have the same names and perform roughly the same functions
13604 as counterparts in the C front end. Changes in the C front end
13605 might affect how things should be done here. Only functions
13606 needed by the back end should be public here; the rest should
13607 be private (static in the C sense). Functions needed by other
13608 g77 front-end modules should be accessed by them via public
13609 ffecom_* names, which should themselves call private versions
13610 in this section so the private versions are easy to recognize
13611 when upgrading to a new gcc and finding interesting changes
13612 in the front end.
5ff904cd 13613
c7e4ee3a
CB
13614 Functions named after rule "foo:" in c-parse.y are named
13615 "bison_rule_foo_" so they are easy to find. */
5ff904cd 13616
c7e4ee3a 13617#if FFECOM_targetCURRENT == FFECOM_targetGCC
5ff904cd 13618
c7e4ee3a
CB
13619static void
13620bison_rule_pushlevel_ ()
13621{
13622 emit_line_note (input_filename, lineno);
13623 pushlevel (0);
13624 clear_last_expr ();
13625 push_momentary ();
13626 expand_start_bindings (0);
13627}
5ff904cd 13628
c7e4ee3a
CB
13629static tree
13630bison_rule_compstmt_ ()
5ff904cd 13631{
c7e4ee3a
CB
13632 tree t;
13633 int keep = kept_level_p ();
5ff904cd 13634
c7e4ee3a
CB
13635 /* Make the temps go away. */
13636 if (! keep)
13637 current_binding_level->names = NULL_TREE;
5ff904cd 13638
c7e4ee3a
CB
13639 emit_line_note (input_filename, lineno);
13640 expand_end_bindings (getdecls (), keep, 0);
13641 t = poplevel (keep, 1, 0);
13642 pop_momentary ();
5ff904cd 13643
c7e4ee3a
CB
13644 return t;
13645}
5ff904cd 13646
c7e4ee3a
CB
13647/* Return a definition for a builtin function named NAME and whose data type
13648 is TYPE. TYPE should be a function type with argument types.
13649 FUNCTION_CODE tells later passes how to compile calls to this function.
13650 See tree.h for its possible values.
5ff904cd 13651
c7e4ee3a
CB
13652 If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME,
13653 the name to be called if we can't opencode the function. */
5ff904cd 13654
26db82d8
BS
13655tree
13656builtin_function (const char *name, tree type, int function_code,
13657 enum built_in_class class,
c7e4ee3a
CB
13658 const char *library_name)
13659{
13660 tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
13661 DECL_EXTERNAL (decl) = 1;
13662 TREE_PUBLIC (decl) = 1;
13663 if (library_name)
13664 DECL_ASSEMBLER_NAME (decl) = get_identifier (library_name);
13665 make_decl_rtl (decl, NULL_PTR, 1);
13666 pushdecl (decl);
26db82d8
BS
13667 DECL_BUILT_IN_CLASS (decl) = class;
13668 DECL_FUNCTION_CODE (decl) = function_code;
5ff904cd 13669
c7e4ee3a 13670 return decl;
5ff904cd
JL
13671}
13672
c7e4ee3a
CB
13673/* Handle when a new declaration NEWDECL
13674 has the same name as an old one OLDDECL
13675 in the same binding contour.
13676 Prints an error message if appropriate.
5ff904cd 13677
c7e4ee3a
CB
13678 If safely possible, alter OLDDECL to look like NEWDECL, and return 1.
13679 Otherwise, return 0. */
5ff904cd 13680
c7e4ee3a
CB
13681static int
13682duplicate_decls (tree newdecl, tree olddecl)
5ff904cd 13683{
c7e4ee3a
CB
13684 int types_match = 1;
13685 int new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL
13686 && DECL_INITIAL (newdecl) != 0);
13687 tree oldtype = TREE_TYPE (olddecl);
13688 tree newtype = TREE_TYPE (newdecl);
5ff904cd 13689
c7e4ee3a
CB
13690 if (olddecl == newdecl)
13691 return 1;
5ff904cd 13692
c7e4ee3a
CB
13693 if (TREE_CODE (newtype) == ERROR_MARK
13694 || TREE_CODE (oldtype) == ERROR_MARK)
13695 types_match = 0;
5ff904cd 13696
c7e4ee3a
CB
13697 /* New decl is completely inconsistent with the old one =>
13698 tell caller to replace the old one.
13699 This is always an error except in the case of shadowing a builtin. */
13700 if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
13701 return 0;
5ff904cd 13702
c7e4ee3a
CB
13703 /* For real parm decl following a forward decl,
13704 return 1 so old decl will be reused. */
13705 if (types_match && TREE_CODE (newdecl) == PARM_DECL
13706 && TREE_ASM_WRITTEN (olddecl) && ! TREE_ASM_WRITTEN (newdecl))
13707 return 1;
5ff904cd 13708
c7e4ee3a
CB
13709 /* The new declaration is the same kind of object as the old one.
13710 The declarations may partially match. Print warnings if they don't
13711 match enough. Ultimately, copy most of the information from the new
13712 decl to the old one, and keep using the old one. */
5ff904cd 13713
c7e4ee3a
CB
13714 if (TREE_CODE (olddecl) == FUNCTION_DECL
13715 && DECL_BUILT_IN (olddecl))
13716 {
13717 /* A function declaration for a built-in function. */
13718 if (!TREE_PUBLIC (newdecl))
13719 return 0;
13720 else if (!types_match)
13721 {
13722 /* Accept the return type of the new declaration if same modes. */
13723 tree oldreturntype = TREE_TYPE (TREE_TYPE (olddecl));
13724 tree newreturntype = TREE_TYPE (TREE_TYPE (newdecl));
5ff904cd 13725
c7e4ee3a
CB
13726 if (TYPE_MODE (oldreturntype) == TYPE_MODE (newreturntype))
13727 {
13728 /* Function types may be shared, so we can't just modify
13729 the return type of olddecl's function type. */
13730 tree newtype
13731 = build_function_type (newreturntype,
13732 TYPE_ARG_TYPES (TREE_TYPE (olddecl)));
5ff904cd 13733
c7e4ee3a
CB
13734 types_match = 1;
13735 if (types_match)
13736 TREE_TYPE (olddecl) = newtype;
13737 }
c7e4ee3a
CB
13738 }
13739 if (!types_match)
13740 return 0;
13741 }
13742 else if (TREE_CODE (olddecl) == FUNCTION_DECL
13743 && DECL_SOURCE_LINE (olddecl) == 0)
5ff904cd 13744 {
c7e4ee3a
CB
13745 /* A function declaration for a predeclared function
13746 that isn't actually built in. */
13747 if (!TREE_PUBLIC (newdecl))
13748 return 0;
13749 else if (!types_match)
13750 {
13751 /* If the types don't match, preserve volatility indication.
13752 Later on, we will discard everything else about the
13753 default declaration. */
13754 TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
13755 }
13756 }
5ff904cd 13757
c7e4ee3a
CB
13758 /* Copy all the DECL_... slots specified in the new decl
13759 except for any that we copy here from the old type.
5ff904cd 13760
c7e4ee3a
CB
13761 Past this point, we don't change OLDTYPE and NEWTYPE
13762 even if we change the types of NEWDECL and OLDDECL. */
5ff904cd 13763
c7e4ee3a
CB
13764 if (types_match)
13765 {
c7e4ee3a
CB
13766 /* Merge the data types specified in the two decls. */
13767 if (TREE_CODE (newdecl) != FUNCTION_DECL || !DECL_BUILT_IN (olddecl))
13768 TREE_TYPE (newdecl)
13769 = TREE_TYPE (olddecl)
13770 = TREE_TYPE (newdecl);
5ff904cd 13771
c7e4ee3a
CB
13772 /* Lay the type out, unless already done. */
13773 if (oldtype != TREE_TYPE (newdecl))
13774 {
13775 if (TREE_TYPE (newdecl) != error_mark_node)
13776 layout_type (TREE_TYPE (newdecl));
13777 if (TREE_CODE (newdecl) != FUNCTION_DECL
13778 && TREE_CODE (newdecl) != TYPE_DECL
13779 && TREE_CODE (newdecl) != CONST_DECL)
13780 layout_decl (newdecl, 0);
13781 }
13782 else
13783 {
13784 /* Since the type is OLDDECL's, make OLDDECL's size go with. */
13785 DECL_SIZE (newdecl) = DECL_SIZE (olddecl);
06ceef4e 13786 DECL_SIZE_UNIT (newdecl) = DECL_SIZE_UNIT (olddecl);
c7e4ee3a
CB
13787 if (TREE_CODE (olddecl) != FUNCTION_DECL)
13788 if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl))
13789 DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl);
13790 }
5ff904cd 13791
c7e4ee3a
CB
13792 /* Keep the old rtl since we can safely use it. */
13793 DECL_RTL (newdecl) = DECL_RTL (olddecl);
5ff904cd 13794
c7e4ee3a
CB
13795 /* Merge the type qualifiers. */
13796 if (DECL_BUILT_IN_NONANSI (olddecl) && TREE_THIS_VOLATILE (olddecl)
13797 && !TREE_THIS_VOLATILE (newdecl))
13798 TREE_THIS_VOLATILE (olddecl) = 0;
13799 if (TREE_READONLY (newdecl))
13800 TREE_READONLY (olddecl) = 1;
13801 if (TREE_THIS_VOLATILE (newdecl))
13802 {
13803 TREE_THIS_VOLATILE (olddecl) = 1;
13804 if (TREE_CODE (newdecl) == VAR_DECL)
13805 make_var_volatile (newdecl);
13806 }
5ff904cd 13807
c7e4ee3a
CB
13808 /* Keep source location of definition rather than declaration.
13809 Likewise, keep decl at outer scope. */
13810 if ((DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0)
13811 || (DECL_CONTEXT (newdecl) != 0 && DECL_CONTEXT (olddecl) == 0))
13812 {
13813 DECL_SOURCE_LINE (newdecl) = DECL_SOURCE_LINE (olddecl);
13814 DECL_SOURCE_FILE (newdecl) = DECL_SOURCE_FILE (olddecl);
5ff904cd 13815
c7e4ee3a
CB
13816 if (DECL_CONTEXT (olddecl) == 0
13817 && TREE_CODE (newdecl) != FUNCTION_DECL)
13818 DECL_CONTEXT (newdecl) = 0;
13819 }
5ff904cd 13820
c7e4ee3a
CB
13821 /* Merge the unused-warning information. */
13822 if (DECL_IN_SYSTEM_HEADER (olddecl))
13823 DECL_IN_SYSTEM_HEADER (newdecl) = 1;
13824 else if (DECL_IN_SYSTEM_HEADER (newdecl))
13825 DECL_IN_SYSTEM_HEADER (olddecl) = 1;
5ff904cd 13826
c7e4ee3a
CB
13827 /* Merge the initialization information. */
13828 if (DECL_INITIAL (newdecl) == 0)
13829 DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
5ff904cd 13830
c7e4ee3a
CB
13831 /* Merge the section attribute.
13832 We want to issue an error if the sections conflict but that must be
13833 done later in decl_attributes since we are called before attributes
13834 are assigned. */
13835 if (DECL_SECTION_NAME (newdecl) == NULL_TREE)
13836 DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl);
5ff904cd 13837
c7e4ee3a
CB
13838#if BUILT_FOR_270
13839 if (TREE_CODE (newdecl) == FUNCTION_DECL)
13840 {
13841 DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl);
13842 DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
13843 }
5ff904cd 13844#endif
c7e4ee3a
CB
13845 }
13846 /* If cannot merge, then use the new type and qualifiers,
13847 and don't preserve the old rtl. */
13848 else
13849 {
13850 TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
13851 TREE_READONLY (olddecl) = TREE_READONLY (newdecl);
13852 TREE_THIS_VOLATILE (olddecl) = TREE_THIS_VOLATILE (newdecl);
13853 TREE_SIDE_EFFECTS (olddecl) = TREE_SIDE_EFFECTS (newdecl);
13854 }
5ff904cd 13855
c7e4ee3a
CB
13856 /* Merge the storage class information. */
13857 /* For functions, static overrides non-static. */
13858 if (TREE_CODE (newdecl) == FUNCTION_DECL)
13859 {
13860 TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl);
13861 /* This is since we don't automatically
13862 copy the attributes of NEWDECL into OLDDECL. */
13863 TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
13864 /* If this clears `static', clear it in the identifier too. */
13865 if (! TREE_PUBLIC (olddecl))
13866 TREE_PUBLIC (DECL_NAME (olddecl)) = 0;
13867 }
13868 if (DECL_EXTERNAL (newdecl))
13869 {
13870 TREE_STATIC (newdecl) = TREE_STATIC (olddecl);
13871 DECL_EXTERNAL (newdecl) = DECL_EXTERNAL (olddecl);
13872 /* An extern decl does not override previous storage class. */
13873 TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
13874 }
13875 else
13876 {
13877 TREE_STATIC (olddecl) = TREE_STATIC (newdecl);
13878 TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
13879 }
5ff904cd 13880
c7e4ee3a
CB
13881 /* If either decl says `inline', this fn is inline,
13882 unless its definition was passed already. */
13883 if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == 0)
13884 DECL_INLINE (olddecl) = 1;
13885 DECL_INLINE (newdecl) = DECL_INLINE (olddecl);
5ff904cd 13886
c7e4ee3a
CB
13887 /* Get rid of any built-in function if new arg types don't match it
13888 or if we have a function definition. */
13889 if (TREE_CODE (newdecl) == FUNCTION_DECL
13890 && DECL_BUILT_IN (olddecl)
13891 && (!types_match || new_is_definition))
13892 {
13893 TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
26db82d8 13894 DECL_BUILT_IN_CLASS (olddecl) = NOT_BUILT_IN;
c7e4ee3a 13895 }
5ff904cd 13896
c7e4ee3a
CB
13897 /* If redeclaring a builtin function, and not a definition,
13898 it stays built in.
13899 Also preserve various other info from the definition. */
13900 if (TREE_CODE (newdecl) == FUNCTION_DECL && !new_is_definition)
13901 {
13902 if (DECL_BUILT_IN (olddecl))
13903 {
26db82d8 13904 DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl);
c7e4ee3a
CB
13905 DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
13906 }
13907 else
13908 DECL_FRAME_SIZE (newdecl) = DECL_FRAME_SIZE (olddecl);
5ff904cd 13909
c7e4ee3a
CB
13910 DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
13911 DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
13912 DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl);
13913 DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
13914 }
5ff904cd 13915
c7e4ee3a
CB
13916 /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
13917 But preserve olddecl's DECL_UID. */
13918 {
13919 register unsigned olddecl_uid = DECL_UID (olddecl);
5ff904cd 13920
c7e4ee3a
CB
13921 memcpy ((char *) olddecl + sizeof (struct tree_common),
13922 (char *) newdecl + sizeof (struct tree_common),
13923 sizeof (struct tree_decl) - sizeof (struct tree_common));
13924 DECL_UID (olddecl) = olddecl_uid;
13925 }
5ff904cd 13926
c7e4ee3a 13927 return 1;
5ff904cd
JL
13928}
13929
c7e4ee3a
CB
13930/* Finish processing of a declaration;
13931 install its initial value.
13932 If the length of an array type is not known before,
13933 it must be determined now, from the initial value, or it is an error. */
13934
5ff904cd 13935static void
c7e4ee3a 13936finish_decl (tree decl, tree init, bool is_top_level)
5ff904cd 13937{
c7e4ee3a
CB
13938 register tree type = TREE_TYPE (decl);
13939 int was_incomplete = (DECL_SIZE (decl) == 0);
13940 int temporary = allocation_temporary_p ();
13941 bool at_top_level = (current_binding_level == global_binding_level);
13942 bool top_level = is_top_level || at_top_level;
5ff904cd 13943
c7e4ee3a
CB
13944 /* Caller should pass TRUE for is_top_level only if we wouldn't be at top
13945 level anyway. */
13946 assert (!is_top_level || !at_top_level);
5ff904cd 13947
c7e4ee3a
CB
13948 if (TREE_CODE (decl) == PARM_DECL)
13949 assert (init == NULL_TREE);
13950 /* Remember that PARM_DECL doesn't have a DECL_INITIAL field per se -- it
13951 overlaps DECL_ARG_TYPE. */
13952 else if (init == NULL_TREE)
13953 assert (DECL_INITIAL (decl) == NULL_TREE);
13954 else
13955 assert (DECL_INITIAL (decl) == error_mark_node);
5ff904cd 13956
c7e4ee3a 13957 if (init != NULL_TREE)
5ff904cd 13958 {
c7e4ee3a
CB
13959 if (TREE_CODE (decl) != TYPE_DECL)
13960 DECL_INITIAL (decl) = init;
13961 else
13962 {
13963 /* typedef foo = bar; store the type of bar as the type of foo. */
13964 TREE_TYPE (decl) = TREE_TYPE (init);
13965 DECL_INITIAL (decl) = init = 0;
13966 }
5ff904cd
JL
13967 }
13968
c7e4ee3a
CB
13969 /* Pop back to the obstack that is current for this binding level. This is
13970 because MAXINDEX, rtl, etc. to be made below must go in the permanent
13971 obstack. But don't discard the temporary data yet. */
13972 pop_obstacks ();
5ff904cd 13973
c7e4ee3a 13974 /* Deduce size of array from initialization, if not already known */
5ff904cd 13975
c7e4ee3a
CB
13976 if (TREE_CODE (type) == ARRAY_TYPE
13977 && TYPE_DOMAIN (type) == 0
13978 && TREE_CODE (decl) != TYPE_DECL)
13979 {
13980 assert (top_level);
13981 assert (was_incomplete);
5ff904cd 13982
c7e4ee3a
CB
13983 layout_decl (decl, 0);
13984 }
5ff904cd 13985
c7e4ee3a
CB
13986 if (TREE_CODE (decl) == VAR_DECL)
13987 {
13988 if (DECL_SIZE (decl) == NULL_TREE
13989 && TYPE_SIZE (TREE_TYPE (decl)) != NULL_TREE)
13990 layout_decl (decl, 0);
5ff904cd 13991
c7e4ee3a
CB
13992 if (DECL_SIZE (decl) == NULL_TREE
13993 && (TREE_STATIC (decl)
13994 ?
13995 /* A static variable with an incomplete type is an error if it is
13996 initialized. Also if it is not file scope. Otherwise, let it
13997 through, but if it is not `extern' then it may cause an error
13998 message later. */
13999 (DECL_INITIAL (decl) != 0 || DECL_CONTEXT (decl) != 0)
14000 :
14001 /* An automatic variable with an incomplete type is an error. */
14002 !DECL_EXTERNAL (decl)))
14003 {
14004 assert ("storage size not known" == NULL);
14005 abort ();
14006 }
5ff904cd 14007
c7e4ee3a
CB
14008 if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl))
14009 && (DECL_SIZE (decl) != 0)
14010 && (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST))
14011 {
14012 assert ("storage size not constant" == NULL);
14013 abort ();
14014 }
14015 }
5ff904cd 14016
c7e4ee3a
CB
14017 /* Output the assembler code and/or RTL code for variables and functions,
14018 unless the type is an undefined structure or union. If not, it will get
14019 done when the type is completed. */
5ff904cd 14020
c7e4ee3a 14021 if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)
5ff904cd 14022 {
c7e4ee3a
CB
14023 rest_of_decl_compilation (decl, NULL,
14024 DECL_CONTEXT (decl) == 0,
14025 0);
5ff904cd 14026
c7e4ee3a
CB
14027 if (DECL_CONTEXT (decl) != 0)
14028 {
14029 /* Recompute the RTL of a local array now if it used to be an
14030 incomplete type. */
14031 if (was_incomplete
14032 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
5ff904cd 14033 {
c7e4ee3a
CB
14034 /* If we used it already as memory, it must stay in memory. */
14035 TREE_ADDRESSABLE (decl) = TREE_USED (decl);
14036 /* If it's still incomplete now, no init will save it. */
14037 if (DECL_SIZE (decl) == 0)
14038 DECL_INITIAL (decl) = 0;
14039 expand_decl (decl);
5ff904cd 14040 }
c7e4ee3a
CB
14041 /* Compute and store the initial value. */
14042 if (TREE_CODE (decl) != FUNCTION_DECL)
14043 expand_decl_init (decl);
14044 }
14045 }
14046 else if (TREE_CODE (decl) == TYPE_DECL)
14047 {
14048 rest_of_decl_compilation (decl, NULL_PTR,
14049 DECL_CONTEXT (decl) == 0,
14050 0);
14051 }
5ff904cd 14052
c7e4ee3a
CB
14053 if (!(TREE_CODE (decl) == FUNCTION_DECL && DECL_INLINE (decl))
14054 && temporary
14055 /* DECL_INITIAL is not defined in PARM_DECLs, since it shares space with
14056 DECL_ARG_TYPE. */
14057 && TREE_CODE (decl) != PARM_DECL)
14058 {
14059 /* We need to remember that this array HAD an initialization, but
14060 discard the actual temporary nodes, since we can't have a permanent
14061 node keep pointing to them. */
14062 /* We make an exception for inline functions, since it's normal for a
14063 local extern redeclaration of an inline function to have a copy of
14064 the top-level decl's DECL_INLINE. */
14065 if ((DECL_INITIAL (decl) != 0)
14066 && (DECL_INITIAL (decl) != error_mark_node))
14067 {
14068 /* If this is a const variable, then preserve the
14069 initializer instead of discarding it so that we can optimize
14070 references to it. */
14071 /* This test used to include TREE_STATIC, but this won't be set
14072 for function level initializers. */
14073 if (TREE_READONLY (decl))
5ff904cd 14074 {
c7e4ee3a 14075 preserve_initializer ();
5ff904cd 14076
c7e4ee3a
CB
14077 /* The initializer and DECL must have the same (or equivalent
14078 types), but if the initializer is a STRING_CST, its type
14079 might not be on the right obstack, so copy the type
14080 of DECL. */
14081 TREE_TYPE (DECL_INITIAL (decl)) = type;
5ff904cd 14082 }
c7e4ee3a
CB
14083 else
14084 DECL_INITIAL (decl) = error_mark_node;
5ff904cd 14085 }
5ff904cd 14086 }
c7e4ee3a 14087
c7e4ee3a
CB
14088 /* If we have gone back from temporary to permanent allocation, actually
14089 free the temporary space that we no longer need. */
14090 if (temporary && !allocation_temporary_p ())
14091 permanent_allocation (0);
5ff904cd 14092
c7e4ee3a
CB
14093 /* At the end of a declaration, throw away any variable type sizes of types
14094 defined inside that declaration. There is no use computing them in the
14095 following function definition. */
14096 if (current_binding_level == global_binding_level)
14097 get_pending_sizes ();
14098}
5ff904cd 14099
c7e4ee3a
CB
14100/* Finish up a function declaration and compile that function
14101 all the way to assembler language output. The free the storage
14102 for the function definition.
5ff904cd 14103
c7e4ee3a 14104 This is called after parsing the body of the function definition.
5ff904cd 14105
c7e4ee3a
CB
14106 NESTED is nonzero if the function being finished is nested in another. */
14107
14108static void
14109finish_function (int nested)
14110{
14111 register tree fndecl = current_function_decl;
14112
14113 assert (fndecl != NULL_TREE);
14114 if (TREE_CODE (fndecl) != ERROR_MARK)
14115 {
14116 if (nested)
14117 assert (DECL_CONTEXT (fndecl) != NULL_TREE);
5ff904cd 14118 else
c7e4ee3a
CB
14119 assert (DECL_CONTEXT (fndecl) == NULL_TREE);
14120 }
5ff904cd 14121
c7e4ee3a
CB
14122/* TREE_READONLY (fndecl) = 1;
14123 This caused &foo to be of type ptr-to-const-function
14124 which then got a warning when stored in a ptr-to-function variable. */
5ff904cd 14125
c7e4ee3a 14126 poplevel (1, 0, 1);
5ff904cd 14127
c7e4ee3a
CB
14128 if (TREE_CODE (fndecl) != ERROR_MARK)
14129 {
14130 BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
5ff904cd 14131
c7e4ee3a 14132 /* Must mark the RESULT_DECL as being in this function. */
5ff904cd 14133
c7e4ee3a 14134 DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;
5ff904cd 14135
c7e4ee3a
CB
14136 /* Obey `register' declarations if `setjmp' is called in this fn. */
14137 /* Generate rtl for function exit. */
14138 expand_function_end (input_filename, lineno, 0);
5ff904cd 14139
c7e4ee3a
CB
14140 /* So we can tell if jump_optimize sets it to 1. */
14141 can_reach_end = 0;
5ff904cd 14142
7189a4b0
GK
14143 /* If this is a nested function, protect the local variables in the stack
14144 above us from being collected while we're compiling this function. */
14145 if (ggc_p && nested)
14146 ggc_push_context ();
14147
c7e4ee3a
CB
14148 /* Run the optimizers and output the assembler code for this function. */
14149 rest_of_compilation (fndecl);
7189a4b0
GK
14150
14151 /* Undo the GC context switch. */
14152 if (ggc_p && nested)
14153 ggc_pop_context ();
c7e4ee3a 14154 }
5ff904cd 14155
c7e4ee3a
CB
14156 /* Free all the tree nodes making up this function. */
14157 /* Switch back to allocating nodes permanently until we start another
14158 function. */
14159 if (!nested)
14160 permanent_allocation (1);
14161
14162 if (TREE_CODE (fndecl) != ERROR_MARK
14163 && !nested
14164 && DECL_SAVED_INSNS (fndecl) == 0)
14165 {
14166 /* Stop pointing to the local nodes about to be freed. */
14167 /* But DECL_INITIAL must remain nonzero so we know this was an actual
14168 function definition. */
14169 /* For a nested function, this is done in pop_f_function_context. */
14170 /* If rest_of_compilation set this to 0, leave it 0. */
14171 if (DECL_INITIAL (fndecl) != 0)
14172 DECL_INITIAL (fndecl) = error_mark_node;
14173 DECL_ARGUMENTS (fndecl) = 0;
5ff904cd 14174 }
c7e4ee3a
CB
14175
14176 if (!nested)
5ff904cd 14177 {
c7e4ee3a
CB
14178 /* Let the error reporting routines know that we're outside a function.
14179 For a nested function, this value is used in pop_c_function_context
14180 and then reset via pop_function_context. */
14181 ffecom_outer_function_decl_ = current_function_decl = NULL;
5ff904cd 14182 }
c7e4ee3a 14183}
5ff904cd 14184
c7e4ee3a
CB
14185/* Plug-in replacement for identifying the name of a decl and, for a
14186 function, what we call it in diagnostics. For now, "program unit"
14187 should suffice, since it's a bit of a hassle to figure out which
14188 of several kinds of things it is. Note that it could conceivably
14189 be a statement function, which probably isn't really a program unit
14190 per se, but if that comes up, it should be easy to check (being a
14191 nested function and all). */
14192
4b731ffa 14193static const char *
c7e4ee3a
CB
14194lang_printable_name (tree decl, int v)
14195{
14196 /* Just to keep GCC quiet about the unused variable.
14197 In theory, differing values of V should produce different
14198 output. */
14199 switch (v)
5ff904cd 14200 {
c7e4ee3a
CB
14201 default:
14202 if (TREE_CODE (decl) == ERROR_MARK)
14203 return "erroneous code";
14204 return IDENTIFIER_POINTER (DECL_NAME (decl));
5ff904cd 14205 }
c7e4ee3a
CB
14206}
14207
14208/* g77's function to print out name of current function that caused
14209 an error. */
14210
14211#if BUILT_FOR_270
b0791fa9
KG
14212static void
14213lang_print_error_function (const char *file)
c7e4ee3a
CB
14214{
14215 static ffeglobal last_g = NULL;
14216 static ffesymbol last_s = NULL;
14217 ffeglobal g;
14218 ffesymbol s;
14219 const char *kind;
14220
14221 if ((ffecom_primary_entry_ == NULL)
14222 || (ffesymbol_global (ffecom_primary_entry_) == NULL))
5ff904cd 14223 {
c7e4ee3a
CB
14224 g = NULL;
14225 s = NULL;
14226 kind = NULL;
5ff904cd
JL
14227 }
14228 else
14229 {
c7e4ee3a
CB
14230 g = ffesymbol_global (ffecom_primary_entry_);
14231 if (ffecom_nested_entry_ == NULL)
14232 {
14233 s = ffecom_primary_entry_;
14234 switch (ffesymbol_kind (s))
14235 {
14236 case FFEINFO_kindFUNCTION:
14237 kind = "function";
14238 break;
5ff904cd 14239
c7e4ee3a
CB
14240 case FFEINFO_kindSUBROUTINE:
14241 kind = "subroutine";
14242 break;
5ff904cd 14243
c7e4ee3a
CB
14244 case FFEINFO_kindPROGRAM:
14245 kind = "program";
14246 break;
14247
14248 case FFEINFO_kindBLOCKDATA:
14249 kind = "block-data";
14250 break;
14251
14252 default:
14253 kind = ffeinfo_kind_message (ffesymbol_kind (s));
14254 break;
14255 }
14256 }
14257 else
14258 {
14259 s = ffecom_nested_entry_;
14260 kind = "statement function";
14261 }
5ff904cd
JL
14262 }
14263
c7e4ee3a 14264 if ((last_g != g) || (last_s != s))
5ff904cd 14265 {
c7e4ee3a
CB
14266 if (file)
14267 fprintf (stderr, "%s: ", file);
14268
14269 if (s == NULL)
14270 fprintf (stderr, "Outside of any program unit:\n");
14271 else
5ff904cd 14272 {
c7e4ee3a
CB
14273 const char *name = ffesymbol_text (s);
14274
14275 fprintf (stderr, "In %s `%s':\n", kind, name);
5ff904cd 14276 }
5ff904cd 14277
c7e4ee3a
CB
14278 last_g = g;
14279 last_s = s;
5ff904cd 14280 }
c7e4ee3a
CB
14281}
14282#endif
5ff904cd 14283
c7e4ee3a 14284/* Similar to `lookup_name' but look only at current binding level. */
5ff904cd 14285
c7e4ee3a
CB
14286static tree
14287lookup_name_current_level (tree name)
14288{
14289 register tree t;
5ff904cd 14290
c7e4ee3a
CB
14291 if (current_binding_level == global_binding_level)
14292 return IDENTIFIER_GLOBAL_VALUE (name);
14293
14294 if (IDENTIFIER_LOCAL_VALUE (name) == 0)
14295 return 0;
14296
14297 for (t = current_binding_level->names; t; t = TREE_CHAIN (t))
14298 if (DECL_NAME (t) == name)
14299 break;
14300
14301 return t;
5ff904cd
JL
14302}
14303
c7e4ee3a 14304/* Create a new `struct binding_level'. */
5ff904cd 14305
c7e4ee3a
CB
14306static struct binding_level *
14307make_binding_level ()
5ff904cd 14308{
c7e4ee3a
CB
14309 /* NOSTRICT */
14310 return (struct binding_level *) xmalloc (sizeof (struct binding_level));
14311}
5ff904cd 14312
c7e4ee3a
CB
14313/* Save and restore the variables in this file and elsewhere
14314 that keep track of the progress of compilation of the current function.
14315 Used for nested functions. */
5ff904cd 14316
c7e4ee3a
CB
14317struct f_function
14318{
14319 struct f_function *next;
14320 tree named_labels;
14321 tree shadowed_labels;
14322 struct binding_level *binding_level;
14323};
5ff904cd 14324
c7e4ee3a 14325struct f_function *f_function_chain;
5ff904cd 14326
c7e4ee3a 14327/* Restore the variables used during compilation of a C function. */
5ff904cd 14328
c7e4ee3a
CB
14329static void
14330pop_f_function_context ()
14331{
14332 struct f_function *p = f_function_chain;
14333 tree link;
5ff904cd 14334
c7e4ee3a
CB
14335 /* Bring back all the labels that were shadowed. */
14336 for (link = shadowed_labels; link; link = TREE_CHAIN (link))
14337 if (DECL_NAME (TREE_VALUE (link)) != 0)
14338 IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link)))
14339 = TREE_VALUE (link);
5ff904cd 14340
c7e4ee3a
CB
14341 if (current_function_decl != error_mark_node
14342 && DECL_SAVED_INSNS (current_function_decl) == 0)
14343 {
14344 /* Stop pointing to the local nodes about to be freed. */
14345 /* But DECL_INITIAL must remain nonzero so we know this was an actual
14346 function definition. */
14347 DECL_INITIAL (current_function_decl) = error_mark_node;
14348 DECL_ARGUMENTS (current_function_decl) = 0;
5ff904cd
JL
14349 }
14350
c7e4ee3a 14351 pop_function_context ();
5ff904cd 14352
c7e4ee3a 14353 f_function_chain = p->next;
5ff904cd 14354
c7e4ee3a
CB
14355 named_labels = p->named_labels;
14356 shadowed_labels = p->shadowed_labels;
14357 current_binding_level = p->binding_level;
5ff904cd 14358
c7e4ee3a
CB
14359 free (p);
14360}
5ff904cd 14361
c7e4ee3a
CB
14362/* Save and reinitialize the variables
14363 used during compilation of a C function. */
5ff904cd 14364
c7e4ee3a
CB
14365static void
14366push_f_function_context ()
14367{
14368 struct f_function *p
14369 = (struct f_function *) xmalloc (sizeof (struct f_function));
5ff904cd 14370
c7e4ee3a
CB
14371 push_function_context ();
14372
14373 p->next = f_function_chain;
14374 f_function_chain = p;
14375
14376 p->named_labels = named_labels;
14377 p->shadowed_labels = shadowed_labels;
14378 p->binding_level = current_binding_level;
14379}
5ff904cd 14380
c7e4ee3a
CB
14381static void
14382push_parm_decl (tree parm)
14383{
14384 int old_immediate_size_expand = immediate_size_expand;
5ff904cd 14385
c7e4ee3a 14386 /* Don't try computing parm sizes now -- wait till fn is called. */
5ff904cd 14387
c7e4ee3a 14388 immediate_size_expand = 0;
5ff904cd 14389
c7e4ee3a 14390 push_obstacks_nochange ();
5ff904cd 14391
c7e4ee3a 14392 /* Fill in arg stuff. */
5ff904cd 14393
c7e4ee3a
CB
14394 DECL_ARG_TYPE (parm) = TREE_TYPE (parm);
14395 DECL_ARG_TYPE_AS_WRITTEN (parm) = TREE_TYPE (parm);
14396 TREE_READONLY (parm) = 1; /* All implementation args are read-only. */
5ff904cd 14397
c7e4ee3a
CB
14398 parm = pushdecl (parm);
14399
14400 immediate_size_expand = old_immediate_size_expand;
14401
14402 finish_decl (parm, NULL_TREE, FALSE);
5ff904cd
JL
14403}
14404
c7e4ee3a 14405/* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL, if appropriate. */
5ff904cd 14406
c7e4ee3a
CB
14407static tree
14408pushdecl_top_level (x)
14409 tree x;
14410{
14411 register tree t;
14412 register struct binding_level *b = current_binding_level;
14413 register tree f = current_function_decl;
5ff904cd 14414
c7e4ee3a
CB
14415 current_binding_level = global_binding_level;
14416 current_function_decl = NULL_TREE;
14417 t = pushdecl (x);
14418 current_binding_level = b;
14419 current_function_decl = f;
14420 return t;
14421}
14422
14423/* Store the list of declarations of the current level.
14424 This is done for the parameter declarations of a function being defined,
14425 after they are modified in the light of any missing parameters. */
14426
14427static tree
14428storedecls (decls)
14429 tree decls;
14430{
14431 return current_binding_level->names = decls;
14432}
14433
14434/* Store the parameter declarations into the current function declaration.
14435 This is called after parsing the parameter declarations, before
14436 digesting the body of the function.
14437
14438 For an old-style definition, modify the function's type
14439 to specify at least the number of arguments. */
5ff904cd
JL
14440
14441static void
c7e4ee3a 14442store_parm_decls (int is_main_program UNUSED)
5ff904cd
JL
14443{
14444 register tree fndecl = current_function_decl;
14445
c7e4ee3a
CB
14446 if (fndecl == error_mark_node)
14447 return;
5ff904cd 14448
c7e4ee3a
CB
14449 /* This is a chain of PARM_DECLs from old-style parm declarations. */
14450 DECL_ARGUMENTS (fndecl) = storedecls (nreverse (getdecls ()));
5ff904cd 14451
c7e4ee3a 14452 /* Initialize the RTL code for the function. */
5ff904cd 14453
c7e4ee3a 14454 init_function_start (fndecl, input_filename, lineno);
56a0044b 14455
c7e4ee3a 14456 /* Set up parameters and prepare for return, for the function. */
5ff904cd 14457
c7e4ee3a
CB
14458 expand_function_start (fndecl, 0);
14459}
5ff904cd 14460
c7e4ee3a
CB
14461static tree
14462start_decl (tree decl, bool is_top_level)
14463{
14464 register tree tem;
14465 bool at_top_level = (current_binding_level == global_binding_level);
14466 bool top_level = is_top_level || at_top_level;
5ff904cd 14467
c7e4ee3a
CB
14468 /* Caller should pass TRUE for is_top_level only if we wouldn't be at top
14469 level anyway. */
14470 assert (!is_top_level || !at_top_level);
5ff904cd 14471
c7e4ee3a
CB
14472 /* The corresponding pop_obstacks is in finish_decl. */
14473 push_obstacks_nochange ();
14474
14475 if (DECL_INITIAL (decl) != NULL_TREE)
14476 {
14477 assert (DECL_INITIAL (decl) == error_mark_node);
14478 assert (!DECL_EXTERNAL (decl));
56a0044b 14479 }
c7e4ee3a
CB
14480 else if (top_level)
14481 assert ((TREE_STATIC (decl) == 1) || DECL_EXTERNAL (decl) == 1);
5ff904cd 14482
c7e4ee3a
CB
14483 /* For Fortran, we by default put things in .common when possible. */
14484 DECL_COMMON (decl) = 1;
5ff904cd 14485
c7e4ee3a
CB
14486 /* Add this decl to the current binding level. TEM may equal DECL or it may
14487 be a previous decl of the same name. */
14488 if (is_top_level)
14489 tem = pushdecl_top_level (decl);
14490 else
14491 tem = pushdecl (decl);
14492
14493 /* For a local variable, define the RTL now. */
14494 if (!top_level
14495 /* But not if this is a duplicate decl and we preserved the rtl from the
14496 previous one (which may or may not happen). */
14497 && DECL_RTL (tem) == 0)
5ff904cd 14498 {
c7e4ee3a
CB
14499 if (TYPE_SIZE (TREE_TYPE (tem)) != 0)
14500 expand_decl (tem);
14501 else if (TREE_CODE (TREE_TYPE (tem)) == ARRAY_TYPE
14502 && DECL_INITIAL (tem) != 0)
14503 expand_decl (tem);
5ff904cd
JL
14504 }
14505
c7e4ee3a 14506 if (DECL_INITIAL (tem) != NULL_TREE)
5ff904cd 14507 {
c7e4ee3a
CB
14508 /* When parsing and digesting the initializer, use temporary storage.
14509 Do this even if we will ignore the value. */
14510 if (at_top_level)
14511 temporary_allocation ();
5ff904cd 14512 }
c7e4ee3a
CB
14513
14514 return tem;
5ff904cd
JL
14515}
14516
c7e4ee3a
CB
14517/* Create the FUNCTION_DECL for a function definition.
14518 DECLSPECS and DECLARATOR are the parts of the declaration;
14519 they describe the function's name and the type it returns,
14520 but twisted together in a fashion that parallels the syntax of C.
5ff904cd 14521
c7e4ee3a
CB
14522 This function creates a binding context for the function body
14523 as well as setting up the FUNCTION_DECL in current_function_decl.
5ff904cd 14524
c7e4ee3a
CB
14525 Returns 1 on success. If the DECLARATOR is not suitable for a function
14526 (it defines a datum instead), we return 0, which tells
14527 yyparse to report a parse error.
5ff904cd 14528
c7e4ee3a
CB
14529 NESTED is nonzero for a function nested within another function. */
14530
14531static void
14532start_function (tree name, tree type, int nested, int public)
5ff904cd 14533{
c7e4ee3a
CB
14534 tree decl1;
14535 tree restype;
14536 int old_immediate_size_expand = immediate_size_expand;
5ff904cd 14537
c7e4ee3a
CB
14538 named_labels = 0;
14539 shadowed_labels = 0;
14540
14541 /* Don't expand any sizes in the return type of the function. */
14542 immediate_size_expand = 0;
14543
14544 if (nested)
5ff904cd 14545 {
c7e4ee3a
CB
14546 assert (!public);
14547 assert (current_function_decl != NULL_TREE);
14548 assert (DECL_CONTEXT (current_function_decl) == NULL_TREE);
14549 }
14550 else
14551 {
14552 assert (current_function_decl == NULL_TREE);
5ff904cd 14553 }
c7e4ee3a
CB
14554
14555 if (TREE_CODE (type) == ERROR_MARK)
14556 decl1 = current_function_decl = error_mark_node;
56a0044b 14557 else
5ff904cd 14558 {
c7e4ee3a
CB
14559 decl1 = build_decl (FUNCTION_DECL,
14560 name,
14561 type);
14562 TREE_PUBLIC (decl1) = public ? 1 : 0;
14563 if (nested)
14564 DECL_INLINE (decl1) = 1;
14565 TREE_STATIC (decl1) = 1;
14566 DECL_EXTERNAL (decl1) = 0;
5ff904cd 14567
c7e4ee3a 14568 announce_function (decl1);
5ff904cd 14569
c7e4ee3a
CB
14570 /* Make the init_value nonzero so pushdecl knows this is not tentative.
14571 error_mark_node is replaced below (in poplevel) with the BLOCK. */
14572 DECL_INITIAL (decl1) = error_mark_node;
5ff904cd 14573
c7e4ee3a
CB
14574 /* Record the decl so that the function name is defined. If we already have
14575 a decl for this name, and it is a FUNCTION_DECL, use the old decl. */
5ff904cd 14576
c7e4ee3a 14577 current_function_decl = pushdecl (decl1);
5ff904cd
JL
14578 }
14579
c7e4ee3a
CB
14580 if (!nested)
14581 ffecom_outer_function_decl_ = current_function_decl;
5ff904cd 14582
c7e4ee3a
CB
14583 pushlevel (0);
14584 current_binding_level->prep_state = 2;
5ff904cd 14585
c7e4ee3a
CB
14586 if (TREE_CODE (current_function_decl) != ERROR_MARK)
14587 {
14588 make_function_rtl (current_function_decl);
5ff904cd 14589
c7e4ee3a
CB
14590 restype = TREE_TYPE (TREE_TYPE (current_function_decl));
14591 DECL_RESULT (current_function_decl)
14592 = build_decl (RESULT_DECL, NULL_TREE, restype);
5ff904cd 14593 }
5ff904cd 14594
c7e4ee3a
CB
14595 if (!nested)
14596 /* Allocate further tree nodes temporarily during compilation of this
14597 function only. */
14598 temporary_allocation ();
5ff904cd 14599
c7e4ee3a
CB
14600 if (!nested && (TREE_CODE (current_function_decl) != ERROR_MARK))
14601 TREE_ADDRESSABLE (current_function_decl) = 1;
14602
14603 immediate_size_expand = old_immediate_size_expand;
14604}
14605\f
14606/* Here are the public functions the GNU back end needs. */
14607
14608tree
14609convert (type, expr)
14610 tree type, expr;
5ff904cd 14611{
c7e4ee3a
CB
14612 register tree e = expr;
14613 register enum tree_code code = TREE_CODE (type);
5ff904cd 14614
c7e4ee3a
CB
14615 if (type == TREE_TYPE (e)
14616 || TREE_CODE (e) == ERROR_MARK)
14617 return e;
14618 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
14619 return fold (build1 (NOP_EXPR, type, e));
14620 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
14621 || code == ERROR_MARK)
14622 return error_mark_node;
14623 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
14624 {
14625 assert ("void value not ignored as it ought to be" == NULL);
14626 return error_mark_node;
14627 }
14628 if (code == VOID_TYPE)
14629 return build1 (CONVERT_EXPR, type, e);
14630 if ((code != RECORD_TYPE)
14631 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
14632 e = ffecom_1 (REALPART_EXPR, TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e))),
14633 e);
14634 if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)
14635 return fold (convert_to_integer (type, e));
14636 if (code == POINTER_TYPE)
14637 return fold (convert_to_pointer (type, e));
14638 if (code == REAL_TYPE)
14639 return fold (convert_to_real (type, e));
14640 if (code == COMPLEX_TYPE)
14641 return fold (convert_to_complex (type, e));
14642 if (code == RECORD_TYPE)
14643 return fold (ffecom_convert_to_complex_ (type, e));
5ff904cd 14644
c7e4ee3a
CB
14645 assert ("conversion to non-scalar type requested" == NULL);
14646 return error_mark_node;
14647}
5ff904cd 14648
c7e4ee3a
CB
14649/* integrate_decl_tree calls this function, but since we don't use the
14650 DECL_LANG_SPECIFIC field, this is a no-op. */
5ff904cd 14651
c7e4ee3a
CB
14652void
14653copy_lang_decl (node)
14654 tree node UNUSED;
14655{
5ff904cd
JL
14656}
14657
c7e4ee3a
CB
14658/* Return the list of declarations of the current level.
14659 Note that this list is in reverse order unless/until
14660 you nreverse it; and when you do nreverse it, you must
14661 store the result back using `storedecls' or you will lose. */
5ff904cd 14662
c7e4ee3a
CB
14663tree
14664getdecls ()
5ff904cd 14665{
c7e4ee3a 14666 return current_binding_level->names;
5ff904cd
JL
14667}
14668
c7e4ee3a 14669/* Nonzero if we are currently in the global binding level. */
5ff904cd 14670
c7e4ee3a
CB
14671int
14672global_bindings_p ()
5ff904cd 14673{
c7e4ee3a
CB
14674 return current_binding_level == global_binding_level;
14675}
5ff904cd 14676
c7e4ee3a
CB
14677/* Print an error message for invalid use of an incomplete type.
14678 VALUE is the expression that was used (or 0 if that isn't known)
14679 and TYPE is the type that was invalid. */
5ff904cd 14680
c7e4ee3a
CB
14681void
14682incomplete_type_error (value, type)
14683 tree value UNUSED;
14684 tree type;
14685{
14686 if (TREE_CODE (type) == ERROR_MARK)
14687 return;
5ff904cd 14688
c7e4ee3a
CB
14689 assert ("incomplete type?!?" == NULL);
14690}
14691
7189a4b0
GK
14692/* Mark ARG for GC. */
14693static void
54551044 14694mark_binding_level (void *arg)
7189a4b0
GK
14695{
14696 struct binding_level *level = *(struct binding_level **) arg;
14697
14698 while (level)
14699 {
14700 ggc_mark_tree (level->names);
14701 ggc_mark_tree (level->blocks);
14702 ggc_mark_tree (level->this_block);
14703 level = level->level_chain;
14704 }
14705}
14706
c7e4ee3a
CB
14707void
14708init_decl_processing ()
5ff904cd 14709{
7189a4b0
GK
14710 static tree *const tree_roots[] = {
14711 &current_function_decl,
14712 &string_type_node,
14713 &ffecom_tree_fun_type_void,
14714 &ffecom_integer_zero_node,
14715 &ffecom_integer_one_node,
14716 &ffecom_tree_subr_type,
14717 &ffecom_tree_ptr_to_subr_type,
14718 &ffecom_tree_blockdata_type,
14719 &ffecom_tree_xargc_,
14720 &ffecom_f2c_integer_type_node,
14721 &ffecom_f2c_ptr_to_integer_type_node,
14722 &ffecom_f2c_address_type_node,
14723 &ffecom_f2c_real_type_node,
14724 &ffecom_f2c_ptr_to_real_type_node,
14725 &ffecom_f2c_doublereal_type_node,
14726 &ffecom_f2c_complex_type_node,
14727 &ffecom_f2c_doublecomplex_type_node,
14728 &ffecom_f2c_longint_type_node,
14729 &ffecom_f2c_logical_type_node,
14730 &ffecom_f2c_flag_type_node,
14731 &ffecom_f2c_ftnlen_type_node,
14732 &ffecom_f2c_ftnlen_zero_node,
14733 &ffecom_f2c_ftnlen_one_node,
14734 &ffecom_f2c_ftnlen_two_node,
14735 &ffecom_f2c_ptr_to_ftnlen_type_node,
14736 &ffecom_f2c_ftnint_type_node,
14737 &ffecom_f2c_ptr_to_ftnint_type_node,
14738 &ffecom_outer_function_decl_,
14739 &ffecom_previous_function_decl_,
14740 &ffecom_which_entrypoint_decl_,
14741 &ffecom_float_zero_,
14742 &ffecom_float_half_,
14743 &ffecom_double_zero_,
14744 &ffecom_double_half_,
14745 &ffecom_func_result_,
14746 &ffecom_func_length_,
14747 &ffecom_multi_type_node_,
14748 &ffecom_multi_retval_,
14749 &named_labels,
14750 &shadowed_labels
14751 };
14752 size_t i;
14753
c7e4ee3a 14754 malloc_init ();
7189a4b0
GK
14755
14756 /* Record our roots. */
14757 for (i = 0; i < sizeof(tree_roots)/sizeof(tree_roots[0]); i++)
14758 ggc_add_tree_root (tree_roots[i], 1);
14759 ggc_add_tree_root (&ffecom_tree_type[0][0],
14760 FFEINFO_basictype*FFEINFO_kindtype);
14761 ggc_add_tree_root (&ffecom_tree_fun_type[0][0],
14762 FFEINFO_basictype*FFEINFO_kindtype);
14763 ggc_add_tree_root (&ffecom_tree_ptr_to_fun_type[0][0],
14764 FFEINFO_basictype*FFEINFO_kindtype);
14765 ggc_add_tree_root (ffecom_gfrt_, FFECOM_gfrt);
14766 ggc_add_root (&current_binding_level, 1, sizeof current_binding_level,
14767 mark_binding_level);
14768 ggc_add_root (&free_binding_level, 1, sizeof current_binding_level,
14769 mark_binding_level);
14770 ggc_add_root (&tracker_head, 1, sizeof tracker_head, mark_tracker_head);
14771
c7e4ee3a
CB
14772 ffe_init_0 ();
14773}
5ff904cd 14774
c7e4ee3a
CB
14775char *
14776init_parse (filename)
14777 char *filename;
14778{
c7e4ee3a
CB
14779 /* Open input file. */
14780 if (filename == 0 || !strcmp (filename, "-"))
5ff904cd 14781 {
c7e4ee3a
CB
14782 finput = stdin;
14783 filename = "stdin";
5ff904cd 14784 }
c7e4ee3a
CB
14785 else
14786 finput = fopen (filename, "r");
14787 if (finput == 0)
14788 pfatal_with_name (filename);
5ff904cd 14789
c7e4ee3a
CB
14790#ifdef IO_BUFFER_SIZE
14791 setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
14792#endif
5ff904cd 14793
c7e4ee3a
CB
14794 /* Make identifier nodes long enough for the language-specific slots. */
14795 set_identifier_size (sizeof (struct lang_identifier));
14796 decl_printable_name = lang_printable_name;
14797#if BUILT_FOR_270
14798 print_error_function = lang_print_error_function;
14799#endif
5ff904cd 14800
c7e4ee3a
CB
14801 return filename;
14802}
5ff904cd 14803
c7e4ee3a
CB
14804void
14805finish_parse ()
14806{
14807 fclose (finput);
14808}
14809
14810/* Delete the node BLOCK from the current binding level.
14811 This is used for the block inside a stmt expr ({...})
14812 so that the block can be reinserted where appropriate. */
14813
14814static void
14815delete_block (block)
14816 tree block;
14817{
14818 tree t;
14819 if (current_binding_level->blocks == block)
14820 current_binding_level->blocks = TREE_CHAIN (block);
14821 for (t = current_binding_level->blocks; t;)
14822 {
14823 if (TREE_CHAIN (t) == block)
14824 TREE_CHAIN (t) = TREE_CHAIN (block);
14825 else
14826 t = TREE_CHAIN (t);
14827 }
14828 TREE_CHAIN (block) = NULL;
14829 /* Clear TREE_USED which is always set by poplevel.
14830 The flag is set again if insert_block is called. */
14831 TREE_USED (block) = 0;
14832}
14833
14834void
14835insert_block (block)
14836 tree block;
14837{
14838 TREE_USED (block) = 1;
14839 current_binding_level->blocks
14840 = chainon (current_binding_level->blocks, block);
14841}
14842
14843int
14844lang_decode_option (argc, argv)
14845 int argc;
14846 char **argv;
14847{
14848 return ffe_decode_option (argc, argv);
5ff904cd
JL
14849}
14850
c7e4ee3a 14851/* used by print-tree.c */
5ff904cd 14852
c7e4ee3a
CB
14853void
14854lang_print_xnode (file, node, indent)
14855 FILE *file UNUSED;
14856 tree node UNUSED;
14857 int indent UNUSED;
5ff904cd 14858{
c7e4ee3a 14859}
5ff904cd 14860
c7e4ee3a
CB
14861void
14862lang_finish ()
14863{
14864 ffe_terminate_0 ();
5ff904cd 14865
c7e4ee3a
CB
14866 if (ffe_is_ffedebug ())
14867 malloc_pool_display (malloc_pool_image ());
5ff904cd
JL
14868}
14869
dafbd854 14870const char *
c7e4ee3a 14871lang_identify ()
5ff904cd 14872{
c7e4ee3a
CB
14873 return "f77";
14874}
5ff904cd 14875
c7e4ee3a
CB
14876void
14877lang_init_options ()
14878{
14879 /* Set default options for Fortran. */
14880 flag_move_all_movables = 1;
14881 flag_reduce_all_givs = 1;
14882 flag_argument_noalias = 2;
41af162c 14883 flag_errno_math = 0;
c64f913e 14884 flag_complex_divide_method = 1;
c7e4ee3a 14885}
5ff904cd 14886
c7e4ee3a
CB
14887void
14888lang_init ()
14889{
14890 /* If the file is output from cpp, it should contain a first line
14891 `# 1 "real-filename"', and the current design of gcc (toplev.c
14892 in particular and the way it sets up information relied on by
14893 INCLUDE) requires that we read this now, and store the
14894 "real-filename" info in master_input_filename. Ask the lexer
14895 to try doing this. */
14896 ffelex_hash_kludge (finput);
14897}
5ff904cd 14898
c7e4ee3a
CB
14899int
14900mark_addressable (exp)
14901 tree exp;
14902{
14903 register tree x = exp;
14904 while (1)
14905 switch (TREE_CODE (x))
14906 {
14907 case ADDR_EXPR:
14908 case COMPONENT_REF:
14909 case ARRAY_REF:
14910 x = TREE_OPERAND (x, 0);
14911 break;
5ff904cd 14912
c7e4ee3a
CB
14913 case CONSTRUCTOR:
14914 TREE_ADDRESSABLE (x) = 1;
14915 return 1;
5ff904cd 14916
c7e4ee3a
CB
14917 case VAR_DECL:
14918 case CONST_DECL:
14919 case PARM_DECL:
14920 case RESULT_DECL:
14921 if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
14922 && DECL_NONLOCAL (x))
14923 {
14924 if (TREE_PUBLIC (x))
14925 {
14926 assert ("address of global register var requested" == NULL);
14927 return 0;
14928 }
14929 assert ("address of register variable requested" == NULL);
14930 }
14931 else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x))
14932 {
14933 if (TREE_PUBLIC (x))
14934 {
14935 assert ("address of global register var requested" == NULL);
14936 return 0;
14937 }
14938 assert ("address of register var requested" == NULL);
14939 }
14940 put_var_into_stack (x);
5ff904cd 14941
c7e4ee3a
CB
14942 /* drops in */
14943 case FUNCTION_DECL:
14944 TREE_ADDRESSABLE (x) = 1;
14945#if 0 /* poplevel deals with this now. */
14946 if (DECL_CONTEXT (x) == 0)
14947 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (x)) = 1;
14948#endif
5ff904cd 14949
c7e4ee3a
CB
14950 default:
14951 return 1;
14952 }
5ff904cd
JL
14953}
14954
c7e4ee3a
CB
14955/* If DECL has a cleanup, build and return that cleanup here.
14956 This is a callback called by expand_expr. */
5ff904cd 14957
c7e4ee3a
CB
14958tree
14959maybe_build_cleanup (decl)
14960 tree decl UNUSED;
5ff904cd 14961{
c7e4ee3a
CB
14962 /* There are no cleanups in Fortran. */
14963 return NULL_TREE;
5ff904cd
JL
14964}
14965
c7e4ee3a
CB
14966/* Exit a binding level.
14967 Pop the level off, and restore the state of the identifier-decl mappings
14968 that were in effect when this level was entered.
5ff904cd 14969
c7e4ee3a
CB
14970 If KEEP is nonzero, this level had explicit declarations, so
14971 and create a "block" (a BLOCK node) for the level
14972 to record its declarations and subblocks for symbol table output.
5ff904cd 14973
c7e4ee3a
CB
14974 If FUNCTIONBODY is nonzero, this level is the body of a function,
14975 so create a block as if KEEP were set and also clear out all
14976 label names.
5ff904cd 14977
c7e4ee3a
CB
14978 If REVERSE is nonzero, reverse the order of decls before putting
14979 them into the BLOCK. */
5ff904cd 14980
c7e4ee3a
CB
14981tree
14982poplevel (keep, reverse, functionbody)
14983 int keep;
14984 int reverse;
14985 int functionbody;
5ff904cd 14986{
c7e4ee3a
CB
14987 register tree link;
14988 /* The chain of decls was accumulated in reverse order.
14989 Put it into forward order, just for cleanliness. */
14990 tree decls;
14991 tree subblocks = current_binding_level->blocks;
14992 tree block = 0;
14993 tree decl;
14994 int block_previously_created;
5ff904cd 14995
c7e4ee3a
CB
14996 /* Get the decls in the order they were written.
14997 Usually current_binding_level->names is in reverse order.
14998 But parameter decls were previously put in forward order. */
702edf1d 14999
c7e4ee3a
CB
15000 if (reverse)
15001 current_binding_level->names
15002 = decls = nreverse (current_binding_level->names);
15003 else
15004 decls = current_binding_level->names;
5ff904cd 15005
c7e4ee3a
CB
15006 /* Output any nested inline functions within this block
15007 if they weren't already output. */
5ff904cd 15008
c7e4ee3a
CB
15009 for (decl = decls; decl; decl = TREE_CHAIN (decl))
15010 if (TREE_CODE (decl) == FUNCTION_DECL
15011 && ! TREE_ASM_WRITTEN (decl)
15012 && DECL_INITIAL (decl) != 0
15013 && TREE_ADDRESSABLE (decl))
15014 {
15015 /* If this decl was copied from a file-scope decl
15016 on account of a block-scope extern decl,
15017 propagate TREE_ADDRESSABLE to the file-scope decl.
15018
15019 DECL_ABSTRACT_ORIGIN can be set to itself if warn_return_type is
15020 true, since then the decl goes through save_for_inline_copying. */
15021 if (DECL_ABSTRACT_ORIGIN (decl) != 0
15022 && DECL_ABSTRACT_ORIGIN (decl) != decl)
15023 TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1;
15024 else if (DECL_SAVED_INSNS (decl) != 0)
15025 {
15026 push_function_context ();
15027 output_inline_function (decl);
15028 pop_function_context ();
15029 }
15030 }
5ff904cd 15031
c7e4ee3a
CB
15032 /* If there were any declarations or structure tags in that level,
15033 or if this level is a function body,
15034 create a BLOCK to record them for the life of this function. */
5ff904cd 15035
c7e4ee3a
CB
15036 block = 0;
15037 block_previously_created = (current_binding_level->this_block != 0);
15038 if (block_previously_created)
15039 block = current_binding_level->this_block;
15040 else if (keep || functionbody)
15041 block = make_node (BLOCK);
15042 if (block != 0)
15043 {
15044 BLOCK_VARS (block) = decls;
15045 BLOCK_SUBBLOCKS (block) = subblocks;
c7e4ee3a 15046 }
5ff904cd 15047
c7e4ee3a 15048 /* In each subblock, record that this is its superior. */
5ff904cd 15049
c7e4ee3a
CB
15050 for (link = subblocks; link; link = TREE_CHAIN (link))
15051 BLOCK_SUPERCONTEXT (link) = block;
5ff904cd 15052
c7e4ee3a 15053 /* Clear out the meanings of the local variables of this level. */
5ff904cd 15054
c7e4ee3a 15055 for (link = decls; link; link = TREE_CHAIN (link))
5ff904cd 15056 {
c7e4ee3a
CB
15057 if (DECL_NAME (link) != 0)
15058 {
15059 /* If the ident. was used or addressed via a local extern decl,
15060 don't forget that fact. */
15061 if (DECL_EXTERNAL (link))
15062 {
15063 if (TREE_USED (link))
15064 TREE_USED (DECL_NAME (link)) = 1;
15065 if (TREE_ADDRESSABLE (link))
15066 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (link)) = 1;
15067 }
15068 IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = 0;
15069 }
5ff904cd 15070 }
5ff904cd 15071
c7e4ee3a
CB
15072 /* If the level being exited is the top level of a function,
15073 check over all the labels, and clear out the current
15074 (function local) meanings of their names. */
5ff904cd 15075
c7e4ee3a 15076 if (functionbody)
5ff904cd 15077 {
c7e4ee3a
CB
15078 /* If this is the top level block of a function,
15079 the vars are the function's parameters.
15080 Don't leave them in the BLOCK because they are
15081 found in the FUNCTION_DECL instead. */
15082
15083 BLOCK_VARS (block) = 0;
5ff904cd
JL
15084 }
15085
c7e4ee3a
CB
15086 /* Pop the current level, and free the structure for reuse. */
15087
15088 {
15089 register struct binding_level *level = current_binding_level;
15090 current_binding_level = current_binding_level->level_chain;
15091
15092 level->level_chain = free_binding_level;
15093 free_binding_level = level;
15094 }
15095
15096 /* Dispose of the block that we just made inside some higher level. */
15097 if (functionbody
15098 && current_function_decl != error_mark_node)
15099 DECL_INITIAL (current_function_decl) = block;
15100 else if (block)
5ff904cd 15101 {
c7e4ee3a
CB
15102 if (!block_previously_created)
15103 current_binding_level->blocks
15104 = chainon (current_binding_level->blocks, block);
5ff904cd 15105 }
c7e4ee3a
CB
15106 /* If we did not make a block for the level just exited,
15107 any blocks made for inner levels
15108 (since they cannot be recorded as subblocks in that level)
15109 must be carried forward so they will later become subblocks
15110 of something else. */
15111 else if (subblocks)
15112 current_binding_level->blocks
15113 = chainon (current_binding_level->blocks, subblocks);
5ff904cd 15114
c7e4ee3a
CB
15115 if (block)
15116 TREE_USED (block) = 1;
15117 return block;
5ff904cd
JL
15118}
15119
c7e4ee3a
CB
15120void
15121print_lang_decl (file, node, indent)
15122 FILE *file UNUSED;
15123 tree node UNUSED;
15124 int indent UNUSED;
15125{
15126}
5ff904cd 15127
c7e4ee3a
CB
15128void
15129print_lang_identifier (file, node, indent)
15130 FILE *file;
15131 tree node;
15132 int indent;
15133{
15134 print_node (file, "global", IDENTIFIER_GLOBAL_VALUE (node), indent + 4);
15135 print_node (file, "local", IDENTIFIER_LOCAL_VALUE (node), indent + 4);
15136}
5ff904cd 15137
c7e4ee3a
CB
15138void
15139print_lang_statistics ()
15140{
15141}
5ff904cd 15142
c7e4ee3a
CB
15143void
15144print_lang_type (file, node, indent)
15145 FILE *file UNUSED;
15146 tree node UNUSED;
15147 int indent UNUSED;
5ff904cd 15148{
c7e4ee3a 15149}
5ff904cd 15150
c7e4ee3a
CB
15151/* Record a decl-node X as belonging to the current lexical scope.
15152 Check for errors (such as an incompatible declaration for the same
15153 name already seen in the same scope).
5ff904cd 15154
c7e4ee3a
CB
15155 Returns either X or an old decl for the same name.
15156 If an old decl is returned, it may have been smashed
15157 to agree with what X says. */
5ff904cd 15158
c7e4ee3a
CB
15159tree
15160pushdecl (x)
15161 tree x;
15162{
15163 register tree t;
15164 register tree name = DECL_NAME (x);
15165 register struct binding_level *b = current_binding_level;
5ff904cd 15166
c7e4ee3a
CB
15167 if ((TREE_CODE (x) == FUNCTION_DECL)
15168 && (DECL_INITIAL (x) == 0)
15169 && DECL_EXTERNAL (x))
15170 DECL_CONTEXT (x) = NULL_TREE;
56a0044b 15171 else
c7e4ee3a
CB
15172 DECL_CONTEXT (x) = current_function_decl;
15173
15174 if (name)
56a0044b 15175 {
c7e4ee3a
CB
15176 if (IDENTIFIER_INVENTED (name))
15177 {
15178#if BUILT_FOR_270
15179 DECL_ARTIFICIAL (x) = 1;
15180#endif
15181 DECL_IN_SYSTEM_HEADER (x) = 1;
15182 }
5ff904cd 15183
c7e4ee3a 15184 t = lookup_name_current_level (name);
5ff904cd 15185
c7e4ee3a 15186 assert ((t == NULL_TREE) || (DECL_CONTEXT (x) == NULL_TREE));
5ff904cd 15187
c7e4ee3a
CB
15188 /* Don't push non-parms onto list for parms until we understand
15189 why we're doing this and whether it works. */
56a0044b 15190
c7e4ee3a
CB
15191 assert ((b == global_binding_level)
15192 || !ffecom_transform_only_dummies_
15193 || TREE_CODE (x) == PARM_DECL);
5ff904cd 15194
c7e4ee3a
CB
15195 if ((t != NULL_TREE) && duplicate_decls (x, t))
15196 return t;
5ff904cd 15197
c7e4ee3a
CB
15198 /* If we are processing a typedef statement, generate a whole new
15199 ..._TYPE node (which will be just an variant of the existing
15200 ..._TYPE node with identical properties) and then install the
15201 TYPE_DECL node generated to represent the typedef name as the
15202 TYPE_NAME of this brand new (duplicate) ..._TYPE node.
5ff904cd 15203
c7e4ee3a
CB
15204 The whole point here is to end up with a situation where each and every
15205 ..._TYPE node the compiler creates will be uniquely associated with
15206 AT MOST one node representing a typedef name. This way, even though
15207 the compiler substitutes corresponding ..._TYPE nodes for TYPE_DECL
15208 (i.e. "typedef name") nodes very early on, later parts of the
15209 compiler can always do the reverse translation and get back the
15210 corresponding typedef name. For example, given:
5ff904cd 15211
c7e4ee3a 15212 typedef struct S MY_TYPE; MY_TYPE object;
5ff904cd 15213
c7e4ee3a
CB
15214 Later parts of the compiler might only know that `object' was of type
15215 `struct S' if it were not for code just below. With this code
15216 however, later parts of the compiler see something like:
5ff904cd 15217
c7e4ee3a 15218 struct S' == struct S typedef struct S' MY_TYPE; struct S' object;
5ff904cd 15219
c7e4ee3a
CB
15220 And they can then deduce (from the node for type struct S') that the
15221 original object declaration was:
5ff904cd 15222
c7e4ee3a 15223 MY_TYPE object;
5ff904cd 15224
c7e4ee3a
CB
15225 Being able to do this is important for proper support of protoize, and
15226 also for generating precise symbolic debugging information which
15227 takes full account of the programmer's (typedef) vocabulary.
5ff904cd 15228
c7e4ee3a
CB
15229 Obviously, we don't want to generate a duplicate ..._TYPE node if the
15230 TYPE_DECL node that we are now processing really represents a
15231 standard built-in type.
5ff904cd 15232
c7e4ee3a
CB
15233 Since all standard types are effectively declared at line zero in the
15234 source file, we can easily check to see if we are working on a
15235 standard type by checking the current value of lineno. */
15236
15237 if (TREE_CODE (x) == TYPE_DECL)
15238 {
15239 if (DECL_SOURCE_LINE (x) == 0)
15240 {
15241 if (TYPE_NAME (TREE_TYPE (x)) == 0)
15242 TYPE_NAME (TREE_TYPE (x)) = x;
15243 }
15244 else if (TREE_TYPE (x) != error_mark_node)
15245 {
15246 tree tt = TREE_TYPE (x);
15247
15248 tt = build_type_copy (tt);
15249 TYPE_NAME (tt) = x;
15250 TREE_TYPE (x) = tt;
15251 }
15252 }
5ff904cd 15253
c7e4ee3a
CB
15254 /* This name is new in its binding level. Install the new declaration
15255 and return it. */
15256 if (b == global_binding_level)
15257 IDENTIFIER_GLOBAL_VALUE (name) = x;
15258 else
15259 IDENTIFIER_LOCAL_VALUE (name) = x;
15260 }
5ff904cd 15261
c7e4ee3a
CB
15262 /* Put decls on list in reverse order. We will reverse them later if
15263 necessary. */
15264 TREE_CHAIN (x) = b->names;
15265 b->names = x;
5ff904cd 15266
c7e4ee3a 15267 return x;
5ff904cd
JL
15268}
15269
c7e4ee3a 15270/* Nonzero if the current level needs to have a BLOCK made. */
5ff904cd 15271
c7e4ee3a
CB
15272static int
15273kept_level_p ()
5ff904cd 15274{
c7e4ee3a
CB
15275 tree decl;
15276
15277 for (decl = current_binding_level->names;
15278 decl;
15279 decl = TREE_CHAIN (decl))
15280 {
15281 if (TREE_USED (decl) || TREE_CODE (decl) != VAR_DECL
15282 || (DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl)))
15283 /* Currently, there aren't supposed to be non-artificial names
15284 at other than the top block for a function -- they're
15285 believed to always be temps. But it's wise to check anyway. */
15286 return 1;
15287 }
15288 return 0;
5ff904cd
JL
15289}
15290
c7e4ee3a
CB
15291/* Enter a new binding level.
15292 If TAG_TRANSPARENT is nonzero, do so only for the name space of variables,
15293 not for that of tags. */
5ff904cd
JL
15294
15295void
c7e4ee3a
CB
15296pushlevel (tag_transparent)
15297 int tag_transparent;
5ff904cd 15298{
c7e4ee3a 15299 register struct binding_level *newlevel = NULL_BINDING_LEVEL;
5ff904cd 15300
c7e4ee3a 15301 assert (! tag_transparent);
5ff904cd 15302
c7e4ee3a
CB
15303 if (current_binding_level == global_binding_level)
15304 {
15305 named_labels = 0;
15306 }
5ff904cd 15307
c7e4ee3a 15308 /* Reuse or create a struct for this binding level. */
5ff904cd 15309
c7e4ee3a 15310 if (free_binding_level)
77f77701 15311 {
c7e4ee3a
CB
15312 newlevel = free_binding_level;
15313 free_binding_level = free_binding_level->level_chain;
77f77701
DB
15314 }
15315 else
c7e4ee3a
CB
15316 {
15317 newlevel = make_binding_level ();
15318 }
77f77701 15319
c7e4ee3a
CB
15320 /* Add this level to the front of the chain (stack) of levels that
15321 are active. */
71b5e532 15322
c7e4ee3a
CB
15323 *newlevel = clear_binding_level;
15324 newlevel->level_chain = current_binding_level;
15325 current_binding_level = newlevel;
5ff904cd
JL
15326}
15327
c7e4ee3a
CB
15328/* Set the BLOCK node for the innermost scope
15329 (the one we are currently in). */
77f77701 15330
5ff904cd 15331void
c7e4ee3a
CB
15332set_block (block)
15333 register tree block;
5ff904cd 15334{
c7e4ee3a 15335 current_binding_level->this_block = block;
5ff904cd
JL
15336}
15337
c7e4ee3a 15338/* ~~gcc/tree.h *should* declare this, because toplev.c references it. */
5ff904cd 15339
c7e4ee3a 15340/* Can't 'yydebug' a front end not generated by yacc/bison! */
bc289659
ML
15341
15342void
c7e4ee3a
CB
15343set_yydebug (value)
15344 int value;
bc289659 15345{
c7e4ee3a
CB
15346 if (value)
15347 fprintf (stderr, "warning: no yacc/bison-generated output to debug!\n");
bc289659
ML
15348}
15349
c7e4ee3a
CB
15350tree
15351signed_or_unsigned_type (unsignedp, type)
15352 int unsignedp;
15353 tree type;
5ff904cd 15354{
c7e4ee3a 15355 tree type2;
5ff904cd 15356
c7e4ee3a
CB
15357 if (! INTEGRAL_TYPE_P (type))
15358 return type;
15359 if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node))
15360 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
15361 if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
15362 return unsignedp ? unsigned_type_node : integer_type_node;
15363 if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node))
15364 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
15365 if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node))
15366 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
15367 if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node))
15368 return (unsignedp ? long_long_unsigned_type_node
15369 : long_long_integer_type_node);
5ff904cd 15370
c7e4ee3a
CB
15371 type2 = type_for_size (TYPE_PRECISION (type), unsignedp);
15372 if (type2 == NULL_TREE)
15373 return type;
f84639ba 15374
c7e4ee3a 15375 return type2;
5ff904cd
JL
15376}
15377
c7e4ee3a
CB
15378tree
15379signed_type (type)
15380 tree type;
5ff904cd 15381{
c7e4ee3a
CB
15382 tree type1 = TYPE_MAIN_VARIANT (type);
15383 ffeinfoKindtype kt;
15384 tree type2;
5ff904cd 15385
c7e4ee3a
CB
15386 if (type1 == unsigned_char_type_node || type1 == char_type_node)
15387 return signed_char_type_node;
15388 if (type1 == unsigned_type_node)
15389 return integer_type_node;
15390 if (type1 == short_unsigned_type_node)
15391 return short_integer_type_node;
15392 if (type1 == long_unsigned_type_node)
15393 return long_integer_type_node;
15394 if (type1 == long_long_unsigned_type_node)
15395 return long_long_integer_type_node;
15396#if 0 /* gcc/c-* files only */
15397 if (type1 == unsigned_intDI_type_node)
15398 return intDI_type_node;
15399 if (type1 == unsigned_intSI_type_node)
15400 return intSI_type_node;
15401 if (type1 == unsigned_intHI_type_node)
15402 return intHI_type_node;
15403 if (type1 == unsigned_intQI_type_node)
15404 return intQI_type_node;
15405#endif
5ff904cd 15406
c7e4ee3a
CB
15407 type2 = type_for_size (TYPE_PRECISION (type1), 0);
15408 if (type2 != NULL_TREE)
15409 return type2;
5ff904cd 15410
c7e4ee3a
CB
15411 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
15412 {
15413 type2 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
5ff904cd 15414
c7e4ee3a
CB
15415 if (type1 == type2)
15416 return ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
15417 }
15418
15419 return type;
5ff904cd
JL
15420}
15421
c7e4ee3a
CB
15422/* Prepare expr to be an argument of a TRUTH_NOT_EXPR,
15423 or validate its data type for an `if' or `while' statement or ?..: exp.
15424
15425 This preparation consists of taking the ordinary
15426 representation of an expression expr and producing a valid tree
15427 boolean expression describing whether expr is nonzero. We could
15428 simply always do build_binary_op (NE_EXPR, expr, integer_zero_node, 1),
15429 but we optimize comparisons, &&, ||, and !.
15430
15431 The resulting type should always be `integer_type_node'. */
5ff904cd
JL
15432
15433tree
c7e4ee3a
CB
15434truthvalue_conversion (expr)
15435 tree expr;
5ff904cd 15436{
c7e4ee3a
CB
15437 if (TREE_CODE (expr) == ERROR_MARK)
15438 return expr;
5ff904cd 15439
c7e4ee3a
CB
15440#if 0 /* This appears to be wrong for C++. */
15441 /* These really should return error_mark_node after 2.4 is stable.
15442 But not all callers handle ERROR_MARK properly. */
15443 switch (TREE_CODE (TREE_TYPE (expr)))
15444 {
15445 case RECORD_TYPE:
15446 error ("struct type value used where scalar is required");
15447 return integer_zero_node;
5ff904cd 15448
c7e4ee3a
CB
15449 case UNION_TYPE:
15450 error ("union type value used where scalar is required");
15451 return integer_zero_node;
5ff904cd 15452
c7e4ee3a
CB
15453 case ARRAY_TYPE:
15454 error ("array type value used where scalar is required");
15455 return integer_zero_node;
5ff904cd 15456
c7e4ee3a
CB
15457 default:
15458 break;
15459 }
15460#endif /* 0 */
5ff904cd 15461
c7e4ee3a
CB
15462 switch (TREE_CODE (expr))
15463 {
15464 /* It is simpler and generates better code to have only TRUTH_*_EXPR
15465 or comparison expressions as truth values at this level. */
15466#if 0
15467 case COMPONENT_REF:
15468 /* A one-bit unsigned bit-field is already acceptable. */
15469 if (1 == TREE_INT_CST_LOW (DECL_SIZE (TREE_OPERAND (expr, 1)))
15470 && TREE_UNSIGNED (TREE_OPERAND (expr, 1)))
15471 return expr;
15472 break;
15473#endif
15474
15475 case EQ_EXPR:
15476 /* It is simpler and generates better code to have only TRUTH_*_EXPR
15477 or comparison expressions as truth values at this level. */
15478#if 0
15479 if (integer_zerop (TREE_OPERAND (expr, 1)))
15480 return build_unary_op (TRUTH_NOT_EXPR, TREE_OPERAND (expr, 0), 0);
15481#endif
15482 case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
15483 case TRUTH_ANDIF_EXPR:
15484 case TRUTH_ORIF_EXPR:
15485 case TRUTH_AND_EXPR:
15486 case TRUTH_OR_EXPR:
15487 case TRUTH_XOR_EXPR:
15488 TREE_TYPE (expr) = integer_type_node;
15489 return expr;
5ff904cd 15490
c7e4ee3a
CB
15491 case ERROR_MARK:
15492 return expr;
5ff904cd 15493
c7e4ee3a
CB
15494 case INTEGER_CST:
15495 return integer_zerop (expr) ? integer_zero_node : integer_one_node;
5ff904cd 15496
c7e4ee3a
CB
15497 case REAL_CST:
15498 return real_zerop (expr) ? integer_zero_node : integer_one_node;
5ff904cd 15499
c7e4ee3a
CB
15500 case ADDR_EXPR:
15501 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 0)))
15502 return build (COMPOUND_EXPR, integer_type_node,
15503 TREE_OPERAND (expr, 0), integer_one_node);
15504 else
15505 return integer_one_node;
5ff904cd 15506
c7e4ee3a
CB
15507 case COMPLEX_EXPR:
15508 return ffecom_2 ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))
15509 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
15510 integer_type_node,
15511 truthvalue_conversion (TREE_OPERAND (expr, 0)),
15512 truthvalue_conversion (TREE_OPERAND (expr, 1)));
5ff904cd 15513
c7e4ee3a
CB
15514 case NEGATE_EXPR:
15515 case ABS_EXPR:
15516 case FLOAT_EXPR:
15517 case FFS_EXPR:
15518 /* These don't change whether an object is non-zero or zero. */
15519 return truthvalue_conversion (TREE_OPERAND (expr, 0));
5ff904cd 15520
c7e4ee3a
CB
15521 case LROTATE_EXPR:
15522 case RROTATE_EXPR:
15523 /* These don't change whether an object is zero or non-zero, but
15524 we can't ignore them if their second arg has side-effects. */
15525 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)))
15526 return build (COMPOUND_EXPR, integer_type_node, TREE_OPERAND (expr, 1),
15527 truthvalue_conversion (TREE_OPERAND (expr, 0)));
15528 else
15529 return truthvalue_conversion (TREE_OPERAND (expr, 0));
5ff904cd 15530
c7e4ee3a
CB
15531 case COND_EXPR:
15532 /* Distribute the conversion into the arms of a COND_EXPR. */
15533 return fold (build (COND_EXPR, integer_type_node, TREE_OPERAND (expr, 0),
15534 truthvalue_conversion (TREE_OPERAND (expr, 1)),
15535 truthvalue_conversion (TREE_OPERAND (expr, 2))));
5ff904cd 15536
c7e4ee3a
CB
15537 case CONVERT_EXPR:
15538 /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
15539 since that affects how `default_conversion' will behave. */
15540 if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE
15541 || TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)
15542 break;
15543 /* fall through... */
15544 case NOP_EXPR:
15545 /* If this is widening the argument, we can ignore it. */
15546 if (TYPE_PRECISION (TREE_TYPE (expr))
15547 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
15548 return truthvalue_conversion (TREE_OPERAND (expr, 0));
15549 break;
5ff904cd 15550
c7e4ee3a
CB
15551 case MINUS_EXPR:
15552 /* With IEEE arithmetic, x - x may not equal 0, so we can't optimize
15553 this case. */
15554 if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
15555 && TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE)
15556 break;
15557 /* fall through... */
15558 case BIT_XOR_EXPR:
15559 /* This and MINUS_EXPR can be changed into a comparison of the
15560 two objects. */
15561 if (TREE_TYPE (TREE_OPERAND (expr, 0))
15562 == TREE_TYPE (TREE_OPERAND (expr, 1)))
15563 return ffecom_2 (NE_EXPR, integer_type_node,
15564 TREE_OPERAND (expr, 0),
15565 TREE_OPERAND (expr, 1));
15566 return ffecom_2 (NE_EXPR, integer_type_node,
15567 TREE_OPERAND (expr, 0),
15568 fold (build1 (NOP_EXPR,
15569 TREE_TYPE (TREE_OPERAND (expr, 0)),
15570 TREE_OPERAND (expr, 1))));
15571
15572 case BIT_AND_EXPR:
15573 if (integer_onep (TREE_OPERAND (expr, 1)))
15574 return expr;
15575 break;
15576
15577 case MODIFY_EXPR:
15578#if 0 /* No such thing in Fortran. */
15579 if (warn_parentheses && C_EXP_ORIGINAL_CODE (expr) == MODIFY_EXPR)
15580 warning ("suggest parentheses around assignment used as truth value");
15581#endif
15582 break;
15583
15584 default:
15585 break;
5ff904cd
JL
15586 }
15587
c7e4ee3a
CB
15588 if (TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE)
15589 return (ffecom_2
15590 ((TREE_SIDE_EFFECTS (expr)
15591 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
15592 integer_type_node,
15593 truthvalue_conversion (ffecom_1 (REALPART_EXPR,
15594 TREE_TYPE (TREE_TYPE (expr)),
15595 expr)),
15596 truthvalue_conversion (ffecom_1 (IMAGPART_EXPR,
15597 TREE_TYPE (TREE_TYPE (expr)),
15598 expr))));
15599
15600 return ffecom_2 (NE_EXPR, integer_type_node,
15601 expr,
15602 convert (TREE_TYPE (expr), integer_zero_node));
15603}
15604
15605tree
15606type_for_mode (mode, unsignedp)
15607 enum machine_mode mode;
15608 int unsignedp;
15609{
15610 int i;
15611 int j;
15612 tree t;
5ff904cd 15613
c7e4ee3a
CB
15614 if (mode == TYPE_MODE (integer_type_node))
15615 return unsignedp ? unsigned_type_node : integer_type_node;
5ff904cd 15616
c7e4ee3a
CB
15617 if (mode == TYPE_MODE (signed_char_type_node))
15618 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
5ff904cd 15619
c7e4ee3a
CB
15620 if (mode == TYPE_MODE (short_integer_type_node))
15621 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
5ff904cd 15622
c7e4ee3a
CB
15623 if (mode == TYPE_MODE (long_integer_type_node))
15624 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
5ff904cd 15625
c7e4ee3a
CB
15626 if (mode == TYPE_MODE (long_long_integer_type_node))
15627 return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node;
5ff904cd 15628
fed3cef0
RK
15629#if HOST_BITS_PER_WIDE_INT >= 64
15630 if (mode == TYPE_MODE (intTI_type_node))
15631 return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
15632#endif
15633
c7e4ee3a
CB
15634 if (mode == TYPE_MODE (float_type_node))
15635 return float_type_node;
5ff904cd 15636
c7e4ee3a
CB
15637 if (mode == TYPE_MODE (double_type_node))
15638 return double_type_node;
5ff904cd 15639
c7e4ee3a
CB
15640 if (mode == TYPE_MODE (build_pointer_type (char_type_node)))
15641 return build_pointer_type (char_type_node);
5ff904cd 15642
c7e4ee3a
CB
15643 if (mode == TYPE_MODE (build_pointer_type (integer_type_node)))
15644 return build_pointer_type (integer_type_node);
5ff904cd 15645
c7e4ee3a
CB
15646 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
15647 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
15648 {
15649 if (((t = ffecom_tree_type[i][j]) != NULL_TREE)
15650 && (mode == TYPE_MODE (t)))
15651 {
15652 if ((i == FFEINFO_basictypeINTEGER) && unsignedp)
15653 return ffecom_tree_type[FFEINFO_basictypeHOLLERITH][j];
15654 else
15655 return t;
15656 }
15657 }
5ff904cd 15658
c7e4ee3a 15659 return 0;
5ff904cd
JL
15660}
15661
c7e4ee3a
CB
15662tree
15663type_for_size (bits, unsignedp)
15664 unsigned bits;
15665 int unsignedp;
5ff904cd 15666{
c7e4ee3a
CB
15667 ffeinfoKindtype kt;
15668 tree type_node;
5ff904cd 15669
c7e4ee3a
CB
15670 if (bits == TYPE_PRECISION (integer_type_node))
15671 return unsignedp ? unsigned_type_node : integer_type_node;
5ff904cd 15672
c7e4ee3a
CB
15673 if (bits == TYPE_PRECISION (signed_char_type_node))
15674 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
5ff904cd 15675
c7e4ee3a
CB
15676 if (bits == TYPE_PRECISION (short_integer_type_node))
15677 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
5ff904cd 15678
c7e4ee3a
CB
15679 if (bits == TYPE_PRECISION (long_integer_type_node))
15680 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
5ff904cd 15681
c7e4ee3a
CB
15682 if (bits == TYPE_PRECISION (long_long_integer_type_node))
15683 return (unsignedp ? long_long_unsigned_type_node
15684 : long_long_integer_type_node);
5ff904cd 15685
c7e4ee3a 15686 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
5ff904cd 15687 {
c7e4ee3a 15688 type_node = ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
5ff904cd 15689
c7e4ee3a
CB
15690 if ((type_node != NULL_TREE) && (bits == TYPE_PRECISION (type_node)))
15691 return unsignedp ? ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt]
15692 : type_node;
15693 }
5ff904cd 15694
c7e4ee3a
CB
15695 return 0;
15696}
5ff904cd 15697
c7e4ee3a
CB
15698tree
15699unsigned_type (type)
15700 tree type;
15701{
15702 tree type1 = TYPE_MAIN_VARIANT (type);
15703 ffeinfoKindtype kt;
15704 tree type2;
5ff904cd 15705
c7e4ee3a
CB
15706 if (type1 == signed_char_type_node || type1 == char_type_node)
15707 return unsigned_char_type_node;
15708 if (type1 == integer_type_node)
15709 return unsigned_type_node;
15710 if (type1 == short_integer_type_node)
15711 return short_unsigned_type_node;
15712 if (type1 == long_integer_type_node)
15713 return long_unsigned_type_node;
15714 if (type1 == long_long_integer_type_node)
15715 return long_long_unsigned_type_node;
15716#if 0 /* gcc/c-* files only */
15717 if (type1 == intDI_type_node)
15718 return unsigned_intDI_type_node;
15719 if (type1 == intSI_type_node)
15720 return unsigned_intSI_type_node;
15721 if (type1 == intHI_type_node)
15722 return unsigned_intHI_type_node;
15723 if (type1 == intQI_type_node)
15724 return unsigned_intQI_type_node;
15725#endif
5ff904cd 15726
c7e4ee3a
CB
15727 type2 = type_for_size (TYPE_PRECISION (type1), 1);
15728 if (type2 != NULL_TREE)
15729 return type2;
5ff904cd 15730
c7e4ee3a
CB
15731 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
15732 {
15733 type2 = ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
5ff904cd 15734
c7e4ee3a
CB
15735 if (type1 == type2)
15736 return ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
15737 }
5ff904cd 15738
c7e4ee3a
CB
15739 return type;
15740}
5ff904cd 15741
7189a4b0
GK
15742/* Callback routines for garbage collection. */
15743
15744int ggc_p = 1;
15745
15746void
15747lang_mark_tree (t)
15748 union tree_node *t ATTRIBUTE_UNUSED;
15749{
15750 if (TREE_CODE (t) == IDENTIFIER_NODE)
15751 {
15752 struct lang_identifier *i = (struct lang_identifier *) t;
15753 ggc_mark_tree (IDENTIFIER_GLOBAL_VALUE (i));
15754 ggc_mark_tree (IDENTIFIER_LOCAL_VALUE (i));
15755 ggc_mark_tree (IDENTIFIER_LABEL_VALUE (i));
15756 }
15757 else if (TYPE_P (t) && TYPE_LANG_SPECIFIC (t))
15758 ggc_mark (TYPE_LANG_SPECIFIC (t));
15759}
15760
15761void
15762lang_mark_false_label_stack (l)
15763 struct label_node *l;
15764{
15765 /* Fortran doesn't use false_label_stack. It better be NULL. */
15766 if (l != NULL)
15767 abort();
15768}
15769
c7e4ee3a
CB
15770#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
15771\f
15772#if FFECOM_GCC_INCLUDE
5ff904cd 15773
c7e4ee3a 15774/* From gcc/cccp.c, the code to handle -I. */
5ff904cd 15775
c7e4ee3a
CB
15776/* Skip leading "./" from a directory name.
15777 This may yield the empty string, which represents the current directory. */
5ff904cd 15778
c7e4ee3a
CB
15779static const char *
15780skip_redundant_dir_prefix (const char *dir)
15781{
15782 while (dir[0] == '.' && dir[1] == '/')
15783 for (dir += 2; *dir == '/'; dir++)
15784 continue;
15785 if (dir[0] == '.' && !dir[1])
15786 dir++;
15787 return dir;
15788}
5ff904cd 15789
c7e4ee3a
CB
15790/* The file_name_map structure holds a mapping of file names for a
15791 particular directory. This mapping is read from the file named
15792 FILE_NAME_MAP_FILE in that directory. Such a file can be used to
15793 map filenames on a file system with severe filename restrictions,
15794 such as DOS. The format of the file name map file is just a series
15795 of lines with two tokens on each line. The first token is the name
15796 to map, and the second token is the actual name to use. */
5ff904cd 15797
c7e4ee3a
CB
15798struct file_name_map
15799{
15800 struct file_name_map *map_next;
15801 char *map_from;
15802 char *map_to;
15803};
5ff904cd 15804
c7e4ee3a 15805#define FILE_NAME_MAP_FILE "header.gcc"
5ff904cd 15806
c7e4ee3a
CB
15807/* Current maximum length of directory names in the search path
15808 for include files. (Altered as we get more of them.) */
5ff904cd 15809
c7e4ee3a 15810static int max_include_len = 0;
5ff904cd 15811
c7e4ee3a
CB
15812struct file_name_list
15813 {
15814 struct file_name_list *next;
15815 char *fname;
15816 /* Mapping of file names for this directory. */
15817 struct file_name_map *name_map;
15818 /* Non-zero if name_map is valid. */
15819 int got_name_map;
15820 };
5ff904cd 15821
c7e4ee3a
CB
15822static struct file_name_list *include = NULL; /* First dir to search */
15823static struct file_name_list *last_include = NULL; /* Last in chain */
5ff904cd 15824
c7e4ee3a
CB
15825/* I/O buffer structure.
15826 The `fname' field is nonzero for source files and #include files
15827 and for the dummy text used for -D and -U.
15828 It is zero for rescanning results of macro expansion
15829 and for expanding macro arguments. */
15830#define INPUT_STACK_MAX 400
15831static struct file_buf {
b0791fa9 15832 const char *fname;
c7e4ee3a 15833 /* Filename specified with #line command. */
b0791fa9 15834 const char *nominal_fname;
c7e4ee3a
CB
15835 /* Record where in the search path this file was found.
15836 For #include_next. */
15837 struct file_name_list *dir;
15838 ffewhereLine line;
15839 ffewhereColumn column;
15840} instack[INPUT_STACK_MAX];
5ff904cd 15841
c7e4ee3a
CB
15842static int last_error_tick = 0; /* Incremented each time we print it. */
15843static int input_file_stack_tick = 0; /* Incremented when status changes. */
5ff904cd 15844
c7e4ee3a
CB
15845/* Current nesting level of input sources.
15846 `instack[indepth]' is the level currently being read. */
15847static int indepth = -1;
5ff904cd 15848
c7e4ee3a 15849typedef struct file_buf FILE_BUF;
5ff904cd 15850
c7e4ee3a 15851typedef unsigned char U_CHAR;
5ff904cd 15852
c7e4ee3a
CB
15853/* table to tell if char can be part of a C identifier. */
15854U_CHAR is_idchar[256];
15855/* table to tell if char can be first char of a c identifier. */
15856U_CHAR is_idstart[256];
15857/* table to tell if c is horizontal space. */
15858U_CHAR is_hor_space[256];
15859/* table to tell if c is horizontal or vertical space. */
15860static U_CHAR is_space[256];
5ff904cd 15861
c7e4ee3a
CB
15862#define SKIP_WHITE_SPACE(p) do { while (is_hor_space[*p]) p++; } while (0)
15863#define SKIP_ALL_WHITE_SPACE(p) do { while (is_space[*p]) p++; } while (0)
5ff904cd 15864
c7e4ee3a
CB
15865/* Nonzero means -I- has been seen,
15866 so don't look for #include "foo" the source-file directory. */
15867static int ignore_srcdir;
5ff904cd 15868
c7e4ee3a
CB
15869#ifndef INCLUDE_LEN_FUDGE
15870#define INCLUDE_LEN_FUDGE 0
15871#endif
5ff904cd 15872
c7e4ee3a
CB
15873static void append_include_chain (struct file_name_list *first,
15874 struct file_name_list *last);
15875static FILE *open_include_file (char *filename,
15876 struct file_name_list *searchptr);
15877static void print_containing_files (ffebadSeverity sev);
15878static const char *skip_redundant_dir_prefix (const char *);
15879static char *read_filename_string (int ch, FILE *f);
15880static struct file_name_map *read_name_map (const char *dirname);
5ff904cd 15881
c7e4ee3a
CB
15882/* Append a chain of `struct file_name_list's
15883 to the end of the main include chain.
15884 FIRST is the beginning of the chain to append, and LAST is the end. */
5ff904cd 15885
c7e4ee3a
CB
15886static void
15887append_include_chain (first, last)
15888 struct file_name_list *first, *last;
5ff904cd 15889{
c7e4ee3a 15890 struct file_name_list *dir;
5ff904cd 15891
c7e4ee3a
CB
15892 if (!first || !last)
15893 return;
5ff904cd 15894
c7e4ee3a
CB
15895 if (include == 0)
15896 include = first;
15897 else
15898 last_include->next = first;
5ff904cd 15899
c7e4ee3a
CB
15900 for (dir = first; ; dir = dir->next) {
15901 int len = strlen (dir->fname) + INCLUDE_LEN_FUDGE;
15902 if (len > max_include_len)
15903 max_include_len = len;
15904 if (dir == last)
15905 break;
15906 }
15907
15908 last->next = NULL;
15909 last_include = last;
5ff904cd
JL
15910}
15911
c7e4ee3a
CB
15912/* Try to open include file FILENAME. SEARCHPTR is the directory
15913 being tried from the include file search path. This function maps
15914 filenames on file systems based on information read by
15915 read_name_map. */
15916
15917static FILE *
15918open_include_file (filename, searchptr)
15919 char *filename;
15920 struct file_name_list *searchptr;
5ff904cd 15921{
c7e4ee3a
CB
15922 register struct file_name_map *map;
15923 register char *from;
15924 char *p, *dir;
5ff904cd 15925
c7e4ee3a
CB
15926 if (searchptr && ! searchptr->got_name_map)
15927 {
15928 searchptr->name_map = read_name_map (searchptr->fname
15929 ? searchptr->fname : ".");
15930 searchptr->got_name_map = 1;
15931 }
5ff904cd 15932
c7e4ee3a
CB
15933 /* First check the mapping for the directory we are using. */
15934 if (searchptr && searchptr->name_map)
15935 {
15936 from = filename;
15937 if (searchptr->fname)
15938 from += strlen (searchptr->fname) + 1;
15939 for (map = searchptr->name_map; map; map = map->map_next)
15940 {
15941 if (! strcmp (map->map_from, from))
15942 {
15943 /* Found a match. */
15944 return fopen (map->map_to, "r");
15945 }
15946 }
15947 }
5ff904cd 15948
c7e4ee3a
CB
15949 /* Try to find a mapping file for the particular directory we are
15950 looking in. Thus #include <sys/types.h> will look up sys/types.h
15951 in /usr/include/header.gcc and look up types.h in
15952 /usr/include/sys/header.gcc. */
15953 p = rindex (filename, '/');
15954#ifdef DIR_SEPARATOR
15955 if (! p) p = rindex (filename, DIR_SEPARATOR);
15956 else {
15957 char *tmp = rindex (filename, DIR_SEPARATOR);
15958 if (tmp != NULL && tmp > p) p = tmp;
15959 }
15960#endif
15961 if (! p)
15962 p = filename;
15963 if (searchptr
15964 && searchptr->fname
15965 && strlen (searchptr->fname) == (size_t) (p - filename)
15966 && ! strncmp (searchptr->fname, filename, (int) (p - filename)))
15967 {
15968 /* FILENAME is in SEARCHPTR, which we've already checked. */
15969 return fopen (filename, "r");
15970 }
15971
15972 if (p == filename)
15973 {
15974 from = filename;
15975 map = read_name_map (".");
15976 }
15977 else
5ff904cd 15978 {
c7e4ee3a
CB
15979 dir = (char *) xmalloc (p - filename + 1);
15980 memcpy (dir, filename, p - filename);
15981 dir[p - filename] = '\0';
15982 from = p + 1;
15983 map = read_name_map (dir);
15984 free (dir);
5ff904cd 15985 }
c7e4ee3a
CB
15986 for (; map; map = map->map_next)
15987 if (! strcmp (map->map_from, from))
15988 return fopen (map->map_to, "r");
5ff904cd 15989
c7e4ee3a 15990 return fopen (filename, "r");
5ff904cd
JL
15991}
15992
c7e4ee3a
CB
15993/* Print the file names and line numbers of the #include
15994 commands which led to the current file. */
5ff904cd 15995
c7e4ee3a
CB
15996static void
15997print_containing_files (ffebadSeverity sev)
15998{
15999 FILE_BUF *ip = NULL;
16000 int i;
16001 int first = 1;
16002 const char *str1;
16003 const char *str2;
5ff904cd 16004
c7e4ee3a
CB
16005 /* If stack of files hasn't changed since we last printed
16006 this info, don't repeat it. */
16007 if (last_error_tick == input_file_stack_tick)
16008 return;
5ff904cd 16009
c7e4ee3a
CB
16010 for (i = indepth; i >= 0; i--)
16011 if (instack[i].fname != NULL) {
16012 ip = &instack[i];
16013 break;
16014 }
5ff904cd 16015
c7e4ee3a
CB
16016 /* Give up if we don't find a source file. */
16017 if (ip == NULL)
16018 return;
5ff904cd 16019
c7e4ee3a
CB
16020 /* Find the other, outer source files. */
16021 for (i--; i >= 0; i--)
16022 if (instack[i].fname != NULL)
16023 {
16024 ip = &instack[i];
16025 if (first)
16026 {
16027 first = 0;
16028 str1 = "In file included";
16029 }
16030 else
16031 {
16032 str1 = "... ...";
16033 }
5ff904cd 16034
c7e4ee3a
CB
16035 if (i == 1)
16036 str2 = ":";
16037 else
16038 str2 = "";
5ff904cd 16039
c7e4ee3a
CB
16040 ffebad_start_msg ("%A from %B at %0%C", sev);
16041 ffebad_here (0, ip->line, ip->column);
16042 ffebad_string (str1);
16043 ffebad_string (ip->nominal_fname);
16044 ffebad_string (str2);
16045 ffebad_finish ();
16046 }
5ff904cd 16047
c7e4ee3a
CB
16048 /* Record we have printed the status as of this time. */
16049 last_error_tick = input_file_stack_tick;
16050}
5ff904cd 16051
c7e4ee3a
CB
16052/* Read a space delimited string of unlimited length from a stdio
16053 file. */
5ff904cd 16054
c7e4ee3a
CB
16055static char *
16056read_filename_string (ch, f)
16057 int ch;
16058 FILE *f;
16059{
16060 char *alloc, *set;
16061 int len;
5ff904cd 16062
c7e4ee3a
CB
16063 len = 20;
16064 set = alloc = xmalloc (len + 1);
16065 if (! is_space[ch])
16066 {
16067 *set++ = ch;
16068 while ((ch = getc (f)) != EOF && ! is_space[ch])
16069 {
16070 if (set - alloc == len)
16071 {
16072 len *= 2;
16073 alloc = xrealloc (alloc, len + 1);
16074 set = alloc + len / 2;
16075 }
16076 *set++ = ch;
16077 }
16078 }
16079 *set = '\0';
16080 ungetc (ch, f);
16081 return alloc;
16082}
5ff904cd 16083
c7e4ee3a 16084/* Read the file name map file for DIRNAME. */
5ff904cd 16085
c7e4ee3a
CB
16086static struct file_name_map *
16087read_name_map (dirname)
16088 const char *dirname;
16089{
16090 /* This structure holds a linked list of file name maps, one per
16091 directory. */
16092 struct file_name_map_list
16093 {
16094 struct file_name_map_list *map_list_next;
16095 char *map_list_name;
16096 struct file_name_map *map_list_map;
16097 };
16098 static struct file_name_map_list *map_list;
16099 register struct file_name_map_list *map_list_ptr;
16100 char *name;
16101 FILE *f;
16102 size_t dirlen;
16103 int separator_needed;
5ff904cd 16104
c7e4ee3a 16105 dirname = skip_redundant_dir_prefix (dirname);
5ff904cd 16106
c7e4ee3a
CB
16107 for (map_list_ptr = map_list; map_list_ptr;
16108 map_list_ptr = map_list_ptr->map_list_next)
16109 if (! strcmp (map_list_ptr->map_list_name, dirname))
16110 return map_list_ptr->map_list_map;
5ff904cd 16111
c7e4ee3a
CB
16112 map_list_ptr = ((struct file_name_map_list *)
16113 xmalloc (sizeof (struct file_name_map_list)));
16114 map_list_ptr->map_list_name = xstrdup (dirname);
16115 map_list_ptr->map_list_map = NULL;
5ff904cd 16116
c7e4ee3a
CB
16117 dirlen = strlen (dirname);
16118 separator_needed = dirlen != 0 && dirname[dirlen - 1] != '/';
16119 name = (char *) xmalloc (dirlen + strlen (FILE_NAME_MAP_FILE) + 2);
16120 strcpy (name, dirname);
16121 name[dirlen] = '/';
16122 strcpy (name + dirlen + separator_needed, FILE_NAME_MAP_FILE);
16123 f = fopen (name, "r");
16124 free (name);
16125 if (!f)
16126 map_list_ptr->map_list_map = NULL;
16127 else
16128 {
16129 int ch;
5ff904cd 16130
c7e4ee3a
CB
16131 while ((ch = getc (f)) != EOF)
16132 {
16133 char *from, *to;
16134 struct file_name_map *ptr;
16135
16136 if (is_space[ch])
16137 continue;
16138 from = read_filename_string (ch, f);
16139 while ((ch = getc (f)) != EOF && is_hor_space[ch])
16140 ;
16141 to = read_filename_string (ch, f);
5ff904cd 16142
c7e4ee3a
CB
16143 ptr = ((struct file_name_map *)
16144 xmalloc (sizeof (struct file_name_map)));
16145 ptr->map_from = from;
5ff904cd 16146
c7e4ee3a
CB
16147 /* Make the real filename absolute. */
16148 if (*to == '/')
16149 ptr->map_to = to;
16150 else
16151 {
16152 ptr->map_to = xmalloc (dirlen + strlen (to) + 2);
16153 strcpy (ptr->map_to, dirname);
16154 ptr->map_to[dirlen] = '/';
16155 strcpy (ptr->map_to + dirlen + separator_needed, to);
16156 free (to);
16157 }
5ff904cd 16158
c7e4ee3a
CB
16159 ptr->map_next = map_list_ptr->map_list_map;
16160 map_list_ptr->map_list_map = ptr;
5ff904cd 16161
c7e4ee3a
CB
16162 while ((ch = getc (f)) != '\n')
16163 if (ch == EOF)
16164 break;
16165 }
16166 fclose (f);
5ff904cd
JL
16167 }
16168
c7e4ee3a
CB
16169 map_list_ptr->map_list_next = map_list;
16170 map_list = map_list_ptr;
5ff904cd 16171
c7e4ee3a 16172 return map_list_ptr->map_list_map;
5ff904cd
JL
16173}
16174
c7e4ee3a 16175static void
b0791fa9 16176ffecom_file_ (const char *name)
5ff904cd 16177{
c7e4ee3a 16178 FILE_BUF *fp;
5ff904cd 16179
c7e4ee3a
CB
16180 /* Do partial setup of input buffer for the sake of generating
16181 early #line directives (when -g is in effect). */
5ff904cd 16182
c7e4ee3a
CB
16183 fp = &instack[++indepth];
16184 memset ((char *) fp, 0, sizeof (FILE_BUF));
16185 if (name == NULL)
16186 name = "";
16187 fp->nominal_fname = fp->fname = name;
16188}
5ff904cd 16189
c7e4ee3a 16190/* Initialize syntactic classifications of characters. */
5ff904cd 16191
c7e4ee3a
CB
16192static void
16193ffecom_initialize_char_syntax_ ()
16194{
16195 register int i;
5ff904cd 16196
c7e4ee3a
CB
16197 /*
16198 * Set up is_idchar and is_idstart tables. These should be
16199 * faster than saying (is_alpha (c) || c == '_'), etc.
16200 * Set up these things before calling any routines tthat
16201 * refer to them.
16202 */
16203 for (i = 'a'; i <= 'z'; i++) {
16204 is_idchar[i - 'a' + 'A'] = 1;
16205 is_idchar[i] = 1;
16206 is_idstart[i - 'a' + 'A'] = 1;
16207 is_idstart[i] = 1;
16208 }
16209 for (i = '0'; i <= '9'; i++)
16210 is_idchar[i] = 1;
16211 is_idchar['_'] = 1;
16212 is_idstart['_'] = 1;
5ff904cd 16213
c7e4ee3a
CB
16214 /* horizontal space table */
16215 is_hor_space[' '] = 1;
16216 is_hor_space['\t'] = 1;
16217 is_hor_space['\v'] = 1;
16218 is_hor_space['\f'] = 1;
16219 is_hor_space['\r'] = 1;
5ff904cd 16220
c7e4ee3a
CB
16221 is_space[' '] = 1;
16222 is_space['\t'] = 1;
16223 is_space['\v'] = 1;
16224 is_space['\f'] = 1;
16225 is_space['\n'] = 1;
16226 is_space['\r'] = 1;
16227}
5ff904cd 16228
c7e4ee3a
CB
16229static void
16230ffecom_close_include_ (FILE *f)
16231{
16232 fclose (f);
5ff904cd 16233
c7e4ee3a
CB
16234 indepth--;
16235 input_file_stack_tick++;
5ff904cd 16236
c7e4ee3a
CB
16237 ffewhere_line_kill (instack[indepth].line);
16238 ffewhere_column_kill (instack[indepth].column);
16239}
5ff904cd 16240
c7e4ee3a
CB
16241static int
16242ffecom_decode_include_option_ (char *spec)
16243{
16244 struct file_name_list *dirtmp;
16245
16246 if (! ignore_srcdir && !strcmp (spec, "-"))
16247 ignore_srcdir = 1;
16248 else
16249 {
16250 dirtmp = (struct file_name_list *)
16251 xmalloc (sizeof (struct file_name_list));
16252 dirtmp->next = 0; /* New one goes on the end */
16253 if (spec[0] != 0)
16254 dirtmp->fname = spec;
16255 else
16256 fatal ("Directory name must immediately follow -I option with no intervening spaces, as in `-Idir', not `-I dir'");
16257 dirtmp->got_name_map = 0;
16258 append_include_chain (dirtmp, dirtmp);
16259 }
16260 return 1;
5ff904cd
JL
16261}
16262
c7e4ee3a
CB
16263/* Open INCLUDEd file. */
16264
16265static FILE *
16266ffecom_open_include_ (char *name, ffewhereLine l, ffewhereColumn c)
5ff904cd 16267{
c7e4ee3a
CB
16268 char *fbeg = name;
16269 size_t flen = strlen (fbeg);
16270 struct file_name_list *search_start = include; /* Chain of dirs to search */
16271 struct file_name_list dsp[1]; /* First in chain, if #include "..." */
16272 struct file_name_list *searchptr = 0;
16273 char *fname; /* Dynamically allocated fname buffer */
16274 FILE *f;
16275 FILE_BUF *fp;
5ff904cd 16276
c7e4ee3a
CB
16277 if (flen == 0)
16278 return NULL;
5ff904cd 16279
c7e4ee3a 16280 dsp[0].fname = NULL;
5ff904cd 16281
c7e4ee3a
CB
16282 /* If -I- was specified, don't search current dir, only spec'd ones. */
16283 if (!ignore_srcdir)
16284 {
16285 for (fp = &instack[indepth]; fp >= instack; fp--)
16286 {
16287 int n;
16288 char *ep;
b0791fa9 16289 const char *nam;
5ff904cd 16290
c7e4ee3a
CB
16291 if ((nam = fp->nominal_fname) != NULL)
16292 {
16293 /* Found a named file. Figure out dir of the file,
16294 and put it in front of the search list. */
16295 dsp[0].next = search_start;
16296 search_start = dsp;
16297#ifndef VMS
16298 ep = rindex (nam, '/');
16299#ifdef DIR_SEPARATOR
16300 if (ep == NULL) ep = rindex (nam, DIR_SEPARATOR);
16301 else {
16302 char *tmp = rindex (nam, DIR_SEPARATOR);
16303 if (tmp != NULL && tmp > ep) ep = tmp;
16304 }
16305#endif
16306#else /* VMS */
16307 ep = rindex (nam, ']');
16308 if (ep == NULL) ep = rindex (nam, '>');
16309 if (ep == NULL) ep = rindex (nam, ':');
16310 if (ep != NULL) ep++;
16311#endif /* VMS */
16312 if (ep != NULL)
16313 {
16314 n = ep - nam;
16315 dsp[0].fname = (char *) xmalloc (n + 1);
16316 strncpy (dsp[0].fname, nam, n);
16317 dsp[0].fname[n] = '\0';
16318 if (n + INCLUDE_LEN_FUDGE > max_include_len)
16319 max_include_len = n + INCLUDE_LEN_FUDGE;
16320 }
16321 else
16322 dsp[0].fname = NULL; /* Current directory */
16323 dsp[0].got_name_map = 0;
16324 break;
16325 }
16326 }
16327 }
5ff904cd 16328
c7e4ee3a
CB
16329 /* Allocate this permanently, because it gets stored in the definitions
16330 of macros. */
16331 fname = xmalloc (max_include_len + flen + 4);
16332 /* + 2 above for slash and terminating null. */
16333 /* + 2 added for '.h' on VMS (to support '#include filename') (NOT USED
16334 for g77 yet). */
5ff904cd 16335
c7e4ee3a 16336 /* If specified file name is absolute, just open it. */
5ff904cd 16337
c7e4ee3a
CB
16338 if (*fbeg == '/'
16339#ifdef DIR_SEPARATOR
16340 || *fbeg == DIR_SEPARATOR
16341#endif
16342 )
16343 {
16344 strncpy (fname, (char *) fbeg, flen);
16345 fname[flen] = 0;
16346 f = open_include_file (fname, NULL_PTR);
5ff904cd 16347 }
c7e4ee3a
CB
16348 else
16349 {
16350 f = NULL;
5ff904cd 16351
c7e4ee3a
CB
16352 /* Search directory path, trying to open the file.
16353 Copy each filename tried into FNAME. */
5ff904cd 16354
c7e4ee3a
CB
16355 for (searchptr = search_start; searchptr; searchptr = searchptr->next)
16356 {
16357 if (searchptr->fname)
16358 {
16359 /* The empty string in a search path is ignored.
16360 This makes it possible to turn off entirely
16361 a standard piece of the list. */
16362 if (searchptr->fname[0] == 0)
16363 continue;
16364 strcpy (fname, skip_redundant_dir_prefix (searchptr->fname));
16365 if (fname[0] && fname[strlen (fname) - 1] != '/')
16366 strcat (fname, "/");
16367 fname[strlen (fname) + flen] = 0;
16368 }
16369 else
16370 fname[0] = 0;
5ff904cd 16371
c7e4ee3a
CB
16372 strncat (fname, fbeg, flen);
16373#ifdef VMS
16374 /* Change this 1/2 Unix 1/2 VMS file specification into a
16375 full VMS file specification */
16376 if (searchptr->fname && (searchptr->fname[0] != 0))
16377 {
16378 /* Fix up the filename */
16379 hack_vms_include_specification (fname);
16380 }
16381 else
16382 {
16383 /* This is a normal VMS filespec, so use it unchanged. */
16384 strncpy (fname, (char *) fbeg, flen);
16385 fname[flen] = 0;
16386#if 0 /* Not for g77. */
16387 /* if it's '#include filename', add the missing .h */
16388 if (index (fname, '.') == NULL)
16389 strcat (fname, ".h");
5ff904cd 16390#endif
c7e4ee3a
CB
16391 }
16392#endif /* VMS */
16393 f = open_include_file (fname, searchptr);
16394#ifdef EACCES
16395 if (f == NULL && errno == EACCES)
16396 {
16397 print_containing_files (FFEBAD_severityWARNING);
16398 ffebad_start_msg ("At %0, INCLUDE file %A exists, but is not readable",
16399 FFEBAD_severityWARNING);
16400 ffebad_string (fname);
16401 ffebad_here (0, l, c);
16402 ffebad_finish ();
16403 }
16404#endif
16405 if (f != NULL)
16406 break;
16407 }
16408 }
5ff904cd 16409
c7e4ee3a 16410 if (f == NULL)
5ff904cd 16411 {
c7e4ee3a 16412 /* A file that was not found. */
5ff904cd 16413
c7e4ee3a
CB
16414 strncpy (fname, (char *) fbeg, flen);
16415 fname[flen] = 0;
16416 print_containing_files (ffebad_severity (FFEBAD_OPEN_INCLUDE));
16417 ffebad_start (FFEBAD_OPEN_INCLUDE);
16418 ffebad_here (0, l, c);
16419 ffebad_string (fname);
16420 ffebad_finish ();
5ff904cd
JL
16421 }
16422
c7e4ee3a
CB
16423 if (dsp[0].fname != NULL)
16424 free (dsp[0].fname);
5ff904cd 16425
c7e4ee3a
CB
16426 if (f == NULL)
16427 return NULL;
5ff904cd 16428
c7e4ee3a
CB
16429 if (indepth >= (INPUT_STACK_MAX - 1))
16430 {
16431 print_containing_files (FFEBAD_severityFATAL);
16432 ffebad_start_msg ("At %0, INCLUDE nesting too deep",
16433 FFEBAD_severityFATAL);
16434 ffebad_string (fname);
16435 ffebad_here (0, l, c);
16436 ffebad_finish ();
16437 return NULL;
16438 }
5ff904cd 16439
c7e4ee3a
CB
16440 instack[indepth].line = ffewhere_line_use (l);
16441 instack[indepth].column = ffewhere_column_use (c);
5ff904cd 16442
c7e4ee3a
CB
16443 fp = &instack[indepth + 1];
16444 memset ((char *) fp, 0, sizeof (FILE_BUF));
16445 fp->nominal_fname = fp->fname = fname;
16446 fp->dir = searchptr;
5ff904cd 16447
c7e4ee3a
CB
16448 indepth++;
16449 input_file_stack_tick++;
5ff904cd 16450
c7e4ee3a
CB
16451 return f;
16452}
16453#endif /* FFECOM_GCC_INCLUDE */
5ff904cd 16454
c7e4ee3a
CB
16455/**INDENT* (Do not reformat this comment even with -fca option.)
16456 Data-gathering files: Given the source file listed below, compiled with
16457 f2c I obtained the output file listed after that, and from the output
16458 file I derived the above code.
5ff904cd 16459
c7e4ee3a
CB
16460-------- (begin input file to f2c)
16461 implicit none
16462 character*10 A1,A2
16463 complex C1,C2
16464 integer I1,I2
16465 real R1,R2
16466 double precision D1,D2
16467C
16468 call getem(A1,A2,C1,C2,I1,I2,R1,R2,D1,D2)
16469c /
16470 call fooI(I1/I2)
16471 call fooR(R1/I1)
16472 call fooD(D1/I1)
16473 call fooC(C1/I1)
16474 call fooR(R1/R2)
16475 call fooD(R1/D1)
16476 call fooD(D1/D2)
16477 call fooD(D1/R1)
16478 call fooC(C1/C2)
16479 call fooC(C1/R1)
16480 call fooZ(C1/D1)
16481c **
16482 call fooI(I1**I2)
16483 call fooR(R1**I1)
16484 call fooD(D1**I1)
16485 call fooC(C1**I1)
16486 call fooR(R1**R2)
16487 call fooD(R1**D1)
16488 call fooD(D1**D2)
16489 call fooD(D1**R1)
16490 call fooC(C1**C2)
16491 call fooC(C1**R1)
16492 call fooZ(C1**D1)
16493c FFEINTRIN_impABS
16494 call fooR(ABS(R1))
16495c FFEINTRIN_impACOS
16496 call fooR(ACOS(R1))
16497c FFEINTRIN_impAIMAG
16498 call fooR(AIMAG(C1))
16499c FFEINTRIN_impAINT
16500 call fooR(AINT(R1))
16501c FFEINTRIN_impALOG
16502 call fooR(ALOG(R1))
16503c FFEINTRIN_impALOG10
16504 call fooR(ALOG10(R1))
16505c FFEINTRIN_impAMAX0
16506 call fooR(AMAX0(I1,I2))
16507c FFEINTRIN_impAMAX1
16508 call fooR(AMAX1(R1,R2))
16509c FFEINTRIN_impAMIN0
16510 call fooR(AMIN0(I1,I2))
16511c FFEINTRIN_impAMIN1
16512 call fooR(AMIN1(R1,R2))
16513c FFEINTRIN_impAMOD
16514 call fooR(AMOD(R1,R2))
16515c FFEINTRIN_impANINT
16516 call fooR(ANINT(R1))
16517c FFEINTRIN_impASIN
16518 call fooR(ASIN(R1))
16519c FFEINTRIN_impATAN
16520 call fooR(ATAN(R1))
16521c FFEINTRIN_impATAN2
16522 call fooR(ATAN2(R1,R2))
16523c FFEINTRIN_impCABS
16524 call fooR(CABS(C1))
16525c FFEINTRIN_impCCOS
16526 call fooC(CCOS(C1))
16527c FFEINTRIN_impCEXP
16528 call fooC(CEXP(C1))
16529c FFEINTRIN_impCHAR
16530 call fooA(CHAR(I1))
16531c FFEINTRIN_impCLOG
16532 call fooC(CLOG(C1))
16533c FFEINTRIN_impCONJG
16534 call fooC(CONJG(C1))
16535c FFEINTRIN_impCOS
16536 call fooR(COS(R1))
16537c FFEINTRIN_impCOSH
16538 call fooR(COSH(R1))
16539c FFEINTRIN_impCSIN
16540 call fooC(CSIN(C1))
16541c FFEINTRIN_impCSQRT
16542 call fooC(CSQRT(C1))
16543c FFEINTRIN_impDABS
16544 call fooD(DABS(D1))
16545c FFEINTRIN_impDACOS
16546 call fooD(DACOS(D1))
16547c FFEINTRIN_impDASIN
16548 call fooD(DASIN(D1))
16549c FFEINTRIN_impDATAN
16550 call fooD(DATAN(D1))
16551c FFEINTRIN_impDATAN2
16552 call fooD(DATAN2(D1,D2))
16553c FFEINTRIN_impDCOS
16554 call fooD(DCOS(D1))
16555c FFEINTRIN_impDCOSH
16556 call fooD(DCOSH(D1))
16557c FFEINTRIN_impDDIM
16558 call fooD(DDIM(D1,D2))
16559c FFEINTRIN_impDEXP
16560 call fooD(DEXP(D1))
16561c FFEINTRIN_impDIM
16562 call fooR(DIM(R1,R2))
16563c FFEINTRIN_impDINT
16564 call fooD(DINT(D1))
16565c FFEINTRIN_impDLOG
16566 call fooD(DLOG(D1))
16567c FFEINTRIN_impDLOG10
16568 call fooD(DLOG10(D1))
16569c FFEINTRIN_impDMAX1
16570 call fooD(DMAX1(D1,D2))
16571c FFEINTRIN_impDMIN1
16572 call fooD(DMIN1(D1,D2))
16573c FFEINTRIN_impDMOD
16574 call fooD(DMOD(D1,D2))
16575c FFEINTRIN_impDNINT
16576 call fooD(DNINT(D1))
16577c FFEINTRIN_impDPROD
16578 call fooD(DPROD(R1,R2))
16579c FFEINTRIN_impDSIGN
16580 call fooD(DSIGN(D1,D2))
16581c FFEINTRIN_impDSIN
16582 call fooD(DSIN(D1))
16583c FFEINTRIN_impDSINH
16584 call fooD(DSINH(D1))
16585c FFEINTRIN_impDSQRT
16586 call fooD(DSQRT(D1))
16587c FFEINTRIN_impDTAN
16588 call fooD(DTAN(D1))
16589c FFEINTRIN_impDTANH
16590 call fooD(DTANH(D1))
16591c FFEINTRIN_impEXP
16592 call fooR(EXP(R1))
16593c FFEINTRIN_impIABS
16594 call fooI(IABS(I1))
16595c FFEINTRIN_impICHAR
16596 call fooI(ICHAR(A1))
16597c FFEINTRIN_impIDIM
16598 call fooI(IDIM(I1,I2))
16599c FFEINTRIN_impIDNINT
16600 call fooI(IDNINT(D1))
16601c FFEINTRIN_impINDEX
16602 call fooI(INDEX(A1,A2))
16603c FFEINTRIN_impISIGN
16604 call fooI(ISIGN(I1,I2))
16605c FFEINTRIN_impLEN
16606 call fooI(LEN(A1))
16607c FFEINTRIN_impLGE
16608 call fooL(LGE(A1,A2))
16609c FFEINTRIN_impLGT
16610 call fooL(LGT(A1,A2))
16611c FFEINTRIN_impLLE
16612 call fooL(LLE(A1,A2))
16613c FFEINTRIN_impLLT
16614 call fooL(LLT(A1,A2))
16615c FFEINTRIN_impMAX0
16616 call fooI(MAX0(I1,I2))
16617c FFEINTRIN_impMAX1
16618 call fooI(MAX1(R1,R2))
16619c FFEINTRIN_impMIN0
16620 call fooI(MIN0(I1,I2))
16621c FFEINTRIN_impMIN1
16622 call fooI(MIN1(R1,R2))
16623c FFEINTRIN_impMOD
16624 call fooI(MOD(I1,I2))
16625c FFEINTRIN_impNINT
16626 call fooI(NINT(R1))
16627c FFEINTRIN_impSIGN
16628 call fooR(SIGN(R1,R2))
16629c FFEINTRIN_impSIN
16630 call fooR(SIN(R1))
16631c FFEINTRIN_impSINH
16632 call fooR(SINH(R1))
16633c FFEINTRIN_impSQRT
16634 call fooR(SQRT(R1))
16635c FFEINTRIN_impTAN
16636 call fooR(TAN(R1))
16637c FFEINTRIN_impTANH
16638 call fooR(TANH(R1))
16639c FFEINTRIN_imp_CMPLX_C
16640 call fooC(cmplx(C1,C2))
16641c FFEINTRIN_imp_CMPLX_D
16642 call fooZ(cmplx(D1,D2))
16643c FFEINTRIN_imp_CMPLX_I
16644 call fooC(cmplx(I1,I2))
16645c FFEINTRIN_imp_CMPLX_R
16646 call fooC(cmplx(R1,R2))
16647c FFEINTRIN_imp_DBLE_C
16648 call fooD(dble(C1))
16649c FFEINTRIN_imp_DBLE_D
16650 call fooD(dble(D1))
16651c FFEINTRIN_imp_DBLE_I
16652 call fooD(dble(I1))
16653c FFEINTRIN_imp_DBLE_R
16654 call fooD(dble(R1))
16655c FFEINTRIN_imp_INT_C
16656 call fooI(int(C1))
16657c FFEINTRIN_imp_INT_D
16658 call fooI(int(D1))
16659c FFEINTRIN_imp_INT_I
16660 call fooI(int(I1))
16661c FFEINTRIN_imp_INT_R
16662 call fooI(int(R1))
16663c FFEINTRIN_imp_REAL_C
16664 call fooR(real(C1))
16665c FFEINTRIN_imp_REAL_D
16666 call fooR(real(D1))
16667c FFEINTRIN_imp_REAL_I
16668 call fooR(real(I1))
16669c FFEINTRIN_imp_REAL_R
16670 call fooR(real(R1))
16671c
16672c FFEINTRIN_imp_INT_D:
16673c
16674c FFEINTRIN_specIDINT
16675 call fooI(IDINT(D1))
16676c
16677c FFEINTRIN_imp_INT_R:
16678c
16679c FFEINTRIN_specIFIX
16680 call fooI(IFIX(R1))
16681c FFEINTRIN_specINT
16682 call fooI(INT(R1))
16683c
16684c FFEINTRIN_imp_REAL_D:
16685c
16686c FFEINTRIN_specSNGL
16687 call fooR(SNGL(D1))
16688c
16689c FFEINTRIN_imp_REAL_I:
16690c
16691c FFEINTRIN_specFLOAT
16692 call fooR(FLOAT(I1))
16693c FFEINTRIN_specREAL
16694 call fooR(REAL(I1))
16695c
16696 end
16697-------- (end input file to f2c)
5ff904cd 16698
c7e4ee3a
CB
16699-------- (begin output from providing above input file as input to:
16700-------- `f2c | gcc -E -C - | sed -e "s:/[*]*://:g" -e "s:[*]*[/]://:g" \
16701-------- -e "s:^#.*$::g"')
5ff904cd 16702
c7e4ee3a
CB
16703// -- translated by f2c (version 19950223).
16704 You must link the resulting object file with the libraries:
16705 -lf2c -lm (in that order)
16706//
5ff904cd 16707
5ff904cd 16708
c7e4ee3a 16709// f2c.h -- Standard Fortran to C header file //
5ff904cd 16710
c7e4ee3a 16711/// barf [ba:rf] 2. "He suggested using FORTRAN, and everybody barfed."
5ff904cd 16712
c7e4ee3a 16713 - From The Shogakukan DICTIONARY OF NEW ENGLISH (Second edition) //
5ff904cd 16714
5ff904cd 16715
5ff904cd 16716
5ff904cd 16717
c7e4ee3a
CB
16718// F2C_INTEGER will normally be `int' but would be `long' on 16-bit systems //
16719// we assume short, float are OK //
16720typedef long int // long int // integer;
16721typedef char *address;
16722typedef short int shortint;
16723typedef float real;
16724typedef double doublereal;
16725typedef struct { real r, i; } complex;
16726typedef struct { doublereal r, i; } doublecomplex;
16727typedef long int // long int // logical;
16728typedef short int shortlogical;
16729typedef char logical1;
16730typedef char integer1;
16731// typedef long long longint; // // system-dependent //
5ff904cd 16732
5ff904cd 16733
5ff904cd 16734
5ff904cd 16735
c7e4ee3a 16736// Extern is for use with -E //
5ff904cd 16737
5ff904cd 16738
5ff904cd 16739
5ff904cd 16740
c7e4ee3a 16741// I/O stuff //
5ff904cd 16742
5ff904cd 16743
5ff904cd 16744
5ff904cd 16745
5ff904cd 16746
5ff904cd 16747
5ff904cd 16748
5ff904cd 16749
c7e4ee3a
CB
16750typedef long int // int or long int // flag;
16751typedef long int // int or long int // ftnlen;
16752typedef long int // int or long int // ftnint;
5ff904cd 16753
5ff904cd 16754
c7e4ee3a
CB
16755//external read, write//
16756typedef struct
16757{ flag cierr;
16758 ftnint ciunit;
16759 flag ciend;
16760 char *cifmt;
16761 ftnint cirec;
16762} cilist;
5ff904cd 16763
c7e4ee3a
CB
16764//internal read, write//
16765typedef struct
16766{ flag icierr;
16767 char *iciunit;
16768 flag iciend;
16769 char *icifmt;
16770 ftnint icirlen;
16771 ftnint icirnum;
16772} icilist;
5ff904cd 16773
c7e4ee3a
CB
16774//open//
16775typedef struct
16776{ flag oerr;
16777 ftnint ounit;
16778 char *ofnm;
16779 ftnlen ofnmlen;
16780 char *osta;
16781 char *oacc;
16782 char *ofm;
16783 ftnint orl;
16784 char *oblnk;
16785} olist;
5ff904cd 16786
c7e4ee3a
CB
16787//close//
16788typedef struct
16789{ flag cerr;
16790 ftnint cunit;
16791 char *csta;
16792} cllist;
5ff904cd 16793
c7e4ee3a
CB
16794//rewind, backspace, endfile//
16795typedef struct
16796{ flag aerr;
16797 ftnint aunit;
16798} alist;
5ff904cd 16799
c7e4ee3a
CB
16800// inquire //
16801typedef struct
16802{ flag inerr;
16803 ftnint inunit;
16804 char *infile;
16805 ftnlen infilen;
16806 ftnint *inex; //parameters in standard's order//
16807 ftnint *inopen;
16808 ftnint *innum;
16809 ftnint *innamed;
16810 char *inname;
16811 ftnlen innamlen;
16812 char *inacc;
16813 ftnlen inacclen;
16814 char *inseq;
16815 ftnlen inseqlen;
16816 char *indir;
16817 ftnlen indirlen;
16818 char *infmt;
16819 ftnlen infmtlen;
16820 char *inform;
16821 ftnint informlen;
16822 char *inunf;
16823 ftnlen inunflen;
16824 ftnint *inrecl;
16825 ftnint *innrec;
16826 char *inblank;
16827 ftnlen inblanklen;
16828} inlist;
5ff904cd 16829
5ff904cd 16830
5ff904cd 16831
c7e4ee3a
CB
16832union Multitype { // for multiple entry points //
16833 integer1 g;
16834 shortint h;
16835 integer i;
16836 // longint j; //
16837 real r;
16838 doublereal d;
16839 complex c;
16840 doublecomplex z;
16841 };
16842
16843typedef union Multitype Multitype;
5ff904cd 16844
c7e4ee3a 16845typedef long Long; // No longer used; formerly in Namelist //
5ff904cd 16846
c7e4ee3a
CB
16847struct Vardesc { // for Namelist //
16848 char *name;
16849 char *addr;
16850 ftnlen *dims;
16851 int type;
16852 };
16853typedef struct Vardesc Vardesc;
5ff904cd 16854
c7e4ee3a
CB
16855struct Namelist {
16856 char *name;
16857 Vardesc **vars;
16858 int nvars;
16859 };
16860typedef struct Namelist Namelist;
5ff904cd 16861
5ff904cd 16862
5ff904cd 16863
5ff904cd 16864
5ff904cd 16865
5ff904cd 16866
5ff904cd 16867
5ff904cd 16868
c7e4ee3a 16869// procedure parameter types for -A and -C++ //
5ff904cd 16870
5ff904cd 16871
5ff904cd 16872
5ff904cd 16873
c7e4ee3a
CB
16874typedef int // Unknown procedure type // (*U_fp)();
16875typedef shortint (*J_fp)();
16876typedef integer (*I_fp)();
16877typedef real (*R_fp)();
16878typedef doublereal (*D_fp)(), (*E_fp)();
16879typedef // Complex // void (*C_fp)();
16880typedef // Double Complex // void (*Z_fp)();
16881typedef logical (*L_fp)();
16882typedef shortlogical (*K_fp)();
16883typedef // Character // void (*H_fp)();
16884typedef // Subroutine // int (*S_fp)();
5ff904cd 16885
c7e4ee3a
CB
16886// E_fp is for real functions when -R is not specified //
16887typedef void C_f; // complex function //
16888typedef void H_f; // character function //
16889typedef void Z_f; // double complex function //
16890typedef doublereal E_f; // real function with -R not specified //
5ff904cd 16891
c7e4ee3a 16892// undef any lower-case symbols that your C compiler predefines, e.g.: //
5ff904cd 16893
5ff904cd 16894
c7e4ee3a
CB
16895// (No such symbols should be defined in a strict ANSI C compiler.
16896 We can avoid trouble with f2c-translated code by using
16897 gcc -ansi [-traditional].) //
16898
5ff904cd 16899
5ff904cd 16900
5ff904cd 16901
5ff904cd 16902
5ff904cd 16903
5ff904cd 16904
5ff904cd 16905
5ff904cd 16906
5ff904cd 16907
5ff904cd 16908
5ff904cd 16909
5ff904cd 16910
5ff904cd 16911
5ff904cd 16912
5ff904cd 16913
5ff904cd 16914
5ff904cd 16915
5ff904cd 16916
5ff904cd 16917
5ff904cd 16918
5ff904cd 16919
5ff904cd 16920
c7e4ee3a
CB
16921// Main program // MAIN__()
16922{
16923 // System generated locals //
16924 integer i__1;
16925 real r__1, r__2;
16926 doublereal d__1, d__2;
16927 complex q__1;
16928 doublecomplex z__1, z__2, z__3;
16929 logical L__1;
16930 char ch__1[1];
16931
16932 // Builtin functions //
16933 void c_div();
16934 integer pow_ii();
16935 double pow_ri(), pow_di();
16936 void pow_ci();
16937 double pow_dd();
16938 void pow_zz();
16939 double acos(), r_imag(), r_int(), log(), r_lg10(), r_mod(), r_nint(),
16940 asin(), atan(), atan2(), c_abs();
16941 void c_cos(), c_exp(), c_log(), r_cnjg();
16942 double cos(), cosh();
16943 void c_sin(), c_sqrt();
16944 double d_dim(), exp(), r_dim(), d_int(), d_lg10(), d_mod(), d_nint(),
16945 d_sign(), sin(), sinh(), sqrt(), tan(), tanh();
16946 integer i_dim(), i_dnnt(), i_indx(), i_sign(), i_len();
16947 logical l_ge(), l_gt(), l_le(), l_lt();
16948 integer i_nint();
16949 double r_sign();
16950
16951 // Local variables //
16952 extern // Subroutine // int fooa_(), fooc_(), food_(), fooi_(), foor_(),
16953 fool_(), fooz_(), getem_();
16954 static char a1[10], a2[10];
16955 static complex c1, c2;
16956 static doublereal d1, d2;
16957 static integer i1, i2;
16958 static real r1, r2;
16959
16960
16961 getem_(a1, a2, &c1, &c2, &i1, &i2, &r1, &r2, &d1, &d2, 10L, 10L);
16962// / //
16963 i__1 = i1 / i2;
16964 fooi_(&i__1);
16965 r__1 = r1 / i1;
16966 foor_(&r__1);
16967 d__1 = d1 / i1;
16968 food_(&d__1);
16969 d__1 = (doublereal) i1;
16970 q__1.r = c1.r / d__1, q__1.i = c1.i / d__1;
16971 fooc_(&q__1);
16972 r__1 = r1 / r2;
16973 foor_(&r__1);
16974 d__1 = r1 / d1;
16975 food_(&d__1);
16976 d__1 = d1 / d2;
16977 food_(&d__1);
16978 d__1 = d1 / r1;
16979 food_(&d__1);
16980 c_div(&q__1, &c1, &c2);
16981 fooc_(&q__1);
16982 q__1.r = c1.r / r1, q__1.i = c1.i / r1;
16983 fooc_(&q__1);
16984 z__1.r = c1.r / d1, z__1.i = c1.i / d1;
16985 fooz_(&z__1);
16986// ** //
16987 i__1 = pow_ii(&i1, &i2);
16988 fooi_(&i__1);
16989 r__1 = pow_ri(&r1, &i1);
16990 foor_(&r__1);
16991 d__1 = pow_di(&d1, &i1);
16992 food_(&d__1);
16993 pow_ci(&q__1, &c1, &i1);
16994 fooc_(&q__1);
16995 d__1 = (doublereal) r1;
16996 d__2 = (doublereal) r2;
16997 r__1 = pow_dd(&d__1, &d__2);
16998 foor_(&r__1);
16999 d__2 = (doublereal) r1;
17000 d__1 = pow_dd(&d__2, &d1);
17001 food_(&d__1);
17002 d__1 = pow_dd(&d1, &d2);
17003 food_(&d__1);
17004 d__2 = (doublereal) r1;
17005 d__1 = pow_dd(&d1, &d__2);
17006 food_(&d__1);
17007 z__2.r = c1.r, z__2.i = c1.i;
17008 z__3.r = c2.r, z__3.i = c2.i;
17009 pow_zz(&z__1, &z__2, &z__3);
17010 q__1.r = z__1.r, q__1.i = z__1.i;
17011 fooc_(&q__1);
17012 z__2.r = c1.r, z__2.i = c1.i;
17013 z__3.r = r1, z__3.i = 0.;
17014 pow_zz(&z__1, &z__2, &z__3);
17015 q__1.r = z__1.r, q__1.i = z__1.i;
17016 fooc_(&q__1);
17017 z__2.r = c1.r, z__2.i = c1.i;
17018 z__3.r = d1, z__3.i = 0.;
17019 pow_zz(&z__1, &z__2, &z__3);
17020 fooz_(&z__1);
17021// FFEINTRIN_impABS //
17022 r__1 = (doublereal)(( r1 ) >= 0 ? ( r1 ) : -( r1 )) ;
17023 foor_(&r__1);
17024// FFEINTRIN_impACOS //
17025 r__1 = acos(r1);
17026 foor_(&r__1);
17027// FFEINTRIN_impAIMAG //
17028 r__1 = r_imag(&c1);
17029 foor_(&r__1);
17030// FFEINTRIN_impAINT //
17031 r__1 = r_int(&r1);
17032 foor_(&r__1);
17033// FFEINTRIN_impALOG //
17034 r__1 = log(r1);
17035 foor_(&r__1);
17036// FFEINTRIN_impALOG10 //
17037 r__1 = r_lg10(&r1);
17038 foor_(&r__1);
17039// FFEINTRIN_impAMAX0 //
17040 r__1 = (real) (( i1 ) >= ( i2 ) ? ( i1 ) : ( i2 )) ;
17041 foor_(&r__1);
17042// FFEINTRIN_impAMAX1 //
17043 r__1 = (doublereal)(( r1 ) >= ( r2 ) ? ( r1 ) : ( r2 )) ;
17044 foor_(&r__1);
17045// FFEINTRIN_impAMIN0 //
17046 r__1 = (real) (( i1 ) <= ( i2 ) ? ( i1 ) : ( i2 )) ;
17047 foor_(&r__1);
17048// FFEINTRIN_impAMIN1 //
17049 r__1 = (doublereal)(( r1 ) <= ( r2 ) ? ( r1 ) : ( r2 )) ;
17050 foor_(&r__1);
17051// FFEINTRIN_impAMOD //
17052 r__1 = r_mod(&r1, &r2);
17053 foor_(&r__1);
17054// FFEINTRIN_impANINT //
17055 r__1 = r_nint(&r1);
17056 foor_(&r__1);
17057// FFEINTRIN_impASIN //
17058 r__1 = asin(r1);
17059 foor_(&r__1);
17060// FFEINTRIN_impATAN //
17061 r__1 = atan(r1);
17062 foor_(&r__1);
17063// FFEINTRIN_impATAN2 //
17064 r__1 = atan2(r1, r2);
17065 foor_(&r__1);
17066// FFEINTRIN_impCABS //
17067 r__1 = c_abs(&c1);
17068 foor_(&r__1);
17069// FFEINTRIN_impCCOS //
17070 c_cos(&q__1, &c1);
17071 fooc_(&q__1);
17072// FFEINTRIN_impCEXP //
17073 c_exp(&q__1, &c1);
17074 fooc_(&q__1);
17075// FFEINTRIN_impCHAR //
17076 *(unsigned char *)&ch__1[0] = i1;
17077 fooa_(ch__1, 1L);
17078// FFEINTRIN_impCLOG //
17079 c_log(&q__1, &c1);
17080 fooc_(&q__1);
17081// FFEINTRIN_impCONJG //
17082 r_cnjg(&q__1, &c1);
17083 fooc_(&q__1);
17084// FFEINTRIN_impCOS //
17085 r__1 = cos(r1);
17086 foor_(&r__1);
17087// FFEINTRIN_impCOSH //
17088 r__1 = cosh(r1);
17089 foor_(&r__1);
17090// FFEINTRIN_impCSIN //
17091 c_sin(&q__1, &c1);
17092 fooc_(&q__1);
17093// FFEINTRIN_impCSQRT //
17094 c_sqrt(&q__1, &c1);
17095 fooc_(&q__1);
17096// FFEINTRIN_impDABS //
17097 d__1 = (( d1 ) >= 0 ? ( d1 ) : -( d1 )) ;
17098 food_(&d__1);
17099// FFEINTRIN_impDACOS //
17100 d__1 = acos(d1);
17101 food_(&d__1);
17102// FFEINTRIN_impDASIN //
17103 d__1 = asin(d1);
17104 food_(&d__1);
17105// FFEINTRIN_impDATAN //
17106 d__1 = atan(d1);
17107 food_(&d__1);
17108// FFEINTRIN_impDATAN2 //
17109 d__1 = atan2(d1, d2);
17110 food_(&d__1);
17111// FFEINTRIN_impDCOS //
17112 d__1 = cos(d1);
17113 food_(&d__1);
17114// FFEINTRIN_impDCOSH //
17115 d__1 = cosh(d1);
17116 food_(&d__1);
17117// FFEINTRIN_impDDIM //
17118 d__1 = d_dim(&d1, &d2);
17119 food_(&d__1);
17120// FFEINTRIN_impDEXP //
17121 d__1 = exp(d1);
17122 food_(&d__1);
17123// FFEINTRIN_impDIM //
17124 r__1 = r_dim(&r1, &r2);
17125 foor_(&r__1);
17126// FFEINTRIN_impDINT //
17127 d__1 = d_int(&d1);
17128 food_(&d__1);
17129// FFEINTRIN_impDLOG //
17130 d__1 = log(d1);
17131 food_(&d__1);
17132// FFEINTRIN_impDLOG10 //
17133 d__1 = d_lg10(&d1);
17134 food_(&d__1);
17135// FFEINTRIN_impDMAX1 //
17136 d__1 = (( d1 ) >= ( d2 ) ? ( d1 ) : ( d2 )) ;
17137 food_(&d__1);
17138// FFEINTRIN_impDMIN1 //
17139 d__1 = (( d1 ) <= ( d2 ) ? ( d1 ) : ( d2 )) ;
17140 food_(&d__1);
17141// FFEINTRIN_impDMOD //
17142 d__1 = d_mod(&d1, &d2);
17143 food_(&d__1);
17144// FFEINTRIN_impDNINT //
17145 d__1 = d_nint(&d1);
17146 food_(&d__1);
17147// FFEINTRIN_impDPROD //
17148 d__1 = (doublereal) r1 * r2;
17149 food_(&d__1);
17150// FFEINTRIN_impDSIGN //
17151 d__1 = d_sign(&d1, &d2);
17152 food_(&d__1);
17153// FFEINTRIN_impDSIN //
17154 d__1 = sin(d1);
17155 food_(&d__1);
17156// FFEINTRIN_impDSINH //
17157 d__1 = sinh(d1);
17158 food_(&d__1);
17159// FFEINTRIN_impDSQRT //
17160 d__1 = sqrt(d1);
17161 food_(&d__1);
17162// FFEINTRIN_impDTAN //
17163 d__1 = tan(d1);
17164 food_(&d__1);
17165// FFEINTRIN_impDTANH //
17166 d__1 = tanh(d1);
17167 food_(&d__1);
17168// FFEINTRIN_impEXP //
17169 r__1 = exp(r1);
17170 foor_(&r__1);
17171// FFEINTRIN_impIABS //
17172 i__1 = (( i1 ) >= 0 ? ( i1 ) : -( i1 )) ;
17173 fooi_(&i__1);
17174// FFEINTRIN_impICHAR //
17175 i__1 = *(unsigned char *)a1;
17176 fooi_(&i__1);
17177// FFEINTRIN_impIDIM //
17178 i__1 = i_dim(&i1, &i2);
17179 fooi_(&i__1);
17180// FFEINTRIN_impIDNINT //
17181 i__1 = i_dnnt(&d1);
17182 fooi_(&i__1);
17183// FFEINTRIN_impINDEX //
17184 i__1 = i_indx(a1, a2, 10L, 10L);
17185 fooi_(&i__1);
17186// FFEINTRIN_impISIGN //
17187 i__1 = i_sign(&i1, &i2);
17188 fooi_(&i__1);
17189// FFEINTRIN_impLEN //
17190 i__1 = i_len(a1, 10L);
17191 fooi_(&i__1);
17192// FFEINTRIN_impLGE //
17193 L__1 = l_ge(a1, a2, 10L, 10L);
17194 fool_(&L__1);
17195// FFEINTRIN_impLGT //
17196 L__1 = l_gt(a1, a2, 10L, 10L);
17197 fool_(&L__1);
17198// FFEINTRIN_impLLE //
17199 L__1 = l_le(a1, a2, 10L, 10L);
17200 fool_(&L__1);
17201// FFEINTRIN_impLLT //
17202 L__1 = l_lt(a1, a2, 10L, 10L);
17203 fool_(&L__1);
17204// FFEINTRIN_impMAX0 //
17205 i__1 = (( i1 ) >= ( i2 ) ? ( i1 ) : ( i2 )) ;
17206 fooi_(&i__1);
17207// FFEINTRIN_impMAX1 //
17208 i__1 = (integer) (doublereal)(( r1 ) >= ( r2 ) ? ( r1 ) : ( r2 )) ;
17209 fooi_(&i__1);
17210// FFEINTRIN_impMIN0 //
17211 i__1 = (( i1 ) <= ( i2 ) ? ( i1 ) : ( i2 )) ;
17212 fooi_(&i__1);
17213// FFEINTRIN_impMIN1 //
17214 i__1 = (integer) (doublereal)(( r1 ) <= ( r2 ) ? ( r1 ) : ( r2 )) ;
17215 fooi_(&i__1);
17216// FFEINTRIN_impMOD //
17217 i__1 = i1 % i2;
17218 fooi_(&i__1);
17219// FFEINTRIN_impNINT //
17220 i__1 = i_nint(&r1);
17221 fooi_(&i__1);
17222// FFEINTRIN_impSIGN //
17223 r__1 = r_sign(&r1, &r2);
17224 foor_(&r__1);
17225// FFEINTRIN_impSIN //
17226 r__1 = sin(r1);
17227 foor_(&r__1);
17228// FFEINTRIN_impSINH //
17229 r__1 = sinh(r1);
17230 foor_(&r__1);
17231// FFEINTRIN_impSQRT //
17232 r__1 = sqrt(r1);
17233 foor_(&r__1);
17234// FFEINTRIN_impTAN //
17235 r__1 = tan(r1);
17236 foor_(&r__1);
17237// FFEINTRIN_impTANH //
17238 r__1 = tanh(r1);
17239 foor_(&r__1);
17240// FFEINTRIN_imp_CMPLX_C //
17241 r__1 = c1.r;
17242 r__2 = c2.r;
17243 q__1.r = r__1, q__1.i = r__2;
17244 fooc_(&q__1);
17245// FFEINTRIN_imp_CMPLX_D //
17246 z__1.r = d1, z__1.i = d2;
17247 fooz_(&z__1);
17248// FFEINTRIN_imp_CMPLX_I //
17249 r__1 = (real) i1;
17250 r__2 = (real) i2;
17251 q__1.r = r__1, q__1.i = r__2;
17252 fooc_(&q__1);
17253// FFEINTRIN_imp_CMPLX_R //
17254 q__1.r = r1, q__1.i = r2;
17255 fooc_(&q__1);
17256// FFEINTRIN_imp_DBLE_C //
17257 d__1 = (doublereal) c1.r;
17258 food_(&d__1);
17259// FFEINTRIN_imp_DBLE_D //
17260 d__1 = d1;
17261 food_(&d__1);
17262// FFEINTRIN_imp_DBLE_I //
17263 d__1 = (doublereal) i1;
17264 food_(&d__1);
17265// FFEINTRIN_imp_DBLE_R //
17266 d__1 = (doublereal) r1;
17267 food_(&d__1);
17268// FFEINTRIN_imp_INT_C //
17269 i__1 = (integer) c1.r;
17270 fooi_(&i__1);
17271// FFEINTRIN_imp_INT_D //
17272 i__1 = (integer) d1;
17273 fooi_(&i__1);
17274// FFEINTRIN_imp_INT_I //
17275 i__1 = i1;
17276 fooi_(&i__1);
17277// FFEINTRIN_imp_INT_R //
17278 i__1 = (integer) r1;
17279 fooi_(&i__1);
17280// FFEINTRIN_imp_REAL_C //
17281 r__1 = c1.r;
17282 foor_(&r__1);
17283// FFEINTRIN_imp_REAL_D //
17284 r__1 = (real) d1;
17285 foor_(&r__1);
17286// FFEINTRIN_imp_REAL_I //
17287 r__1 = (real) i1;
17288 foor_(&r__1);
17289// FFEINTRIN_imp_REAL_R //
17290 r__1 = r1;
17291 foor_(&r__1);
17292
17293// FFEINTRIN_imp_INT_D: //
17294
17295// FFEINTRIN_specIDINT //
17296 i__1 = (integer) d1;
17297 fooi_(&i__1);
17298
17299// FFEINTRIN_imp_INT_R: //
17300
17301// FFEINTRIN_specIFIX //
17302 i__1 = (integer) r1;
17303 fooi_(&i__1);
17304// FFEINTRIN_specINT //
17305 i__1 = (integer) r1;
17306 fooi_(&i__1);
17307
17308// FFEINTRIN_imp_REAL_D: //
5ff904cd 17309
c7e4ee3a
CB
17310// FFEINTRIN_specSNGL //
17311 r__1 = (real) d1;
17312 foor_(&r__1);
5ff904cd 17313
c7e4ee3a 17314// FFEINTRIN_imp_REAL_I: //
5ff904cd 17315
c7e4ee3a
CB
17316// FFEINTRIN_specFLOAT //
17317 r__1 = (real) i1;
17318 foor_(&r__1);
17319// FFEINTRIN_specREAL //
17320 r__1 = (real) i1;
17321 foor_(&r__1);
5ff904cd 17322
c7e4ee3a 17323} // MAIN__ //
5ff904cd 17324
c7e4ee3a 17325-------- (end output file from f2c)
5ff904cd 17326
c7e4ee3a 17327*/
This page took 2.541441 seconds and 5 git commands to generate.