]> gcc.gnu.org Git - gcc.git/blame - gcc/f/com.c
* optabs.c (init_traps): Fix typo in last change.
[gcc.git] / gcc / f / com.c
CommitLineData
5ff904cd 1/* com.c -- Implementation File (module.c template V1.0)
44d2eabc 2 Copyright (C) 1995-1998 Free Software Foundation, Inc.
25d7717e 3 Contributed by James Craig Burley.
5ff904cd
JL
4
5This file is part of GNU Fortran.
6
7GNU Fortran is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU Fortran is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Fortran; see the file COPYING. If not, write to
19the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2002111-1307, USA.
21
22 Related Modules:
23 None
24
25 Description:
26 Contains compiler-specific functions.
27
28 Modifications:
29*/
30
31/* Understanding this module means understanding the interface between
32 the g77 front end and the gcc back end (or, perhaps, some other
33 back end). In here are the functions called by the front end proper
34 to notify whatever back end is in place about certain things, and
35 also the back-end-specific functions. It's a bear to deal with, so
36 lately I've been trying to simplify things, especially with regard
37 to the gcc-back-end-specific stuff.
38
39 Building expressions generally seems quite easy, but building decls
40 has been challenging and is undergoing revision. gcc has several
41 kinds of decls:
42
43 TYPE_DECL -- a type (int, float, struct, function, etc.)
44 CONST_DECL -- a constant of some type other than function
45 LABEL_DECL -- a variable or a constant?
46 PARM_DECL -- an argument to a function (a variable that is a dummy)
47 RESULT_DECL -- the return value of a function (a variable)
48 VAR_DECL -- other variable (can hold a ptr-to-function, struct, int, etc.)
49 FUNCTION_DECL -- a function (either the actual function or an extern ref)
50 FIELD_DECL -- a field in a struct or union (goes into types)
51
52 g77 has a set of functions that somewhat parallels the gcc front end
53 when it comes to building decls:
54
55 Internal Function (one we define, not just declare as extern):
56 int yes;
57 yes = suspend_momentary ();
58 if (is_nested) push_f_function_context ();
59 start_function (get_identifier ("function_name"), function_type,
60 is_nested, is_public);
61 // for each arg, build PARM_DECL and call push_parm_decl (decl) with it;
62 store_parm_decls (is_main_program);
c7e4ee3a 63 ffecom_start_compstmt ();
5ff904cd 64 // for stmts and decls inside function, do appropriate things;
c7e4ee3a 65 ffecom_end_compstmt ();
5ff904cd
JL
66 finish_function (is_nested);
67 if (is_nested) pop_f_function_context ();
68 if (is_nested) resume_momentary (yes);
69
70 Everything Else:
71 int yes;
72 tree d;
73 tree init;
74 yes = suspend_momentary ();
75 // fill in external, public, static, &c for decl, and
76 // set DECL_INITIAL to error_mark_node if going to initialize
77 // set is_top_level TRUE only if not at top level and decl
78 // must go in top level (i.e. not within current function decl context)
79 d = start_decl (decl, is_top_level);
80 init = ...; // if have initializer
81 finish_decl (d, init, is_top_level);
82 resume_momentary (yes);
83
84*/
85
86/* Include files. */
87
95a1b676 88#include "proj.h"
5ff904cd 89#if FFECOM_targetCURRENT == FFECOM_targetGCC
5ff904cd
JL
90#include "flags.j"
91#include "rtl.j"
8b45da67 92#include "toplev.j"
5ff904cd 93#include "tree.j"
95a1b676 94#include "output.j" /* Must follow tree.j so TREE_CODE is defined! */
5ff904cd
JL
95#include "convert.j"
96#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
97
98#define FFECOM_GCC_INCLUDE 1 /* Enable -I. */
99
100/* BEGIN stuff from gcc/cccp.c. */
101
102/* The following symbols should be autoconfigured:
103 HAVE_FCNTL_H
104 HAVE_STDLIB_H
105 HAVE_SYS_TIME_H
106 HAVE_UNISTD_H
107 STDC_HEADERS
108 TIME_WITH_SYS_TIME
109 In the mean time, we'll get by with approximations based
110 on existing GCC configuration symbols. */
111
112#ifdef POSIX
113# ifndef HAVE_STDLIB_H
114# define HAVE_STDLIB_H 1
115# endif
116# ifndef HAVE_UNISTD_H
117# define HAVE_UNISTD_H 1
118# endif
119# ifndef STDC_HEADERS
120# define STDC_HEADERS 1
121# endif
122#endif /* defined (POSIX) */
123
124#if defined (POSIX) || (defined (USG) && !defined (VMS))
125# ifndef HAVE_FCNTL_H
126# define HAVE_FCNTL_H 1
127# endif
128#endif
129
130#ifndef RLIMIT_STACK
131# include <time.h>
132#else
133# if TIME_WITH_SYS_TIME
134# include <sys/time.h>
135# include <time.h>
136# else
137# if HAVE_SYS_TIME_H
138# include <sys/time.h>
139# else
140# include <time.h>
141# endif
142# endif
143# include <sys/resource.h>
144#endif
145
146#if HAVE_FCNTL_H
147# include <fcntl.h>
148#endif
149
150/* This defines "errno" properly for VMS, and gives us EACCES. */
151#include <errno.h>
152
153#if HAVE_STDLIB_H
154# include <stdlib.h>
155#else
156char *getenv ();
157#endif
158
5ff904cd
JL
159#if HAVE_UNISTD_H
160# include <unistd.h>
161#endif
162
163/* VMS-specific definitions */
164#ifdef VMS
165#include <descrip.h>
166#define O_RDONLY 0 /* Open arg for Read/Only */
167#define O_WRONLY 1 /* Open arg for Write/Only */
168#define read(fd,buf,size) VMS_read (fd,buf,size)
169#define write(fd,buf,size) VMS_write (fd,buf,size)
170#define open(fname,mode,prot) VMS_open (fname,mode,prot)
171#define fopen(fname,mode) VMS_fopen (fname,mode)
172#define freopen(fname,mode,ofile) VMS_freopen (fname,mode,ofile)
173#define strncat(dst,src,cnt) VMS_strncat (dst,src,cnt)
174#define fstat(fd,stbuf) VMS_fstat (fd,stbuf)
175static int VMS_fstat (), VMS_stat ();
176static char * VMS_strncat ();
177static int VMS_read ();
178static int VMS_write ();
179static int VMS_open ();
180static FILE * VMS_fopen ();
181static FILE * VMS_freopen ();
182static void hack_vms_include_specification ();
183typedef struct { unsigned :16, :16, :16; } vms_ino_t;
184#define ino_t vms_ino_t
185#define INCLUDE_LEN_FUDGE 10 /* leave room for VMS syntax conversion */
186#ifdef __GNUC__
187#define BSTRING /* VMS/GCC supplies the bstring routines */
188#endif /* __GNUC__ */
189#endif /* VMS */
190
191#ifndef O_RDONLY
192#define O_RDONLY 0
193#endif
194
195/* END stuff from gcc/cccp.c. */
196
5ff904cd
JL
197#define FFECOM_DETERMINE_TYPES 1 /* for com.h */
198#include "com.h"
199#include "bad.h"
200#include "bld.h"
201#include "equiv.h"
202#include "expr.h"
203#include "implic.h"
204#include "info.h"
205#include "malloc.h"
206#include "src.h"
207#include "st.h"
208#include "storag.h"
209#include "symbol.h"
210#include "target.h"
211#include "top.h"
212#include "type.h"
213
214/* Externals defined here. */
215
5ff904cd
JL
216#if FFECOM_targetCURRENT == FFECOM_targetGCC
217
218/* tree.h declares a bunch of stuff that it expects the front end to
219 define. Here are the definitions, which in the C front end are
220 found in the file c-decl.c. */
221
5ff904cd
JL
222tree current_function_decl;
223
c7e4ee3a
CB
224/* ~~gcc/tree.h *should* declare this, because toplev.c and dwarfout.c
225 reference it. */
5ff904cd 226
f425a887 227const char * const language_string = "GNU F77";
5ff904cd 228
77f77701
DB
229/* Stream for reading from the input file. */
230FILE *finput;
231
5ff904cd
JL
232/* These definitions parallel those in c-decl.c so that code from that
233 module can be used pretty much as is. Much of these defs aren't
234 otherwise used, i.e. by g77 code per se, except some of them are used
235 to build some of them that are. The ones that are global (i.e. not
236 "static") are those that ste.c and such might use (directly
237 or by using com macros that reference them in their definitions). */
238
5ff904cd
JL
239tree string_type_node;
240
241static tree double_ftype_double;
242static tree float_ftype_float;
243static tree ldouble_ftype_ldouble;
244
245/* The rest of these are inventions for g77, though there might be
246 similar things in the C front end. As they are found, these
247 inventions should be renamed to be canonical. Note that only
248 the ones currently required to be global are so. */
249
250static tree ffecom_tree_fun_type_void;
251static tree ffecom_tree_ptr_to_fun_type_void;
252
253tree ffecom_integer_type_node; /* Abbrev for _tree_type[blah][blah]. */
254tree ffecom_integer_zero_node; /* Like *_*_* with g77's integer type. */
255tree ffecom_integer_one_node; /* " */
256tree ffecom_tree_type[FFEINFO_basictype][FFEINFO_kindtype];
257
258/* _fun_type things are the f2c-specific versions. For -fno-f2c,
259 just use build_function_type and build_pointer_type on the
260 appropriate _tree_type array element. */
261
262static tree ffecom_tree_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
263static tree ffecom_tree_ptr_to_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
264static tree ffecom_tree_subr_type;
265static tree ffecom_tree_ptr_to_subr_type;
266static tree ffecom_tree_blockdata_type;
267
268static tree ffecom_tree_xargc_;
269
270ffecomSymbol ffecom_symbol_null_
271=
272{
273 NULL_TREE,
274 NULL_TREE,
275 NULL_TREE,
0816ebdd
KG
276 NULL_TREE,
277 false
5ff904cd
JL
278};
279ffeinfoKindtype ffecom_pointer_kind_ = FFEINFO_basictypeNONE;
280ffeinfoKindtype ffecom_label_kind_ = FFEINFO_basictypeNONE;
281
282int ffecom_f2c_typecode_[FFEINFO_basictype][FFEINFO_kindtype];
283tree ffecom_f2c_integer_type_node;
284tree ffecom_f2c_ptr_to_integer_type_node;
285tree ffecom_f2c_address_type_node;
286tree ffecom_f2c_real_type_node;
287tree ffecom_f2c_ptr_to_real_type_node;
288tree ffecom_f2c_doublereal_type_node;
289tree ffecom_f2c_complex_type_node;
290tree ffecom_f2c_doublecomplex_type_node;
291tree ffecom_f2c_longint_type_node;
292tree ffecom_f2c_logical_type_node;
293tree ffecom_f2c_flag_type_node;
294tree ffecom_f2c_ftnlen_type_node;
295tree ffecom_f2c_ftnlen_zero_node;
296tree ffecom_f2c_ftnlen_one_node;
297tree ffecom_f2c_ftnlen_two_node;
298tree ffecom_f2c_ptr_to_ftnlen_type_node;
299tree ffecom_f2c_ftnint_type_node;
300tree ffecom_f2c_ptr_to_ftnint_type_node;
301#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
302
303/* Simple definitions and enumerations. */
304
305#ifndef FFECOM_sizeMAXSTACKITEM
306#define FFECOM_sizeMAXSTACKITEM 32*1024 /* Keep user-declared things
307 larger than this # bytes
308 off stack if possible. */
309#endif
310
311/* For systems that have large enough stacks, they should define
312 this to 0, and here, for ease of use later on, we just undefine
313 it if it is 0. */
314
315#if FFECOM_sizeMAXSTACKITEM == 0
316#undef FFECOM_sizeMAXSTACKITEM
317#endif
318
319typedef enum
320 {
321 FFECOM_rttypeVOID_,
6d433196 322 FFECOM_rttypeVOIDSTAR_, /* C's `void *' type. */
795232f7
JL
323 FFECOM_rttypeFTNINT_, /* f2c's `ftnint' type. */
324 FFECOM_rttypeINTEGER_, /* f2c's `integer' type. */
325 FFECOM_rttypeLONGINT_, /* f2c's `longint' type. */
326 FFECOM_rttypeLOGICAL_, /* f2c's `logical' type. */
327 FFECOM_rttypeREAL_F2C_, /* f2c's `real' returned as `double'. */
328 FFECOM_rttypeREAL_GNU_, /* `real' returned as such. */
5ff904cd 329 FFECOM_rttypeCOMPLEX_F2C_, /* f2c's `complex' returned via 1st arg. */
795232f7 330 FFECOM_rttypeCOMPLEX_GNU_, /* f2c's `complex' returned directly. */
5ff904cd 331 FFECOM_rttypeDOUBLE_, /* C's `double' type. */
795232f7 332 FFECOM_rttypeDOUBLEREAL_, /* f2c's `doublereal' type. */
5ff904cd 333 FFECOM_rttypeDBLCMPLX_F2C_, /* f2c's `doublecomplex' returned via 1st arg. */
795232f7 334 FFECOM_rttypeDBLCMPLX_GNU_, /* f2c's `doublecomplex' returned directly. */
5ff904cd
JL
335 FFECOM_rttypeCHARACTER_, /* f2c `char *'/`ftnlen' pair. */
336 FFECOM_rttype_
337 } ffecomRttype_;
338
339/* Internal typedefs. */
340
341#if FFECOM_targetCURRENT == FFECOM_targetGCC
342typedef struct _ffecom_concat_list_ ffecomConcatList_;
5ff904cd
JL
343#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
344
345/* Private include files. */
346
347
348/* Internal structure definitions. */
349
350#if FFECOM_targetCURRENT == FFECOM_targetGCC
351struct _ffecom_concat_list_
352 {
353 ffebld *exprs;
354 int count;
355 int max;
356 ffetargetCharacterSize minlen;
357 ffetargetCharacterSize maxlen;
358 };
5ff904cd
JL
359#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
360
361/* Static functions (internal). */
362
363#if FFECOM_targetCURRENT == FFECOM_targetGCC
26f096f9 364static tree ffecom_arglist_expr_ (const char *argstring, ffebld args);
5ff904cd
JL
365static tree ffecom_widest_expr_type_ (ffebld list);
366static bool ffecom_overlap_ (tree dest_decl, tree dest_offset,
367 tree dest_size, tree source_tree,
368 ffebld source, bool scalar_arg);
369static bool ffecom_args_overlapping_ (tree dest_tree, ffebld dest,
370 tree args, tree callee_commons,
371 bool scalar_args);
26f096f9 372static tree ffecom_build_f2c_string_ (int i, const char *s);
5ff904cd
JL
373static tree ffecom_call_ (tree fn, ffeinfoKindtype kt,
374 bool is_f2c_complex, tree type,
375 tree args, tree dest_tree,
376 ffebld dest, bool *dest_used,
c7e4ee3a 377 tree callee_commons, bool scalar_args, tree hook);
5ff904cd
JL
378static tree ffecom_call_binop_ (tree fn, ffeinfoKindtype kt,
379 bool is_f2c_complex, tree type,
380 ffebld left, ffebld right,
381 tree dest_tree, ffebld dest,
382 bool *dest_used, tree callee_commons,
c7e4ee3a 383 bool scalar_args, tree hook);
86fc7a6c
CB
384static void ffecom_char_args_x_ (tree *xitem, tree *length,
385 ffebld expr, bool with_null);
5ff904cd
JL
386static tree ffecom_check_size_overflow_ (ffesymbol s, tree type, bool dummy);
387static tree ffecom_char_enhance_arg_ (tree *xtype, ffesymbol s);
388static ffecomConcatList_
389 ffecom_concat_list_gather_ (ffecomConcatList_ catlist,
390 ffebld expr,
391 ffetargetCharacterSize max);
392static void ffecom_concat_list_kill_ (ffecomConcatList_ catlist);
393static ffecomConcatList_ ffecom_concat_list_new_ (ffebld expr,
394 ffetargetCharacterSize max);
26f096f9
KG
395static void ffecom_debug_kludge_ (tree aggr, const char *aggr_type,
396 ffesymbol member, tree member_type,
397 ffetargetOffset offset);
5ff904cd 398static void ffecom_do_entry_ (ffesymbol fn, int entrynum);
092a4ef8
RH
399static tree ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest,
400 bool *dest_used, bool assignp, bool widenp);
5ff904cd
JL
401static tree ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree,
402 ffebld dest, bool *dest_used);
c7e4ee3a 403static tree ffecom_expr_power_integer_ (ffebld expr);
5ff904cd 404static void ffecom_expr_transform_ (ffebld expr);
26f096f9 405static void ffecom_f2c_make_type_ (tree *type, int tcode, const char *name);
5ff904cd
JL
406static void ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size,
407 int code);
408static ffeglobal ffecom_finish_global_ (ffeglobal global);
409static ffesymbol ffecom_finish_symbol_transform_ (ffesymbol s);
26f096f9 410static tree ffecom_get_appended_identifier_ (char us, const char *text);
5ff904cd 411static tree ffecom_get_external_identifier_ (ffesymbol s);
26f096f9 412static tree ffecom_get_identifier_ (const char *text);
5ff904cd
JL
413static tree ffecom_gen_sfuncdef_ (ffesymbol s,
414 ffeinfoBasictype bt,
415 ffeinfoKindtype kt);
26f096f9 416static const char *ffecom_gfrt_args_ (ffecomGfrt ix);
5ff904cd
JL
417static tree ffecom_gfrt_tree_ (ffecomGfrt ix);
418static tree ffecom_init_zero_ (tree decl);
419static tree ffecom_intrinsic_ichar_ (tree tree_type, ffebld arg,
420 tree *maybe_tree);
421static tree ffecom_intrinsic_len_ (ffebld expr);
422static void ffecom_let_char_ (tree dest_tree,
423 tree dest_length,
424 ffetargetCharacterSize dest_size,
425 ffebld source);
426static void ffecom_make_gfrt_ (ffecomGfrt ix);
427static void ffecom_member_phase1_ (ffestorag mst, ffestorag st);
428#ifdef SOMEONE_GETS_DEBUG_SUPPORT_WORKING
429static void ffecom_member_phase2_ (ffestorag mst, ffestorag st);
430#endif
c7e4ee3a
CB
431static void ffecom_prepare_let_char_ (ffetargetCharacterSize dest_size,
432 ffebld source);
5ff904cd
JL
433static void ffecom_push_dummy_decls_ (ffebld dumlist,
434 bool stmtfunc);
435static void ffecom_start_progunit_ (void);
436static ffesymbol ffecom_sym_transform_ (ffesymbol s);
437static ffesymbol ffecom_sym_transform_assign_ (ffesymbol s);
438static void ffecom_transform_common_ (ffesymbol s);
439static void ffecom_transform_equiv_ (ffestorag st);
440static tree ffecom_transform_namelist_ (ffesymbol s);
441static void ffecom_tree_canonize_ptr_ (tree *decl, tree *offset,
442 tree t);
443static void ffecom_tree_canonize_ref_ (tree *decl, tree *offset,
444 tree *size, tree tree);
445static tree ffecom_tree_divide_ (tree tree_type, tree left, tree right,
446 tree dest_tree, ffebld dest,
c7e4ee3a 447 bool *dest_used, tree hook);
5ff904cd
JL
448static tree ffecom_type_localvar_ (ffesymbol s,
449 ffeinfoBasictype bt,
450 ffeinfoKindtype kt);
451static tree ffecom_type_namelist_ (void);
452#if 0
453static tree ffecom_type_permanent_copy_ (tree t);
454#endif
455static tree ffecom_type_vardesc_ (void);
456static tree ffecom_vardesc_ (ffebld expr);
457static tree ffecom_vardesc_array_ (ffesymbol s);
458static tree ffecom_vardesc_dims_ (ffesymbol s);
26f096f9
KG
459static tree ffecom_convert_narrow_ (tree type, tree expr);
460static tree ffecom_convert_widen_ (tree type, tree expr);
5ff904cd
JL
461#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
462
463/* These are static functions that parallel those found in the C front
464 end and thus have the same names. */
465
466#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a 467static tree bison_rule_compstmt_ (void);
5ff904cd 468static void bison_rule_pushlevel_ (void);
26f096f9 469static tree builtin_function (const char *name, tree type,
5ff904cd 470 enum built_in_function function_code,
26f096f9 471 const char *library_name);
c7e4ee3a 472static void delete_block (tree block);
5ff904cd
JL
473static int duplicate_decls (tree newdecl, tree olddecl);
474static void finish_decl (tree decl, tree init, bool is_top_level);
475static void finish_function (int nested);
4b731ffa 476static const char *lang_printable_name (tree decl, int v);
5ff904cd
JL
477static tree lookup_name_current_level (tree name);
478static struct binding_level *make_binding_level (void);
479static void pop_f_function_context (void);
480static void push_f_function_context (void);
481static void push_parm_decl (tree parm);
482static tree pushdecl_top_level (tree decl);
c7e4ee3a 483static int kept_level_p (void);
5ff904cd
JL
484static tree storedecls (tree decls);
485static void store_parm_decls (int is_main_program);
486static tree start_decl (tree decl, bool is_top_level);
487static void start_function (tree name, tree type, int nested, int public);
488#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
489#if FFECOM_GCC_INCLUDE
490static void ffecom_file_ (char *name);
491static void ffecom_initialize_char_syntax_ (void);
492static void ffecom_close_include_ (FILE *f);
493static int ffecom_decode_include_option_ (char *spec);
494static FILE *ffecom_open_include_ (char *name, ffewhereLine l,
495 ffewhereColumn c);
496#endif /* FFECOM_GCC_INCLUDE */
497
498/* Static objects accessed by functions in this module. */
499
500static ffesymbol ffecom_primary_entry_ = NULL;
501static ffesymbol ffecom_nested_entry_ = NULL;
502static ffeinfoKind ffecom_primary_entry_kind_;
503static bool ffecom_primary_entry_is_proc_;
504#if FFECOM_targetCURRENT == FFECOM_targetGCC
505static tree ffecom_outer_function_decl_;
506static tree ffecom_previous_function_decl_;
507static tree ffecom_which_entrypoint_decl_;
5ff904cd
JL
508static tree ffecom_float_zero_ = NULL_TREE;
509static tree ffecom_float_half_ = NULL_TREE;
510static tree ffecom_double_zero_ = NULL_TREE;
511static tree ffecom_double_half_ = NULL_TREE;
512static tree ffecom_func_result_;/* For functions. */
513static tree ffecom_func_length_;/* For CHARACTER fns. */
514static ffebld ffecom_list_blockdata_;
515static ffebld ffecom_list_common_;
516static ffebld ffecom_master_arglist_;
517static ffeinfoBasictype ffecom_master_bt_;
518static ffeinfoKindtype ffecom_master_kt_;
519static ffetargetCharacterSize ffecom_master_size_;
520static int ffecom_num_fns_ = 0;
521static int ffecom_num_entrypoints_ = 0;
522static bool ffecom_is_altreturning_ = FALSE;
523static tree ffecom_multi_type_node_;
524static tree ffecom_multi_retval_;
525static tree
526 ffecom_multi_fields_[FFEINFO_basictype][FFEINFO_kindtype];
527static bool ffecom_member_namelisted_; /* _member_phase1_ namelisted? */
528static bool ffecom_doing_entry_ = FALSE;
529static bool ffecom_transform_only_dummies_ = FALSE;
ff852b44
CB
530static int ffecom_typesize_pointer_;
531static int ffecom_typesize_integer1_;
5ff904cd
JL
532
533/* Holds pointer-to-function expressions. */
534
535static tree ffecom_gfrt_[FFECOM_gfrt]
536=
537{
538#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) NULL_TREE,
539#include "com-rt.def"
540#undef DEFGFRT
541};
542
543/* Holds the external names of the functions. */
544
26f096f9 545static const char *ffecom_gfrt_name_[FFECOM_gfrt]
5ff904cd
JL
546=
547{
548#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) NAME,
549#include "com-rt.def"
550#undef DEFGFRT
551};
552
553/* Whether the function returns. */
554
555static bool ffecom_gfrt_volatile_[FFECOM_gfrt]
556=
557{
558#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) VOLATILE,
559#include "com-rt.def"
560#undef DEFGFRT
561};
562
563/* Whether the function returns type complex. */
564
565static bool ffecom_gfrt_complex_[FFECOM_gfrt]
566=
567{
568#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) COMPLEX,
569#include "com-rt.def"
570#undef DEFGFRT
571};
572
573/* Type code for the function return value. */
574
575static ffecomRttype_ ffecom_gfrt_type_[FFECOM_gfrt]
576=
577{
578#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) TYPE,
579#include "com-rt.def"
580#undef DEFGFRT
581};
582
583/* String of codes for the function's arguments. */
584
26f096f9 585static const char *ffecom_gfrt_argstring_[FFECOM_gfrt]
5ff904cd
JL
586=
587{
588#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) ARGS,
589#include "com-rt.def"
590#undef DEFGFRT
591};
592#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
593
594/* Internal macros. */
595
596#if FFECOM_targetCURRENT == FFECOM_targetGCC
597
598/* We let tm.h override the types used here, to handle trivial differences
599 such as the choice of unsigned int or long unsigned int for size_t.
600 When machines start needing nontrivial differences in the size type,
601 it would be best to do something here to figure out automatically
602 from other information what type to use. */
603
ff852b44
CB
604#ifndef SIZE_TYPE
605#define SIZE_TYPE "long unsigned int"
606#endif
5ff904cd 607
5ff904cd
JL
608#define ffecom_concat_list_count_(catlist) ((catlist).count)
609#define ffecom_concat_list_expr_(catlist,i) ((catlist).exprs[(i)])
610#define ffecom_concat_list_maxlen_(catlist) ((catlist).maxlen)
611#define ffecom_concat_list_minlen_(catlist) ((catlist).minlen)
612
86fc7a6c
CB
613#define ffecom_char_args_(i,l,e) ffecom_char_args_x_((i),(l),(e),FALSE)
614#define ffecom_char_args_with_null_(i,l,e) ffecom_char_args_x_((i),(l),(e),TRUE)
615
5ff904cd
JL
616/* For each binding contour we allocate a binding_level structure
617 * which records the names defined in that contour.
618 * Contours include:
619 * 0) the global one
620 * 1) one for each function definition,
621 * where internal declarations of the parameters appear.
622 *
623 * The current meaning of a name can be found by searching the levels from
624 * the current one out to the global one.
625 */
626
627/* Note that the information in the `names' component of the global contour
628 is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */
629
630struct binding_level
631 {
c7e4ee3a
CB
632 /* A chain of _DECL nodes for all variables, constants, functions,
633 and typedef types. These are in the reverse of the order supplied.
634 */
5ff904cd
JL
635 tree names;
636
c7e4ee3a
CB
637 /* For each level (except not the global one),
638 a chain of BLOCK nodes for all the levels
639 that were entered and exited one level down. */
5ff904cd
JL
640 tree blocks;
641
c7e4ee3a
CB
642 /* The BLOCK node for this level, if one has been preallocated.
643 If 0, the BLOCK is allocated (if needed) when the level is popped. */
5ff904cd
JL
644 tree this_block;
645
646 /* The binding level which this one is contained in (inherits from). */
647 struct binding_level *level_chain;
c7e4ee3a
CB
648
649 /* 0: no ffecom_prepare_* functions called at this level yet;
650 1: ffecom_prepare* functions called, except not ffecom_prepare_end;
651 2: ffecom_prepare_end called. */
652 int prep_state;
5ff904cd
JL
653 };
654
655#define NULL_BINDING_LEVEL (struct binding_level *) NULL
656
657/* The binding level currently in effect. */
658
659static struct binding_level *current_binding_level;
660
661/* A chain of binding_level structures awaiting reuse. */
662
663static struct binding_level *free_binding_level;
664
665/* The outermost binding level, for names of file scope.
666 This is created when the compiler is started and exists
667 through the entire run. */
668
669static struct binding_level *global_binding_level;
670
671/* Binding level structures are initialized by copying this one. */
672
673static struct binding_level clear_binding_level
674=
c7e4ee3a 675{NULL, NULL, NULL, NULL_BINDING_LEVEL, 0};
5ff904cd
JL
676
677/* Language-dependent contents of an identifier. */
678
679struct lang_identifier
680 {
681 struct tree_identifier ignore;
682 tree global_value, local_value, label_value;
683 bool invented;
684 };
685
686/* Macros for access to language-specific slots in an identifier. */
687/* Each of these slots contains a DECL node or null. */
688
689/* This represents the value which the identifier has in the
690 file-scope namespace. */
691#define IDENTIFIER_GLOBAL_VALUE(NODE) \
692 (((struct lang_identifier *)(NODE))->global_value)
693/* This represents the value which the identifier has in the current
694 scope. */
695#define IDENTIFIER_LOCAL_VALUE(NODE) \
696 (((struct lang_identifier *)(NODE))->local_value)
697/* This represents the value which the identifier has as a label in
698 the current label scope. */
699#define IDENTIFIER_LABEL_VALUE(NODE) \
700 (((struct lang_identifier *)(NODE))->label_value)
701/* This is nonzero if the identifier was "made up" by g77 code. */
702#define IDENTIFIER_INVENTED(NODE) \
703 (((struct lang_identifier *)(NODE))->invented)
704
705/* In identifiers, C uses the following fields in a special way:
706 TREE_PUBLIC to record that there was a previous local extern decl.
707 TREE_USED to record that such a decl was used.
708 TREE_ADDRESSABLE to record that the address of such a decl was used. */
709
710/* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function
711 that have names. Here so we can clear out their names' definitions
712 at the end of the function. */
713
714static tree named_labels;
715
716/* A list of LABEL_DECLs from outer contexts that are currently shadowed. */
717
718static tree shadowed_labels;
719
720#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
721\f
6b55276e
CB
722/* Return the subscript expression, modified to do range-checking.
723
724 `array' is the array to be checked against.
725 `element' is the subscript expression to check.
726 `dim' is the dimension number (starting at 0).
727 `total_dims' is the total number of dimensions (0 for CHARACTER substring).
728*/
729
730static tree
731ffecom_subscript_check_ (tree array, tree element, int dim, int total_dims,
732 char *array_name)
733{
734 tree low = TYPE_MIN_VALUE (TYPE_DOMAIN (array));
735 tree high = TYPE_MAX_VALUE (TYPE_DOMAIN (array));
736 tree cond;
737 tree die;
738 tree args;
739
740 if (element == error_mark_node)
741 return element;
742
ff852b44
CB
743 if (TREE_TYPE (low) != TREE_TYPE (element))
744 {
745 if (TYPE_PRECISION (TREE_TYPE (low))
746 > TYPE_PRECISION (TREE_TYPE (element)))
747 element = convert (TREE_TYPE (low), element);
748 else
749 {
750 low = convert (TREE_TYPE (element), low);
751 if (high)
752 high = convert (TREE_TYPE (element), high);
753 }
754 }
755
6b55276e
CB
756 element = ffecom_save_tree (element);
757 cond = ffecom_2 (LE_EXPR, integer_type_node,
758 low,
759 element);
760 if (high)
761 {
762 cond = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
763 cond,
764 ffecom_2 (LE_EXPR, integer_type_node,
765 element,
766 high));
767 }
768
769 {
770 int len;
771 char *proc;
772 char *var;
773 tree arg3;
774 tree arg2;
775 tree arg1;
776 tree arg4;
777
778 switch (total_dims)
779 {
780 case 0:
781 var = xmalloc (strlen (array_name) + 20);
782 sprintf (&var[0], "%s[%s-substring]",
783 array_name,
784 dim ? "end" : "start");
785 len = strlen (var) + 1;
786 break;
787
788 case 1:
789 len = strlen (array_name) + 1;
790 var = array_name;
791 break;
792
793 default:
794 var = xmalloc (strlen (array_name) + 40);
795 sprintf (&var[0], "%s[subscript-%d-of-%d]",
796 array_name,
797 dim + 1, total_dims);
798 len = strlen (var) + 1;
799 break;
800 }
801
802 arg1 = build_string (len, var);
803
804 if (total_dims != 1)
805 free (var);
806
807 TREE_TYPE (arg1)
808 = build_type_variant (build_array_type (char_type_node,
809 build_range_type
810 (integer_type_node,
811 integer_one_node,
812 build_int_2 (len, 0))),
813 1, 0);
814 TREE_CONSTANT (arg1) = 1;
815 TREE_STATIC (arg1) = 1;
816 arg1 = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg1)),
817 arg1);
818
819 /* s_rnge adds one to the element to print it, so bias against
820 that -- want to print a faithful *subscript* value. */
821 arg2 = convert (ffecom_f2c_ftnint_type_node,
822 ffecom_2 (MINUS_EXPR,
823 TREE_TYPE (element),
824 element,
825 convert (TREE_TYPE (element),
826 integer_one_node)));
827
828 proc = xmalloc ((len = strlen (input_filename)
829 + IDENTIFIER_LENGTH (DECL_NAME (current_function_decl))
830 + 2));
831
832 sprintf (&proc[0], "%s/%s",
833 input_filename,
834 IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));
835 arg3 = build_string (len, proc);
836
837 free (proc);
838
839 TREE_TYPE (arg3)
840 = build_type_variant (build_array_type (char_type_node,
841 build_range_type
842 (integer_type_node,
843 integer_one_node,
844 build_int_2 (len, 0))),
845 1, 0);
846 TREE_CONSTANT (arg3) = 1;
847 TREE_STATIC (arg3) = 1;
848 arg3 = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg3)),
849 arg3);
850
851 arg4 = convert (ffecom_f2c_ftnint_type_node,
852 build_int_2 (lineno, 0));
853
854 arg1 = build_tree_list (NULL_TREE, arg1);
855 arg2 = build_tree_list (NULL_TREE, arg2);
856 arg3 = build_tree_list (NULL_TREE, arg3);
857 arg4 = build_tree_list (NULL_TREE, arg4);
858 TREE_CHAIN (arg3) = arg4;
859 TREE_CHAIN (arg2) = arg3;
860 TREE_CHAIN (arg1) = arg2;
861
862 args = arg1;
863 }
864 die = ffecom_call_gfrt (FFECOM_gfrtRANGE,
865 args, NULL_TREE);
866 TREE_SIDE_EFFECTS (die) = 1;
867
868 element = ffecom_3 (COND_EXPR,
869 TREE_TYPE (element),
870 cond,
871 element,
872 die);
873
874 return element;
875}
876
877/* Return the computed element of an array reference.
878
ff852b44
CB
879 `item' is NULL_TREE, or the transformed pointer to the array.
880 `expr' is the original opARRAYREF expression, which is transformed
881 if `item' is NULL_TREE.
882 `want_ptr' is non-zero if a pointer to the element, instead of
6b55276e
CB
883 the element itself, is to be returned. */
884
885static tree
886ffecom_arrayref_ (tree item, ffebld expr, int want_ptr)
887{
888 ffebld dims[FFECOM_dimensionsMAX];
889 int i;
890 int total_dims;
ff852b44
CB
891 int flatten = ffe_is_flatten_arrays ();
892 int need_ptr;
6b55276e
CB
893 tree array;
894 tree element;
ff852b44
CB
895 tree tree_type;
896 tree tree_type_x;
6b55276e 897 char *array_name;
ff852b44
CB
898 ffetype type;
899 ffebld list;
6b55276e
CB
900
901 if (ffebld_op (ffebld_left (expr)) == FFEBLD_opSYMTER)
902 array_name = ffesymbol_text (ffebld_symter (ffebld_left (expr)));
903 else
904 array_name = "[expr?]";
905
906 /* Build up ARRAY_REFs in reverse order (since we're column major
907 here in Fortran land). */
908
ff852b44
CB
909 for (i = 0, list = ffebld_right (expr);
910 list != NULL;
911 ++i, list = ffebld_trail (list))
912 {
913 dims[i] = ffebld_head (list);
914 type = ffeinfo_type (ffebld_basictype (dims[i]),
915 ffebld_kindtype (dims[i]));
916 if (! flatten
917 && ffecom_typesize_pointer_ > ffecom_typesize_integer1_
918 && ffetype_size (type) > ffecom_typesize_integer1_)
919 /* E.g. ARRAY(INDEX), given INTEGER*8 INDEX, on a system with 64-bit
920 pointers and 32-bit integers. Do the full 64-bit pointer
921 arithmetic, for codes using arrays for nonstandard heap-like
922 work. */
923 flatten = 1;
924 }
6b55276e
CB
925
926 total_dims = i;
927
ff852b44
CB
928 need_ptr = want_ptr || flatten;
929
930 if (! item)
931 {
932 if (need_ptr)
933 item = ffecom_ptr_to_expr (ffebld_left (expr));
934 else
935 item = ffecom_expr (ffebld_left (expr));
936
937 if (item == error_mark_node)
938 return item;
939
940 if (ffeinfo_where (ffebld_info (expr)) == FFEINFO_whereFLEETING
941 && ! mark_addressable (item))
942 return error_mark_node;
943 }
944
945 if (item == error_mark_node)
946 return item;
947
6b55276e
CB
948 if (need_ptr)
949 {
ff852b44
CB
950 tree min;
951
6b55276e
CB
952 for (--i, array = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item)));
953 i >= 0;
954 --i, array = TYPE_MAIN_VARIANT (TREE_TYPE (array)))
955 {
ff852b44
CB
956 min = TYPE_MIN_VALUE (TYPE_DOMAIN (array));
957 element = ffecom_expr_ (dims[i], NULL, NULL, NULL, FALSE, TRUE);
6b55276e
CB
958 if (ffe_is_subscript_check ())
959 element = ffecom_subscript_check_ (array, element, i, total_dims,
960 array_name);
ff852b44
CB
961 if (element == error_mark_node)
962 return element;
963
964 /* Widen integral arithmetic as desired while preserving
965 signedness. */
966 tree_type = TREE_TYPE (element);
967 tree_type_x = tree_type;
968 if (tree_type
969 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
970 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
971 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
972
973 if (TREE_TYPE (min) != tree_type_x)
974 min = convert (tree_type_x, min);
975 if (TREE_TYPE (element) != tree_type_x)
976 element = convert (tree_type_x, element);
977
6b55276e
CB
978 item = ffecom_2 (PLUS_EXPR,
979 build_pointer_type (TREE_TYPE (array)),
980 item,
981 size_binop (MULT_EXPR,
982 size_in_bytes (TREE_TYPE (array)),
ff852b44
CB
983 fold (build (MINUS_EXPR,
984 tree_type_x,
985 element,
986 min))));
6b55276e
CB
987 }
988 if (! want_ptr)
989 {
990 item = ffecom_1 (INDIRECT_REF,
991 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item))),
992 item);
993 }
994 }
995 else
996 {
997 for (--i;
998 i >= 0;
999 --i)
1000 {
1001 array = TYPE_MAIN_VARIANT (TREE_TYPE (item));
1002
1003 element = ffecom_expr_ (dims[i], NULL, NULL, NULL, FALSE, TRUE);
1004 if (ffe_is_subscript_check ())
1005 element = ffecom_subscript_check_ (array, element, i, total_dims,
1006 array_name);
ff852b44
CB
1007 if (element == error_mark_node)
1008 return element;
1009
1010 /* Widen integral arithmetic as desired while preserving
1011 signedness. */
1012 tree_type = TREE_TYPE (element);
1013 tree_type_x = tree_type;
1014 if (tree_type
1015 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
1016 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
1017 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
1018
1019 element = convert (tree_type_x, element);
1020
6b55276e
CB
1021 item = ffecom_2 (ARRAY_REF,
1022 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item))),
1023 item,
1024 element);
1025 }
1026 }
1027
1028 return item;
1029}
1030
5ff904cd
JL
1031/* This is like gcc's stabilize_reference -- in fact, most of the code
1032 comes from that -- but it handles the situation where the reference
1033 is going to have its subparts picked at, and it shouldn't change
1034 (or trigger extra invocations of functions in the subtrees) due to
1035 this. save_expr is a bit overzealous, because we don't need the
1036 entire thing calculated and saved like a temp. So, for DECLs, no
1037 change is needed, because these are stable aggregates, and ARRAY_REF
1038 and such might well be stable too, but for things like calculations,
1039 we do need to calculate a snapshot of a value before picking at it. */
1040
1041#if FFECOM_targetCURRENT == FFECOM_targetGCC
1042static tree
1043ffecom_stabilize_aggregate_ (tree ref)
1044{
1045 tree result;
1046 enum tree_code code = TREE_CODE (ref);
1047
1048 switch (code)
1049 {
1050 case VAR_DECL:
1051 case PARM_DECL:
1052 case RESULT_DECL:
1053 /* No action is needed in this case. */
1054 return ref;
1055
1056 case NOP_EXPR:
1057 case CONVERT_EXPR:
1058 case FLOAT_EXPR:
1059 case FIX_TRUNC_EXPR:
1060 case FIX_FLOOR_EXPR:
1061 case FIX_ROUND_EXPR:
1062 case FIX_CEIL_EXPR:
1063 result = build_nt (code, stabilize_reference (TREE_OPERAND (ref, 0)));
1064 break;
1065
1066 case INDIRECT_REF:
1067 result = build_nt (INDIRECT_REF,
1068 stabilize_reference_1 (TREE_OPERAND (ref, 0)));
1069 break;
1070
1071 case COMPONENT_REF:
1072 result = build_nt (COMPONENT_REF,
1073 stabilize_reference (TREE_OPERAND (ref, 0)),
1074 TREE_OPERAND (ref, 1));
1075 break;
1076
1077 case BIT_FIELD_REF:
1078 result = build_nt (BIT_FIELD_REF,
1079 stabilize_reference (TREE_OPERAND (ref, 0)),
1080 stabilize_reference_1 (TREE_OPERAND (ref, 1)),
1081 stabilize_reference_1 (TREE_OPERAND (ref, 2)));
1082 break;
1083
1084 case ARRAY_REF:
1085 result = build_nt (ARRAY_REF,
1086 stabilize_reference (TREE_OPERAND (ref, 0)),
1087 stabilize_reference_1 (TREE_OPERAND (ref, 1)));
1088 break;
1089
1090 case COMPOUND_EXPR:
1091 result = build_nt (COMPOUND_EXPR,
1092 stabilize_reference_1 (TREE_OPERAND (ref, 0)),
1093 stabilize_reference (TREE_OPERAND (ref, 1)));
1094 break;
1095
1096 case RTL_EXPR:
1097 result = build1 (INDIRECT_REF, TREE_TYPE (ref),
1098 save_expr (build1 (ADDR_EXPR,
1099 build_pointer_type (TREE_TYPE (ref)),
1100 ref)));
1101 break;
1102
1103
1104 default:
1105 return save_expr (ref);
1106
1107 case ERROR_MARK:
1108 return error_mark_node;
1109 }
1110
1111 TREE_TYPE (result) = TREE_TYPE (ref);
1112 TREE_READONLY (result) = TREE_READONLY (ref);
1113 TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (ref);
1114 TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (ref);
1115 TREE_RAISES (result) = TREE_RAISES (ref);
1116
1117 return result;
1118}
1119#endif
1120
1121/* A rip-off of gcc's convert.c convert_to_complex function,
1122 reworked to handle complex implemented as C structures
1123 (RECORD_TYPE with two fields, real and imaginary `r' and `i'). */
1124
1125#if FFECOM_targetCURRENT == FFECOM_targetGCC
1126static tree
1127ffecom_convert_to_complex_ (tree type, tree expr)
1128{
1129 register enum tree_code form = TREE_CODE (TREE_TYPE (expr));
1130 tree subtype;
1131
1132 assert (TREE_CODE (type) == RECORD_TYPE);
1133
1134 subtype = TREE_TYPE (TYPE_FIELDS (type));
1135
1136 if (form == REAL_TYPE || form == INTEGER_TYPE || form == ENUMERAL_TYPE)
1137 {
1138 expr = convert (subtype, expr);
1139 return ffecom_2 (COMPLEX_EXPR, type, expr,
1140 convert (subtype, integer_zero_node));
1141 }
1142
1143 if (form == RECORD_TYPE)
1144 {
1145 tree elt_type = TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr)));
1146 if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype))
1147 return expr;
1148 else
1149 {
1150 expr = save_expr (expr);
1151 return ffecom_2 (COMPLEX_EXPR,
1152 type,
1153 convert (subtype,
1154 ffecom_1 (REALPART_EXPR,
1155 TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))),
1156 expr)),
1157 convert (subtype,
1158 ffecom_1 (IMAGPART_EXPR,
1159 TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))),
1160 expr)));
1161 }
1162 }
1163
1164 if (form == POINTER_TYPE || form == REFERENCE_TYPE)
1165 error ("pointer value used where a complex was expected");
1166 else
1167 error ("aggregate value used where a complex was expected");
1168
1169 return ffecom_2 (COMPLEX_EXPR, type,
1170 convert (subtype, integer_zero_node),
1171 convert (subtype, integer_zero_node));
1172}
1173#endif
1174
1175/* Like gcc's convert(), but crashes if widening might happen. */
1176
1177#if FFECOM_targetCURRENT == FFECOM_targetGCC
1178static tree
1179ffecom_convert_narrow_ (type, expr)
1180 tree type, expr;
1181{
1182 register tree e = expr;
1183 register enum tree_code code = TREE_CODE (type);
1184
1185 if (type == TREE_TYPE (e)
1186 || TREE_CODE (e) == ERROR_MARK)
1187 return e;
1188 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
1189 return fold (build1 (NOP_EXPR, type, e));
1190 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
1191 || code == ERROR_MARK)
1192 return error_mark_node;
1193 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
1194 {
1195 assert ("void value not ignored as it ought to be" == NULL);
1196 return error_mark_node;
1197 }
1198 assert (code != VOID_TYPE);
1199 if ((code != RECORD_TYPE)
1200 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
1201 assert ("converting COMPLEX to REAL" == NULL);
1202 assert (code != ENUMERAL_TYPE);
1203 if (code == INTEGER_TYPE)
1204 {
a74de6ea
CB
1205 assert ((TREE_CODE (TREE_TYPE (e)) == INTEGER_TYPE
1206 && TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (e)))
1207 || (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE
1208 && (TYPE_PRECISION (type)
1209 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e))))));
5ff904cd
JL
1210 return fold (convert_to_integer (type, e));
1211 }
1212 if (code == POINTER_TYPE)
1213 {
1214 assert (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE);
1215 return fold (convert_to_pointer (type, e));
1216 }
1217 if (code == REAL_TYPE)
1218 {
1219 assert (TREE_CODE (TREE_TYPE (e)) == REAL_TYPE);
1220 assert (TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (e)));
1221 return fold (convert_to_real (type, e));
1222 }
1223 if (code == COMPLEX_TYPE)
1224 {
1225 assert (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE);
1226 assert (TYPE_PRECISION (TREE_TYPE (type)) <= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e))));
1227 return fold (convert_to_complex (type, e));
1228 }
1229 if (code == RECORD_TYPE)
1230 {
1231 assert (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE);
270fc4e8
CB
1232 /* Check that at least the first field name agrees. */
1233 assert (DECL_NAME (TYPE_FIELDS (type))
1234 == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e))));
5ff904cd
JL
1235 assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1236 <= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))));
270fc4e8
CB
1237 if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1238 == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))))
1239 return e;
5ff904cd
JL
1240 return fold (ffecom_convert_to_complex_ (type, e));
1241 }
1242
1243 assert ("conversion to non-scalar type requested" == NULL);
1244 return error_mark_node;
1245}
1246#endif
1247
1248/* Like gcc's convert(), but crashes if narrowing might happen. */
1249
1250#if FFECOM_targetCURRENT == FFECOM_targetGCC
1251static tree
1252ffecom_convert_widen_ (type, expr)
1253 tree type, expr;
1254{
1255 register tree e = expr;
1256 register enum tree_code code = TREE_CODE (type);
1257
1258 if (type == TREE_TYPE (e)
1259 || TREE_CODE (e) == ERROR_MARK)
1260 return e;
1261 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
1262 return fold (build1 (NOP_EXPR, type, e));
1263 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
1264 || code == ERROR_MARK)
1265 return error_mark_node;
1266 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
1267 {
1268 assert ("void value not ignored as it ought to be" == NULL);
1269 return error_mark_node;
1270 }
1271 assert (code != VOID_TYPE);
1272 if ((code != RECORD_TYPE)
1273 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
1274 assert ("narrowing COMPLEX to REAL" == NULL);
1275 assert (code != ENUMERAL_TYPE);
1276 if (code == INTEGER_TYPE)
1277 {
a74de6ea
CB
1278 assert ((TREE_CODE (TREE_TYPE (e)) == INTEGER_TYPE
1279 && TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (e)))
1280 || (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE
1281 && (TYPE_PRECISION (type)
1282 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e))))));
5ff904cd
JL
1283 return fold (convert_to_integer (type, e));
1284 }
1285 if (code == POINTER_TYPE)
1286 {
1287 assert (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE);
1288 return fold (convert_to_pointer (type, e));
1289 }
1290 if (code == REAL_TYPE)
1291 {
1292 assert (TREE_CODE (TREE_TYPE (e)) == REAL_TYPE);
1293 assert (TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (e)));
1294 return fold (convert_to_real (type, e));
1295 }
1296 if (code == COMPLEX_TYPE)
1297 {
1298 assert (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE);
1299 assert (TYPE_PRECISION (TREE_TYPE (type)) >= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e))));
1300 return fold (convert_to_complex (type, e));
1301 }
1302 if (code == RECORD_TYPE)
1303 {
1304 assert (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE);
270fc4e8
CB
1305 /* Check that at least the first field name agrees. */
1306 assert (DECL_NAME (TYPE_FIELDS (type))
1307 == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e))));
5ff904cd
JL
1308 assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1309 >= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))));
270fc4e8
CB
1310 if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1311 == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))))
1312 return e;
5ff904cd
JL
1313 return fold (ffecom_convert_to_complex_ (type, e));
1314 }
1315
1316 assert ("conversion to non-scalar type requested" == NULL);
1317 return error_mark_node;
1318}
1319#endif
1320
1321/* Handles making a COMPLEX type, either the standard
1322 (but buggy?) gbe way, or the safer (but less elegant?)
1323 f2c way. */
1324
1325#if FFECOM_targetCURRENT == FFECOM_targetGCC
1326static tree
1327ffecom_make_complex_type_ (tree subtype)
1328{
1329 tree type;
1330 tree realfield;
1331 tree imagfield;
1332
1333 if (ffe_is_emulate_complex ())
1334 {
1335 type = make_node (RECORD_TYPE);
1336 realfield = ffecom_decl_field (type, NULL_TREE, "r", subtype);
1337 imagfield = ffecom_decl_field (type, realfield, "i", subtype);
1338 TYPE_FIELDS (type) = realfield;
1339 layout_type (type);
1340 }
1341 else
1342 {
1343 type = make_node (COMPLEX_TYPE);
1344 TREE_TYPE (type) = subtype;
1345 layout_type (type);
1346 }
1347
1348 return type;
1349}
1350#endif
1351
1352/* Chooses either the gbe or the f2c way to build a
1353 complex constant. */
1354
1355#if FFECOM_targetCURRENT == FFECOM_targetGCC
1356static tree
1357ffecom_build_complex_constant_ (tree type, tree realpart, tree imagpart)
1358{
1359 tree bothparts;
1360
1361 if (ffe_is_emulate_complex ())
1362 {
1363 bothparts = build_tree_list (TYPE_FIELDS (type), realpart);
1364 TREE_CHAIN (bothparts) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), imagpart);
1365 bothparts = build (CONSTRUCTOR, type, NULL_TREE, bothparts);
1366 }
1367 else
1368 {
1369 bothparts = build_complex (type, realpart, imagpart);
1370 }
1371
1372 return bothparts;
1373}
1374#endif
1375
1376#if FFECOM_targetCURRENT == FFECOM_targetGCC
1377static tree
26f096f9 1378ffecom_arglist_expr_ (const char *c, ffebld expr)
5ff904cd
JL
1379{
1380 tree list;
1381 tree *plist = &list;
1382 tree trail = NULL_TREE; /* Append char length args here. */
1383 tree *ptrail = &trail;
1384 tree length;
1385 ffebld exprh;
1386 tree item;
1387 bool ptr = FALSE;
1388 tree wanted = NULL_TREE;
e2fa159e
JL
1389 static char zed[] = "0";
1390
1391 if (c == NULL)
1392 c = &zed[0];
5ff904cd
JL
1393
1394 while (expr != NULL)
1395 {
1396 if (*c != '\0')
1397 {
1398 ptr = FALSE;
1399 if (*c == '&')
1400 {
1401 ptr = TRUE;
1402 ++c;
1403 }
1404 switch (*(c++))
1405 {
1406 case '\0':
1407 ptr = TRUE;
1408 wanted = NULL_TREE;
1409 break;
1410
1411 case 'a':
1412 assert (ptr);
1413 wanted = NULL_TREE;
1414 break;
1415
1416 case 'c':
1417 wanted = ffecom_f2c_complex_type_node;
1418 break;
1419
1420 case 'd':
1421 wanted = ffecom_f2c_doublereal_type_node;
1422 break;
1423
1424 case 'e':
1425 wanted = ffecom_f2c_doublecomplex_type_node;
1426 break;
1427
1428 case 'f':
1429 wanted = ffecom_f2c_real_type_node;
1430 break;
1431
1432 case 'i':
1433 wanted = ffecom_f2c_integer_type_node;
1434 break;
1435
1436 case 'j':
1437 wanted = ffecom_f2c_longint_type_node;
1438 break;
1439
1440 default:
1441 assert ("bad argstring code" == NULL);
1442 wanted = NULL_TREE;
1443 break;
1444 }
1445 }
1446
1447 exprh = ffebld_head (expr);
1448 if (exprh == NULL)
1449 wanted = NULL_TREE;
1450
1451 if ((wanted == NULL_TREE)
1452 || (ptr
1453 && (TYPE_MODE
1454 (ffecom_tree_type[ffeinfo_basictype (ffebld_info (exprh))]
1455 [ffeinfo_kindtype (ffebld_info (exprh))])
1456 == TYPE_MODE (wanted))))
1457 *plist
1458 = build_tree_list (NULL_TREE,
1459 ffecom_arg_ptr_to_expr (exprh,
1460 &length));
1461 else
1462 {
1463 item = ffecom_arg_expr (exprh, &length);
1464 item = ffecom_convert_widen_ (wanted, item);
1465 if (ptr)
1466 {
1467 item = ffecom_1 (ADDR_EXPR,
1468 build_pointer_type (TREE_TYPE (item)),
1469 item);
1470 }
1471 *plist
1472 = build_tree_list (NULL_TREE,
1473 item);
1474 }
1475
1476 plist = &TREE_CHAIN (*plist);
1477 expr = ffebld_trail (expr);
1478 if (length != NULL_TREE)
1479 {
1480 *ptrail = build_tree_list (NULL_TREE, length);
1481 ptrail = &TREE_CHAIN (*ptrail);
1482 }
1483 }
1484
e2fa159e
JL
1485 /* We've run out of args in the call; if the implementation expects
1486 more, supply null pointers for them, which the implementation can
1487 check to see if an arg was omitted. */
1488
1489 while (*c != '\0' && *c != '0')
1490 {
1491 if (*c == '&')
1492 ++c;
1493 else
1494 assert ("missing arg to run-time routine!" == NULL);
1495
1496 switch (*(c++))
1497 {
1498 case '\0':
1499 case 'a':
1500 case 'c':
1501 case 'd':
1502 case 'e':
1503 case 'f':
1504 case 'i':
1505 case 'j':
1506 break;
1507
1508 default:
1509 assert ("bad arg string code" == NULL);
1510 break;
1511 }
1512 *plist
1513 = build_tree_list (NULL_TREE,
1514 null_pointer_node);
1515 plist = &TREE_CHAIN (*plist);
1516 }
1517
5ff904cd
JL
1518 *plist = trail;
1519
1520 return list;
1521}
1522#endif
1523
1524#if FFECOM_targetCURRENT == FFECOM_targetGCC
1525static tree
1526ffecom_widest_expr_type_ (ffebld list)
1527{
1528 ffebld item;
1529 ffebld widest = NULL;
1530 ffetype type;
1531 ffetype widest_type = NULL;
1532 tree t;
1533
1534 for (; list != NULL; list = ffebld_trail (list))
1535 {
1536 item = ffebld_head (list);
1537 if (item == NULL)
1538 continue;
1539 if ((widest != NULL)
1540 && (ffeinfo_basictype (ffebld_info (item))
1541 != ffeinfo_basictype (ffebld_info (widest))))
1542 continue;
1543 type = ffeinfo_type (ffeinfo_basictype (ffebld_info (item)),
1544 ffeinfo_kindtype (ffebld_info (item)));
1545 if ((widest == FFEINFO_kindtypeNONE)
1546 || (ffetype_size (type)
1547 > ffetype_size (widest_type)))
1548 {
1549 widest = item;
1550 widest_type = type;
1551 }
1552 }
1553
1554 assert (widest != NULL);
1555 t = ffecom_tree_type[ffeinfo_basictype (ffebld_info (widest))]
1556 [ffeinfo_kindtype (ffebld_info (widest))];
1557 assert (t != NULL_TREE);
1558 return t;
1559}
1560#endif
1561
d6cd84e0
CB
1562/* Check whether a partial overlap between two expressions is possible.
1563
1564 Can *starting* to write a portion of expr1 change the value
1565 computed (perhaps already, *partially*) by expr2?
1566
1567 Currently, this is a concern only for a COMPLEX expr1. But if it
1568 isn't in COMMON or local EQUIVALENCE, since we don't support
1569 aliasing of arguments, it isn't a concern. */
1570
1571static bool
1572ffecom_possible_partial_overlap_ (ffebld expr1, ffebld expr2)
1573{
1574 ffesymbol sym;
1575 ffestorag st;
1576
1577 switch (ffebld_op (expr1))
1578 {
1579 case FFEBLD_opSYMTER:
1580 sym = ffebld_symter (expr1);
1581 break;
1582
1583 case FFEBLD_opARRAYREF:
1584 if (ffebld_op (ffebld_left (expr1)) != FFEBLD_opSYMTER)
1585 return FALSE;
1586 sym = ffebld_symter (ffebld_left (expr1));
1587 break;
1588
1589 default:
1590 return FALSE;
1591 }
1592
1593 if (ffesymbol_where (sym) != FFEINFO_whereCOMMON
1594 && (ffesymbol_where (sym) != FFEINFO_whereLOCAL
1595 || ! (st = ffesymbol_storage (sym))
1596 || ! ffestorag_parent (st)))
1597 return FALSE;
1598
1599 /* It's in COMMON or local EQUIVALENCE. */
1600
1601 return TRUE;
1602}
1603
5ff904cd
JL
1604/* Check whether dest and source might overlap. ffebld versions of these
1605 might or might not be passed, will be NULL if not.
1606
1607 The test is really whether source_tree is modifiable and, if modified,
1608 might overlap destination such that the value(s) in the destination might
1609 change before it is finally modified. dest_* are the canonized
1610 destination itself. */
1611
1612#if FFECOM_targetCURRENT == FFECOM_targetGCC
1613static bool
1614ffecom_overlap_ (tree dest_decl, tree dest_offset, tree dest_size,
1615 tree source_tree, ffebld source UNUSED,
1616 bool scalar_arg)
1617{
1618 tree source_decl;
1619 tree source_offset;
1620 tree source_size;
1621 tree t;
1622
1623 if (source_tree == NULL_TREE)
1624 return FALSE;
1625
1626 switch (TREE_CODE (source_tree))
1627 {
1628 case ERROR_MARK:
1629 case IDENTIFIER_NODE:
1630 case INTEGER_CST:
1631 case REAL_CST:
1632 case COMPLEX_CST:
1633 case STRING_CST:
1634 case CONST_DECL:
1635 case VAR_DECL:
1636 case RESULT_DECL:
1637 case FIELD_DECL:
1638 case MINUS_EXPR:
1639 case MULT_EXPR:
1640 case TRUNC_DIV_EXPR:
1641 case CEIL_DIV_EXPR:
1642 case FLOOR_DIV_EXPR:
1643 case ROUND_DIV_EXPR:
1644 case TRUNC_MOD_EXPR:
1645 case CEIL_MOD_EXPR:
1646 case FLOOR_MOD_EXPR:
1647 case ROUND_MOD_EXPR:
1648 case RDIV_EXPR:
1649 case EXACT_DIV_EXPR:
1650 case FIX_TRUNC_EXPR:
1651 case FIX_CEIL_EXPR:
1652 case FIX_FLOOR_EXPR:
1653 case FIX_ROUND_EXPR:
1654 case FLOAT_EXPR:
1655 case EXPON_EXPR:
1656 case NEGATE_EXPR:
1657 case MIN_EXPR:
1658 case MAX_EXPR:
1659 case ABS_EXPR:
1660 case FFS_EXPR:
1661 case LSHIFT_EXPR:
1662 case RSHIFT_EXPR:
1663 case LROTATE_EXPR:
1664 case RROTATE_EXPR:
1665 case BIT_IOR_EXPR:
1666 case BIT_XOR_EXPR:
1667 case BIT_AND_EXPR:
1668 case BIT_ANDTC_EXPR:
1669 case BIT_NOT_EXPR:
1670 case TRUTH_ANDIF_EXPR:
1671 case TRUTH_ORIF_EXPR:
1672 case TRUTH_AND_EXPR:
1673 case TRUTH_OR_EXPR:
1674 case TRUTH_XOR_EXPR:
1675 case TRUTH_NOT_EXPR:
1676 case LT_EXPR:
1677 case LE_EXPR:
1678 case GT_EXPR:
1679 case GE_EXPR:
1680 case EQ_EXPR:
1681 case NE_EXPR:
1682 case COMPLEX_EXPR:
1683 case CONJ_EXPR:
1684 case REALPART_EXPR:
1685 case IMAGPART_EXPR:
1686 case LABEL_EXPR:
1687 case COMPONENT_REF:
1688 return FALSE;
1689
1690 case COMPOUND_EXPR:
1691 return ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1692 TREE_OPERAND (source_tree, 1), NULL,
1693 scalar_arg);
1694
1695 case MODIFY_EXPR:
1696 return ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1697 TREE_OPERAND (source_tree, 0), NULL,
1698 scalar_arg);
1699
1700 case CONVERT_EXPR:
1701 case NOP_EXPR:
1702 case NON_LVALUE_EXPR:
1703 case PLUS_EXPR:
1704 if (TREE_CODE (TREE_TYPE (source_tree)) != POINTER_TYPE)
1705 return TRUE;
1706
1707 ffecom_tree_canonize_ptr_ (&source_decl, &source_offset,
1708 source_tree);
1709 source_size = TYPE_SIZE (TREE_TYPE (TREE_TYPE (source_tree)));
1710 break;
1711
1712 case COND_EXPR:
1713 return
1714 ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1715 TREE_OPERAND (source_tree, 1), NULL,
1716 scalar_arg)
1717 || ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1718 TREE_OPERAND (source_tree, 2), NULL,
1719 scalar_arg);
1720
1721
1722 case ADDR_EXPR:
1723 ffecom_tree_canonize_ref_ (&source_decl, &source_offset,
1724 &source_size,
1725 TREE_OPERAND (source_tree, 0));
1726 break;
1727
1728 case PARM_DECL:
1729 if (TREE_CODE (TREE_TYPE (source_tree)) != POINTER_TYPE)
1730 return TRUE;
1731
1732 source_decl = source_tree;
1733 source_offset = size_zero_node;
1734 source_size = TYPE_SIZE (TREE_TYPE (TREE_TYPE (source_tree)));
1735 break;
1736
1737 case SAVE_EXPR:
1738 case REFERENCE_EXPR:
1739 case PREDECREMENT_EXPR:
1740 case PREINCREMENT_EXPR:
1741 case POSTDECREMENT_EXPR:
1742 case POSTINCREMENT_EXPR:
1743 case INDIRECT_REF:
1744 case ARRAY_REF:
1745 case CALL_EXPR:
1746 default:
1747 return TRUE;
1748 }
1749
1750 /* Come here when source_decl, source_offset, and source_size filled
1751 in appropriately. */
1752
1753 if (source_decl == NULL_TREE)
1754 return FALSE; /* No decl involved, so no overlap. */
1755
1756 if (source_decl != dest_decl)
1757 return FALSE; /* Different decl, no overlap. */
1758
1759 if (TREE_CODE (dest_size) == ERROR_MARK)
1760 return TRUE; /* Assignment into entire assumed-size
1761 array? Shouldn't happen.... */
1762
1763 t = ffecom_2 (LE_EXPR, integer_type_node,
1764 ffecom_2 (PLUS_EXPR, TREE_TYPE (dest_offset),
1765 dest_offset,
1766 convert (TREE_TYPE (dest_offset),
1767 dest_size)),
1768 convert (TREE_TYPE (dest_offset),
1769 source_offset));
1770
1771 if (integer_onep (t))
1772 return FALSE; /* Destination precedes source. */
1773
1774 if (!scalar_arg
1775 || (source_size == NULL_TREE)
1776 || (TREE_CODE (source_size) == ERROR_MARK)
1777 || integer_zerop (source_size))
1778 return TRUE; /* No way to tell if dest follows source. */
1779
1780 t = ffecom_2 (LE_EXPR, integer_type_node,
1781 ffecom_2 (PLUS_EXPR, TREE_TYPE (source_offset),
1782 source_offset,
1783 convert (TREE_TYPE (source_offset),
1784 source_size)),
1785 convert (TREE_TYPE (source_offset),
1786 dest_offset));
1787
1788 if (integer_onep (t))
1789 return FALSE; /* Destination follows source. */
1790
1791 return TRUE; /* Destination and source overlap. */
1792}
1793#endif
1794
1795/* Check whether dest might overlap any of a list of arguments or is
1796 in a COMMON area the callee might know about (and thus modify). */
1797
1798#if FFECOM_targetCURRENT == FFECOM_targetGCC
1799static bool
1800ffecom_args_overlapping_ (tree dest_tree, ffebld dest UNUSED,
1801 tree args, tree callee_commons,
1802 bool scalar_args)
1803{
1804 tree arg;
1805 tree dest_decl;
1806 tree dest_offset;
1807 tree dest_size;
1808
1809 ffecom_tree_canonize_ref_ (&dest_decl, &dest_offset, &dest_size,
1810 dest_tree);
1811
1812 if (dest_decl == NULL_TREE)
1813 return FALSE; /* Seems unlikely! */
1814
1815 /* If the decl cannot be determined reliably, or if its in COMMON
1816 and the callee isn't known to not futz with COMMON via other
1817 means, overlap might happen. */
1818
1819 if ((TREE_CODE (dest_decl) == ERROR_MARK)
1820 || ((callee_commons != NULL_TREE)
1821 && TREE_PUBLIC (dest_decl)))
1822 return TRUE;
1823
1824 for (; args != NULL_TREE; args = TREE_CHAIN (args))
1825 {
1826 if (((arg = TREE_VALUE (args)) != NULL_TREE)
1827 && ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1828 arg, NULL, scalar_args))
1829 return TRUE;
1830 }
1831
1832 return FALSE;
1833}
1834#endif
1835
1836/* Build a string for a variable name as used by NAMELIST. This means that
1837 if we're using the f2c library, we build an uppercase string, since
1838 f2c does this. */
1839
1840#if FFECOM_targetCURRENT == FFECOM_targetGCC
1841static tree
26f096f9 1842ffecom_build_f2c_string_ (int i, const char *s)
5ff904cd
JL
1843{
1844 if (!ffe_is_f2c_library ())
1845 return build_string (i, s);
1846
1847 {
1848 char *tmp;
26f096f9 1849 const char *p;
5ff904cd
JL
1850 char *q;
1851 char space[34];
1852 tree t;
1853
1854 if (((size_t) i) > ARRAY_SIZE (space))
1855 tmp = malloc_new_ks (malloc_pool_image (), "f2c_string", i);
1856 else
1857 tmp = &space[0];
1858
1859 for (p = s, q = tmp; *p != '\0'; ++p, ++q)
1860 *q = ffesrc_toupper (*p);
1861 *q = '\0';
1862
1863 t = build_string (i, tmp);
1864
1865 if (((size_t) i) > ARRAY_SIZE (space))
1866 malloc_kill_ks (malloc_pool_image (), tmp, i);
1867
1868 return t;
1869 }
1870}
1871
1872#endif
1873/* Returns CALL_EXPR or equivalent with given type (pass NULL_TREE for
1874 type to just get whatever the function returns), handling the
1875 f2c value-returning convention, if required, by prepending
1876 to the arglist a pointer to a temporary to receive the return value. */
1877
1878#if FFECOM_targetCURRENT == FFECOM_targetGCC
1879static tree
1880ffecom_call_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex,
1881 tree type, tree args, tree dest_tree,
1882 ffebld dest, bool *dest_used, tree callee_commons,
c7e4ee3a 1883 bool scalar_args, tree hook)
5ff904cd
JL
1884{
1885 tree item;
1886 tree tempvar;
1887
1888 if (dest_used != NULL)
1889 *dest_used = FALSE;
1890
1891 if (is_f2c_complex)
1892 {
1893 if ((dest_used == NULL)
1894 || (dest == NULL)
1895 || (ffeinfo_basictype (ffebld_info (dest))
1896 != FFEINFO_basictypeCOMPLEX)
1897 || (ffeinfo_kindtype (ffebld_info (dest)) != kt)
1898 || ((type != NULL_TREE) && (TREE_TYPE (dest_tree) != type))
1899 || ffecom_args_overlapping_ (dest_tree, dest, args,
1900 callee_commons,
1901 scalar_args))
1902 {
c7e4ee3a
CB
1903#ifdef HOHO
1904 tempvar = ffecom_make_tempvar (ffecom_tree_type
5ff904cd
JL
1905 [FFEINFO_basictypeCOMPLEX][kt],
1906 FFETARGET_charactersizeNONE,
c7e4ee3a
CB
1907 -1);
1908#else
1909 tempvar = hook;
1910 assert (tempvar);
1911#endif
5ff904cd
JL
1912 }
1913 else
1914 {
1915 *dest_used = TRUE;
1916 tempvar = dest_tree;
1917 type = NULL_TREE;
1918 }
1919
1920 item
1921 = build_tree_list (NULL_TREE,
1922 ffecom_1 (ADDR_EXPR,
c7e4ee3a 1923 build_pointer_type (TREE_TYPE (tempvar)),
5ff904cd
JL
1924 tempvar));
1925 TREE_CHAIN (item) = args;
1926
1927 item = ffecom_3s (CALL_EXPR, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), fn,
1928 item, NULL_TREE);
1929
1930 if (tempvar != dest_tree)
1931 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), item, tempvar);
1932 }
1933 else
1934 item = ffecom_3s (CALL_EXPR, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), fn,
1935 args, NULL_TREE);
1936
1937 if ((type != NULL_TREE) && (TREE_TYPE (item) != type))
1938 item = ffecom_convert_narrow_ (type, item);
1939
1940 return item;
1941}
1942#endif
1943
1944/* Given two arguments, transform them and make a call to the given
1945 function via ffecom_call_. */
1946
1947#if FFECOM_targetCURRENT == FFECOM_targetGCC
1948static tree
1949ffecom_call_binop_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex,
1950 tree type, ffebld left, ffebld right,
1951 tree dest_tree, ffebld dest, bool *dest_used,
c7e4ee3a 1952 tree callee_commons, bool scalar_args, tree hook)
5ff904cd
JL
1953{
1954 tree left_tree;
1955 tree right_tree;
1956 tree left_length;
1957 tree right_length;
1958
5ff904cd
JL
1959 left_tree = ffecom_arg_ptr_to_expr (left, &left_length);
1960 right_tree = ffecom_arg_ptr_to_expr (right, &right_length);
5ff904cd
JL
1961
1962 left_tree = build_tree_list (NULL_TREE, left_tree);
1963 right_tree = build_tree_list (NULL_TREE, right_tree);
1964 TREE_CHAIN (left_tree) = right_tree;
1965
1966 if (left_length != NULL_TREE)
1967 {
1968 left_length = build_tree_list (NULL_TREE, left_length);
1969 TREE_CHAIN (right_tree) = left_length;
1970 }
1971
1972 if (right_length != NULL_TREE)
1973 {
1974 right_length = build_tree_list (NULL_TREE, right_length);
1975 if (left_length != NULL_TREE)
1976 TREE_CHAIN (left_length) = right_length;
1977 else
1978 TREE_CHAIN (right_tree) = right_length;
1979 }
1980
1981 return ffecom_call_ (fn, kt, is_f2c_complex, type, left_tree,
1982 dest_tree, dest, dest_used, callee_commons,
c7e4ee3a 1983 scalar_args, hook);
5ff904cd
JL
1984}
1985#endif
1986
c7e4ee3a 1987/* Return ptr/length args for char subexpression
5ff904cd
JL
1988
1989 Handles CHARACTER-type CONTER, SYMTER, SUBSTR, ARRAYREF, and FUNCREF
1990 subexpressions by constructing the appropriate trees for the ptr-to-
1991 character-text and length-of-character-text arguments in a calling
86fc7a6c
CB
1992 sequence.
1993
1994 Note that if with_null is TRUE, and the expression is an opCONTER,
1995 a null byte is appended to the string. */
5ff904cd
JL
1996
1997#if FFECOM_targetCURRENT == FFECOM_targetGCC
1998static void
86fc7a6c 1999ffecom_char_args_x_ (tree *xitem, tree *length, ffebld expr, bool with_null)
5ff904cd
JL
2000{
2001 tree item;
2002 tree high;
2003 ffetargetCharacter1 val;
86fc7a6c 2004 ffetargetCharacterSize newlen;
5ff904cd
JL
2005
2006 switch (ffebld_op (expr))
2007 {
2008 case FFEBLD_opCONTER:
2009 val = ffebld_constant_character1 (ffebld_conter (expr));
86fc7a6c
CB
2010 newlen = ffetarget_length_character1 (val);
2011 if (with_null)
2012 {
c7e4ee3a 2013 /* Begin FFETARGET-NULL-KLUDGE. */
86fc7a6c 2014 if (newlen != 0)
c7e4ee3a 2015 ++newlen;
86fc7a6c
CB
2016 }
2017 *length = build_int_2 (newlen, 0);
5ff904cd 2018 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
86fc7a6c 2019 high = build_int_2 (newlen, 0);
5ff904cd 2020 TREE_TYPE (high) = ffecom_f2c_ftnlen_type_node;
c7e4ee3a 2021 item = build_string (newlen,
5ff904cd 2022 ffetarget_text_character1 (val));
c7e4ee3a 2023 /* End FFETARGET-NULL-KLUDGE. */
5ff904cd
JL
2024 TREE_TYPE (item)
2025 = build_type_variant
2026 (build_array_type
2027 (char_type_node,
2028 build_range_type
2029 (ffecom_f2c_ftnlen_type_node,
2030 ffecom_f2c_ftnlen_one_node,
2031 high)),
2032 1, 0);
2033 TREE_CONSTANT (item) = 1;
2034 TREE_STATIC (item) = 1;
2035 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
2036 item);
2037 break;
2038
2039 case FFEBLD_opSYMTER:
2040 {
2041 ffesymbol s = ffebld_symter (expr);
2042
2043 item = ffesymbol_hook (s).decl_tree;
2044 if (item == NULL_TREE)
2045 {
2046 s = ffecom_sym_transform_ (s);
2047 item = ffesymbol_hook (s).decl_tree;
2048 }
2049 if (ffesymbol_kind (s) == FFEINFO_kindENTITY)
2050 {
2051 if (ffesymbol_size (s) == FFETARGET_charactersizeNONE)
2052 *length = ffesymbol_hook (s).length_tree;
2053 else
2054 {
2055 *length = build_int_2 (ffesymbol_size (s), 0);
2056 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
2057 }
2058 }
2059 else if (item == error_mark_node)
2060 *length = error_mark_node;
c7e4ee3a
CB
2061 else
2062 /* FFEINFO_kindFUNCTION. */
5ff904cd
JL
2063 *length = NULL_TREE;
2064 if (!ffesymbol_hook (s).addr
2065 && (item != error_mark_node))
2066 item = ffecom_1 (ADDR_EXPR,
2067 build_pointer_type (TREE_TYPE (item)),
2068 item);
2069 }
2070 break;
2071
2072 case FFEBLD_opARRAYREF:
2073 {
5ff904cd 2074 ffecom_char_args_ (&item, length, ffebld_left (expr));
5ff904cd
JL
2075
2076 if (item == error_mark_node || *length == error_mark_node)
2077 {
2078 item = *length = error_mark_node;
2079 break;
2080 }
2081
6b55276e 2082 item = ffecom_arrayref_ (item, expr, 1);
5ff904cd
JL
2083 }
2084 break;
2085
2086 case FFEBLD_opSUBSTR:
2087 {
2088 ffebld start;
2089 ffebld end;
2090 ffebld thing = ffebld_right (expr);
2091 tree start_tree;
2092 tree end_tree;
6b55276e
CB
2093 char *char_name;
2094 ffebld left_symter;
2095 tree array;
5ff904cd
JL
2096
2097 assert (ffebld_op (thing) == FFEBLD_opITEM);
2098 start = ffebld_head (thing);
2099 thing = ffebld_trail (thing);
2100 assert (ffebld_trail (thing) == NULL);
2101 end = ffebld_head (thing);
2102
6b55276e
CB
2103 /* Determine name for pretty-printing range-check errors. */
2104 for (left_symter = ffebld_left (expr);
2105 left_symter && ffebld_op (left_symter) == FFEBLD_opARRAYREF;
2106 left_symter = ffebld_left (left_symter))
2107 ;
2108 if (ffebld_op (left_symter) == FFEBLD_opSYMTER)
2109 char_name = ffesymbol_text (ffebld_symter (left_symter));
2110 else
2111 char_name = "[expr?]";
2112
5ff904cd 2113 ffecom_char_args_ (&item, length, ffebld_left (expr));
5ff904cd
JL
2114
2115 if (item == error_mark_node || *length == error_mark_node)
2116 {
2117 item = *length = error_mark_node;
2118 break;
2119 }
2120
6b55276e
CB
2121 array = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item)));
2122
ff852b44
CB
2123 /* ~~~~Handle INTEGER*8 start/end, a la FFEBLD_opARRAYREF. */
2124
5ff904cd
JL
2125 if (start == NULL)
2126 {
2127 if (end == NULL)
2128 ;
2129 else
2130 {
6b55276e
CB
2131 end_tree = ffecom_expr (end);
2132 if (ffe_is_subscript_check ())
2133 end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0,
2134 char_name);
5ff904cd 2135 end_tree = convert (ffecom_f2c_ftnlen_type_node,
6b55276e 2136 end_tree);
5ff904cd
JL
2137
2138 if (end_tree == error_mark_node)
2139 {
2140 item = *length = error_mark_node;
2141 break;
2142 }
2143
2144 *length = end_tree;
2145 }
2146 }
2147 else
2148 {
6b55276e
CB
2149 start_tree = ffecom_expr (start);
2150 if (ffe_is_subscript_check ())
2151 start_tree = ffecom_subscript_check_ (array, start_tree, 0, 0,
2152 char_name);
5ff904cd 2153 start_tree = convert (ffecom_f2c_ftnlen_type_node,
6b55276e 2154 start_tree);
5ff904cd
JL
2155
2156 if (start_tree == error_mark_node)
2157 {
2158 item = *length = error_mark_node;
2159 break;
2160 }
2161
2162 start_tree = ffecom_save_tree (start_tree);
2163
2164 item = ffecom_2 (PLUS_EXPR, TREE_TYPE (item),
2165 item,
2166 ffecom_2 (MINUS_EXPR,
2167 TREE_TYPE (start_tree),
2168 start_tree,
2169 ffecom_f2c_ftnlen_one_node));
2170
2171 if (end == NULL)
2172 {
2173 *length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
2174 ffecom_f2c_ftnlen_one_node,
2175 ffecom_2 (MINUS_EXPR,
2176 ffecom_f2c_ftnlen_type_node,
2177 *length,
2178 start_tree));
2179 }
2180 else
2181 {
6b55276e
CB
2182 end_tree = ffecom_expr (end);
2183 if (ffe_is_subscript_check ())
2184 end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0,
2185 char_name);
5ff904cd 2186 end_tree = convert (ffecom_f2c_ftnlen_type_node,
6b55276e 2187 end_tree);
5ff904cd
JL
2188
2189 if (end_tree == error_mark_node)
2190 {
2191 item = *length = error_mark_node;
2192 break;
2193 }
2194
2195 *length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
2196 ffecom_f2c_ftnlen_one_node,
2197 ffecom_2 (MINUS_EXPR,
2198 ffecom_f2c_ftnlen_type_node,
2199 end_tree, start_tree));
2200 }
2201 }
2202 }
2203 break;
2204
2205 case FFEBLD_opFUNCREF:
2206 {
2207 ffesymbol s = ffebld_symter (ffebld_left (expr));
2208 tree tempvar;
2209 tree args;
2210 ffetargetCharacterSize size = ffeinfo_size (ffebld_info (expr));
2211 ffecomGfrt ix;
2212
2213 if (size == FFETARGET_charactersizeNONE)
c7e4ee3a
CB
2214 /* ~~Kludge alert! This should someday be fixed. */
2215 size = 24;
5ff904cd
JL
2216
2217 *length = build_int_2 (size, 0);
2218 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
2219
2220 if (ffeinfo_where (ffebld_info (ffebld_left (expr)))
2221 == FFEINFO_whereINTRINSIC)
2222 {
2223 if (size == 1)
c7e4ee3a
CB
2224 {
2225 /* Invocation of an intrinsic returning CHARACTER*1. */
5ff904cd
JL
2226 item = ffecom_expr_intrinsic_ (expr, NULL_TREE,
2227 NULL, NULL);
2228 break;
2229 }
2230 ix = ffeintrin_gfrt_direct (ffebld_symter_implementation (ffebld_left (expr)));
2231 assert (ix != FFECOM_gfrt);
2232 item = ffecom_gfrt_tree_ (ix);
2233 }
2234 else
2235 {
2236 ix = FFECOM_gfrt;
2237 item = ffesymbol_hook (s).decl_tree;
2238 if (item == NULL_TREE)
2239 {
2240 s = ffecom_sym_transform_ (s);
2241 item = ffesymbol_hook (s).decl_tree;
2242 }
2243 if (item == error_mark_node)
2244 {
2245 item = *length = error_mark_node;
2246 break;
2247 }
2248
2249 if (!ffesymbol_hook (s).addr)
2250 item = ffecom_1_fn (item);
2251 }
2252
c7e4ee3a 2253#ifdef HOHO
5ff904cd 2254 tempvar = ffecom_push_tempvar (char_type_node, size, -1, TRUE);
c7e4ee3a
CB
2255#else
2256 tempvar = ffebld_nonter_hook (expr);
2257 assert (tempvar);
2258#endif
5ff904cd
JL
2259 tempvar = ffecom_1 (ADDR_EXPR,
2260 build_pointer_type (TREE_TYPE (tempvar)),
2261 tempvar);
2262
5ff904cd
JL
2263 args = build_tree_list (NULL_TREE, tempvar);
2264
2265 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT) /* Sfunc args by value. */
2266 TREE_CHAIN (args) = ffecom_list_expr (ffebld_right (expr));
2267 else
2268 {
2269 TREE_CHAIN (args) = build_tree_list (NULL_TREE, *length);
2270 if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC)
2271 {
2272 TREE_CHAIN (TREE_CHAIN (args))
2273 = ffecom_arglist_expr_ (ffecom_gfrt_args_ (ix),
2274 ffebld_right (expr));
2275 }
2276 else
2277 {
2278 TREE_CHAIN (TREE_CHAIN (args))
2279 = ffecom_list_ptr_to_expr (ffebld_right (expr));
2280 }
2281 }
2282
2283 item = ffecom_3s (CALL_EXPR,
2284 TREE_TYPE (TREE_TYPE (TREE_TYPE (item))),
2285 item, args, NULL_TREE);
2286 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), item,
2287 tempvar);
5ff904cd
JL
2288 }
2289 break;
2290
2291 case FFEBLD_opCONVERT:
2292
5ff904cd 2293 ffecom_char_args_ (&item, length, ffebld_left (expr));
5ff904cd
JL
2294
2295 if (item == error_mark_node || *length == error_mark_node)
2296 {
2297 item = *length = error_mark_node;
2298 break;
2299 }
2300
2301 if ((ffebld_size_known (ffebld_left (expr))
2302 == FFETARGET_charactersizeNONE)
2303 || (ffebld_size_known (ffebld_left (expr)) < (ffebld_size (expr))))
2304 { /* Possible blank-padding needed, copy into
2305 temporary. */
2306 tree tempvar;
2307 tree args;
2308 tree newlen;
2309
c7e4ee3a
CB
2310#ifdef HOHO
2311 tempvar = ffecom_make_tempvar (char_type_node,
2312 ffebld_size (expr), -1);
2313#else
2314 tempvar = ffebld_nonter_hook (expr);
2315 assert (tempvar);
2316#endif
5ff904cd
JL
2317 tempvar = ffecom_1 (ADDR_EXPR,
2318 build_pointer_type (TREE_TYPE (tempvar)),
2319 tempvar);
2320
2321 newlen = build_int_2 (ffebld_size (expr), 0);
2322 TREE_TYPE (newlen) = ffecom_f2c_ftnlen_type_node;
2323
2324 args = build_tree_list (NULL_TREE, tempvar);
2325 TREE_CHAIN (args) = build_tree_list (NULL_TREE, item);
2326 TREE_CHAIN (TREE_CHAIN (args)) = build_tree_list (NULL_TREE, newlen);
2327 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (args)))
2328 = build_tree_list (NULL_TREE, *length);
2329
c7e4ee3a 2330 item = ffecom_call_gfrt (FFECOM_gfrtCOPY, args, NULL_TREE);
5ff904cd
JL
2331 TREE_SIDE_EFFECTS (item) = 1;
2332 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), fold (item),
2333 tempvar);
2334 *length = newlen;
2335 }
2336 else
2337 { /* Just truncate the length. */
2338 *length = build_int_2 (ffebld_size (expr), 0);
2339 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
2340 }
2341 break;
2342
2343 default:
2344 assert ("bad op for single char arg expr" == NULL);
2345 item = NULL_TREE;
2346 break;
2347 }
2348
2349 *xitem = item;
2350}
2351#endif
2352
2353/* Check the size of the type to be sure it doesn't overflow the
2354 "portable" capacities of the compiler back end. `dummy' types
2355 can generally overflow the normal sizes as long as the computations
2356 themselves don't overflow. A particular target of the back end
2357 must still enforce its size requirements, though, and the back
2358 end takes care of this in stor-layout.c. */
2359
2360#if FFECOM_targetCURRENT == FFECOM_targetGCC
2361static tree
2362ffecom_check_size_overflow_ (ffesymbol s, tree type, bool dummy)
2363{
2364 if (TREE_CODE (type) == ERROR_MARK)
2365 return type;
2366
2367 if (TYPE_SIZE (type) == NULL_TREE)
2368 return type;
2369
2370 if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
2371 return type;
2372
2373 if ((tree_int_cst_sgn (TYPE_SIZE (type)) < 0)
2b0c2df0
CB
2374 || (!dummy && (((TREE_INT_CST_HIGH (TYPE_SIZE (type)) != 0))
2375 || TREE_OVERFLOW (TYPE_SIZE (type)))))
5ff904cd
JL
2376 {
2377 ffebad_start (FFEBAD_ARRAY_LARGE);
2378 ffebad_string (ffesymbol_text (s));
2379 ffebad_here (0, ffesymbol_where_line (s), ffesymbol_where_column (s));
2380 ffebad_finish ();
2381
2382 return error_mark_node;
2383 }
2384
2385 return type;
2386}
2387#endif
2388
2389/* Builds a length argument (PARM_DECL). Also wraps type in an array type
2390 where the dimension info is (1:size) where <size> is ffesymbol_size(s) if
2391 known, length_arg if not known (FFETARGET_charactersizeNONE). */
2392
2393#if FFECOM_targetCURRENT == FFECOM_targetGCC
2394static tree
2395ffecom_char_enhance_arg_ (tree *xtype, ffesymbol s)
2396{
2397 ffetargetCharacterSize sz = ffesymbol_size (s);
2398 tree highval;
2399 tree tlen;
2400 tree type = *xtype;
2401
2402 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT)
2403 tlen = NULL_TREE; /* A statement function, no length passed. */
2404 else
2405 {
2406 if (ffesymbol_where (s) == FFEINFO_whereDUMMY)
2407 tlen = ffecom_get_invented_identifier ("__g77_length_%s",
c7e4ee3a 2408 ffesymbol_text (s), -1);
5ff904cd
JL
2409 else
2410 tlen = ffecom_get_invented_identifier ("__g77_%s",
c7e4ee3a 2411 "length", -1);
5ff904cd
JL
2412 tlen = build_decl (PARM_DECL, tlen, ffecom_f2c_ftnlen_type_node);
2413#if BUILT_FOR_270
2414 DECL_ARTIFICIAL (tlen) = 1;
2415#endif
2416 }
2417
2418 if (sz == FFETARGET_charactersizeNONE)
2419 {
2420 assert (tlen != NULL_TREE);
2b0c2df0 2421 highval = variable_size (tlen);
5ff904cd
JL
2422 }
2423 else
2424 {
2425 highval = build_int_2 (sz, 0);
2426 TREE_TYPE (highval) = ffecom_f2c_ftnlen_type_node;
2427 }
2428
2429 type = build_array_type (type,
2430 build_range_type (ffecom_f2c_ftnlen_type_node,
2431 ffecom_f2c_ftnlen_one_node,
2432 highval));
2433
2434 *xtype = type;
2435 return tlen;
2436}
2437
2438#endif
2439/* ffecom_concat_list_gather_ -- Gather list of concatenated string exprs
2440
2441 ffecomConcatList_ catlist;
2442 ffebld expr; // expr of CHARACTER basictype.
2443 ffetargetCharacterSize max; // max chars to gather or _...NONE if no max
2444 catlist = ffecom_concat_list_gather_(catlist,expr,max);
2445
2446 Scans expr for character subexpressions, updates and returns catlist
2447 accordingly. */
2448
2449#if FFECOM_targetCURRENT == FFECOM_targetGCC
2450static ffecomConcatList_
2451ffecom_concat_list_gather_ (ffecomConcatList_ catlist, ffebld expr,
2452 ffetargetCharacterSize max)
2453{
2454 ffetargetCharacterSize sz;
2455
2456recurse: /* :::::::::::::::::::: */
2457
2458 if (expr == NULL)
2459 return catlist;
2460
2461 if ((max != FFETARGET_charactersizeNONE) && (catlist.minlen >= max))
2462 return catlist; /* Don't append any more items. */
2463
2464 switch (ffebld_op (expr))
2465 {
2466 case FFEBLD_opCONTER:
2467 case FFEBLD_opSYMTER:
2468 case FFEBLD_opARRAYREF:
2469 case FFEBLD_opFUNCREF:
2470 case FFEBLD_opSUBSTR:
2471 case FFEBLD_opCONVERT: /* Callers should strip this off beforehand
2472 if they don't need to preserve it. */
2473 if (catlist.count == catlist.max)
2474 { /* Make a (larger) list. */
2475 ffebld *newx;
2476 int newmax;
2477
2478 newmax = (catlist.max == 0) ? 8 : catlist.max * 2;
2479 newx = malloc_new_ks (malloc_pool_image (), "catlist",
2480 newmax * sizeof (newx[0]));
2481 if (catlist.max != 0)
2482 {
2483 memcpy (newx, catlist.exprs, catlist.max * sizeof (newx[0]));
2484 malloc_kill_ks (malloc_pool_image (), catlist.exprs,
2485 catlist.max * sizeof (newx[0]));
2486 }
2487 catlist.max = newmax;
2488 catlist.exprs = newx;
2489 }
2490 if ((sz = ffebld_size_known (expr)) != FFETARGET_charactersizeNONE)
2491 catlist.minlen += sz;
2492 else
2493 ++catlist.minlen; /* Not true for F90; can be 0 length. */
2494 if ((sz = ffebld_size_max (expr)) == FFETARGET_charactersizeNONE)
2495 catlist.maxlen = sz;
2496 else
2497 catlist.maxlen += sz;
2498 if ((max != FFETARGET_charactersizeNONE) && (catlist.minlen > max))
2499 { /* This item overlaps (or is beyond) the end
2500 of the destination. */
2501 switch (ffebld_op (expr))
2502 {
2503 case FFEBLD_opCONTER:
2504 case FFEBLD_opSYMTER:
2505 case FFEBLD_opARRAYREF:
2506 case FFEBLD_opFUNCREF:
2507 case FFEBLD_opSUBSTR:
c7e4ee3a
CB
2508 /* ~~Do useful truncations here. */
2509 break;
5ff904cd
JL
2510
2511 default:
2512 assert ("op changed or inconsistent switches!" == NULL);
2513 break;
2514 }
2515 }
2516 catlist.exprs[catlist.count++] = expr;
2517 return catlist;
2518
2519 case FFEBLD_opPAREN:
2520 expr = ffebld_left (expr);
2521 goto recurse; /* :::::::::::::::::::: */
2522
2523 case FFEBLD_opCONCATENATE:
2524 catlist = ffecom_concat_list_gather_ (catlist, ffebld_left (expr), max);
2525 expr = ffebld_right (expr);
2526 goto recurse; /* :::::::::::::::::::: */
2527
2528#if 0 /* Breaks passing small actual arg to larger
2529 dummy arg of sfunc */
2530 case FFEBLD_opCONVERT:
2531 expr = ffebld_left (expr);
2532 {
2533 ffetargetCharacterSize cmax;
2534
2535 cmax = catlist.len + ffebld_size_known (expr);
2536
2537 if ((max == FFETARGET_charactersizeNONE) || (max > cmax))
2538 max = cmax;
2539 }
2540 goto recurse; /* :::::::::::::::::::: */
2541#endif
2542
2543 case FFEBLD_opANY:
2544 return catlist;
2545
2546 default:
2547 assert ("bad op in _gather_" == NULL);
2548 return catlist;
2549 }
2550}
2551
2552#endif
2553/* ffecom_concat_list_kill_ -- Kill list of concatenated string exprs
2554
2555 ffecomConcatList_ catlist;
2556 ffecom_concat_list_kill_(catlist);
2557
2558 Anything allocated within the list info is deallocated. */
2559
2560#if FFECOM_targetCURRENT == FFECOM_targetGCC
2561static void
2562ffecom_concat_list_kill_ (ffecomConcatList_ catlist)
2563{
2564 if (catlist.max != 0)
2565 malloc_kill_ks (malloc_pool_image (), catlist.exprs,
2566 catlist.max * sizeof (catlist.exprs[0]));
2567}
2568
2569#endif
c7e4ee3a 2570/* Make list of concatenated string exprs.
5ff904cd
JL
2571
2572 Returns a flattened list of concatenated subexpressions given a
2573 tree of such expressions. */
2574
2575#if FFECOM_targetCURRENT == FFECOM_targetGCC
2576static ffecomConcatList_
2577ffecom_concat_list_new_ (ffebld expr, ffetargetCharacterSize max)
2578{
2579 ffecomConcatList_ catlist;
2580
2581 catlist.maxlen = catlist.minlen = catlist.max = catlist.count = 0;
2582 return ffecom_concat_list_gather_ (catlist, expr, max);
2583}
2584
2585#endif
2586
2587/* Provide some kind of useful info on member of aggregate area,
2588 since current g77/gcc technology does not provide debug info
2589 on these members. */
2590
2591#if FFECOM_targetCURRENT == FFECOM_targetGCC
2592static void
26f096f9 2593ffecom_debug_kludge_ (tree aggr, const char *aggr_type, ffesymbol member,
5ff904cd
JL
2594 tree member_type UNUSED, ffetargetOffset offset)
2595{
2596 tree value;
2597 tree decl;
2598 int len;
2599 char *buff;
2600 char space[120];
2601#if 0
2602 tree type_id;
2603
2604 for (type_id = member_type;
2605 TREE_CODE (type_id) != IDENTIFIER_NODE;
2606 )
2607 {
2608 switch (TREE_CODE (type_id))
2609 {
2610 case INTEGER_TYPE:
2611 case REAL_TYPE:
2612 type_id = TYPE_NAME (type_id);
2613 break;
2614
2615 case ARRAY_TYPE:
2616 case COMPLEX_TYPE:
2617 type_id = TREE_TYPE (type_id);
2618 break;
2619
2620 default:
2621 assert ("no IDENTIFIER_NODE for type!" == NULL);
2622 type_id = error_mark_node;
2623 break;
2624 }
2625 }
2626#endif
2627
2628 if (ffecom_transform_only_dummies_
2629 || !ffe_is_debug_kludge ())
2630 return; /* Can't do this yet, maybe later. */
2631
2632 len = 60
2633 + strlen (aggr_type)
2634 + IDENTIFIER_LENGTH (DECL_NAME (aggr));
2635#if 0
2636 + IDENTIFIER_LENGTH (type_id);
2637#endif
2638
2639 if (((size_t) len) >= ARRAY_SIZE (space))
2640 buff = malloc_new_ks (malloc_pool_image (), "debug_kludge", len + 1);
2641 else
2642 buff = &space[0];
2643
2644 sprintf (&buff[0], "At (%s) `%s' plus %ld bytes",
2645 aggr_type,
2646 IDENTIFIER_POINTER (DECL_NAME (aggr)),
2647 (long int) offset);
2648
2649 value = build_string (len, buff);
2650 TREE_TYPE (value)
2651 = build_type_variant (build_array_type (char_type_node,
2652 build_range_type
2653 (integer_type_node,
2654 integer_one_node,
2655 build_int_2 (strlen (buff), 0))),
2656 1, 0);
2657 decl = build_decl (VAR_DECL,
2658 ffecom_get_identifier_ (ffesymbol_text (member)),
2659 TREE_TYPE (value));
2660 TREE_CONSTANT (decl) = 1;
2661 TREE_STATIC (decl) = 1;
2662 DECL_INITIAL (decl) = error_mark_node;
2663 DECL_IN_SYSTEM_HEADER (decl) = 1; /* Don't let -Wunused complain. */
2664 decl = start_decl (decl, FALSE);
2665 finish_decl (decl, value, FALSE);
2666
2667 if (buff != &space[0])
2668 malloc_kill_ks (malloc_pool_image (), buff, len + 1);
2669}
2670#endif
2671
2672/* ffecom_do_entry_ -- Do compilation of a particular entrypoint
2673
2674 ffesymbol fn; // the SUBROUTINE, FUNCTION, or ENTRY symbol itself
2675 int i; // entry# for this entrypoint (used by master fn)
2676 ffecom_do_entrypoint_(s,i);
2677
2678 Makes a public entry point that calls our private master fn (already
2679 compiled). */
2680
2681#if FFECOM_targetCURRENT == FFECOM_targetGCC
2682static void
2683ffecom_do_entry_ (ffesymbol fn, int entrynum)
2684{
2685 ffebld item;
2686 tree type; /* Type of function. */
2687 tree multi_retval; /* Var holding return value (union). */
2688 tree result; /* Var holding result. */
2689 ffeinfoBasictype bt;
2690 ffeinfoKindtype kt;
2691 ffeglobal g;
2692 ffeglobalType gt;
2693 bool charfunc; /* All entry points return same type
2694 CHARACTER. */
2695 bool cmplxfunc; /* Use f2c way of returning COMPLEX. */
2696 bool multi; /* Master fn has multiple return types. */
2697 bool altreturning = FALSE; /* This entry point has alternate returns. */
2698 int yes;
44d2eabc
JL
2699 int old_lineno = lineno;
2700 char *old_input_filename = input_filename;
2701
2702 input_filename = ffesymbol_where_filename (fn);
2703 lineno = ffesymbol_where_filelinenum (fn);
5ff904cd
JL
2704
2705 /* c-parse.y indeed does call suspend_momentary and not only ignores the
2706 return value, but also never calls resume_momentary, when starting an
2707 outer function (see "fndef:", "setspecs:", and so on). So g77 does the
2708 same thing. It shouldn't be a problem since start_function calls
2709 temporary_allocation, but it might be necessary. If it causes a problem
2710 here, then maybe there's a bug lurking in gcc. NOTE: This identical
2711 comment appears twice in thist file. */
2712
2713 suspend_momentary ();
2714
2715 ffecom_doing_entry_ = TRUE; /* Don't bother with array dimensions. */
2716
2717 switch (ffecom_primary_entry_kind_)
2718 {
2719 case FFEINFO_kindFUNCTION:
2720
2721 /* Determine actual return type for function. */
2722
2723 gt = FFEGLOBAL_typeFUNC;
2724 bt = ffesymbol_basictype (fn);
2725 kt = ffesymbol_kindtype (fn);
2726 if (bt == FFEINFO_basictypeNONE)
2727 {
2728 ffeimplic_establish_symbol (fn);
2729 if (ffesymbol_funcresult (fn) != NULL)
2730 ffeimplic_establish_symbol (ffesymbol_funcresult (fn));
2731 bt = ffesymbol_basictype (fn);
2732 kt = ffesymbol_kindtype (fn);
2733 }
2734
2735 if (bt == FFEINFO_basictypeCHARACTER)
2736 charfunc = TRUE, cmplxfunc = FALSE;
2737 else if ((bt == FFEINFO_basictypeCOMPLEX)
2738 && ffesymbol_is_f2c (fn))
2739 charfunc = FALSE, cmplxfunc = TRUE;
2740 else
2741 charfunc = cmplxfunc = FALSE;
2742
2743 if (charfunc)
2744 type = ffecom_tree_fun_type_void;
2745 else if (ffesymbol_is_f2c (fn))
2746 type = ffecom_tree_fun_type[bt][kt];
2747 else
2748 type = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
2749
2750 if ((type == NULL_TREE)
2751 || (TREE_TYPE (type) == NULL_TREE))
2752 type = ffecom_tree_fun_type_void; /* _sym_exec_transition. */
2753
2754 multi = (ffecom_master_bt_ == FFEINFO_basictypeNONE);
2755 break;
2756
2757 case FFEINFO_kindSUBROUTINE:
2758 gt = FFEGLOBAL_typeSUBR;
2759 bt = FFEINFO_basictypeNONE;
2760 kt = FFEINFO_kindtypeNONE;
2761 if (ffecom_is_altreturning_)
2762 { /* Am _I_ altreturning? */
2763 for (item = ffesymbol_dummyargs (fn);
2764 item != NULL;
2765 item = ffebld_trail (item))
2766 {
2767 if (ffebld_op (ffebld_head (item)) == FFEBLD_opSTAR)
2768 {
2769 altreturning = TRUE;
2770 break;
2771 }
2772 }
2773 if (altreturning)
2774 type = ffecom_tree_subr_type;
2775 else
2776 type = ffecom_tree_fun_type_void;
2777 }
2778 else
2779 type = ffecom_tree_fun_type_void;
2780 charfunc = FALSE;
2781 cmplxfunc = FALSE;
2782 multi = FALSE;
2783 break;
2784
2785 default:
2786 assert ("say what??" == NULL);
2787 /* Fall through. */
2788 case FFEINFO_kindANY:
2789 gt = FFEGLOBAL_typeANY;
2790 bt = FFEINFO_basictypeNONE;
2791 kt = FFEINFO_kindtypeNONE;
2792 type = error_mark_node;
2793 charfunc = FALSE;
2794 cmplxfunc = FALSE;
2795 multi = FALSE;
2796 break;
2797 }
2798
2799 /* build_decl uses the current lineno and input_filename to set the decl
2800 source info. So, I've putzed with ffestd and ffeste code to update that
2801 source info to point to the appropriate statement just before calling
2802 ffecom_do_entrypoint (which calls this fn). */
2803
2804 start_function (ffecom_get_external_identifier_ (fn),
2805 type,
2806 0, /* nested/inline */
2807 1); /* TREE_PUBLIC */
2808
2809 if (((g = ffesymbol_global (fn)) != NULL)
2810 && ((ffeglobal_type (g) == gt)
2811 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
2812 {
2813 ffeglobal_set_hook (g, current_function_decl);
2814 }
2815
2816 /* Reset args in master arg list so they get retransitioned. */
2817
2818 for (item = ffecom_master_arglist_;
2819 item != NULL;
2820 item = ffebld_trail (item))
2821 {
2822 ffebld arg;
2823 ffesymbol s;
2824
2825 arg = ffebld_head (item);
2826 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2827 continue; /* Alternate return or some such thing. */
2828 s = ffebld_symter (arg);
2829 ffesymbol_hook (s).decl_tree = NULL_TREE;
2830 ffesymbol_hook (s).length_tree = NULL_TREE;
2831 }
2832
2833 /* Build dummy arg list for this entry point. */
2834
2835 yes = suspend_momentary ();
2836
2837 if (charfunc || cmplxfunc)
2838 { /* Prepend arg for where result goes. */
2839 tree type;
2840 tree length;
2841
2842 if (charfunc)
2843 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
2844 else
2845 type = ffecom_tree_type[FFEINFO_basictypeCOMPLEX][kt];
2846
2847 result = ffecom_get_invented_identifier ("__g77_%s",
c7e4ee3a 2848 "result", -1);
5ff904cd
JL
2849
2850 /* Make length arg _and_ enhance type info for CHAR arg itself. */
2851
2852 if (charfunc)
2853 length = ffecom_char_enhance_arg_ (&type, fn);
2854 else
2855 length = NULL_TREE; /* Not ref'd if !charfunc. */
2856
2857 type = build_pointer_type (type);
2858 result = build_decl (PARM_DECL, result, type);
2859
2860 push_parm_decl (result);
2861 ffecom_func_result_ = result;
2862
2863 if (charfunc)
2864 {
2865 push_parm_decl (length);
2866 ffecom_func_length_ = length;
2867 }
2868 }
2869 else
2870 result = DECL_RESULT (current_function_decl);
2871
2872 ffecom_push_dummy_decls_ (ffesymbol_dummyargs (fn), FALSE);
2873
2874 resume_momentary (yes);
2875
2876 store_parm_decls (0);
2877
c7e4ee3a
CB
2878 ffecom_start_compstmt ();
2879 /* Disallow temp vars at this level. */
2880 current_binding_level->prep_state = 2;
5ff904cd
JL
2881
2882 /* Make local var to hold return type for multi-type master fn. */
2883
2884 if (multi)
2885 {
2886 yes = suspend_momentary ();
2887
2888 multi_retval = ffecom_get_invented_identifier ("__g77_%s",
c7e4ee3a 2889 "multi_retval", -1);
5ff904cd
JL
2890 multi_retval = build_decl (VAR_DECL, multi_retval,
2891 ffecom_multi_type_node_);
2892 multi_retval = start_decl (multi_retval, FALSE);
2893 finish_decl (multi_retval, NULL_TREE, FALSE);
2894
2895 resume_momentary (yes);
2896 }
2897 else
2898 multi_retval = NULL_TREE; /* Not actually ref'd if !multi. */
2899
2900 /* Here we emit the actual code for the entry point. */
2901
2902 {
2903 ffebld list;
2904 ffebld arg;
2905 ffesymbol s;
2906 tree arglist = NULL_TREE;
2907 tree *plist = &arglist;
2908 tree prepend;
2909 tree call;
2910 tree actarg;
2911 tree master_fn;
2912
2913 /* Prepare actual arg list based on master arg list. */
2914
2915 for (list = ffecom_master_arglist_;
2916 list != NULL;
2917 list = ffebld_trail (list))
2918 {
2919 arg = ffebld_head (list);
2920 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2921 continue;
2922 s = ffebld_symter (arg);
702edf1d
CB
2923 if (ffesymbol_hook (s).decl_tree == NULL_TREE
2924 || ffesymbol_hook (s).decl_tree == error_mark_node)
5ff904cd
JL
2925 actarg = null_pointer_node; /* We don't have this arg. */
2926 else
2927 actarg = ffesymbol_hook (s).decl_tree;
2928 *plist = build_tree_list (NULL_TREE, actarg);
2929 plist = &TREE_CHAIN (*plist);
2930 }
2931
2932 /* This code appends the length arguments for character
2933 variables/arrays. */
2934
2935 for (list = ffecom_master_arglist_;
2936 list != NULL;
2937 list = ffebld_trail (list))
2938 {
2939 arg = ffebld_head (list);
2940 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2941 continue;
2942 s = ffebld_symter (arg);
2943 if (ffesymbol_basictype (s) != FFEINFO_basictypeCHARACTER)
2944 continue; /* Only looking for CHARACTER arguments. */
2945 if (ffesymbol_kind (s) != FFEINFO_kindENTITY)
2946 continue; /* Only looking for variables and arrays. */
702edf1d
CB
2947 if (ffesymbol_hook (s).length_tree == NULL_TREE
2948 || ffesymbol_hook (s).length_tree == error_mark_node)
5ff904cd
JL
2949 actarg = ffecom_f2c_ftnlen_zero_node; /* We don't have this arg. */
2950 else
2951 actarg = ffesymbol_hook (s).length_tree;
2952 *plist = build_tree_list (NULL_TREE, actarg);
2953 plist = &TREE_CHAIN (*plist);
2954 }
2955
2956 /* Prepend character-value return info to actual arg list. */
2957
2958 if (charfunc)
2959 {
2960 prepend = build_tree_list (NULL_TREE, ffecom_func_result_);
2961 TREE_CHAIN (prepend)
2962 = build_tree_list (NULL_TREE, ffecom_func_length_);
2963 TREE_CHAIN (TREE_CHAIN (prepend)) = arglist;
2964 arglist = prepend;
2965 }
2966
2967 /* Prepend multi-type return value to actual arg list. */
2968
2969 if (multi)
2970 {
2971 prepend
2972 = build_tree_list (NULL_TREE,
2973 ffecom_1 (ADDR_EXPR,
2974 build_pointer_type (TREE_TYPE (multi_retval)),
2975 multi_retval));
2976 TREE_CHAIN (prepend) = arglist;
2977 arglist = prepend;
2978 }
2979
2980 /* Prepend my entry-point number to the actual arg list. */
2981
2982 prepend = build_tree_list (NULL_TREE, build_int_2 (entrynum, 0));
2983 TREE_CHAIN (prepend) = arglist;
2984 arglist = prepend;
2985
2986 /* Build the call to the master function. */
2987
2988 master_fn = ffecom_1_fn (ffecom_previous_function_decl_);
2989 call = ffecom_3s (CALL_EXPR,
2990 TREE_TYPE (TREE_TYPE (TREE_TYPE (master_fn))),
2991 master_fn, arglist, NULL_TREE);
2992
2993 /* Decide whether the master function is a function or subroutine, and
2994 handle the return value for my entry point. */
2995
2996 if (charfunc || ((ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE)
2997 && !altreturning))
2998 {
2999 expand_expr_stmt (call);
3000 expand_null_return ();
3001 }
3002 else if (multi && cmplxfunc)
3003 {
3004 expand_expr_stmt (call);
3005 result
3006 = ffecom_1 (INDIRECT_REF,
3007 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result))),
3008 result);
3009 result = ffecom_modify (NULL_TREE, result,
3010 ffecom_2 (COMPONENT_REF, TREE_TYPE (result),
3011 multi_retval,
3012 ffecom_multi_fields_[bt][kt]));
3013 expand_expr_stmt (result);
3014 expand_null_return ();
3015 }
3016 else if (multi)
3017 {
3018 expand_expr_stmt (call);
3019 result
3020 = ffecom_modify (NULL_TREE, result,
3021 convert (TREE_TYPE (result),
3022 ffecom_2 (COMPONENT_REF,
3023 ffecom_tree_type[bt][kt],
3024 multi_retval,
3025 ffecom_multi_fields_[bt][kt])));
3026 expand_return (result);
3027 }
3028 else if (cmplxfunc)
3029 {
3030 result
3031 = ffecom_1 (INDIRECT_REF,
3032 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result))),
3033 result);
3034 result = ffecom_modify (NULL_TREE, result, call);
3035 expand_expr_stmt (result);
3036 expand_null_return ();
3037 }
3038 else
3039 {
3040 result = ffecom_modify (NULL_TREE,
3041 result,
3042 convert (TREE_TYPE (result),
3043 call));
3044 expand_return (result);
3045 }
3046
3047 clear_momentary ();
3048 }
3049
c7e4ee3a 3050 ffecom_end_compstmt ();
5ff904cd
JL
3051
3052 finish_function (0);
3053
44d2eabc
JL
3054 lineno = old_lineno;
3055 input_filename = old_input_filename;
3056
5ff904cd
JL
3057 ffecom_doing_entry_ = FALSE;
3058}
3059
3060#endif
3061/* Transform expr into gcc tree with possible destination
3062
3063 Recursive descent on expr while making corresponding tree nodes and
3064 attaching type info and such. If destination supplied and compatible
3065 with temporary that would be made in certain cases, temporary isn't
092a4ef8 3066 made, destination used instead, and dest_used flag set TRUE. */
5ff904cd
JL
3067
3068#if FFECOM_targetCURRENT == FFECOM_targetGCC
3069static tree
092a4ef8
RH
3070ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest,
3071 bool *dest_used, bool assignp, bool widenp)
5ff904cd
JL
3072{
3073 tree item;
3074 tree list;
3075 tree args;
3076 ffeinfoBasictype bt;
3077 ffeinfoKindtype kt;
3078 tree t;
5ff904cd 3079 tree dt; /* decl_tree for an ffesymbol. */
092a4ef8 3080 tree tree_type, tree_type_x;
af752698 3081 tree left, right;
5ff904cd
JL
3082 ffesymbol s;
3083 enum tree_code code;
3084
3085 assert (expr != NULL);
3086
3087 if (dest_used != NULL)
3088 *dest_used = FALSE;
3089
3090 bt = ffeinfo_basictype (ffebld_info (expr));
3091 kt = ffeinfo_kindtype (ffebld_info (expr));
af752698 3092 tree_type = ffecom_tree_type[bt][kt];
5ff904cd 3093
092a4ef8
RH
3094 /* Widen integral arithmetic as desired while preserving signedness. */
3095 tree_type_x = NULL_TREE;
3096 if (widenp && tree_type
3097 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
3098 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
3099 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
3100
5ff904cd
JL
3101 switch (ffebld_op (expr))
3102 {
3103 case FFEBLD_opACCTER:
5ff904cd
JL
3104 {
3105 ffebitCount i;
3106 ffebit bits = ffebld_accter_bits (expr);
3107 ffetargetOffset source_offset = 0;
a6fa6420 3108 ffetargetOffset dest_offset = ffebld_accter_pad (expr);
5ff904cd
JL
3109 tree purpose;
3110
a6fa6420
CB
3111 assert (dest_offset == 0
3112 || (bt == FFEINFO_basictypeCHARACTER
3113 && kt == FFEINFO_kindtypeCHARACTER1));
5ff904cd
JL
3114
3115 list = item = NULL;
3116 for (;;)
3117 {
3118 ffebldConstantUnion cu;
3119 ffebitCount length;
3120 bool value;
3121 ffebldConstantArray ca = ffebld_accter (expr);
3122
3123 ffebit_test (bits, source_offset, &value, &length);
3124 if (length == 0)
3125 break;
3126
3127 if (value)
3128 {
3129 for (i = 0; i < length; ++i)
3130 {
3131 cu = ffebld_constantarray_get (ca, bt, kt,
3132 source_offset + i);
3133
3134 t = ffecom_constantunion (&cu, bt, kt, tree_type);
3135
a6fa6420
CB
3136 if (i == 0
3137 && dest_offset != 0)
3138 purpose = build_int_2 (dest_offset, 0);
5ff904cd
JL
3139 else
3140 purpose = NULL_TREE;
3141
3142 if (list == NULL_TREE)
3143 list = item = build_tree_list (purpose, t);
3144 else
3145 {
3146 TREE_CHAIN (item) = build_tree_list (purpose, t);
3147 item = TREE_CHAIN (item);
3148 }
3149 }
3150 }
3151 source_offset += length;
a6fa6420 3152 dest_offset += length;
5ff904cd
JL
3153 }
3154 }
3155
a6fa6420
CB
3156 item = build_int_2 ((ffebld_accter_size (expr)
3157 + ffebld_accter_pad (expr)) - 1, 0);
5ff904cd
JL
3158 ffebit_kill (ffebld_accter_bits (expr));
3159 TREE_TYPE (item) = ffecom_integer_type_node;
3160 item
3161 = build_array_type
3162 (tree_type,
3163 build_range_type (ffecom_integer_type_node,
3164 ffecom_integer_zero_node,
3165 item));
3166 list = build (CONSTRUCTOR, item, NULL_TREE, list);
3167 TREE_CONSTANT (list) = 1;
3168 TREE_STATIC (list) = 1;
3169 return list;
3170
3171 case FFEBLD_opARRTER:
5ff904cd
JL
3172 {
3173 ffetargetOffset i;
3174
a6fa6420
CB
3175 list = NULL_TREE;
3176 if (ffebld_arrter_pad (expr) == 0)
3177 item = NULL_TREE;
3178 else
3179 {
3180 assert (bt == FFEINFO_basictypeCHARACTER
3181 && kt == FFEINFO_kindtypeCHARACTER1);
3182
3183 /* Becomes PURPOSE first time through loop. */
3184 item = build_int_2 (ffebld_arrter_pad (expr), 0);
3185 }
3186
5ff904cd
JL
3187 for (i = 0; i < ffebld_arrter_size (expr); ++i)
3188 {
3189 ffebldConstantUnion cu
3190 = ffebld_constantarray_get (ffebld_arrter (expr), bt, kt, i);
3191
3192 t = ffecom_constantunion (&cu, bt, kt, tree_type);
3193
3194 if (list == NULL_TREE)
a6fa6420
CB
3195 /* Assume item is PURPOSE first time through loop. */
3196 list = item = build_tree_list (item, t);
5ff904cd
JL
3197 else
3198 {
3199 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
3200 item = TREE_CHAIN (item);
3201 }
3202 }
3203 }
3204
a6fa6420
CB
3205 item = build_int_2 ((ffebld_arrter_size (expr)
3206 + ffebld_arrter_pad (expr)) - 1, 0);
5ff904cd
JL
3207 TREE_TYPE (item) = ffecom_integer_type_node;
3208 item
3209 = build_array_type
3210 (tree_type,
3211 build_range_type (ffecom_integer_type_node,
a6fa6420 3212 ffecom_integer_zero_node,
5ff904cd
JL
3213 item));
3214 list = build (CONSTRUCTOR, item, NULL_TREE, list);
3215 TREE_CONSTANT (list) = 1;
3216 TREE_STATIC (list) = 1;
3217 return list;
3218
3219 case FFEBLD_opCONTER:
c264f113 3220 assert (ffebld_conter_pad (expr) == 0);
5ff904cd
JL
3221 item
3222 = ffecom_constantunion (&ffebld_constant_union (ffebld_conter (expr)),
3223 bt, kt, tree_type);
3224 return item;
3225
3226 case FFEBLD_opSYMTER:
3227 if ((ffebld_symter_generic (expr) != FFEINTRIN_genNONE)
3228 || (ffebld_symter_specific (expr) != FFEINTRIN_specNONE))
3229 return ffecom_ptr_to_expr (expr); /* Same as %REF(intrinsic). */
3230 s = ffebld_symter (expr);
3231 t = ffesymbol_hook (s).decl_tree;
3232
3233 if (assignp)
3234 { /* ASSIGN'ed-label expr. */
3235 if (ffe_is_ugly_assign ())
3236 {
3237 /* User explicitly wants ASSIGN'ed variables to be at the same
3238 memory address as the variables when used in non-ASSIGN
3239 contexts. That can make old, arcane, non-standard code
3240 work, but don't try to do it when a pointer wouldn't fit
3241 in the normal variable (take other approach, and warn,
3242 instead). */
3243
3244 if (t == NULL_TREE)
3245 {
3246 s = ffecom_sym_transform_ (s);
3247 t = ffesymbol_hook (s).decl_tree;
3248 assert (t != NULL_TREE);
3249 }
3250
3251 if (t == error_mark_node)
3252 return t;
3253
3254 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (t)))
3255 >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
3256 {
3257 if (ffesymbol_hook (s).addr)
3258 t = ffecom_1 (INDIRECT_REF,
3259 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), t);
3260 return t;
3261 }
3262
3263 if (ffesymbol_hook (s).assign_tree == NULL_TREE)
3264 {
3265 ffebad_start_msg ("ASSIGN'ed label cannot fit into `%A' at %0 -- using wider sibling",
3266 FFEBAD_severityWARNING);
3267 ffebad_string (ffesymbol_text (s));
3268 ffebad_here (0, ffesymbol_where_line (s),
3269 ffesymbol_where_column (s));
3270 ffebad_finish ();
3271 }
3272 }
3273
3274 /* Don't use the normal variable's tree for ASSIGN, though mark
3275 it as in the system header (housekeeping). Use an explicit,
3276 specially created sibling that is known to be wide enough
3277 to hold pointers to labels. */
3278
3279 if (t != NULL_TREE
3280 && TREE_CODE (t) == VAR_DECL)
3281 DECL_IN_SYSTEM_HEADER (t) = 1; /* Don't let -Wunused complain. */
3282
3283 t = ffesymbol_hook (s).assign_tree;
3284 if (t == NULL_TREE)
3285 {
3286 s = ffecom_sym_transform_assign_ (s);
3287 t = ffesymbol_hook (s).assign_tree;
3288 assert (t != NULL_TREE);
3289 }
3290 }
3291 else
3292 {
3293 if (t == NULL_TREE)
3294 {
3295 s = ffecom_sym_transform_ (s);
3296 t = ffesymbol_hook (s).decl_tree;
3297 assert (t != NULL_TREE);
3298 }
3299 if (ffesymbol_hook (s).addr)
3300 t = ffecom_1 (INDIRECT_REF,
3301 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), t);
3302 }
3303 return t;
3304
3305 case FFEBLD_opARRAYREF:
ff852b44 3306 return ffecom_arrayref_ (NULL_TREE, expr, 0);
5ff904cd
JL
3307
3308 case FFEBLD_opUPLUS:
092a4ef8 3309 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
af752698 3310 return ffecom_1 (NOP_EXPR, tree_type, left);
5ff904cd 3311
c7e4ee3a
CB
3312 case FFEBLD_opPAREN:
3313 /* ~~~Make sure Fortran rules respected here */
092a4ef8 3314 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
af752698 3315 return ffecom_1 (NOP_EXPR, tree_type, left);
5ff904cd
JL
3316
3317 case FFEBLD_opUMINUS:
092a4ef8 3318 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
af752698
RH
3319 if (tree_type_x)
3320 {
3321 tree_type = tree_type_x;
3322 left = convert (tree_type, left);
3323 }
3324 return ffecom_1 (NEGATE_EXPR, tree_type, left);
5ff904cd
JL
3325
3326 case FFEBLD_opADD:
092a4ef8
RH
3327 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3328 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
af752698
RH
3329 if (tree_type_x)
3330 {
3331 tree_type = tree_type_x;
3332 left = convert (tree_type, left);
3333 right = convert (tree_type, right);
3334 }
3335 return ffecom_2 (PLUS_EXPR, tree_type, left, right);
5ff904cd
JL
3336
3337 case FFEBLD_opSUBTRACT:
092a4ef8
RH
3338 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3339 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
af752698
RH
3340 if (tree_type_x)
3341 {
3342 tree_type = tree_type_x;
3343 left = convert (tree_type, left);
3344 right = convert (tree_type, right);
3345 }
3346 return ffecom_2 (MINUS_EXPR, tree_type, left, right);
5ff904cd
JL
3347
3348 case FFEBLD_opMULTIPLY:
092a4ef8
RH
3349 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3350 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
af752698
RH
3351 if (tree_type_x)
3352 {
3353 tree_type = tree_type_x;
3354 left = convert (tree_type, left);
3355 right = convert (tree_type, right);
3356 }
3357 return ffecom_2 (MULT_EXPR, tree_type, left, right);
5ff904cd
JL
3358
3359 case FFEBLD_opDIVIDE:
092a4ef8
RH
3360 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3361 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
af752698
RH
3362 if (tree_type_x)
3363 {
3364 tree_type = tree_type_x;
3365 left = convert (tree_type, left);
3366 right = convert (tree_type, right);
3367 }
3368 return ffecom_tree_divide_ (tree_type, left, right,
c7e4ee3a
CB
3369 dest_tree, dest, dest_used,
3370 ffebld_nonter_hook (expr));
5ff904cd
JL
3371
3372 case FFEBLD_opPOWER:
5ff904cd
JL
3373 {
3374 ffebld left = ffebld_left (expr);
3375 ffebld right = ffebld_right (expr);
3376 ffecomGfrt code;
3377 ffeinfoKindtype rtkt;
270fc4e8 3378 ffeinfoKindtype ltkt;
5ff904cd
JL
3379
3380 switch (ffeinfo_basictype (ffebld_info (right)))
3381 {
3382 case FFEINFO_basictypeINTEGER:
3383 if (1 || optimize)
3384 {
c7e4ee3a 3385 item = ffecom_expr_power_integer_ (expr);
5ff904cd
JL
3386 if (item != NULL_TREE)
3387 return item;
3388 }
3389
3390 rtkt = FFEINFO_kindtypeINTEGER1;
3391 switch (ffeinfo_basictype (ffebld_info (left)))
3392 {
3393 case FFEINFO_basictypeINTEGER:
3394 if ((ffeinfo_kindtype (ffebld_info (left))
3395 == FFEINFO_kindtypeINTEGER4)
3396 || (ffeinfo_kindtype (ffebld_info (right))
3397 == FFEINFO_kindtypeINTEGER4))
3398 {
3399 code = FFECOM_gfrtPOW_QQ;
270fc4e8 3400 ltkt = FFEINFO_kindtypeINTEGER4;
5ff904cd
JL
3401 rtkt = FFEINFO_kindtypeINTEGER4;
3402 }
3403 else
6a047254
CB
3404 {
3405 code = FFECOM_gfrtPOW_II;
3406 ltkt = FFEINFO_kindtypeINTEGER1;
3407 }
5ff904cd
JL
3408 break;
3409
3410 case FFEINFO_basictypeREAL:
3411 if (ffeinfo_kindtype (ffebld_info (left))
3412 == FFEINFO_kindtypeREAL1)
6a047254
CB
3413 {
3414 code = FFECOM_gfrtPOW_RI;
3415 ltkt = FFEINFO_kindtypeREAL1;
3416 }
5ff904cd 3417 else
6a047254
CB
3418 {
3419 code = FFECOM_gfrtPOW_DI;
3420 ltkt = FFEINFO_kindtypeREAL2;
3421 }
5ff904cd
JL
3422 break;
3423
3424 case FFEINFO_basictypeCOMPLEX:
3425 if (ffeinfo_kindtype (ffebld_info (left))
3426 == FFEINFO_kindtypeREAL1)
6a047254
CB
3427 {
3428 code = FFECOM_gfrtPOW_CI; /* Overlapping result okay. */
3429 ltkt = FFEINFO_kindtypeREAL1;
3430 }
5ff904cd 3431 else
6a047254
CB
3432 {
3433 code = FFECOM_gfrtPOW_ZI; /* Overlapping result okay. */
3434 ltkt = FFEINFO_kindtypeREAL2;
3435 }
5ff904cd
JL
3436 break;
3437
3438 default:
3439 assert ("bad pow_*i" == NULL);
3440 code = FFECOM_gfrtPOW_CI; /* Overlapping result okay. */
6a047254 3441 ltkt = FFEINFO_kindtypeREAL1;
5ff904cd
JL
3442 break;
3443 }
270fc4e8 3444 if (ffeinfo_kindtype (ffebld_info (left)) != ltkt)
5ff904cd 3445 left = ffeexpr_convert (left, NULL, NULL,
6a047254 3446 ffeinfo_basictype (ffebld_info (left)),
270fc4e8 3447 ltkt, 0,
5ff904cd
JL
3448 FFETARGET_charactersizeNONE,
3449 FFEEXPR_contextLET);
3450 if (ffeinfo_kindtype (ffebld_info (right)) != rtkt)
3451 right = ffeexpr_convert (right, NULL, NULL,
3452 FFEINFO_basictypeINTEGER,
3453 rtkt, 0,
3454 FFETARGET_charactersizeNONE,
3455 FFEEXPR_contextLET);
3456 break;
3457
3458 case FFEINFO_basictypeREAL:
3459 if (ffeinfo_kindtype (ffebld_info (left)) == FFEINFO_kindtypeREAL1)
3460 left = ffeexpr_convert (left, NULL, NULL, FFEINFO_basictypeREAL,
3461 FFEINFO_kindtypeREALDOUBLE, 0,
3462 FFETARGET_charactersizeNONE,
3463 FFEEXPR_contextLET);
3464 if (ffeinfo_kindtype (ffebld_info (right))
3465 == FFEINFO_kindtypeREAL1)
3466 right = ffeexpr_convert (right, NULL, NULL,
3467 FFEINFO_basictypeREAL,
3468 FFEINFO_kindtypeREALDOUBLE, 0,
3469 FFETARGET_charactersizeNONE,
3470 FFEEXPR_contextLET);
3471 code = FFECOM_gfrtPOW_DD;
3472 break;
3473
3474 case FFEINFO_basictypeCOMPLEX:
3475 if (ffeinfo_kindtype (ffebld_info (left)) == FFEINFO_kindtypeREAL1)
3476 left = ffeexpr_convert (left, NULL, NULL,
3477 FFEINFO_basictypeCOMPLEX,
3478 FFEINFO_kindtypeREALDOUBLE, 0,
3479 FFETARGET_charactersizeNONE,
3480 FFEEXPR_contextLET);
3481 if (ffeinfo_kindtype (ffebld_info (right))
3482 == FFEINFO_kindtypeREAL1)
3483 right = ffeexpr_convert (right, NULL, NULL,
3484 FFEINFO_basictypeCOMPLEX,
3485 FFEINFO_kindtypeREALDOUBLE, 0,
3486 FFETARGET_charactersizeNONE,
3487 FFEEXPR_contextLET);
3488 code = FFECOM_gfrtPOW_ZZ; /* Overlapping result okay. */
3489 break;
3490
3491 default:
3492 assert ("bad pow_x*" == NULL);
3493 code = FFECOM_gfrtPOW_II;
3494 break;
3495 }
3496 return ffecom_call_binop_ (ffecom_gfrt_tree_ (code),
3497 ffecom_gfrt_kindtype (code),
3498 (ffe_is_f2c_library ()
3499 && ffecom_gfrt_complex_[code]),
3500 tree_type, left, right,
3501 dest_tree, dest, dest_used,
c7e4ee3a
CB
3502 NULL_TREE, FALSE,
3503 ffebld_nonter_hook (expr));
5ff904cd
JL
3504 }
3505
3506 case FFEBLD_opNOT:
5ff904cd
JL
3507 switch (bt)
3508 {
3509 case FFEINFO_basictypeLOGICAL:
83ffecd2 3510 item = ffecom_truth_value_invert (ffecom_expr (ffebld_left (expr)));
5ff904cd
JL
3511 return convert (tree_type, item);
3512
3513 case FFEINFO_basictypeINTEGER:
3514 return ffecom_1 (BIT_NOT_EXPR, tree_type,
3515 ffecom_expr (ffebld_left (expr)));
3516
3517 default:
3518 assert ("NOT bad basictype" == NULL);
3519 /* Fall through. */
3520 case FFEINFO_basictypeANY:
3521 return error_mark_node;
3522 }
3523 break;
3524
3525 case FFEBLD_opFUNCREF:
3526 assert (ffeinfo_basictype (ffebld_info (expr))
3527 != FFEINFO_basictypeCHARACTER);
3528 /* Fall through. */
3529 case FFEBLD_opSUBRREF:
5ff904cd
JL
3530 if (ffeinfo_where (ffebld_info (ffebld_left (expr)))
3531 == FFEINFO_whereINTRINSIC)
3532 { /* Invocation of an intrinsic. */
3533 item = ffecom_expr_intrinsic_ (expr, dest_tree, dest,
3534 dest_used);
3535 return item;
3536 }
3537 s = ffebld_symter (ffebld_left (expr));
3538 dt = ffesymbol_hook (s).decl_tree;
3539 if (dt == NULL_TREE)
3540 {
3541 s = ffecom_sym_transform_ (s);
3542 dt = ffesymbol_hook (s).decl_tree;
3543 }
3544 if (dt == error_mark_node)
3545 return dt;
3546
3547 if (ffesymbol_hook (s).addr)
3548 item = dt;
3549 else
3550 item = ffecom_1_fn (dt);
3551
5ff904cd
JL
3552 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT)
3553 args = ffecom_list_expr (ffebld_right (expr));
3554 else
3555 args = ffecom_list_ptr_to_expr (ffebld_right (expr));
5ff904cd 3556
702edf1d
CB
3557 if (args == error_mark_node)
3558 return error_mark_node;
3559
5ff904cd
JL
3560 item = ffecom_call_ (item, kt,
3561 ffesymbol_is_f2c (s)
3562 && (bt == FFEINFO_basictypeCOMPLEX)
3563 && (ffesymbol_where (s)
3564 != FFEINFO_whereCONSTANT),
3565 tree_type,
3566 args,
3567 dest_tree, dest, dest_used,
c7e4ee3a
CB
3568 error_mark_node, FALSE,
3569 ffebld_nonter_hook (expr));
5ff904cd
JL
3570 TREE_SIDE_EFFECTS (item) = 1;
3571 return item;
3572
3573 case FFEBLD_opAND:
5ff904cd
JL
3574 switch (bt)
3575 {
3576 case FFEINFO_basictypeLOGICAL:
3577 item
3578 = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
3579 ffecom_truth_value (ffecom_expr (ffebld_left (expr))),
3580 ffecom_truth_value (ffecom_expr (ffebld_right (expr))));
3581 return convert (tree_type, item);
3582
3583 case FFEINFO_basictypeINTEGER:
3584 return ffecom_2 (BIT_AND_EXPR, tree_type,
3585 ffecom_expr (ffebld_left (expr)),
3586 ffecom_expr (ffebld_right (expr)));
3587
3588 default:
3589 assert ("AND bad basictype" == NULL);
3590 /* Fall through. */
3591 case FFEINFO_basictypeANY:
3592 return error_mark_node;
3593 }
3594 break;
3595
3596 case FFEBLD_opOR:
5ff904cd
JL
3597 switch (bt)
3598 {
3599 case FFEINFO_basictypeLOGICAL:
3600 item
3601 = ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
3602 ffecom_truth_value (ffecom_expr (ffebld_left (expr))),
3603 ffecom_truth_value (ffecom_expr (ffebld_right (expr))));
3604 return convert (tree_type, item);
3605
3606 case FFEINFO_basictypeINTEGER:
3607 return ffecom_2 (BIT_IOR_EXPR, tree_type,
3608 ffecom_expr (ffebld_left (expr)),
3609 ffecom_expr (ffebld_right (expr)));
3610
3611 default:
3612 assert ("OR bad basictype" == NULL);
3613 /* Fall through. */
3614 case FFEINFO_basictypeANY:
3615 return error_mark_node;
3616 }
3617 break;
3618
3619 case FFEBLD_opXOR:
3620 case FFEBLD_opNEQV:
5ff904cd
JL
3621 switch (bt)
3622 {
3623 case FFEINFO_basictypeLOGICAL:
3624 item
3625 = ffecom_2 (NE_EXPR, integer_type_node,
3626 ffecom_expr (ffebld_left (expr)),
3627 ffecom_expr (ffebld_right (expr)));
3628 return convert (tree_type, ffecom_truth_value (item));
3629
3630 case FFEINFO_basictypeINTEGER:
3631 return ffecom_2 (BIT_XOR_EXPR, tree_type,
3632 ffecom_expr (ffebld_left (expr)),
3633 ffecom_expr (ffebld_right (expr)));
3634
3635 default:
3636 assert ("XOR/NEQV bad basictype" == NULL);
3637 /* Fall through. */
3638 case FFEINFO_basictypeANY:
3639 return error_mark_node;
3640 }
3641 break;
3642
3643 case FFEBLD_opEQV:
5ff904cd
JL
3644 switch (bt)
3645 {
3646 case FFEINFO_basictypeLOGICAL:
3647 item
3648 = ffecom_2 (EQ_EXPR, integer_type_node,
3649 ffecom_expr (ffebld_left (expr)),
3650 ffecom_expr (ffebld_right (expr)));
3651 return convert (tree_type, ffecom_truth_value (item));
3652
3653 case FFEINFO_basictypeINTEGER:
3654 return
3655 ffecom_1 (BIT_NOT_EXPR, tree_type,
3656 ffecom_2 (BIT_XOR_EXPR, tree_type,
3657 ffecom_expr (ffebld_left (expr)),
3658 ffecom_expr (ffebld_right (expr))));
3659
3660 default:
3661 assert ("EQV bad basictype" == NULL);
3662 /* Fall through. */
3663 case FFEINFO_basictypeANY:
3664 return error_mark_node;
3665 }
3666 break;
3667
3668 case FFEBLD_opCONVERT:
3669 if (ffebld_op (ffebld_left (expr)) == FFEBLD_opANY)
3670 return error_mark_node;
3671
5ff904cd
JL
3672 switch (bt)
3673 {
3674 case FFEINFO_basictypeLOGICAL:
3675 case FFEINFO_basictypeINTEGER:
3676 case FFEINFO_basictypeREAL:
3677 return convert (tree_type, ffecom_expr (ffebld_left (expr)));
3678
3679 case FFEINFO_basictypeCOMPLEX:
3680 switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr))))
3681 {
3682 case FFEINFO_basictypeINTEGER:
3683 case FFEINFO_basictypeLOGICAL:
3684 case FFEINFO_basictypeREAL:
3685 item = ffecom_expr (ffebld_left (expr));
3686 if (item == error_mark_node)
3687 return error_mark_node;
3688 /* convert() takes care of converting to the subtype first,
3689 at least in gcc-2.7.2. */
3690 item = convert (tree_type, item);
3691 return item;
3692
3693 case FFEINFO_basictypeCOMPLEX:
3694 return convert (tree_type, ffecom_expr (ffebld_left (expr)));
3695
3696 default:
3697 assert ("CONVERT COMPLEX bad basictype" == NULL);
3698 /* Fall through. */
3699 case FFEINFO_basictypeANY:
3700 return error_mark_node;
3701 }
3702 break;
3703
3704 default:
3705 assert ("CONVERT bad basictype" == NULL);
3706 /* Fall through. */
3707 case FFEINFO_basictypeANY:
3708 return error_mark_node;
3709 }
3710 break;
3711
3712 case FFEBLD_opLT:
3713 code = LT_EXPR;
3714 goto relational; /* :::::::::::::::::::: */
3715
3716 case FFEBLD_opLE:
3717 code = LE_EXPR;
3718 goto relational; /* :::::::::::::::::::: */
3719
3720 case FFEBLD_opEQ:
3721 code = EQ_EXPR;
3722 goto relational; /* :::::::::::::::::::: */
3723
3724 case FFEBLD_opNE:
3725 code = NE_EXPR;
3726 goto relational; /* :::::::::::::::::::: */
3727
3728 case FFEBLD_opGT:
3729 code = GT_EXPR;
3730 goto relational; /* :::::::::::::::::::: */
3731
3732 case FFEBLD_opGE:
3733 code = GE_EXPR;
3734
3735 relational: /* :::::::::::::::::::: */
5ff904cd
JL
3736 switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr))))
3737 {
3738 case FFEINFO_basictypeLOGICAL:
3739 case FFEINFO_basictypeINTEGER:
3740 case FFEINFO_basictypeREAL:
3741 item = ffecom_2 (code, integer_type_node,
3742 ffecom_expr (ffebld_left (expr)),
3743 ffecom_expr (ffebld_right (expr)));
3744 return convert (tree_type, item);
3745
3746 case FFEINFO_basictypeCOMPLEX:
3747 assert (code == EQ_EXPR || code == NE_EXPR);
3748 {
3749 tree real_type;
3750 tree arg1 = ffecom_expr (ffebld_left (expr));
3751 tree arg2 = ffecom_expr (ffebld_right (expr));
3752
3753 if (arg1 == error_mark_node || arg2 == error_mark_node)
3754 return error_mark_node;
3755
3756 arg1 = ffecom_save_tree (arg1);
3757 arg2 = ffecom_save_tree (arg2);
3758
3759 if (TREE_CODE (TREE_TYPE (arg1)) == COMPLEX_TYPE)
3760 {
3761 real_type = TREE_TYPE (TREE_TYPE (arg1));
3762 assert (real_type == TREE_TYPE (TREE_TYPE (arg2)));
3763 }
3764 else
3765 {
3766 real_type = TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg1)));
3767 assert (real_type == TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg2))));
3768 }
3769
3770 item
3771 = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
3772 ffecom_2 (EQ_EXPR, integer_type_node,
3773 ffecom_1 (REALPART_EXPR, real_type, arg1),
3774 ffecom_1 (REALPART_EXPR, real_type, arg2)),
3775 ffecom_2 (EQ_EXPR, integer_type_node,
3776 ffecom_1 (IMAGPART_EXPR, real_type, arg1),
3777 ffecom_1 (IMAGPART_EXPR, real_type,
3778 arg2)));
3779 if (code == EQ_EXPR)
3780 item = ffecom_truth_value (item);
3781 else
3782 item = ffecom_truth_value_invert (item);
3783 return convert (tree_type, item);
3784 }
3785
3786 case FFEINFO_basictypeCHARACTER:
5ff904cd
JL
3787 {
3788 ffebld left = ffebld_left (expr);
3789 ffebld right = ffebld_right (expr);
3790 tree left_tree;
3791 tree right_tree;
3792 tree left_length;
3793 tree right_length;
3794
3795 /* f2c run-time functions do the implicit blank-padding for us,
3796 so we don't usually have to implement blank-padding ourselves.
3797 (The exception is when we pass an argument to a separately
3798 compiled statement function -- if we know the arg is not the
3799 same length as the dummy, we must truncate or extend it. If
3800 we "inline" statement functions, that necessity goes away as
3801 well.)
3802
3803 Strip off the CONVERT operators that blank-pad. (Truncation by
3804 CONVERT shouldn't happen here, but it can happen in
3805 assignments.) */
3806
3807 while (ffebld_op (left) == FFEBLD_opCONVERT)
3808 left = ffebld_left (left);
3809 while (ffebld_op (right) == FFEBLD_opCONVERT)
3810 right = ffebld_left (right);
3811
3812 left_tree = ffecom_arg_ptr_to_expr (left, &left_length);
3813 right_tree = ffecom_arg_ptr_to_expr (right, &right_length);
3814
3815 if (left_tree == error_mark_node || left_length == error_mark_node
3816 || right_tree == error_mark_node
3817 || right_length == error_mark_node)
c7e4ee3a 3818 return error_mark_node;
5ff904cd
JL
3819
3820 if ((ffebld_size_known (left) == 1)
3821 && (ffebld_size_known (right) == 1))
3822 {
3823 left_tree
3824 = ffecom_1 (INDIRECT_REF,
3825 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree))),
3826 left_tree);
3827 right_tree
3828 = ffecom_1 (INDIRECT_REF,
3829 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree))),
3830 right_tree);
3831
3832 item
3833 = ffecom_2 (code, integer_type_node,
3834 ffecom_2 (ARRAY_REF,
3835 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree))),
3836 left_tree,
3837 integer_one_node),
3838 ffecom_2 (ARRAY_REF,
3839 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree))),
3840 right_tree,
3841 integer_one_node));
3842 }
3843 else
3844 {
3845 item = build_tree_list (NULL_TREE, left_tree);
3846 TREE_CHAIN (item) = build_tree_list (NULL_TREE, right_tree);
3847 TREE_CHAIN (TREE_CHAIN (item)) = build_tree_list (NULL_TREE,
3848 left_length);
3849 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item)))
3850 = build_tree_list (NULL_TREE, right_length);
c7e4ee3a 3851 item = ffecom_call_gfrt (FFECOM_gfrtCMP, item, NULL_TREE);
5ff904cd
JL
3852 item = ffecom_2 (code, integer_type_node,
3853 item,
3854 convert (TREE_TYPE (item),
3855 integer_zero_node));
3856 }
3857 item = convert (tree_type, item);
3858 }
3859
5ff904cd
JL
3860 return item;
3861
3862 default:
3863 assert ("relational bad basictype" == NULL);
3864 /* Fall through. */
3865 case FFEINFO_basictypeANY:
3866 return error_mark_node;
3867 }
3868 break;
3869
3870 case FFEBLD_opPERCENT_LOC:
5ff904cd
JL
3871 item = ffecom_arg_ptr_to_expr (ffebld_left (expr), &list);
3872 return convert (tree_type, item);
3873
3874 case FFEBLD_opITEM:
3875 case FFEBLD_opSTAR:
3876 case FFEBLD_opBOUNDS:
3877 case FFEBLD_opREPEAT:
3878 case FFEBLD_opLABTER:
3879 case FFEBLD_opLABTOK:
3880 case FFEBLD_opIMPDO:
3881 case FFEBLD_opCONCATENATE:
3882 case FFEBLD_opSUBSTR:
3883 default:
3884 assert ("bad op" == NULL);
3885 /* Fall through. */
3886 case FFEBLD_opANY:
3887 return error_mark_node;
3888 }
3889
3890#if 1
3891 assert ("didn't think anything got here anymore!!" == NULL);
3892#else
3893 switch (ffebld_arity (expr))
3894 {
3895 case 2:
3896 TREE_OPERAND (item, 0) = ffecom_expr (ffebld_left (expr));
3897 TREE_OPERAND (item, 1) = ffecom_expr (ffebld_right (expr));
3898 if (TREE_OPERAND (item, 0) == error_mark_node
3899 || TREE_OPERAND (item, 1) == error_mark_node)
3900 return error_mark_node;
3901 break;
3902
3903 case 1:
3904 TREE_OPERAND (item, 0) = ffecom_expr (ffebld_left (expr));
3905 if (TREE_OPERAND (item, 0) == error_mark_node)
3906 return error_mark_node;
3907 break;
3908
3909 default:
3910 break;
3911 }
3912
3913 return fold (item);
3914#endif
3915}
3916
3917#endif
3918/* Returns the tree that does the intrinsic invocation.
3919
3920 Note: this function applies only to intrinsics returning
3921 CHARACTER*1 or non-CHARACTER results, and to intrinsic
3922 subroutines. */
3923
3924#if FFECOM_targetCURRENT == FFECOM_targetGCC
3925static tree
3926ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree,
3927 ffebld dest, bool *dest_used)
3928{
3929 tree expr_tree;
3930 tree saved_expr1; /* For those who need it. */
3931 tree saved_expr2; /* For those who need it. */
3932 ffeinfoBasictype bt;
3933 ffeinfoKindtype kt;
3934 tree tree_type;
3935 tree arg1_type;
3936 tree real_type; /* REAL type corresponding to COMPLEX. */
3937 tree tempvar;
3938 ffebld list = ffebld_right (expr); /* List of (some) args. */
3939 ffebld arg1; /* For handy reference. */
3940 ffebld arg2;
3941 ffebld arg3;
3942 ffeintrinImp codegen_imp;
3943 ffecomGfrt gfrt;
3944
3945 assert (ffebld_op (ffebld_left (expr)) == FFEBLD_opSYMTER);
3946
3947 if (dest_used != NULL)
3948 *dest_used = FALSE;
3949
3950 bt = ffeinfo_basictype (ffebld_info (expr));
3951 kt = ffeinfo_kindtype (ffebld_info (expr));
3952 tree_type = ffecom_tree_type[bt][kt];
3953
3954 if (list != NULL)
3955 {
3956 arg1 = ffebld_head (list);
3957 if (arg1 != NULL && ffebld_op (arg1) == FFEBLD_opANY)
3958 return error_mark_node;
3959 if ((list = ffebld_trail (list)) != NULL)
3960 {
3961 arg2 = ffebld_head (list);
3962 if (arg2 != NULL && ffebld_op (arg2) == FFEBLD_opANY)
3963 return error_mark_node;
3964 if ((list = ffebld_trail (list)) != NULL)
3965 {
3966 arg3 = ffebld_head (list);
3967 if (arg3 != NULL && ffebld_op (arg3) == FFEBLD_opANY)
3968 return error_mark_node;
3969 }
3970 else
3971 arg3 = NULL;
3972 }
3973 else
3974 arg2 = arg3 = NULL;
3975 }
3976 else
3977 arg1 = arg2 = arg3 = NULL;
3978
3979 /* <list> ends up at the opITEM of the 3rd arg, or NULL if there are < 3
3980 args. This is used by the MAX/MIN expansions. */
3981
3982 if (arg1 != NULL)
3983 arg1_type = ffecom_tree_type
3984 [ffeinfo_basictype (ffebld_info (arg1))]
3985 [ffeinfo_kindtype (ffebld_info (arg1))];
3986 else
3987 arg1_type = NULL_TREE; /* Really not needed, but might catch bugs
3988 here. */
3989
3990 /* There are several ways for each of the cases in the following switch
3991 statements to exit (from simplest to use to most complicated):
3992
3993 break; (when expr_tree == NULL)
3994
3995 A standard call is made to the specific intrinsic just as if it had been
3996 passed in as a dummy procedure and called as any old procedure. This
3997 method can produce slower code but in some cases it's the easiest way for
3998 now. However, if a (presumably faster) direct call is available,
3999 that is used, so this is the easiest way in many more cases now.
4000
4001 gfrt = FFECOM_gfrtWHATEVER;
4002 break;
4003
4004 gfrt contains the gfrt index of a library function to call, passing the
4005 argument(s) by value rather than by reference. Used when a more
4006 careful choice of library function is needed than that provided
4007 by the vanilla `break;'.
4008
4009 return expr_tree;
4010
4011 The expr_tree has been completely set up and is ready to be returned
4012 as is. No further actions are taken. Use this when the tree is not
4013 in the simple form for one of the arity_n labels. */
4014
4015 /* For info on how the switch statement cases were written, see the files
4016 enclosed in comments below the switch statement. */
4017
4018 codegen_imp = ffebld_symter_implementation (ffebld_left (expr));
4019 gfrt = ffeintrin_gfrt_direct (codegen_imp);
4020 if (gfrt == FFECOM_gfrt)
4021 gfrt = ffeintrin_gfrt_indirect (codegen_imp);
4022
4023 switch (codegen_imp)
4024 {
4025 case FFEINTRIN_impABS:
4026 case FFEINTRIN_impCABS:
4027 case FFEINTRIN_impCDABS:
4028 case FFEINTRIN_impDABS:
4029 case FFEINTRIN_impIABS:
4030 if (ffeinfo_basictype (ffebld_info (arg1))
4031 == FFEINFO_basictypeCOMPLEX)
4032 {
4033 if (kt == FFEINFO_kindtypeREAL1)
4034 gfrt = FFECOM_gfrtCABS;
4035 else if (kt == FFEINFO_kindtypeREAL2)
4036 gfrt = FFECOM_gfrtCDABS;
4037 break;
4038 }
4039 return ffecom_1 (ABS_EXPR, tree_type,
4040 convert (tree_type, ffecom_expr (arg1)));
4041
4042 case FFEINTRIN_impACOS:
4043 case FFEINTRIN_impDACOS:
4044 break;
4045
4046 case FFEINTRIN_impAIMAG:
4047 case FFEINTRIN_impDIMAG:
4048 case FFEINTRIN_impIMAGPART:
4049 if (TREE_CODE (arg1_type) == COMPLEX_TYPE)
4050 arg1_type = TREE_TYPE (arg1_type);
4051 else
4052 arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type));
4053
4054 return
4055 convert (tree_type,
4056 ffecom_1 (IMAGPART_EXPR, arg1_type,
4057 ffecom_expr (arg1)));
4058
4059 case FFEINTRIN_impAINT:
4060 case FFEINTRIN_impDINT:
c7e4ee3a
CB
4061#if 0
4062 /* ~~Someday implement FIX_TRUNC_EXPR yielding same type as arg. */
5ff904cd
JL
4063 return ffecom_1 (FIX_TRUNC_EXPR, tree_type, ffecom_expr (arg1));
4064#else /* in the meantime, must use floor to avoid range problems with ints */
4065 /* r__1 = r1 >= 0 ? floor(r1) : -floor(-r1); */
4066 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
4067 return
4068 convert (tree_type,
4069 ffecom_3 (COND_EXPR, double_type_node,
4070 ffecom_truth_value
4071 (ffecom_2 (GE_EXPR, integer_type_node,
4072 saved_expr1,
4073 convert (arg1_type,
4074 ffecom_float_zero_))),
4075 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
4076 build_tree_list (NULL_TREE,
4077 convert (double_type_node,
c7e4ee3a
CB
4078 saved_expr1)),
4079 NULL_TREE),
5ff904cd
JL
4080 ffecom_1 (NEGATE_EXPR, double_type_node,
4081 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
4082 build_tree_list (NULL_TREE,
4083 convert (double_type_node,
4084 ffecom_1 (NEGATE_EXPR,
4085 arg1_type,
c7e4ee3a
CB
4086 saved_expr1))),
4087 NULL_TREE)
5ff904cd
JL
4088 ))
4089 );
4090#endif
4091
4092 case FFEINTRIN_impANINT:
4093 case FFEINTRIN_impDNINT:
4094#if 0 /* This way of doing it won't handle real
4095 numbers of large magnitudes. */
4096 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
4097 expr_tree = convert (tree_type,
4098 convert (integer_type_node,
4099 ffecom_3 (COND_EXPR, tree_type,
4100 ffecom_truth_value
4101 (ffecom_2 (GE_EXPR,
4102 integer_type_node,
4103 saved_expr1,
4104 ffecom_float_zero_)),
4105 ffecom_2 (PLUS_EXPR,
4106 tree_type,
4107 saved_expr1,
4108 ffecom_float_half_),
4109 ffecom_2 (MINUS_EXPR,
4110 tree_type,
4111 saved_expr1,
4112 ffecom_float_half_))));
4113 return expr_tree;
4114#else /* So we instead call floor. */
4115 /* r__1 = r1 >= 0 ? floor(r1 + .5) : -floor(.5 - r1) */
4116 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
4117 return
4118 convert (tree_type,
4119 ffecom_3 (COND_EXPR, double_type_node,
4120 ffecom_truth_value
4121 (ffecom_2 (GE_EXPR, integer_type_node,
4122 saved_expr1,
4123 convert (arg1_type,
4124 ffecom_float_zero_))),
4125 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
4126 build_tree_list (NULL_TREE,
4127 convert (double_type_node,
4128 ffecom_2 (PLUS_EXPR,
4129 arg1_type,
4130 saved_expr1,
4131 convert (arg1_type,
c7e4ee3a
CB
4132 ffecom_float_half_)))),
4133 NULL_TREE),
5ff904cd
JL
4134 ffecom_1 (NEGATE_EXPR, double_type_node,
4135 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
4136 build_tree_list (NULL_TREE,
4137 convert (double_type_node,
4138 ffecom_2 (MINUS_EXPR,
4139 arg1_type,
4140 convert (arg1_type,
4141 ffecom_float_half_),
c7e4ee3a
CB
4142 saved_expr1))),
4143 NULL_TREE))
5ff904cd
JL
4144 )
4145 );
4146#endif
4147
4148 case FFEINTRIN_impASIN:
4149 case FFEINTRIN_impDASIN:
4150 case FFEINTRIN_impATAN:
4151 case FFEINTRIN_impDATAN:
4152 case FFEINTRIN_impATAN2:
4153 case FFEINTRIN_impDATAN2:
4154 break;
4155
4156 case FFEINTRIN_impCHAR:
4157 case FFEINTRIN_impACHAR:
c7e4ee3a
CB
4158#ifdef HOHO
4159 tempvar = ffecom_make_tempvar (char_type_node, 1, -1);
4160#else
4161 tempvar = ffebld_nonter_hook (expr);
4162 assert (tempvar);
4163#endif
5ff904cd
JL
4164 {
4165 tree tmv = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (tempvar)));
4166
4167 expr_tree = ffecom_modify (tmv,
4168 ffecom_2 (ARRAY_REF, tmv, tempvar,
4169 integer_one_node),
4170 convert (tmv, ffecom_expr (arg1)));
4171 }
4172 expr_tree = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar),
4173 expr_tree,
4174 tempvar);
4175 expr_tree = ffecom_1 (ADDR_EXPR,
4176 build_pointer_type (TREE_TYPE (expr_tree)),
4177 expr_tree);
4178 return expr_tree;
4179
4180 case FFEINTRIN_impCMPLX:
4181 case FFEINTRIN_impDCMPLX:
4182 if (arg2 == NULL)
4183 return
4184 convert (tree_type, ffecom_expr (arg1));
4185
4186 real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
4187 return
4188 ffecom_2 (COMPLEX_EXPR, tree_type,
4189 convert (real_type, ffecom_expr (arg1)),
4190 convert (real_type,
4191 ffecom_expr (arg2)));
4192
4193 case FFEINTRIN_impCOMPLEX:
4194 return
4195 ffecom_2 (COMPLEX_EXPR, tree_type,
4196 ffecom_expr (arg1),
4197 ffecom_expr (arg2));
4198
4199 case FFEINTRIN_impCONJG:
4200 case FFEINTRIN_impDCONJG:
4201 {
4202 tree arg1_tree;
4203
4204 real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
4205 arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4206 return
4207 ffecom_2 (COMPLEX_EXPR, tree_type,
4208 ffecom_1 (REALPART_EXPR, real_type, arg1_tree),
4209 ffecom_1 (NEGATE_EXPR, real_type,
4210 ffecom_1 (IMAGPART_EXPR, real_type, arg1_tree)));
4211 }
4212
4213 case FFEINTRIN_impCOS:
4214 case FFEINTRIN_impCCOS:
4215 case FFEINTRIN_impCDCOS:
4216 case FFEINTRIN_impDCOS:
4217 if (bt == FFEINFO_basictypeCOMPLEX)
4218 {
4219 if (kt == FFEINFO_kindtypeREAL1)
4220 gfrt = FFECOM_gfrtCCOS; /* Overlapping result okay. */
4221 else if (kt == FFEINFO_kindtypeREAL2)
4222 gfrt = FFECOM_gfrtCDCOS; /* Overlapping result okay. */
4223 }
4224 break;
4225
4226 case FFEINTRIN_impCOSH:
4227 case FFEINTRIN_impDCOSH:
4228 break;
4229
4230 case FFEINTRIN_impDBLE:
4231 case FFEINTRIN_impDFLOAT:
4232 case FFEINTRIN_impDREAL:
4233 case FFEINTRIN_impFLOAT:
4234 case FFEINTRIN_impIDINT:
4235 case FFEINTRIN_impIFIX:
4236 case FFEINTRIN_impINT2:
4237 case FFEINTRIN_impINT8:
4238 case FFEINTRIN_impINT:
4239 case FFEINTRIN_impLONG:
4240 case FFEINTRIN_impREAL:
4241 case FFEINTRIN_impSHORT:
4242 case FFEINTRIN_impSNGL:
4243 return convert (tree_type, ffecom_expr (arg1));
4244
4245 case FFEINTRIN_impDIM:
4246 case FFEINTRIN_impDDIM:
4247 case FFEINTRIN_impIDIM:
4248 saved_expr1 = ffecom_save_tree (convert (tree_type,
4249 ffecom_expr (arg1)));
4250 saved_expr2 = ffecom_save_tree (convert (tree_type,
4251 ffecom_expr (arg2)));
4252 return
4253 ffecom_3 (COND_EXPR, tree_type,
4254 ffecom_truth_value
4255 (ffecom_2 (GT_EXPR, integer_type_node,
4256 saved_expr1,
4257 saved_expr2)),
4258 ffecom_2 (MINUS_EXPR, tree_type,
4259 saved_expr1,
4260 saved_expr2),
4261 convert (tree_type, ffecom_float_zero_));
4262
4263 case FFEINTRIN_impDPROD:
4264 return
4265 ffecom_2 (MULT_EXPR, tree_type,
4266 convert (tree_type, ffecom_expr (arg1)),
4267 convert (tree_type, ffecom_expr (arg2)));
4268
4269 case FFEINTRIN_impEXP:
4270 case FFEINTRIN_impCDEXP:
4271 case FFEINTRIN_impCEXP:
4272 case FFEINTRIN_impDEXP:
4273 if (bt == FFEINFO_basictypeCOMPLEX)
4274 {
4275 if (kt == FFEINFO_kindtypeREAL1)
4276 gfrt = FFECOM_gfrtCEXP; /* Overlapping result okay. */
4277 else if (kt == FFEINFO_kindtypeREAL2)
4278 gfrt = FFECOM_gfrtCDEXP; /* Overlapping result okay. */
4279 }
4280 break;
4281
4282 case FFEINTRIN_impICHAR:
4283 case FFEINTRIN_impIACHAR:
4284#if 0 /* The simple approach. */
4285 ffecom_char_args_ (&expr_tree, &saved_expr1 /* Ignored */ , arg1);
4286 expr_tree
4287 = ffecom_1 (INDIRECT_REF,
4288 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
4289 expr_tree);
4290 expr_tree
4291 = ffecom_2 (ARRAY_REF,
4292 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
4293 expr_tree,
4294 integer_one_node);
4295 return convert (tree_type, expr_tree);
4296#else /* The more interesting (and more optimal) approach. */
4297 expr_tree = ffecom_intrinsic_ichar_ (tree_type, arg1, &saved_expr1);
4298 expr_tree = ffecom_3 (COND_EXPR, tree_type,
4299 saved_expr1,
4300 expr_tree,
4301 convert (tree_type, integer_zero_node));
4302 return expr_tree;
4303#endif
4304
4305 case FFEINTRIN_impINDEX:
4306 break;
4307
4308 case FFEINTRIN_impLEN:
4309#if 0
4310 break; /* The simple approach. */
4311#else
4312 return ffecom_intrinsic_len_ (arg1); /* The more optimal approach. */
4313#endif
4314
4315 case FFEINTRIN_impLGE:
4316 case FFEINTRIN_impLGT:
4317 case FFEINTRIN_impLLE:
4318 case FFEINTRIN_impLLT:
4319 break;
4320
4321 case FFEINTRIN_impLOG:
4322 case FFEINTRIN_impALOG:
4323 case FFEINTRIN_impCDLOG:
4324 case FFEINTRIN_impCLOG:
4325 case FFEINTRIN_impDLOG:
4326 if (bt == FFEINFO_basictypeCOMPLEX)
4327 {
4328 if (kt == FFEINFO_kindtypeREAL1)
4329 gfrt = FFECOM_gfrtCLOG; /* Overlapping result okay. */
4330 else if (kt == FFEINFO_kindtypeREAL2)
4331 gfrt = FFECOM_gfrtCDLOG; /* Overlapping result okay. */
4332 }
4333 break;
4334
4335 case FFEINTRIN_impLOG10:
4336 case FFEINTRIN_impALOG10:
4337 case FFEINTRIN_impDLOG10:
4338 if (gfrt != FFECOM_gfrt)
4339 break; /* Already picked one, stick with it. */
4340
4341 if (kt == FFEINFO_kindtypeREAL1)
4342 gfrt = FFECOM_gfrtALOG10;
4343 else if (kt == FFEINFO_kindtypeREAL2)
4344 gfrt = FFECOM_gfrtDLOG10;
4345 break;
4346
4347 case FFEINTRIN_impMAX:
4348 case FFEINTRIN_impAMAX0:
4349 case FFEINTRIN_impAMAX1:
4350 case FFEINTRIN_impDMAX1:
4351 case FFEINTRIN_impMAX0:
4352 case FFEINTRIN_impMAX1:
4353 if (bt != ffeinfo_basictype (ffebld_info (arg1)))
4354 arg1_type = ffecom_widest_expr_type_ (ffebld_right (expr));
4355 else
4356 arg1_type = tree_type;
4357 expr_tree = ffecom_2 (MAX_EXPR, arg1_type,
4358 convert (arg1_type, ffecom_expr (arg1)),
4359 convert (arg1_type, ffecom_expr (arg2)));
4360 for (; list != NULL; list = ffebld_trail (list))
4361 {
4362 if ((ffebld_head (list) == NULL)
4363 || (ffebld_op (ffebld_head (list)) == FFEBLD_opANY))
4364 continue;
4365 expr_tree = ffecom_2 (MAX_EXPR, arg1_type,
4366 expr_tree,
4367 convert (arg1_type,
4368 ffecom_expr (ffebld_head (list))));
4369 }
4370 return convert (tree_type, expr_tree);
4371
4372 case FFEINTRIN_impMIN:
4373 case FFEINTRIN_impAMIN0:
4374 case FFEINTRIN_impAMIN1:
4375 case FFEINTRIN_impDMIN1:
4376 case FFEINTRIN_impMIN0:
4377 case FFEINTRIN_impMIN1:
4378 if (bt != ffeinfo_basictype (ffebld_info (arg1)))
4379 arg1_type = ffecom_widest_expr_type_ (ffebld_right (expr));
4380 else
4381 arg1_type = tree_type;
4382 expr_tree = ffecom_2 (MIN_EXPR, arg1_type,
4383 convert (arg1_type, ffecom_expr (arg1)),
4384 convert (arg1_type, ffecom_expr (arg2)));
4385 for (; list != NULL; list = ffebld_trail (list))
4386 {
4387 if ((ffebld_head (list) == NULL)
4388 || (ffebld_op (ffebld_head (list)) == FFEBLD_opANY))
4389 continue;
4390 expr_tree = ffecom_2 (MIN_EXPR, arg1_type,
4391 expr_tree,
4392 convert (arg1_type,
4393 ffecom_expr (ffebld_head (list))));
4394 }
4395 return convert (tree_type, expr_tree);
4396
4397 case FFEINTRIN_impMOD:
4398 case FFEINTRIN_impAMOD:
4399 case FFEINTRIN_impDMOD:
4400 if (bt != FFEINFO_basictypeREAL)
4401 return ffecom_2 (TRUNC_MOD_EXPR, tree_type,
4402 convert (tree_type, ffecom_expr (arg1)),
4403 convert (tree_type, ffecom_expr (arg2)));
4404
4405 if (kt == FFEINFO_kindtypeREAL1)
4406 gfrt = FFECOM_gfrtAMOD;
4407 else if (kt == FFEINFO_kindtypeREAL2)
4408 gfrt = FFECOM_gfrtDMOD;
4409 break;
4410
4411 case FFEINTRIN_impNINT:
4412 case FFEINTRIN_impIDNINT:
c7e4ee3a
CB
4413#if 0
4414 /* ~~Ideally FIX_ROUND_EXPR would be implemented, but it ain't yet. */
5ff904cd
JL
4415 return ffecom_1 (FIX_ROUND_EXPR, tree_type, ffecom_expr (arg1));
4416#else
4417 /* i__1 = r1 >= 0 ? floor(r1 + .5) : -floor(.5 - r1); */
4418 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
4419 return
4420 convert (ffecom_integer_type_node,
4421 ffecom_3 (COND_EXPR, arg1_type,
4422 ffecom_truth_value
4423 (ffecom_2 (GE_EXPR, integer_type_node,
4424 saved_expr1,
4425 convert (arg1_type,
4426 ffecom_float_zero_))),
4427 ffecom_2 (PLUS_EXPR, arg1_type,
4428 saved_expr1,
4429 convert (arg1_type,
4430 ffecom_float_half_)),
4431 ffecom_2 (MINUS_EXPR, arg1_type,
4432 saved_expr1,
4433 convert (arg1_type,
4434 ffecom_float_half_))));
4435#endif
4436
4437 case FFEINTRIN_impSIGN:
4438 case FFEINTRIN_impDSIGN:
4439 case FFEINTRIN_impISIGN:
4440 {
4441 tree arg2_tree = ffecom_expr (arg2);
4442
4443 saved_expr1
4444 = ffecom_save_tree
4445 (ffecom_1 (ABS_EXPR, tree_type,
4446 convert (tree_type,
4447 ffecom_expr (arg1))));
4448 expr_tree
4449 = ffecom_3 (COND_EXPR, tree_type,
4450 ffecom_truth_value
4451 (ffecom_2 (GE_EXPR, integer_type_node,
4452 arg2_tree,
4453 convert (TREE_TYPE (arg2_tree),
4454 integer_zero_node))),
4455 saved_expr1,
4456 ffecom_1 (NEGATE_EXPR, tree_type, saved_expr1));
4457 /* Make sure SAVE_EXPRs get referenced early enough. */
4458 expr_tree
4459 = ffecom_2 (COMPOUND_EXPR, tree_type,
4460 convert (void_type_node, saved_expr1),
4461 expr_tree);
4462 }
4463 return expr_tree;
4464
4465 case FFEINTRIN_impSIN:
4466 case FFEINTRIN_impCDSIN:
4467 case FFEINTRIN_impCSIN:
4468 case FFEINTRIN_impDSIN:
4469 if (bt == FFEINFO_basictypeCOMPLEX)
4470 {
4471 if (kt == FFEINFO_kindtypeREAL1)
4472 gfrt = FFECOM_gfrtCSIN; /* Overlapping result okay. */
4473 else if (kt == FFEINFO_kindtypeREAL2)
4474 gfrt = FFECOM_gfrtCDSIN; /* Overlapping result okay. */
4475 }
4476 break;
4477
4478 case FFEINTRIN_impSINH:
4479 case FFEINTRIN_impDSINH:
4480 break;
4481
4482 case FFEINTRIN_impSQRT:
4483 case FFEINTRIN_impCDSQRT:
4484 case FFEINTRIN_impCSQRT:
4485 case FFEINTRIN_impDSQRT:
4486 if (bt == FFEINFO_basictypeCOMPLEX)
4487 {
4488 if (kt == FFEINFO_kindtypeREAL1)
4489 gfrt = FFECOM_gfrtCSQRT; /* Overlapping result okay. */
4490 else if (kt == FFEINFO_kindtypeREAL2)
4491 gfrt = FFECOM_gfrtCDSQRT; /* Overlapping result okay. */
4492 }
4493 break;
4494
4495 case FFEINTRIN_impTAN:
4496 case FFEINTRIN_impDTAN:
4497 case FFEINTRIN_impTANH:
4498 case FFEINTRIN_impDTANH:
4499 break;
4500
4501 case FFEINTRIN_impREALPART:
4502 if (TREE_CODE (arg1_type) == COMPLEX_TYPE)
4503 arg1_type = TREE_TYPE (arg1_type);
4504 else
4505 arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type));
4506
4507 return
4508 convert (tree_type,
4509 ffecom_1 (REALPART_EXPR, arg1_type,
4510 ffecom_expr (arg1)));
4511
4512 case FFEINTRIN_impIAND:
4513 case FFEINTRIN_impAND:
4514 return ffecom_2 (BIT_AND_EXPR, tree_type,
4515 convert (tree_type,
4516 ffecom_expr (arg1)),
4517 convert (tree_type,
4518 ffecom_expr (arg2)));
4519
4520 case FFEINTRIN_impIOR:
4521 case FFEINTRIN_impOR:
4522 return ffecom_2 (BIT_IOR_EXPR, tree_type,
4523 convert (tree_type,
4524 ffecom_expr (arg1)),
4525 convert (tree_type,
4526 ffecom_expr (arg2)));
4527
4528 case FFEINTRIN_impIEOR:
4529 case FFEINTRIN_impXOR:
4530 return ffecom_2 (BIT_XOR_EXPR, tree_type,
4531 convert (tree_type,
4532 ffecom_expr (arg1)),
4533 convert (tree_type,
4534 ffecom_expr (arg2)));
4535
4536 case FFEINTRIN_impLSHIFT:
4537 return ffecom_2 (LSHIFT_EXPR, tree_type,
4538 ffecom_expr (arg1),
4539 convert (integer_type_node,
4540 ffecom_expr (arg2)));
4541
4542 case FFEINTRIN_impRSHIFT:
4543 return ffecom_2 (RSHIFT_EXPR, tree_type,
4544 ffecom_expr (arg1),
4545 convert (integer_type_node,
4546 ffecom_expr (arg2)));
4547
4548 case FFEINTRIN_impNOT:
4549 return ffecom_1 (BIT_NOT_EXPR, tree_type, ffecom_expr (arg1));
4550
4551 case FFEINTRIN_impBIT_SIZE:
4552 return convert (tree_type, TYPE_SIZE (arg1_type));
4553
4554 case FFEINTRIN_impBTEST:
4555 {
4556 ffetargetLogical1 true;
4557 ffetargetLogical1 false;
4558 tree true_tree;
4559 tree false_tree;
4560
4561 ffetarget_logical1 (&true, TRUE);
4562 ffetarget_logical1 (&false, FALSE);
4563 if (true == 1)
4564 true_tree = convert (tree_type, integer_one_node);
4565 else
4566 true_tree = convert (tree_type, build_int_2 (true, 0));
4567 if (false == 0)
4568 false_tree = convert (tree_type, integer_zero_node);
4569 else
4570 false_tree = convert (tree_type, build_int_2 (false, 0));
4571
4572 return
4573 ffecom_3 (COND_EXPR, tree_type,
4574 ffecom_truth_value
4575 (ffecom_2 (EQ_EXPR, integer_type_node,
4576 ffecom_2 (BIT_AND_EXPR, arg1_type,
4577 ffecom_expr (arg1),
4578 ffecom_2 (LSHIFT_EXPR, arg1_type,
4579 convert (arg1_type,
4580 integer_one_node),
4581 convert (integer_type_node,
4582 ffecom_expr (arg2)))),
4583 convert (arg1_type,
4584 integer_zero_node))),
4585 false_tree,
4586 true_tree);
4587 }
4588
4589 case FFEINTRIN_impIBCLR:
4590 return
4591 ffecom_2 (BIT_AND_EXPR, tree_type,
4592 ffecom_expr (arg1),
4593 ffecom_1 (BIT_NOT_EXPR, tree_type,
4594 ffecom_2 (LSHIFT_EXPR, tree_type,
4595 convert (tree_type,
4596 integer_one_node),
4597 convert (integer_type_node,
4598 ffecom_expr (arg2)))));
4599
4600 case FFEINTRIN_impIBITS:
4601 {
4602 tree arg3_tree = ffecom_save_tree (convert (integer_type_node,
4603 ffecom_expr (arg3)));
4604 tree uns_type
4605 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4606
4607 expr_tree
4608 = ffecom_2 (BIT_AND_EXPR, tree_type,
4609 ffecom_2 (RSHIFT_EXPR, tree_type,
4610 ffecom_expr (arg1),
4611 convert (integer_type_node,
4612 ffecom_expr (arg2))),
4613 convert (tree_type,
4614 ffecom_2 (RSHIFT_EXPR, uns_type,
4615 ffecom_1 (BIT_NOT_EXPR,
4616 uns_type,
4617 convert (uns_type,
4618 integer_zero_node)),
4619 ffecom_2 (MINUS_EXPR,
4620 integer_type_node,
4621 TYPE_SIZE (uns_type),
4622 arg3_tree))));
4623#if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4624 expr_tree
4625 = ffecom_3 (COND_EXPR, tree_type,
4626 ffecom_truth_value
4627 (ffecom_2 (NE_EXPR, integer_type_node,
4628 arg3_tree,
4629 integer_zero_node)),
4630 expr_tree,
4631 convert (tree_type, integer_zero_node));
4632#endif
4633 }
4634 return expr_tree;
4635
4636 case FFEINTRIN_impIBSET:
4637 return
4638 ffecom_2 (BIT_IOR_EXPR, tree_type,
4639 ffecom_expr (arg1),
4640 ffecom_2 (LSHIFT_EXPR, tree_type,
4641 convert (tree_type, integer_one_node),
4642 convert (integer_type_node,
4643 ffecom_expr (arg2))));
4644
4645 case FFEINTRIN_impISHFT:
4646 {
4647 tree arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4648 tree arg2_tree = ffecom_save_tree (convert (integer_type_node,
4649 ffecom_expr (arg2)));
4650 tree uns_type
4651 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4652
4653 expr_tree
4654 = ffecom_3 (COND_EXPR, tree_type,
4655 ffecom_truth_value
4656 (ffecom_2 (GE_EXPR, integer_type_node,
4657 arg2_tree,
4658 integer_zero_node)),
4659 ffecom_2 (LSHIFT_EXPR, tree_type,
4660 arg1_tree,
4661 arg2_tree),
4662 convert (tree_type,
4663 ffecom_2 (RSHIFT_EXPR, uns_type,
4664 convert (uns_type, arg1_tree),
4665 ffecom_1 (NEGATE_EXPR,
4666 integer_type_node,
4667 arg2_tree))));
4668#if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4669 expr_tree
4670 = ffecom_3 (COND_EXPR, tree_type,
4671 ffecom_truth_value
4672 (ffecom_2 (NE_EXPR, integer_type_node,
4673 arg2_tree,
4674 TYPE_SIZE (uns_type))),
4675 expr_tree,
4676 convert (tree_type, integer_zero_node));
4677#endif
4678 /* Make sure SAVE_EXPRs get referenced early enough. */
4679 expr_tree
4680 = ffecom_2 (COMPOUND_EXPR, tree_type,
4681 convert (void_type_node, arg1_tree),
4682 ffecom_2 (COMPOUND_EXPR, tree_type,
4683 convert (void_type_node, arg2_tree),
4684 expr_tree));
4685 }
4686 return expr_tree;
4687
4688 case FFEINTRIN_impISHFTC:
4689 {
4690 tree arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4691 tree arg2_tree = ffecom_save_tree (convert (integer_type_node,
4692 ffecom_expr (arg2)));
4693 tree arg3_tree = (arg3 == NULL) ? TYPE_SIZE (tree_type)
4694 : ffecom_save_tree (convert (integer_type_node, ffecom_expr (arg3)));
4695 tree shift_neg;
4696 tree shift_pos;
4697 tree mask_arg1;
4698 tree masked_arg1;
4699 tree uns_type
4700 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4701
4702 mask_arg1
4703 = ffecom_2 (LSHIFT_EXPR, tree_type,
4704 ffecom_1 (BIT_NOT_EXPR, tree_type,
4705 convert (tree_type, integer_zero_node)),
4706 arg3_tree);
4707#if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4708 mask_arg1
4709 = ffecom_3 (COND_EXPR, tree_type,
4710 ffecom_truth_value
4711 (ffecom_2 (NE_EXPR, integer_type_node,
4712 arg3_tree,
4713 TYPE_SIZE (uns_type))),
4714 mask_arg1,
4715 convert (tree_type, integer_zero_node));
4716#endif
4717 mask_arg1 = ffecom_save_tree (mask_arg1);
4718 masked_arg1
4719 = ffecom_2 (BIT_AND_EXPR, tree_type,
4720 arg1_tree,
4721 ffecom_1 (BIT_NOT_EXPR, tree_type,
4722 mask_arg1));
4723 masked_arg1 = ffecom_save_tree (masked_arg1);
4724 shift_neg
4725 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4726 convert (tree_type,
4727 ffecom_2 (RSHIFT_EXPR, uns_type,
4728 convert (uns_type, masked_arg1),
4729 ffecom_1 (NEGATE_EXPR,
4730 integer_type_node,
4731 arg2_tree))),
4732 ffecom_2 (LSHIFT_EXPR, tree_type,
4733 arg1_tree,
4734 ffecom_2 (PLUS_EXPR, integer_type_node,
4735 arg2_tree,
4736 arg3_tree)));
4737 shift_pos
4738 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4739 ffecom_2 (LSHIFT_EXPR, tree_type,
4740 arg1_tree,
4741 arg2_tree),
4742 convert (tree_type,
4743 ffecom_2 (RSHIFT_EXPR, uns_type,
4744 convert (uns_type, masked_arg1),
4745 ffecom_2 (MINUS_EXPR,
4746 integer_type_node,
4747 arg3_tree,
4748 arg2_tree))));
4749 expr_tree
4750 = ffecom_3 (COND_EXPR, tree_type,
4751 ffecom_truth_value
4752 (ffecom_2 (LT_EXPR, integer_type_node,
4753 arg2_tree,
4754 integer_zero_node)),
4755 shift_neg,
4756 shift_pos);
4757 expr_tree
4758 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4759 ffecom_2 (BIT_AND_EXPR, tree_type,
4760 mask_arg1,
4761 arg1_tree),
4762 ffecom_2 (BIT_AND_EXPR, tree_type,
4763 ffecom_1 (BIT_NOT_EXPR, tree_type,
4764 mask_arg1),
4765 expr_tree));
4766 expr_tree
4767 = ffecom_3 (COND_EXPR, tree_type,
4768 ffecom_truth_value
4769 (ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
4770 ffecom_2 (EQ_EXPR, integer_type_node,
4771 ffecom_1 (ABS_EXPR,
4772 integer_type_node,
4773 arg2_tree),
4774 arg3_tree),
4775 ffecom_2 (EQ_EXPR, integer_type_node,
4776 arg2_tree,
4777 integer_zero_node))),
4778 arg1_tree,
4779 expr_tree);
4780 /* Make sure SAVE_EXPRs get referenced early enough. */
4781 expr_tree
4782 = ffecom_2 (COMPOUND_EXPR, tree_type,
4783 convert (void_type_node, arg1_tree),
4784 ffecom_2 (COMPOUND_EXPR, tree_type,
4785 convert (void_type_node, arg2_tree),
4786 ffecom_2 (COMPOUND_EXPR, tree_type,
4787 convert (void_type_node,
4788 mask_arg1),
4789 ffecom_2 (COMPOUND_EXPR, tree_type,
4790 convert (void_type_node,
4791 masked_arg1),
4792 expr_tree))));
4793 expr_tree
4794 = ffecom_2 (COMPOUND_EXPR, tree_type,
4795 convert (void_type_node,
4796 arg3_tree),
4797 expr_tree);
4798 }
4799 return expr_tree;
4800
4801 case FFEINTRIN_impLOC:
4802 {
4803 tree arg1_tree = ffecom_expr (arg1);
4804
4805 expr_tree
4806 = convert (tree_type,
4807 ffecom_1 (ADDR_EXPR,
4808 build_pointer_type (TREE_TYPE (arg1_tree)),
4809 arg1_tree));
4810 }
4811 return expr_tree;
4812
4813 case FFEINTRIN_impMVBITS:
4814 {
4815 tree arg1_tree;
4816 tree arg2_tree;
4817 tree arg3_tree;
4818 ffebld arg4 = ffebld_head (ffebld_trail (list));
4819 tree arg4_tree;
4820 tree arg4_type;
4821 ffebld arg5 = ffebld_head (ffebld_trail (ffebld_trail (list)));
4822 tree arg5_tree;
4823 tree prep_arg1;
4824 tree prep_arg4;
4825 tree arg5_plus_arg3;
4826
5ff904cd
JL
4827 arg2_tree = convert (integer_type_node,
4828 ffecom_expr (arg2));
4829 arg3_tree = ffecom_save_tree (convert (integer_type_node,
4830 ffecom_expr (arg3)));
c7e4ee3a 4831 arg4_tree = ffecom_expr_rw (NULL_TREE, arg4);
5ff904cd
JL
4832 arg4_type = TREE_TYPE (arg4_tree);
4833
4834 arg1_tree = ffecom_save_tree (convert (arg4_type,
4835 ffecom_expr (arg1)));
4836
4837 arg5_tree = ffecom_save_tree (convert (integer_type_node,
4838 ffecom_expr (arg5)));
4839
5ff904cd
JL
4840 prep_arg1
4841 = ffecom_2 (LSHIFT_EXPR, arg4_type,
4842 ffecom_2 (BIT_AND_EXPR, arg4_type,
4843 ffecom_2 (RSHIFT_EXPR, arg4_type,
4844 arg1_tree,
4845 arg2_tree),
4846 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4847 ffecom_2 (LSHIFT_EXPR, arg4_type,
4848 ffecom_1 (BIT_NOT_EXPR,
4849 arg4_type,
4850 convert
4851 (arg4_type,
4852 integer_zero_node)),
4853 arg3_tree))),
4854 arg5_tree);
4855 arg5_plus_arg3
4856 = ffecom_save_tree (ffecom_2 (PLUS_EXPR, arg4_type,
4857 arg5_tree,
4858 arg3_tree));
4859 prep_arg4
4860 = ffecom_2 (LSHIFT_EXPR, arg4_type,
4861 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4862 convert (arg4_type,
4863 integer_zero_node)),
4864 arg5_plus_arg3);
4865#if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4866 prep_arg4
4867 = ffecom_3 (COND_EXPR, arg4_type,
4868 ffecom_truth_value
4869 (ffecom_2 (NE_EXPR, integer_type_node,
4870 arg5_plus_arg3,
4871 convert (TREE_TYPE (arg5_plus_arg3),
4872 TYPE_SIZE (arg4_type)))),
4873 prep_arg4,
4874 convert (arg4_type, integer_zero_node));
4875#endif
4876 prep_arg4
4877 = ffecom_2 (BIT_AND_EXPR, arg4_type,
4878 arg4_tree,
4879 ffecom_2 (BIT_IOR_EXPR, arg4_type,
4880 prep_arg4,
4881 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4882 ffecom_2 (LSHIFT_EXPR, arg4_type,
4883 ffecom_1 (BIT_NOT_EXPR,
4884 arg4_type,
4885 convert
4886 (arg4_type,
4887 integer_zero_node)),
4888 arg5_tree))));
4889 prep_arg1
4890 = ffecom_2 (BIT_IOR_EXPR, arg4_type,
4891 prep_arg1,
4892 prep_arg4);
4893#if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4894 prep_arg1
4895 = ffecom_3 (COND_EXPR, arg4_type,
4896 ffecom_truth_value
4897 (ffecom_2 (NE_EXPR, integer_type_node,
4898 arg3_tree,
4899 convert (TREE_TYPE (arg3_tree),
4900 integer_zero_node))),
4901 prep_arg1,
4902 arg4_tree);
4903 prep_arg1
4904 = ffecom_3 (COND_EXPR, arg4_type,
4905 ffecom_truth_value
4906 (ffecom_2 (NE_EXPR, integer_type_node,
4907 arg3_tree,
4908 convert (TREE_TYPE (arg3_tree),
4909 TYPE_SIZE (arg4_type)))),
4910 prep_arg1,
4911 arg1_tree);
4912#endif
4913 expr_tree
4914 = ffecom_2s (MODIFY_EXPR, void_type_node,
4915 arg4_tree,
4916 prep_arg1);
4917 /* Make sure SAVE_EXPRs get referenced early enough. */
4918 expr_tree
4919 = ffecom_2 (COMPOUND_EXPR, void_type_node,
4920 arg1_tree,
4921 ffecom_2 (COMPOUND_EXPR, void_type_node,
4922 arg3_tree,
4923 ffecom_2 (COMPOUND_EXPR, void_type_node,
4924 arg5_tree,
4925 ffecom_2 (COMPOUND_EXPR, void_type_node,
4926 arg5_plus_arg3,
4927 expr_tree))));
4928 expr_tree
4929 = ffecom_2 (COMPOUND_EXPR, void_type_node,
4930 arg4_tree,
4931 expr_tree);
4932
4933 }
4934 return expr_tree;
4935
4936 case FFEINTRIN_impDERF:
4937 case FFEINTRIN_impERF:
4938 case FFEINTRIN_impDERFC:
4939 case FFEINTRIN_impERFC:
4940 break;
4941
4942 case FFEINTRIN_impIARGC:
4943 /* extern int xargc; i__1 = xargc - 1; */
4944 expr_tree = ffecom_2 (MINUS_EXPR, TREE_TYPE (ffecom_tree_xargc_),
4945 ffecom_tree_xargc_,
4946 convert (TREE_TYPE (ffecom_tree_xargc_),
4947 integer_one_node));
4948 return expr_tree;
4949
4950 case FFEINTRIN_impSIGNAL_func:
4951 case FFEINTRIN_impSIGNAL_subr:
4952 {
4953 tree arg1_tree;
4954 tree arg2_tree;
4955 tree arg3_tree;
4956
5ff904cd
JL
4957 arg1_tree = convert (ffecom_f2c_integer_type_node,
4958 ffecom_expr (arg1));
4959 arg1_tree = ffecom_1 (ADDR_EXPR,
4960 build_pointer_type (TREE_TYPE (arg1_tree)),
4961 arg1_tree);
4962
4963 /* Pass procedure as a pointer to it, anything else by value. */
4964 if (ffeinfo_kind (ffebld_info (arg2)) == FFEINFO_kindENTITY)
4965 arg2_tree = convert (integer_type_node, ffecom_expr (arg2));
4966 else
4967 arg2_tree = ffecom_ptr_to_expr (arg2);
4968 arg2_tree = convert (TREE_TYPE (null_pointer_node),
4969 arg2_tree);
4970
4971 if (arg3 != NULL)
c7e4ee3a 4972 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
4973 else
4974 arg3_tree = NULL_TREE;
4975
5ff904cd
JL
4976 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4977 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
4978 TREE_CHAIN (arg1_tree) = arg2_tree;
4979
4980 expr_tree
4981 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4982 ffecom_gfrt_kindtype (gfrt),
4983 FALSE,
4984 ((codegen_imp == FFEINTRIN_impSIGNAL_subr) ?
4985 NULL_TREE :
4986 tree_type),
4987 arg1_tree,
c7e4ee3a
CB
4988 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4989 ffebld_nonter_hook (expr));
5ff904cd
JL
4990
4991 if (arg3_tree != NULL_TREE)
4992 expr_tree
4993 = ffecom_modify (NULL_TREE, arg3_tree,
4994 convert (TREE_TYPE (arg3_tree),
4995 expr_tree));
4996 }
4997 return expr_tree;
4998
4999 case FFEINTRIN_impALARM:
5000 {
5001 tree arg1_tree;
5002 tree arg2_tree;
5003 tree arg3_tree;
5004
5ff904cd
JL
5005 arg1_tree = convert (ffecom_f2c_integer_type_node,
5006 ffecom_expr (arg1));
5007 arg1_tree = ffecom_1 (ADDR_EXPR,
5008 build_pointer_type (TREE_TYPE (arg1_tree)),
5009 arg1_tree);
5010
5011 /* Pass procedure as a pointer to it, anything else by value. */
5012 if (ffeinfo_kind (ffebld_info (arg2)) == FFEINFO_kindENTITY)
5013 arg2_tree = convert (integer_type_node, ffecom_expr (arg2));
5014 else
5015 arg2_tree = ffecom_ptr_to_expr (arg2);
5016 arg2_tree = convert (TREE_TYPE (null_pointer_node),
5017 arg2_tree);
5018
5019 if (arg3 != NULL)
c7e4ee3a 5020 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
5021 else
5022 arg3_tree = NULL_TREE;
5023
5ff904cd
JL
5024 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5025 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5026 TREE_CHAIN (arg1_tree) = arg2_tree;
5027
5028 expr_tree
5029 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5030 ffecom_gfrt_kindtype (gfrt),
5031 FALSE,
5032 NULL_TREE,
5033 arg1_tree,
c7e4ee3a
CB
5034 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5035 ffebld_nonter_hook (expr));
5ff904cd
JL
5036
5037 if (arg3_tree != NULL_TREE)
5038 expr_tree
5039 = ffecom_modify (NULL_TREE, arg3_tree,
5040 convert (TREE_TYPE (arg3_tree),
5041 expr_tree));
5042 }
5043 return expr_tree;
5044
5045 case FFEINTRIN_impCHDIR_subr:
5046 case FFEINTRIN_impFDATE_subr:
5047 case FFEINTRIN_impFGET_subr:
5048 case FFEINTRIN_impFPUT_subr:
5049 case FFEINTRIN_impGETCWD_subr:
5050 case FFEINTRIN_impHOSTNM_subr:
5051 case FFEINTRIN_impSYSTEM_subr:
5052 case FFEINTRIN_impUNLINK_subr:
5053 {
5054 tree arg1_len = integer_zero_node;
5055 tree arg1_tree;
5056 tree arg2_tree;
5057
5ff904cd
JL
5058 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
5059
5060 if (arg2 != NULL)
c7e4ee3a 5061 arg2_tree = ffecom_expr_w (NULL_TREE, arg2);
5ff904cd
JL
5062 else
5063 arg2_tree = NULL_TREE;
5064
5ff904cd
JL
5065 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5066 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5067 TREE_CHAIN (arg1_tree) = arg1_len;
5068
5069 expr_tree
5070 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5071 ffecom_gfrt_kindtype (gfrt),
5072 FALSE,
5073 NULL_TREE,
5074 arg1_tree,
c7e4ee3a
CB
5075 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5076 ffebld_nonter_hook (expr));
5ff904cd
JL
5077
5078 if (arg2_tree != NULL_TREE)
5079 expr_tree
5080 = ffecom_modify (NULL_TREE, arg2_tree,
5081 convert (TREE_TYPE (arg2_tree),
5082 expr_tree));
5083 }
5084 return expr_tree;
5085
5086 case FFEINTRIN_impEXIT:
5087 if (arg1 != NULL)
5088 break;
5089
5090 expr_tree = build_tree_list (NULL_TREE,
5091 ffecom_1 (ADDR_EXPR,
5092 build_pointer_type
5093 (ffecom_integer_type_node),
5094 integer_zero_node));
5095
5096 return
5097 ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5098 ffecom_gfrt_kindtype (gfrt),
5099 FALSE,
5100 void_type_node,
5101 expr_tree,
c7e4ee3a
CB
5102 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5103 ffebld_nonter_hook (expr));
5ff904cd
JL
5104
5105 case FFEINTRIN_impFLUSH:
5106 if (arg1 == NULL)
5107 gfrt = FFECOM_gfrtFLUSH;
5108 else
5109 gfrt = FFECOM_gfrtFLUSH1;
5110 break;
5111
5112 case FFEINTRIN_impCHMOD_subr:
5113 case FFEINTRIN_impLINK_subr:
5114 case FFEINTRIN_impRENAME_subr:
5115 case FFEINTRIN_impSYMLNK_subr:
5116 {
5117 tree arg1_len = integer_zero_node;
5118 tree arg1_tree;
5119 tree arg2_len = integer_zero_node;
5120 tree arg2_tree;
5121 tree arg3_tree;
5122
5ff904cd
JL
5123 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
5124 arg2_tree = ffecom_arg_ptr_to_expr (arg2, &arg2_len);
5125 if (arg3 != NULL)
c7e4ee3a 5126 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
5127 else
5128 arg3_tree = NULL_TREE;
5129
5ff904cd
JL
5130 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5131 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5132 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5133 arg2_len = build_tree_list (NULL_TREE, arg2_len);
5134 TREE_CHAIN (arg1_tree) = arg2_tree;
5135 TREE_CHAIN (arg2_tree) = arg1_len;
5136 TREE_CHAIN (arg1_len) = arg2_len;
5137 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5138 ffecom_gfrt_kindtype (gfrt),
5139 FALSE,
5140 NULL_TREE,
5141 arg1_tree,
c7e4ee3a
CB
5142 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5143 ffebld_nonter_hook (expr));
5ff904cd
JL
5144 if (arg3_tree != NULL_TREE)
5145 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5146 convert (TREE_TYPE (arg3_tree),
5147 expr_tree));
5148 }
5149 return expr_tree;
5150
5151 case FFEINTRIN_impLSTAT_subr:
5152 case FFEINTRIN_impSTAT_subr:
5153 {
5154 tree arg1_len = integer_zero_node;
5155 tree arg1_tree;
5156 tree arg2_tree;
5157 tree arg3_tree;
5158
5ff904cd
JL
5159 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
5160
5161 arg2_tree = ffecom_ptr_to_expr (arg2);
5162
5163 if (arg3 != NULL)
c7e4ee3a 5164 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
5165 else
5166 arg3_tree = NULL_TREE;
5167
5ff904cd
JL
5168 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5169 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5170 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5171 TREE_CHAIN (arg1_tree) = arg2_tree;
5172 TREE_CHAIN (arg2_tree) = arg1_len;
5173 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5174 ffecom_gfrt_kindtype (gfrt),
5175 FALSE,
5176 NULL_TREE,
5177 arg1_tree,
c7e4ee3a
CB
5178 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5179 ffebld_nonter_hook (expr));
5ff904cd
JL
5180 if (arg3_tree != NULL_TREE)
5181 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5182 convert (TREE_TYPE (arg3_tree),
5183 expr_tree));
5184 }
5185 return expr_tree;
5186
5187 case FFEINTRIN_impFGETC_subr:
5188 case FFEINTRIN_impFPUTC_subr:
5189 {
5190 tree arg1_tree;
5191 tree arg2_tree;
5192 tree arg2_len = integer_zero_node;
5193 tree arg3_tree;
5194
5ff904cd
JL
5195 arg1_tree = convert (ffecom_f2c_integer_type_node,
5196 ffecom_expr (arg1));
5197 arg1_tree = ffecom_1 (ADDR_EXPR,
5198 build_pointer_type (TREE_TYPE (arg1_tree)),
5199 arg1_tree);
5200
5201 arg2_tree = ffecom_arg_ptr_to_expr (arg2, &arg2_len);
c7e4ee3a 5202 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
5203
5204 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5205 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5206 arg2_len = build_tree_list (NULL_TREE, arg2_len);
5207 TREE_CHAIN (arg1_tree) = arg2_tree;
5208 TREE_CHAIN (arg2_tree) = arg2_len;
5209
5210 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5211 ffecom_gfrt_kindtype (gfrt),
5212 FALSE,
5213 NULL_TREE,
5214 arg1_tree,
c7e4ee3a
CB
5215 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5216 ffebld_nonter_hook (expr));
5ff904cd
JL
5217 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5218 convert (TREE_TYPE (arg3_tree),
5219 expr_tree));
5220 }
5221 return expr_tree;
5222
5223 case FFEINTRIN_impFSTAT_subr:
5224 {
5225 tree arg1_tree;
5226 tree arg2_tree;
5227 tree arg3_tree;
5228
5ff904cd
JL
5229 arg1_tree = convert (ffecom_f2c_integer_type_node,
5230 ffecom_expr (arg1));
5231 arg1_tree = ffecom_1 (ADDR_EXPR,
5232 build_pointer_type (TREE_TYPE (arg1_tree)),
5233 arg1_tree);
5234
5235 arg2_tree = convert (ffecom_f2c_ptr_to_integer_type_node,
5236 ffecom_ptr_to_expr (arg2));
5237
5238 if (arg3 == NULL)
5239 arg3_tree = NULL_TREE;
5240 else
c7e4ee3a 5241 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
5242
5243 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5244 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5245 TREE_CHAIN (arg1_tree) = arg2_tree;
5246 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5247 ffecom_gfrt_kindtype (gfrt),
5248 FALSE,
5249 NULL_TREE,
5250 arg1_tree,
c7e4ee3a
CB
5251 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5252 ffebld_nonter_hook (expr));
5ff904cd
JL
5253 if (arg3_tree != NULL_TREE) {
5254 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5255 convert (TREE_TYPE (arg3_tree),
5256 expr_tree));
5257 }
5258 }
5259 return expr_tree;
5260
5261 case FFEINTRIN_impKILL_subr:
5262 {
5263 tree arg1_tree;
5264 tree arg2_tree;
5265 tree arg3_tree;
5266
5ff904cd
JL
5267 arg1_tree = convert (ffecom_f2c_integer_type_node,
5268 ffecom_expr (arg1));
5269 arg1_tree = ffecom_1 (ADDR_EXPR,
5270 build_pointer_type (TREE_TYPE (arg1_tree)),
5271 arg1_tree);
5272
5273 arg2_tree = convert (ffecom_f2c_integer_type_node,
5274 ffecom_expr (arg2));
5275 arg2_tree = ffecom_1 (ADDR_EXPR,
5276 build_pointer_type (TREE_TYPE (arg2_tree)),
5277 arg2_tree);
5278
5279 if (arg3 == NULL)
5280 arg3_tree = NULL_TREE;
5281 else
c7e4ee3a 5282 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5ff904cd
JL
5283
5284 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5285 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5286 TREE_CHAIN (arg1_tree) = arg2_tree;
5287 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5288 ffecom_gfrt_kindtype (gfrt),
5289 FALSE,
5290 NULL_TREE,
5291 arg1_tree,
c7e4ee3a
CB
5292 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5293 ffebld_nonter_hook (expr));
5ff904cd
JL
5294 if (arg3_tree != NULL_TREE) {
5295 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5296 convert (TREE_TYPE (arg3_tree),
5297 expr_tree));
5298 }
5299 }
5300 return expr_tree;
5301
5302 case FFEINTRIN_impCTIME_subr:
5303 case FFEINTRIN_impTTYNAM_subr:
5304 {
5305 tree arg1_len = integer_zero_node;
5306 tree arg1_tree;
5307 tree arg2_tree;
5308
2b0bdd9a 5309 arg1_tree = ffecom_arg_ptr_to_expr (arg2, &arg1_len);
5ff904cd 5310
c56f65d6 5311 arg2_tree = convert (((codegen_imp == FFEINTRIN_impCTIME_subr) ?
5ff904cd
JL
5312 ffecom_f2c_longint_type_node :
5313 ffecom_f2c_integer_type_node),
2b0bdd9a 5314 ffecom_expr (arg1));
5ff904cd
JL
5315 arg2_tree = ffecom_1 (ADDR_EXPR,
5316 build_pointer_type (TREE_TYPE (arg2_tree)),
5317 arg2_tree);
5318
5ff904cd
JL
5319 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5320 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5321 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5322 TREE_CHAIN (arg1_len) = arg2_tree;
5323 TREE_CHAIN (arg1_tree) = arg1_len;
5324
5325 expr_tree
5326 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5327 ffecom_gfrt_kindtype (gfrt),
5328 FALSE,
5329 NULL_TREE,
5330 arg1_tree,
c7e4ee3a
CB
5331 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5332 ffebld_nonter_hook (expr));
2b0bdd9a 5333 TREE_SIDE_EFFECTS (expr_tree) = 1;
5ff904cd
JL
5334 }
5335 return expr_tree;
5336
5337 case FFEINTRIN_impIRAND:
5338 case FFEINTRIN_impRAND:
5339 /* Arg defaults to 0 (normal random case) */
5340 {
5341 tree arg1_tree;
5342
5343 if (arg1 == NULL)
5344 arg1_tree = ffecom_integer_zero_node;
5345 else
5346 arg1_tree = ffecom_expr (arg1);
5347 arg1_tree = convert (ffecom_f2c_integer_type_node,
5348 arg1_tree);
5349 arg1_tree = ffecom_1 (ADDR_EXPR,
5350 build_pointer_type (TREE_TYPE (arg1_tree)),
5351 arg1_tree);
5352 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5353
5354 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5355 ffecom_gfrt_kindtype (gfrt),
5356 FALSE,
5357 ((codegen_imp == FFEINTRIN_impIRAND) ?
5358 ffecom_f2c_integer_type_node :
de7f278a 5359 ffecom_f2c_real_type_node),
5ff904cd
JL
5360 arg1_tree,
5361 dest_tree, dest, dest_used,
c7e4ee3a
CB
5362 NULL_TREE, TRUE,
5363 ffebld_nonter_hook (expr));
5ff904cd
JL
5364 }
5365 return expr_tree;
5366
5367 case FFEINTRIN_impFTELL_subr:
5368 case FFEINTRIN_impUMASK_subr:
5369 {
5370 tree arg1_tree;
5371 tree arg2_tree;
5372
5ff904cd
JL
5373 arg1_tree = convert (ffecom_f2c_integer_type_node,
5374 ffecom_expr (arg1));
5375 arg1_tree = ffecom_1 (ADDR_EXPR,
5376 build_pointer_type (TREE_TYPE (arg1_tree)),
5377 arg1_tree);
5378
5379 if (arg2 == NULL)
5380 arg2_tree = NULL_TREE;
5381 else
c7e4ee3a 5382 arg2_tree = ffecom_expr_w (NULL_TREE, arg2);
5ff904cd
JL
5383
5384 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5385 ffecom_gfrt_kindtype (gfrt),
5386 FALSE,
5387 NULL_TREE,
5388 build_tree_list (NULL_TREE, arg1_tree),
5389 NULL_TREE, NULL, NULL, NULL_TREE,
c7e4ee3a
CB
5390 TRUE,
5391 ffebld_nonter_hook (expr));
5ff904cd
JL
5392 if (arg2_tree != NULL_TREE) {
5393 expr_tree = ffecom_modify (NULL_TREE, arg2_tree,
5394 convert (TREE_TYPE (arg2_tree),
5395 expr_tree));
5396 }
5397 }
5398 return expr_tree;
5399
5400 case FFEINTRIN_impCPU_TIME:
5401 case FFEINTRIN_impSECOND_subr:
5402 {
5403 tree arg1_tree;
5404
c7e4ee3a 5405 arg1_tree = ffecom_expr_w (NULL_TREE, arg1);
5ff904cd
JL
5406
5407 expr_tree
5408 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5409 ffecom_gfrt_kindtype (gfrt),
5410 FALSE,
5411 NULL_TREE,
5412 NULL_TREE,
c7e4ee3a
CB
5413 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5414 ffebld_nonter_hook (expr));
5ff904cd
JL
5415
5416 expr_tree
5417 = ffecom_modify (NULL_TREE, arg1_tree,
5418 convert (TREE_TYPE (arg1_tree),
5419 expr_tree));
5420 }
5421 return expr_tree;
5422
5423 case FFEINTRIN_impDTIME_subr:
5424 case FFEINTRIN_impETIME_subr:
5425 {
5426 tree arg1_tree;
2b0bdd9a 5427 tree result_tree;
5ff904cd 5428
2b0bdd9a 5429 result_tree = ffecom_expr_w (NULL_TREE, arg2);
5ff904cd 5430
2b0bdd9a 5431 arg1_tree = ffecom_ptr_to_expr (arg1);
5ff904cd 5432
5ff904cd
JL
5433 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5434 ffecom_gfrt_kindtype (gfrt),
5435 FALSE,
5436 NULL_TREE,
2b0bdd9a 5437 build_tree_list (NULL_TREE, arg1_tree),
5ff904cd 5438 NULL_TREE, NULL, NULL, NULL_TREE,
c7e4ee3a
CB
5439 TRUE,
5440 ffebld_nonter_hook (expr));
2b0bdd9a
CB
5441 expr_tree = ffecom_modify (NULL_TREE, result_tree,
5442 convert (TREE_TYPE (result_tree),
5ff904cd
JL
5443 expr_tree));
5444 }
5445 return expr_tree;
5446
c7e4ee3a 5447 /* Straightforward calls of libf2c routines: */
5ff904cd
JL
5448 case FFEINTRIN_impABORT:
5449 case FFEINTRIN_impACCESS:
5450 case FFEINTRIN_impBESJ0:
5451 case FFEINTRIN_impBESJ1:
5452 case FFEINTRIN_impBESJN:
5453 case FFEINTRIN_impBESY0:
5454 case FFEINTRIN_impBESY1:
5455 case FFEINTRIN_impBESYN:
5456 case FFEINTRIN_impCHDIR_func:
5457 case FFEINTRIN_impCHMOD_func:
5458 case FFEINTRIN_impDATE:
9e8e701d 5459 case FFEINTRIN_impDATE_AND_TIME:
5ff904cd
JL
5460 case FFEINTRIN_impDBESJ0:
5461 case FFEINTRIN_impDBESJ1:
5462 case FFEINTRIN_impDBESJN:
5463 case FFEINTRIN_impDBESY0:
5464 case FFEINTRIN_impDBESY1:
5465 case FFEINTRIN_impDBESYN:
5466 case FFEINTRIN_impDTIME_func:
5467 case FFEINTRIN_impETIME_func:
5468 case FFEINTRIN_impFGETC_func:
5469 case FFEINTRIN_impFGET_func:
5470 case FFEINTRIN_impFNUM:
5471 case FFEINTRIN_impFPUTC_func:
5472 case FFEINTRIN_impFPUT_func:
5473 case FFEINTRIN_impFSEEK:
5474 case FFEINTRIN_impFSTAT_func:
5475 case FFEINTRIN_impFTELL_func:
5476 case FFEINTRIN_impGERROR:
5477 case FFEINTRIN_impGETARG:
5478 case FFEINTRIN_impGETCWD_func:
5479 case FFEINTRIN_impGETENV:
5480 case FFEINTRIN_impGETGID:
5481 case FFEINTRIN_impGETLOG:
5482 case FFEINTRIN_impGETPID:
5483 case FFEINTRIN_impGETUID:
5484 case FFEINTRIN_impGMTIME:
5485 case FFEINTRIN_impHOSTNM_func:
5486 case FFEINTRIN_impIDATE_unix:
5487 case FFEINTRIN_impIDATE_vxt:
5488 case FFEINTRIN_impIERRNO:
5489 case FFEINTRIN_impISATTY:
5490 case FFEINTRIN_impITIME:
5491 case FFEINTRIN_impKILL_func:
5492 case FFEINTRIN_impLINK_func:
5493 case FFEINTRIN_impLNBLNK:
5494 case FFEINTRIN_impLSTAT_func:
5495 case FFEINTRIN_impLTIME:
5496 case FFEINTRIN_impMCLOCK8:
5497 case FFEINTRIN_impMCLOCK:
5498 case FFEINTRIN_impPERROR:
5499 case FFEINTRIN_impRENAME_func:
5500 case FFEINTRIN_impSECNDS:
5501 case FFEINTRIN_impSECOND_func:
5502 case FFEINTRIN_impSLEEP:
5503 case FFEINTRIN_impSRAND:
5504 case FFEINTRIN_impSTAT_func:
5505 case FFEINTRIN_impSYMLNK_func:
5506 case FFEINTRIN_impSYSTEM_CLOCK:
5507 case FFEINTRIN_impSYSTEM_func:
5508 case FFEINTRIN_impTIME8:
5509 case FFEINTRIN_impTIME_unix:
5510 case FFEINTRIN_impTIME_vxt:
5511 case FFEINTRIN_impUMASK_func:
5512 case FFEINTRIN_impUNLINK_func:
5513 break;
5514
5515 case FFEINTRIN_impCTIME_func: /* CHARACTER functions not handled here. */
5516 case FFEINTRIN_impFDATE_func: /* CHARACTER functions not handled here. */
5517 case FFEINTRIN_impTTYNAM_func: /* CHARACTER functions not handled here. */
5518 case FFEINTRIN_impNONE:
5519 case FFEINTRIN_imp: /* Hush up gcc warning. */
5520 fprintf (stderr, "No %s implementation.\n",
5521 ffeintrin_name_implementation (ffebld_symter_implementation (ffebld_left (expr))));
5522 assert ("unimplemented intrinsic" == NULL);
5523 return error_mark_node;
5524 }
5525
5526 assert (gfrt != FFECOM_gfrt); /* Must have an implementation! */
5527
5ff904cd
JL
5528 expr_tree = ffecom_arglist_expr_ (ffecom_gfrt_args_ (gfrt),
5529 ffebld_right (expr));
5ff904cd
JL
5530
5531 return ffecom_call_ (ffecom_gfrt_tree_ (gfrt), ffecom_gfrt_kindtype (gfrt),
5532 (ffe_is_f2c_library () && ffecom_gfrt_complex_[gfrt]),
5533 tree_type,
5534 expr_tree, dest_tree, dest, dest_used,
c7e4ee3a
CB
5535 NULL_TREE, TRUE,
5536 ffebld_nonter_hook (expr));
5ff904cd 5537
c7e4ee3a
CB
5538 /* See bottom of this file for f2c transforms used to determine
5539 many of the above implementations. The info seems to confuse
5540 Emacs's C mode indentation, which is why it's been moved to
5541 the bottom of this source file. */
5542}
5ff904cd 5543
c7e4ee3a
CB
5544#endif
5545/* For power (exponentiation) where right-hand operand is type INTEGER,
5546 generate in-line code to do it the fast way (which, if the operand
5547 is a constant, might just mean a series of multiplies). */
5ff904cd 5548
c7e4ee3a
CB
5549#if FFECOM_targetCURRENT == FFECOM_targetGCC
5550static tree
5551ffecom_expr_power_integer_ (ffebld expr)
5552{
5553 tree l = ffecom_expr (ffebld_left (expr));
5554 tree r = ffecom_expr (ffebld_right (expr));
5555 tree ltype = TREE_TYPE (l);
5556 tree rtype = TREE_TYPE (r);
5557 tree result = NULL_TREE;
5ff904cd 5558
c7e4ee3a
CB
5559 if (l == error_mark_node
5560 || r == error_mark_node)
5561 return error_mark_node;
5ff904cd 5562
c7e4ee3a
CB
5563 if (TREE_CODE (r) == INTEGER_CST)
5564 {
5565 int sgn = tree_int_cst_sgn (r);
5ff904cd 5566
c7e4ee3a
CB
5567 if (sgn == 0)
5568 return convert (ltype, integer_one_node);
5ff904cd 5569
c7e4ee3a
CB
5570 if ((TREE_CODE (ltype) == INTEGER_TYPE)
5571 && (sgn < 0))
5572 {
5573 /* Reciprocal of integer is either 0, -1, or 1, so after
5574 calculating that (which we leave to the back end to do
5575 or not do optimally), don't bother with any multiplying. */
5ff904cd 5576
c7e4ee3a
CB
5577 result = ffecom_tree_divide_ (ltype,
5578 convert (ltype, integer_one_node),
5579 l,
5580 NULL_TREE, NULL, NULL, NULL_TREE);
5581 r = ffecom_1 (NEGATE_EXPR,
5582 rtype,
5583 r);
5584 if ((TREE_INT_CST_LOW (r) & 1) == 0)
5585 result = ffecom_1 (ABS_EXPR, rtype,
5586 result);
5587 }
5ff904cd 5588
c7e4ee3a
CB
5589 /* Generate appropriate series of multiplies, preceded
5590 by divide if the exponent is negative. */
5ff904cd 5591
c7e4ee3a 5592 l = save_expr (l);
5ff904cd 5593
c7e4ee3a
CB
5594 if (sgn < 0)
5595 {
5596 l = ffecom_tree_divide_ (ltype,
5597 convert (ltype, integer_one_node),
5598 l,
5599 NULL_TREE, NULL, NULL,
5600 ffebld_nonter_hook (expr));
5601 r = ffecom_1 (NEGATE_EXPR, rtype, r);
5602 assert (TREE_CODE (r) == INTEGER_CST);
5ff904cd 5603
c7e4ee3a
CB
5604 if (tree_int_cst_sgn (r) < 0)
5605 { /* The "most negative" number. */
5606 r = ffecom_1 (NEGATE_EXPR, rtype,
5607 ffecom_2 (RSHIFT_EXPR, rtype,
5608 r,
5609 integer_one_node));
5610 l = save_expr (l);
5611 l = ffecom_2 (MULT_EXPR, ltype,
5612 l,
5613 l);
5614 }
5615 }
5ff904cd 5616
c7e4ee3a
CB
5617 for (;;)
5618 {
5619 if (TREE_INT_CST_LOW (r) & 1)
5620 {
5621 if (result == NULL_TREE)
5622 result = l;
5623 else
5624 result = ffecom_2 (MULT_EXPR, ltype,
5625 result,
5626 l);
5627 }
5ff904cd 5628
c7e4ee3a
CB
5629 r = ffecom_2 (RSHIFT_EXPR, rtype,
5630 r,
5631 integer_one_node);
5632 if (integer_zerop (r))
5633 break;
5634 assert (TREE_CODE (r) == INTEGER_CST);
5ff904cd 5635
c7e4ee3a
CB
5636 l = save_expr (l);
5637 l = ffecom_2 (MULT_EXPR, ltype,
5638 l,
5639 l);
5640 }
5641 return result;
5642 }
5ff904cd 5643
c7e4ee3a
CB
5644 /* Though rhs isn't a constant, in-line code cannot be expanded
5645 while transforming dummies
5646 because the back end cannot be easily convinced to generate
5647 stores (MODIFY_EXPR), handle temporaries, and so on before
5648 all the appropriate rtx's have been generated for things like
5649 dummy args referenced in rhs -- which doesn't happen until
5650 store_parm_decls() is called (expand_function_start, I believe,
5651 does the actual rtx-stuffing of PARM_DECLs).
5ff904cd 5652
c7e4ee3a
CB
5653 So, in this case, let the caller generate the call to the
5654 run-time-library function to evaluate the power for us. */
5ff904cd 5655
c7e4ee3a
CB
5656 if (ffecom_transform_only_dummies_)
5657 return NULL_TREE;
5ff904cd 5658
c7e4ee3a
CB
5659 /* Right-hand operand not a constant, expand in-line code to figure
5660 out how to do the multiplies, &c.
5ff904cd 5661
c7e4ee3a
CB
5662 The returned expression is expressed this way in GNU C, where l and
5663 r are the "inputs":
5ff904cd 5664
c7e4ee3a
CB
5665 ({ typeof (r) rtmp = r;
5666 typeof (l) ltmp = l;
5667 typeof (l) result;
5ff904cd 5668
c7e4ee3a
CB
5669 if (rtmp == 0)
5670 result = 1;
5671 else
5672 {
5673 if ((basetypeof (l) == basetypeof (int))
5674 && (rtmp < 0))
5675 {
5676 result = ((typeof (l)) 1) / ltmp;
5677 if ((ltmp < 0) && (((-rtmp) & 1) == 0))
5678 result = -result;
5679 }
5680 else
5681 {
5682 result = 1;
5683 if ((basetypeof (l) != basetypeof (int))
5684 && (rtmp < 0))
5685 {
5686 ltmp = ((typeof (l)) 1) / ltmp;
5687 rtmp = -rtmp;
5688 if (rtmp < 0)
5689 {
5690 rtmp = -(rtmp >> 1);
5691 ltmp *= ltmp;
5692 }
5693 }
5694 for (;;)
5695 {
5696 if (rtmp & 1)
5697 result *= ltmp;
5698 if ((rtmp >>= 1) == 0)
5699 break;
5700 ltmp *= ltmp;
5701 }
5702 }
5703 }
5704 result;
5705 })
5ff904cd 5706
c7e4ee3a
CB
5707 Note that some of the above is compile-time collapsable, such as
5708 the first part of the if statements that checks the base type of
5709 l against int. The if statements are phrased that way to suggest
5710 an easy way to generate the if/else constructs here, knowing that
5711 the back end should (and probably does) eliminate the resulting
5712 dead code (either the int case or the non-int case), something
5713 it couldn't do without the redundant phrasing, requiring explicit
5714 dead-code elimination here, which would be kind of difficult to
5715 read. */
5ff904cd 5716
c7e4ee3a
CB
5717 {
5718 tree rtmp;
5719 tree ltmp;
5720 tree divide;
5721 tree basetypeof_l_is_int;
5722 tree se;
5723 tree t;
5ff904cd 5724
c7e4ee3a
CB
5725 basetypeof_l_is_int
5726 = build_int_2 ((TREE_CODE (ltype) == INTEGER_TYPE), 0);
5ff904cd 5727
c7e4ee3a 5728 se = expand_start_stmt_expr ();
5ff904cd 5729
c7e4ee3a
CB
5730 ffecom_start_compstmt ();
5731
5732#ifndef HAHA
5733 rtmp = ffecom_make_tempvar ("power_r", rtype,
5734 FFETARGET_charactersizeNONE, -1);
5735 ltmp = ffecom_make_tempvar ("power_l", ltype,
5736 FFETARGET_charactersizeNONE, -1);
5737 result = ffecom_make_tempvar ("power_res", ltype,
5738 FFETARGET_charactersizeNONE, -1);
5739 if (TREE_CODE (ltype) == COMPLEX_TYPE
5740 || TREE_CODE (ltype) == RECORD_TYPE)
5741 divide = ffecom_make_tempvar ("power_div", ltype,
5742 FFETARGET_charactersizeNONE, -1);
5743 else
5744 divide = NULL_TREE;
5745#else /* HAHA */
5746 {
5747 tree hook;
5748
5749 hook = ffebld_nonter_hook (expr);
5750 assert (hook);
5751 assert (TREE_CODE (hook) == TREE_VEC);
5752 assert (TREE_VEC_LENGTH (hook) == 4);
5753 rtmp = TREE_VEC_ELT (hook, 0);
5754 ltmp = TREE_VEC_ELT (hook, 1);
5755 result = TREE_VEC_ELT (hook, 2);
5756 divide = TREE_VEC_ELT (hook, 3);
5757 if (TREE_CODE (ltype) == COMPLEX_TYPE
5758 || TREE_CODE (ltype) == RECORD_TYPE)
5759 assert (divide);
5760 else
5761 assert (! divide);
5762 }
5763#endif /* HAHA */
5ff904cd 5764
c7e4ee3a
CB
5765 expand_expr_stmt (ffecom_modify (void_type_node,
5766 rtmp,
5767 r));
5768 expand_expr_stmt (ffecom_modify (void_type_node,
5769 ltmp,
5770 l));
5771 expand_start_cond (ffecom_truth_value
5772 (ffecom_2 (EQ_EXPR, integer_type_node,
5773 rtmp,
5774 convert (rtype, integer_zero_node))),
5775 0);
5776 expand_expr_stmt (ffecom_modify (void_type_node,
5777 result,
5778 convert (ltype, integer_one_node)));
5779 expand_start_else ();
5780 if (! integer_zerop (basetypeof_l_is_int))
5781 {
5782 expand_start_cond (ffecom_2 (LT_EXPR, integer_type_node,
5783 rtmp,
5784 convert (rtype,
5785 integer_zero_node)),
5786 0);
5787 expand_expr_stmt (ffecom_modify (void_type_node,
5788 result,
5789 ffecom_tree_divide_
5790 (ltype,
5791 convert (ltype, integer_one_node),
5792 ltmp,
5793 NULL_TREE, NULL, NULL,
5794 divide)));
5795 expand_start_cond (ffecom_truth_value
5796 (ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
5797 ffecom_2 (LT_EXPR, integer_type_node,
5798 ltmp,
5799 convert (ltype,
5800 integer_zero_node)),
5801 ffecom_2 (EQ_EXPR, integer_type_node,
5802 ffecom_2 (BIT_AND_EXPR,
5803 rtype,
5804 ffecom_1 (NEGATE_EXPR,
5805 rtype,
5806 rtmp),
5807 convert (rtype,
5808 integer_one_node)),
5809 convert (rtype,
5810 integer_zero_node)))),
5811 0);
5812 expand_expr_stmt (ffecom_modify (void_type_node,
5813 result,
5814 ffecom_1 (NEGATE_EXPR,
5815 ltype,
5816 result)));
5817 expand_end_cond ();
5818 expand_start_else ();
5819 }
5820 expand_expr_stmt (ffecom_modify (void_type_node,
5821 result,
5822 convert (ltype, integer_one_node)));
5823 expand_start_cond (ffecom_truth_value
5824 (ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
5825 ffecom_truth_value_invert
5826 (basetypeof_l_is_int),
5827 ffecom_2 (LT_EXPR, integer_type_node,
5828 rtmp,
5829 convert (rtype,
5830 integer_zero_node)))),
5831 0);
5832 expand_expr_stmt (ffecom_modify (void_type_node,
5833 ltmp,
5834 ffecom_tree_divide_
5835 (ltype,
5836 convert (ltype, integer_one_node),
5837 ltmp,
5838 NULL_TREE, NULL, NULL,
5839 divide)));
5840 expand_expr_stmt (ffecom_modify (void_type_node,
5841 rtmp,
5842 ffecom_1 (NEGATE_EXPR, rtype,
5843 rtmp)));
5844 expand_start_cond (ffecom_truth_value
5845 (ffecom_2 (LT_EXPR, integer_type_node,
5846 rtmp,
5847 convert (rtype, integer_zero_node))),
5848 0);
5849 expand_expr_stmt (ffecom_modify (void_type_node,
5850 rtmp,
5851 ffecom_1 (NEGATE_EXPR, rtype,
5852 ffecom_2 (RSHIFT_EXPR,
5853 rtype,
5854 rtmp,
5855 integer_one_node))));
5856 expand_expr_stmt (ffecom_modify (void_type_node,
5857 ltmp,
5858 ffecom_2 (MULT_EXPR, ltype,
5859 ltmp,
5860 ltmp)));
5861 expand_end_cond ();
5862 expand_end_cond ();
5863 expand_start_loop (1);
5864 expand_start_cond (ffecom_truth_value
5865 (ffecom_2 (BIT_AND_EXPR, rtype,
5866 rtmp,
5867 convert (rtype, integer_one_node))),
5868 0);
5869 expand_expr_stmt (ffecom_modify (void_type_node,
5870 result,
5871 ffecom_2 (MULT_EXPR, ltype,
5872 result,
5873 ltmp)));
5874 expand_end_cond ();
5875 expand_exit_loop_if_false (NULL,
5876 ffecom_truth_value
5877 (ffecom_modify (rtype,
5878 rtmp,
5879 ffecom_2 (RSHIFT_EXPR,
5880 rtype,
5881 rtmp,
5882 integer_one_node))));
5883 expand_expr_stmt (ffecom_modify (void_type_node,
5884 ltmp,
5885 ffecom_2 (MULT_EXPR, ltype,
5886 ltmp,
5887 ltmp)));
5888 expand_end_loop ();
5889 expand_end_cond ();
5890 if (!integer_zerop (basetypeof_l_is_int))
5891 expand_end_cond ();
5892 expand_expr_stmt (result);
5ff904cd 5893
c7e4ee3a 5894 t = ffecom_end_compstmt ();
5ff904cd 5895
c7e4ee3a 5896 result = expand_end_stmt_expr (se);
5ff904cd 5897
c7e4ee3a 5898 /* This code comes from c-parse.in, after its expand_end_stmt_expr. */
5ff904cd 5899
c7e4ee3a
CB
5900 if (TREE_CODE (t) == BLOCK)
5901 {
5902 /* Make a BIND_EXPR for the BLOCK already made. */
5903 result = build (BIND_EXPR, TREE_TYPE (result),
5904 NULL_TREE, result, t);
5905 /* Remove the block from the tree at this point.
5906 It gets put back at the proper place
5907 when the BIND_EXPR is expanded. */
5908 delete_block (t);
5909 }
5910 else
5911 result = t;
5912 }
5ff904cd 5913
c7e4ee3a
CB
5914 return result;
5915}
5ff904cd 5916
c7e4ee3a
CB
5917#endif
5918/* ffecom_expr_transform_ -- Transform symbols in expr
5ff904cd 5919
c7e4ee3a
CB
5920 ffebld expr; // FFE expression.
5921 ffecom_expr_transform_ (expr);
5ff904cd 5922
c7e4ee3a 5923 Recursive descent on expr while transforming any untransformed SYMTERs. */
5ff904cd 5924
c7e4ee3a
CB
5925#if FFECOM_targetCURRENT == FFECOM_targetGCC
5926static void
5927ffecom_expr_transform_ (ffebld expr)
5928{
5929 tree t;
5930 ffesymbol s;
5ff904cd 5931
c7e4ee3a 5932tail_recurse: /* :::::::::::::::::::: */
5ff904cd 5933
c7e4ee3a
CB
5934 if (expr == NULL)
5935 return;
5ff904cd 5936
c7e4ee3a
CB
5937 switch (ffebld_op (expr))
5938 {
5939 case FFEBLD_opSYMTER:
5940 s = ffebld_symter (expr);
5941 t = ffesymbol_hook (s).decl_tree;
5942 if ((t == NULL_TREE)
5943 && ((ffesymbol_kind (s) != FFEINFO_kindNONE)
5944 || ((ffesymbol_where (s) != FFEINFO_whereNONE)
5945 && (ffesymbol_where (s) != FFEINFO_whereINTRINSIC))))
5946 {
5947 s = ffecom_sym_transform_ (s);
5948 t = ffesymbol_hook (s).decl_tree; /* Sfunc expr non-dummy,
5949 DIMENSION expr? */
5950 }
5951 break; /* Ok if (t == NULL) here. */
5ff904cd 5952
c7e4ee3a
CB
5953 case FFEBLD_opITEM:
5954 ffecom_expr_transform_ (ffebld_head (expr));
5955 expr = ffebld_trail (expr);
5956 goto tail_recurse; /* :::::::::::::::::::: */
5ff904cd 5957
c7e4ee3a
CB
5958 default:
5959 break;
5960 }
5ff904cd 5961
c7e4ee3a
CB
5962 switch (ffebld_arity (expr))
5963 {
5964 case 2:
5965 ffecom_expr_transform_ (ffebld_left (expr));
5966 expr = ffebld_right (expr);
5967 goto tail_recurse; /* :::::::::::::::::::: */
5ff904cd 5968
c7e4ee3a
CB
5969 case 1:
5970 expr = ffebld_left (expr);
5971 goto tail_recurse; /* :::::::::::::::::::: */
5ff904cd 5972
c7e4ee3a
CB
5973 default:
5974 break;
5975 }
5ff904cd 5976
c7e4ee3a
CB
5977 return;
5978}
5ff904cd 5979
c7e4ee3a
CB
5980#endif
5981/* Make a type based on info in live f2c.h file. */
5ff904cd 5982
c7e4ee3a
CB
5983#if FFECOM_targetCURRENT == FFECOM_targetGCC
5984static void
5985ffecom_f2c_make_type_ (tree *type, int tcode, const char *name)
5986{
5987 switch (tcode)
5988 {
5989 case FFECOM_f2ccodeCHAR:
5990 *type = make_signed_type (CHAR_TYPE_SIZE);
5991 break;
5ff904cd 5992
c7e4ee3a
CB
5993 case FFECOM_f2ccodeSHORT:
5994 *type = make_signed_type (SHORT_TYPE_SIZE);
5995 break;
5ff904cd 5996
c7e4ee3a
CB
5997 case FFECOM_f2ccodeINT:
5998 *type = make_signed_type (INT_TYPE_SIZE);
5999 break;
5ff904cd 6000
c7e4ee3a
CB
6001 case FFECOM_f2ccodeLONG:
6002 *type = make_signed_type (LONG_TYPE_SIZE);
6003 break;
5ff904cd 6004
c7e4ee3a
CB
6005 case FFECOM_f2ccodeLONGLONG:
6006 *type = make_signed_type (LONG_LONG_TYPE_SIZE);
6007 break;
5ff904cd 6008
c7e4ee3a
CB
6009 case FFECOM_f2ccodeCHARPTR:
6010 *type = build_pointer_type (DEFAULT_SIGNED_CHAR
6011 ? signed_char_type_node
6012 : unsigned_char_type_node);
6013 break;
5ff904cd 6014
c7e4ee3a
CB
6015 case FFECOM_f2ccodeFLOAT:
6016 *type = make_node (REAL_TYPE);
6017 TYPE_PRECISION (*type) = FLOAT_TYPE_SIZE;
6018 layout_type (*type);
6019 break;
6020
6021 case FFECOM_f2ccodeDOUBLE:
6022 *type = make_node (REAL_TYPE);
6023 TYPE_PRECISION (*type) = DOUBLE_TYPE_SIZE;
6024 layout_type (*type);
6025 break;
6026
6027 case FFECOM_f2ccodeLONGDOUBLE:
6028 *type = make_node (REAL_TYPE);
6029 TYPE_PRECISION (*type) = LONG_DOUBLE_TYPE_SIZE;
6030 layout_type (*type);
6031 break;
5ff904cd 6032
c7e4ee3a
CB
6033 case FFECOM_f2ccodeTWOREALS:
6034 *type = ffecom_make_complex_type_ (ffecom_f2c_real_type_node);
6035 break;
5ff904cd 6036
c7e4ee3a
CB
6037 case FFECOM_f2ccodeTWODOUBLEREALS:
6038 *type = ffecom_make_complex_type_ (ffecom_f2c_doublereal_type_node);
6039 break;
5ff904cd 6040
c7e4ee3a
CB
6041 default:
6042 assert ("unexpected FFECOM_f2ccodeXYZZY!" == NULL);
6043 *type = error_mark_node;
6044 return;
6045 }
5ff904cd 6046
c7e4ee3a
CB
6047 pushdecl (build_decl (TYPE_DECL,
6048 ffecom_get_invented_identifier ("__g77_f2c_%s",
6049 name, -1),
6050 *type));
6051}
5ff904cd 6052
c7e4ee3a
CB
6053#endif
6054#if FFECOM_targetCURRENT == FFECOM_targetGCC
6055/* Set the f2c list-directed-I/O code for whatever (integral) type has the
6056 given size. */
5ff904cd 6057
c7e4ee3a
CB
6058static void
6059ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size,
6060 int code)
6061{
6062 int j;
6063 tree t;
5ff904cd 6064
c7e4ee3a
CB
6065 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
6066 if (((t = ffecom_tree_type[bt][j]) != NULL_TREE)
6067 && (TREE_INT_CST_LOW (TYPE_SIZE (t)) == size))
6068 {
6069 assert (code != -1);
6070 ffecom_f2c_typecode_[bt][j] = code;
6071 code = -1;
6072 }
6073}
5ff904cd 6074
c7e4ee3a
CB
6075#endif
6076/* Finish up globals after doing all program units in file
5ff904cd 6077
c7e4ee3a 6078 Need to handle only uninitialized COMMON areas. */
5ff904cd 6079
c7e4ee3a
CB
6080#if FFECOM_targetCURRENT == FFECOM_targetGCC
6081static ffeglobal
6082ffecom_finish_global_ (ffeglobal global)
6083{
6084 tree cbtype;
6085 tree cbt;
6086 tree size;
5ff904cd 6087
c7e4ee3a
CB
6088 if (ffeglobal_type (global) != FFEGLOBAL_typeCOMMON)
6089 return global;
5ff904cd 6090
c7e4ee3a
CB
6091 if (ffeglobal_common_init (global))
6092 return global;
5ff904cd 6093
c7e4ee3a
CB
6094 cbt = ffeglobal_hook (global);
6095 if ((cbt == NULL_TREE)
6096 || !ffeglobal_common_have_size (global))
6097 return global; /* No need to make common, never ref'd. */
5ff904cd 6098
c7e4ee3a 6099 suspend_momentary ();
5ff904cd 6100
c7e4ee3a 6101 DECL_EXTERNAL (cbt) = 0;
5ff904cd 6102
c7e4ee3a 6103 /* Give the array a size now. */
5ff904cd 6104
c7e4ee3a
CB
6105 size = build_int_2 ((ffeglobal_common_size (global)
6106 + ffeglobal_common_pad (global)) - 1,
6107 0);
5ff904cd 6108
c7e4ee3a
CB
6109 cbtype = TREE_TYPE (cbt);
6110 TYPE_DOMAIN (cbtype) = build_range_type (integer_type_node,
6111 integer_zero_node,
6112 size);
6113 if (!TREE_TYPE (size))
6114 TREE_TYPE (size) = TYPE_DOMAIN (cbtype);
6115 layout_type (cbtype);
5ff904cd 6116
c7e4ee3a
CB
6117 cbt = start_decl (cbt, FALSE);
6118 assert (cbt == ffeglobal_hook (global));
5ff904cd 6119
c7e4ee3a 6120 finish_decl (cbt, NULL_TREE, FALSE);
5ff904cd 6121
c7e4ee3a
CB
6122 return global;
6123}
5ff904cd 6124
c7e4ee3a
CB
6125#endif
6126/* Finish up any untransformed symbols. */
5ff904cd 6127
c7e4ee3a
CB
6128#if FFECOM_targetCURRENT == FFECOM_targetGCC
6129static ffesymbol
6130ffecom_finish_symbol_transform_ (ffesymbol s)
5ff904cd 6131{
c7e4ee3a
CB
6132 if ((s == NULL) || (TREE_CODE (current_function_decl) == ERROR_MARK))
6133 return s;
5ff904cd 6134
c7e4ee3a
CB
6135 /* It's easy to know to transform an untransformed symbol, to make sure
6136 we put out debugging info for it. But COMMON variables, unlike
6137 EQUIVALENCE ones, aren't given declarations in addition to the
6138 tree expressions that specify offsets, because COMMON variables
6139 can be referenced in the outer scope where only dummy arguments
6140 (PARM_DECLs) should really be seen. To be safe, just don't do any
6141 VAR_DECLs for COMMON variables when we transform them for real
6142 use, and therefore we do all the VAR_DECL creating here. */
5ff904cd 6143
c7e4ee3a
CB
6144 if (ffesymbol_hook (s).decl_tree == NULL_TREE)
6145 {
6146 if (ffesymbol_kind (s) != FFEINFO_kindNONE
6147 || (ffesymbol_where (s) != FFEINFO_whereNONE
6148 && ffesymbol_where (s) != FFEINFO_whereINTRINSIC
6149 && ffesymbol_where (s) != FFEINFO_whereDUMMY))
6150 /* Not transformed, and not CHARACTER*(*), and not a dummy
6151 argument, which can happen only if the entry point names
6152 it "rides in on" are all invalidated for other reasons. */
6153 s = ffecom_sym_transform_ (s);
6154 }
5ff904cd 6155
c7e4ee3a
CB
6156 if ((ffesymbol_where (s) == FFEINFO_whereCOMMON)
6157 && (ffesymbol_hook (s).decl_tree != error_mark_node))
6158 {
6159#ifdef SOMEONE_GETS_DEBUG_SUPPORT_WORKING
6160 int yes = suspend_momentary ();
5ff904cd 6161
c7e4ee3a
CB
6162 /* This isn't working, at least for dbxout. The .s file looks
6163 okay to me (burley), but in gdb 4.9 at least, the variables
6164 appear to reside somewhere outside of the common area, so
6165 it doesn't make sense to mislead anyone by generating the info
6166 on those variables until this is fixed. NOTE: Same problem
6167 with EQUIVALENCE, sadly...see similar #if later. */
6168 ffecom_member_phase2_ (ffesymbol_storage (ffesymbol_common (s)),
6169 ffesymbol_storage (s));
5ff904cd 6170
c7e4ee3a
CB
6171 resume_momentary (yes);
6172#endif
5ff904cd
JL
6173 }
6174
c7e4ee3a
CB
6175 return s;
6176}
5ff904cd 6177
c7e4ee3a
CB
6178#endif
6179/* Append underscore(s) to name before calling get_identifier. "us"
6180 is nonzero if the name already contains an underscore and thus
6181 needs two underscores appended. */
5ff904cd 6182
c7e4ee3a
CB
6183#if FFECOM_targetCURRENT == FFECOM_targetGCC
6184static tree
6185ffecom_get_appended_identifier_ (char us, const char *name)
6186{
6187 int i;
6188 char *newname;
6189 tree id;
5ff904cd 6190
c7e4ee3a
CB
6191 newname = xmalloc ((i = strlen (name)) + 1
6192 + ffe_is_underscoring ()
6193 + us);
6194 memcpy (newname, name, i);
6195 newname[i] = '_';
6196 newname[i + us] = '_';
6197 newname[i + 1 + us] = '\0';
6198 id = get_identifier (newname);
5ff904cd 6199
c7e4ee3a 6200 free (newname);
5ff904cd 6201
c7e4ee3a
CB
6202 return id;
6203}
5ff904cd 6204
c7e4ee3a
CB
6205#endif
6206/* Decide whether to append underscore to name before calling
6207 get_identifier. */
5ff904cd 6208
c7e4ee3a
CB
6209#if FFECOM_targetCURRENT == FFECOM_targetGCC
6210static tree
6211ffecom_get_external_identifier_ (ffesymbol s)
6212{
6213 char us;
6214 const char *name = ffesymbol_text (s);
5ff904cd 6215
c7e4ee3a 6216 /* If name is a built-in name, just return it as is. */
5ff904cd 6217
c7e4ee3a
CB
6218 if (!ffe_is_underscoring ()
6219 || (strcmp (name, FFETARGET_nameBLANK_COMMON) == 0)
6220#if FFETARGET_isENFORCED_MAIN_NAME
6221 || (strcmp (name, FFETARGET_nameENFORCED_NAME) == 0)
6222#else
6223 || (strcmp (name, FFETARGET_nameUNNAMED_MAIN) == 0)
6224#endif
6225 || (strcmp (name, FFETARGET_nameUNNAMED_BLOCK_DATA) == 0))
6226 return get_identifier (name);
5ff904cd 6227
c7e4ee3a
CB
6228 us = ffe_is_second_underscore ()
6229 ? (strchr (name, '_') != NULL)
6230 : 0;
5ff904cd 6231
c7e4ee3a
CB
6232 return ffecom_get_appended_identifier_ (us, name);
6233}
5ff904cd 6234
c7e4ee3a
CB
6235#endif
6236/* Decide whether to append underscore to internal name before calling
6237 get_identifier.
6238
6239 This is for non-external, top-function-context names only. Transform
6240 identifier so it doesn't conflict with the transformed result
6241 of using a _different_ external name. E.g. if "CALL FOO" is
6242 transformed into "FOO_();", then the variable in "FOO_ = 3"
6243 must be transformed into something that does not conflict, since
6244 these two things should be independent.
5ff904cd 6245
c7e4ee3a
CB
6246 The transformation is as follows. If the name does not contain
6247 an underscore, there is no possible conflict, so just return.
6248 If the name does contain an underscore, then transform it just
6249 like we transform an external identifier. */
5ff904cd 6250
c7e4ee3a
CB
6251#if FFECOM_targetCURRENT == FFECOM_targetGCC
6252static tree
6253ffecom_get_identifier_ (const char *name)
6254{
6255 /* If name does not contain an underscore, just return it as is. */
6256
6257 if (!ffe_is_underscoring ()
6258 || (strchr (name, '_') == NULL))
6259 return get_identifier (name);
6260
6261 return ffecom_get_appended_identifier_ (ffe_is_second_underscore (),
6262 name);
5ff904cd
JL
6263}
6264
6265#endif
c7e4ee3a 6266/* ffecom_gen_sfuncdef_ -- Generate definition of statement function
5ff904cd 6267
c7e4ee3a
CB
6268 tree t;
6269 ffesymbol s; // kindFUNCTION, whereIMMEDIATE.
6270 t = ffecom_gen_sfuncdef_(s,ffesymbol_basictype(s),
6271 ffesymbol_kindtype(s));
5ff904cd 6272
c7e4ee3a
CB
6273 Call after setting up containing function and getting trees for all
6274 other symbols. */
5ff904cd
JL
6275
6276#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
6277static tree
6278ffecom_gen_sfuncdef_ (ffesymbol s, ffeinfoBasictype bt, ffeinfoKindtype kt)
5ff904cd 6279{
c7e4ee3a
CB
6280 ffebld expr = ffesymbol_sfexpr (s);
6281 tree type;
6282 tree func;
6283 tree result;
6284 bool charfunc = (bt == FFEINFO_basictypeCHARACTER);
6285 static bool recurse = FALSE;
6286 int yes;
6287 int old_lineno = lineno;
6288 char *old_input_filename = input_filename;
5ff904cd 6289
c7e4ee3a 6290 ffecom_nested_entry_ = s;
5ff904cd 6291
c7e4ee3a
CB
6292 /* For now, we don't have a handy pointer to where the sfunc is actually
6293 defined, though that should be easy to add to an ffesymbol. (The
6294 token/where info available might well point to the place where the type
6295 of the sfunc is declared, especially if that precedes the place where
6296 the sfunc itself is defined, which is typically the case.) We should
6297 put out a null pointer rather than point somewhere wrong, but I want to
6298 see how it works at this point. */
5ff904cd 6299
c7e4ee3a
CB
6300 input_filename = ffesymbol_where_filename (s);
6301 lineno = ffesymbol_where_filelinenum (s);
5ff904cd 6302
c7e4ee3a
CB
6303 /* Pretransform the expression so any newly discovered things belong to the
6304 outer program unit, not to the statement function. */
5ff904cd 6305
c7e4ee3a 6306 ffecom_expr_transform_ (expr);
5ff904cd 6307
c7e4ee3a
CB
6308 /* Make sure no recursive invocation of this fn (a specific case of failing
6309 to pretransform an sfunc's expression, i.e. where its expression
6310 references another untransformed sfunc) happens. */
6311
6312 assert (!recurse);
6313 recurse = TRUE;
6314
6315 yes = suspend_momentary ();
6316
6317 push_f_function_context ();
6318
6319 if (charfunc)
6320 type = void_type_node;
6321 else
5ff904cd 6322 {
c7e4ee3a
CB
6323 type = ffecom_tree_type[bt][kt];
6324 if (type == NULL_TREE)
6325 type = integer_type_node; /* _sym_exec_transition reports
6326 error. */
6327 }
5ff904cd 6328
c7e4ee3a
CB
6329 start_function (ffecom_get_identifier_ (ffesymbol_text (s)),
6330 build_function_type (type, NULL_TREE),
6331 1, /* nested/inline */
6332 0); /* TREE_PUBLIC */
5ff904cd 6333
c7e4ee3a
CB
6334 /* We don't worry about COMPLEX return values here, because this is
6335 entirely internal to our code, and gcc has the ability to return COMPLEX
6336 directly as a value. */
6337
6338 yes = suspend_momentary ();
6339
6340 if (charfunc)
6341 { /* Prepend arg for where result goes. */
6342 tree type;
6343
6344 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
6345
6346 result = ffecom_get_invented_identifier ("__g77_%s",
6347 "result", -1);
6348
6349 ffecom_char_enhance_arg_ (&type, s); /* Ignore returned length. */
6350
6351 type = build_pointer_type (type);
6352 result = build_decl (PARM_DECL, result, type);
6353
6354 push_parm_decl (result);
5ff904cd 6355 }
c7e4ee3a
CB
6356 else
6357 result = NULL_TREE; /* Not ref'd if !charfunc. */
5ff904cd 6358
c7e4ee3a 6359 ffecom_push_dummy_decls_ (ffesymbol_dummyargs (s), TRUE);
5ff904cd 6360
c7e4ee3a 6361 resume_momentary (yes);
5ff904cd 6362
c7e4ee3a
CB
6363 store_parm_decls (0);
6364
6365 ffecom_start_compstmt ();
6366
6367 if (expr != NULL)
5ff904cd 6368 {
c7e4ee3a
CB
6369 if (charfunc)
6370 {
6371 ffetargetCharacterSize sz = ffesymbol_size (s);
6372 tree result_length;
5ff904cd 6373
c7e4ee3a
CB
6374 result_length = build_int_2 (sz, 0);
6375 TREE_TYPE (result_length) = ffecom_f2c_ftnlen_type_node;
5ff904cd 6376
c7e4ee3a 6377 ffecom_prepare_let_char_ (sz, expr);
5ff904cd 6378
c7e4ee3a 6379 ffecom_prepare_end ();
5ff904cd 6380
c7e4ee3a
CB
6381 ffecom_let_char_ (result, result_length, sz, expr);
6382 expand_null_return ();
6383 }
6384 else
6385 {
6386 ffecom_prepare_expr (expr);
5ff904cd 6387
c7e4ee3a 6388 ffecom_prepare_end ();
5ff904cd 6389
c7e4ee3a
CB
6390 expand_return (ffecom_modify (NULL_TREE,
6391 DECL_RESULT (current_function_decl),
6392 ffecom_expr (expr)));
6393 }
5ff904cd 6394
c7e4ee3a
CB
6395 clear_momentary ();
6396 }
5ff904cd 6397
c7e4ee3a 6398 ffecom_end_compstmt ();
5ff904cd 6399
c7e4ee3a
CB
6400 func = current_function_decl;
6401 finish_function (1);
5ff904cd 6402
c7e4ee3a 6403 pop_f_function_context ();
5ff904cd 6404
c7e4ee3a 6405 resume_momentary (yes);
5ff904cd 6406
c7e4ee3a
CB
6407 recurse = FALSE;
6408
6409 lineno = old_lineno;
6410 input_filename = old_input_filename;
6411
6412 ffecom_nested_entry_ = NULL;
6413
6414 return func;
5ff904cd
JL
6415}
6416
6417#endif
5ff904cd 6418
c7e4ee3a
CB
6419#if FFECOM_targetCURRENT == FFECOM_targetGCC
6420static const char *
6421ffecom_gfrt_args_ (ffecomGfrt ix)
5ff904cd 6422{
c7e4ee3a
CB
6423 return ffecom_gfrt_argstring_[ix];
6424}
5ff904cd 6425
c7e4ee3a
CB
6426#endif
6427#if FFECOM_targetCURRENT == FFECOM_targetGCC
6428static tree
6429ffecom_gfrt_tree_ (ffecomGfrt ix)
6430{
6431 if (ffecom_gfrt_[ix] == NULL_TREE)
6432 ffecom_make_gfrt_ (ix);
6433
6434 return ffecom_1 (ADDR_EXPR,
6435 build_pointer_type (TREE_TYPE (ffecom_gfrt_[ix])),
6436 ffecom_gfrt_[ix]);
5ff904cd
JL
6437}
6438
6439#endif
c7e4ee3a 6440/* Return initialize-to-zero expression for this VAR_DECL. */
5ff904cd
JL
6441
6442#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
6443static tree
6444ffecom_init_zero_ (tree decl)
5ff904cd 6445{
c7e4ee3a
CB
6446 tree init;
6447 int incremental = TREE_STATIC (decl);
6448 tree type = TREE_TYPE (decl);
5ff904cd 6449
c7e4ee3a
CB
6450 if (incremental)
6451 {
6452 int momentary = suspend_momentary ();
6453 push_obstacks_nochange ();
6454 if (TREE_PERMANENT (decl))
6455 end_temporary_allocation ();
6456 make_decl_rtl (decl, NULL, TREE_PUBLIC (decl) ? 1 : 0);
6457 assemble_variable (decl, TREE_PUBLIC (decl) ? 1 : 0, 0, 1);
6458 pop_obstacks ();
6459 resume_momentary (momentary);
6460 }
5ff904cd 6461
c7e4ee3a 6462 push_momentary ();
5ff904cd 6463
c7e4ee3a
CB
6464 if ((TREE_CODE (type) != ARRAY_TYPE)
6465 && (TREE_CODE (type) != RECORD_TYPE)
6466 && (TREE_CODE (type) != UNION_TYPE)
6467 && !incremental)
6468 init = convert (type, integer_zero_node);
6469 else if (!incremental)
6470 {
6471 int momentary = suspend_momentary ();
5ff904cd 6472
c7e4ee3a
CB
6473 init = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
6474 TREE_CONSTANT (init) = 1;
6475 TREE_STATIC (init) = 1;
5ff904cd 6476
c7e4ee3a
CB
6477 resume_momentary (momentary);
6478 }
6479 else
6480 {
6481 int momentary = suspend_momentary ();
5ff904cd 6482
c7e4ee3a
CB
6483 assemble_zeros (int_size_in_bytes (type));
6484 init = error_mark_node;
5ff904cd 6485
c7e4ee3a
CB
6486 resume_momentary (momentary);
6487 }
5ff904cd 6488
c7e4ee3a 6489 pop_momentary_nofree ();
5ff904cd 6490
c7e4ee3a 6491 return init;
5ff904cd
JL
6492}
6493
6494#endif
5ff904cd 6495#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
6496static tree
6497ffecom_intrinsic_ichar_ (tree tree_type, ffebld arg,
6498 tree *maybe_tree)
5ff904cd 6499{
c7e4ee3a
CB
6500 tree expr_tree;
6501 tree length_tree;
5ff904cd 6502
c7e4ee3a 6503 switch (ffebld_op (arg))
6829256f 6504 {
c7e4ee3a
CB
6505 case FFEBLD_opCONTER: /* For F90, check 0-length. */
6506 if (ffetarget_length_character1
6507 (ffebld_constant_character1
6508 (ffebld_conter (arg))) == 0)
6509 {
6510 *maybe_tree = integer_zero_node;
6511 return convert (tree_type, integer_zero_node);
6512 }
5ff904cd 6513
c7e4ee3a
CB
6514 *maybe_tree = integer_one_node;
6515 expr_tree = build_int_2 (*ffetarget_text_character1
6516 (ffebld_constant_character1
6517 (ffebld_conter (arg))),
6518 0);
6519 TREE_TYPE (expr_tree) = tree_type;
6520 return expr_tree;
5ff904cd 6521
c7e4ee3a
CB
6522 case FFEBLD_opSYMTER:
6523 case FFEBLD_opARRAYREF:
6524 case FFEBLD_opFUNCREF:
6525 case FFEBLD_opSUBSTR:
6526 ffecom_char_args_ (&expr_tree, &length_tree, arg);
5ff904cd 6527
c7e4ee3a
CB
6528 if ((expr_tree == error_mark_node)
6529 || (length_tree == error_mark_node))
6530 {
6531 *maybe_tree = error_mark_node;
6532 return error_mark_node;
6533 }
5ff904cd 6534
c7e4ee3a
CB
6535 if (integer_zerop (length_tree))
6536 {
6537 *maybe_tree = integer_zero_node;
6538 return convert (tree_type, integer_zero_node);
6539 }
6540
6541 expr_tree
6542 = ffecom_1 (INDIRECT_REF,
6543 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
6544 expr_tree);
6545 expr_tree
6546 = ffecom_2 (ARRAY_REF,
6547 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
6548 expr_tree,
6549 integer_one_node);
6550 expr_tree = convert (tree_type, expr_tree);
6551
6552 if (TREE_CODE (length_tree) == INTEGER_CST)
6553 *maybe_tree = integer_one_node;
6554 else /* Must check length at run time. */
6555 *maybe_tree
6556 = ffecom_truth_value
6557 (ffecom_2 (GT_EXPR, integer_type_node,
6558 length_tree,
6559 ffecom_f2c_ftnlen_zero_node));
6560 return expr_tree;
6561
6562 case FFEBLD_opPAREN:
6563 case FFEBLD_opCONVERT:
6564 if (ffeinfo_size (ffebld_info (arg)) == 0)
6565 {
6566 *maybe_tree = integer_zero_node;
6567 return convert (tree_type, integer_zero_node);
6568 }
6569 return ffecom_intrinsic_ichar_ (tree_type, ffebld_left (arg),
6570 maybe_tree);
6571
6572 case FFEBLD_opCONCATENATE:
6573 {
6574 tree maybe_left;
6575 tree maybe_right;
6576 tree expr_left;
6577 tree expr_right;
6578
6579 expr_left = ffecom_intrinsic_ichar_ (tree_type, ffebld_left (arg),
6580 &maybe_left);
6581 expr_right = ffecom_intrinsic_ichar_ (tree_type, ffebld_right (arg),
6582 &maybe_right);
6583 *maybe_tree = ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
6584 maybe_left,
6585 maybe_right);
6586 expr_tree = ffecom_3 (COND_EXPR, tree_type,
6587 maybe_left,
6588 expr_left,
6589 expr_right);
6590 return expr_tree;
6591 }
6592
6593 default:
6594 assert ("bad op in ICHAR" == NULL);
6595 return error_mark_node;
6596 }
5ff904cd
JL
6597}
6598
6599#endif
c7e4ee3a
CB
6600/* ffecom_intrinsic_len_ -- Return length info for char arg (LEN())
6601
6602 tree length_arg;
6603 ffebld expr;
6604 length_arg = ffecom_intrinsic_len_ (expr);
6605
6606 Handles CHARACTER-type CONTER, SYMTER, SUBSTR, ARRAYREF, and FUNCREF
6607 subexpressions by constructing the appropriate tree for the
6608 length-of-character-text argument in a calling sequence. */
5ff904cd
JL
6609
6610#if FFECOM_targetCURRENT == FFECOM_targetGCC
6611static tree
c7e4ee3a 6612ffecom_intrinsic_len_ (ffebld expr)
5ff904cd 6613{
c7e4ee3a
CB
6614 ffetargetCharacter1 val;
6615 tree length;
6616
6617 switch (ffebld_op (expr))
6618 {
6619 case FFEBLD_opCONTER:
6620 val = ffebld_constant_character1 (ffebld_conter (expr));
6621 length = build_int_2 (ffetarget_length_character1 (val), 0);
6622 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6623 break;
6624
6625 case FFEBLD_opSYMTER:
6626 {
6627 ffesymbol s = ffebld_symter (expr);
6628 tree item;
6629
6630 item = ffesymbol_hook (s).decl_tree;
6631 if (item == NULL_TREE)
6632 {
6633 s = ffecom_sym_transform_ (s);
6634 item = ffesymbol_hook (s).decl_tree;
6635 }
6636 if (ffesymbol_kind (s) == FFEINFO_kindENTITY)
6637 {
6638 if (ffesymbol_size (s) == FFETARGET_charactersizeNONE)
6639 length = ffesymbol_hook (s).length_tree;
6640 else
6641 {
6642 length = build_int_2 (ffesymbol_size (s), 0);
6643 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6644 }
6645 }
6646 else if (item == error_mark_node)
6647 length = error_mark_node;
6648 else /* FFEINFO_kindFUNCTION: */
6649 length = NULL_TREE;
6650 }
6651 break;
5ff904cd 6652
c7e4ee3a
CB
6653 case FFEBLD_opARRAYREF:
6654 length = ffecom_intrinsic_len_ (ffebld_left (expr));
6655 break;
5ff904cd 6656
c7e4ee3a
CB
6657 case FFEBLD_opSUBSTR:
6658 {
6659 ffebld start;
6660 ffebld end;
6661 ffebld thing = ffebld_right (expr);
6662 tree start_tree;
6663 tree end_tree;
5ff904cd 6664
c7e4ee3a
CB
6665 assert (ffebld_op (thing) == FFEBLD_opITEM);
6666 start = ffebld_head (thing);
6667 thing = ffebld_trail (thing);
6668 assert (ffebld_trail (thing) == NULL);
6669 end = ffebld_head (thing);
5ff904cd 6670
c7e4ee3a 6671 length = ffecom_intrinsic_len_ (ffebld_left (expr));
5ff904cd 6672
c7e4ee3a
CB
6673 if (length == error_mark_node)
6674 break;
5ff904cd 6675
c7e4ee3a
CB
6676 if (start == NULL)
6677 {
6678 if (end == NULL)
6679 ;
6680 else
6681 {
6682 length = convert (ffecom_f2c_ftnlen_type_node,
6683 ffecom_expr (end));
6684 }
6685 }
6686 else
6687 {
6688 start_tree = convert (ffecom_f2c_ftnlen_type_node,
6689 ffecom_expr (start));
5ff904cd 6690
c7e4ee3a
CB
6691 if (start_tree == error_mark_node)
6692 {
6693 length = error_mark_node;
6694 break;
6695 }
5ff904cd 6696
c7e4ee3a
CB
6697 if (end == NULL)
6698 {
6699 length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6700 ffecom_f2c_ftnlen_one_node,
6701 ffecom_2 (MINUS_EXPR,
6702 ffecom_f2c_ftnlen_type_node,
6703 length,
6704 start_tree));
6705 }
6706 else
6707 {
6708 end_tree = convert (ffecom_f2c_ftnlen_type_node,
6709 ffecom_expr (end));
5ff904cd 6710
c7e4ee3a
CB
6711 if (end_tree == error_mark_node)
6712 {
6713 length = error_mark_node;
6714 break;
6715 }
5ff904cd 6716
c7e4ee3a
CB
6717 length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6718 ffecom_f2c_ftnlen_one_node,
6719 ffecom_2 (MINUS_EXPR,
6720 ffecom_f2c_ftnlen_type_node,
6721 end_tree, start_tree));
6722 }
6723 }
6724 }
6725 break;
5ff904cd 6726
c7e4ee3a
CB
6727 case FFEBLD_opCONCATENATE:
6728 length
6729 = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6730 ffecom_intrinsic_len_ (ffebld_left (expr)),
6731 ffecom_intrinsic_len_ (ffebld_right (expr)));
6732 break;
5ff904cd 6733
c7e4ee3a
CB
6734 case FFEBLD_opFUNCREF:
6735 case FFEBLD_opCONVERT:
6736 length = build_int_2 (ffebld_size (expr), 0);
6737 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6738 break;
5ff904cd 6739
c7e4ee3a
CB
6740 default:
6741 assert ("bad op for single char arg expr" == NULL);
6742 length = ffecom_f2c_ftnlen_zero_node;
6743 break;
6744 }
5ff904cd 6745
c7e4ee3a 6746 assert (length != NULL_TREE);
5ff904cd 6747
c7e4ee3a 6748 return length;
5ff904cd
JL
6749}
6750
6751#endif
c7e4ee3a 6752/* Handle CHARACTER assignments.
5ff904cd 6753
c7e4ee3a
CB
6754 Generates code to do the assignment. Used by ordinary assignment
6755 statement handler ffecom_let_stmt and by statement-function
6756 handler to generate code for a statement function. */
5ff904cd
JL
6757
6758#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
6759static void
6760ffecom_let_char_ (tree dest_tree, tree dest_length,
6761 ffetargetCharacterSize dest_size, ffebld source)
5ff904cd 6762{
c7e4ee3a
CB
6763 ffecomConcatList_ catlist;
6764 tree source_length;
6765 tree source_tree;
6766 tree expr_tree;
5ff904cd 6767
c7e4ee3a
CB
6768 if ((dest_tree == error_mark_node)
6769 || (dest_length == error_mark_node))
6770 return;
5ff904cd 6771
c7e4ee3a
CB
6772 assert (dest_tree != NULL_TREE);
6773 assert (dest_length != NULL_TREE);
5ff904cd 6774
c7e4ee3a
CB
6775 /* Source might be an opCONVERT, which just means it is a different size
6776 than the destination. Since the underlying implementation here handles
6777 that (directly or via the s_copy or s_cat run-time-library functions),
6778 we don't need the "convenience" of an opCONVERT that tells us to
6779 truncate or blank-pad, particularly since the resulting implementation
6780 would probably be slower than otherwise. */
5ff904cd 6781
c7e4ee3a
CB
6782 while (ffebld_op (source) == FFEBLD_opCONVERT)
6783 source = ffebld_left (source);
5ff904cd 6784
c7e4ee3a
CB
6785 catlist = ffecom_concat_list_new_ (source, dest_size);
6786 switch (ffecom_concat_list_count_ (catlist))
6787 {
6788 case 0: /* Shouldn't happen, but in case it does... */
6789 ffecom_concat_list_kill_ (catlist);
6790 source_tree = null_pointer_node;
6791 source_length = ffecom_f2c_ftnlen_zero_node;
6792 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6793 TREE_CHAIN (expr_tree) = build_tree_list (NULL_TREE, source_tree);
6794 TREE_CHAIN (TREE_CHAIN (expr_tree))
6795 = build_tree_list (NULL_TREE, dest_length);
6796 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6797 = build_tree_list (NULL_TREE, source_length);
5ff904cd 6798
c7e4ee3a
CB
6799 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCOPY, expr_tree, NULL_TREE);
6800 TREE_SIDE_EFFECTS (expr_tree) = 1;
5ff904cd 6801
c7e4ee3a 6802 expand_expr_stmt (expr_tree);
5ff904cd 6803
c7e4ee3a 6804 return;
5ff904cd 6805
c7e4ee3a
CB
6806 case 1: /* The (fairly) easy case. */
6807 ffecom_char_args_ (&source_tree, &source_length,
6808 ffecom_concat_list_expr_ (catlist, 0));
6809 ffecom_concat_list_kill_ (catlist);
6810 assert (source_tree != NULL_TREE);
6811 assert (source_length != NULL_TREE);
6812
6813 if ((source_tree == error_mark_node)
6814 || (source_length == error_mark_node))
6815 return;
6816
6817 if (dest_size == 1)
6818 {
6819 dest_tree
6820 = ffecom_1 (INDIRECT_REF,
6821 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6822 (dest_tree))),
6823 dest_tree);
6824 dest_tree
6825 = ffecom_2 (ARRAY_REF,
6826 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6827 (dest_tree))),
6828 dest_tree,
6829 integer_one_node);
6830 source_tree
6831 = ffecom_1 (INDIRECT_REF,
6832 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6833 (source_tree))),
6834 source_tree);
6835 source_tree
6836 = ffecom_2 (ARRAY_REF,
6837 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6838 (source_tree))),
6839 source_tree,
6840 integer_one_node);
5ff904cd 6841
c7e4ee3a 6842 expr_tree = ffecom_modify (void_type_node, dest_tree, source_tree);
5ff904cd 6843
c7e4ee3a 6844 expand_expr_stmt (expr_tree);
5ff904cd 6845
c7e4ee3a
CB
6846 return;
6847 }
5ff904cd 6848
c7e4ee3a
CB
6849 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6850 TREE_CHAIN (expr_tree) = build_tree_list (NULL_TREE, source_tree);
6851 TREE_CHAIN (TREE_CHAIN (expr_tree))
6852 = build_tree_list (NULL_TREE, dest_length);
6853 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6854 = build_tree_list (NULL_TREE, source_length);
5ff904cd 6855
c7e4ee3a
CB
6856 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCOPY, expr_tree, NULL_TREE);
6857 TREE_SIDE_EFFECTS (expr_tree) = 1;
5ff904cd 6858
c7e4ee3a 6859 expand_expr_stmt (expr_tree);
5ff904cd 6860
c7e4ee3a 6861 return;
5ff904cd 6862
c7e4ee3a
CB
6863 default: /* Must actually concatenate things. */
6864 break;
6865 }
5ff904cd 6866
c7e4ee3a 6867 /* Heavy-duty concatenation. */
5ff904cd 6868
c7e4ee3a
CB
6869 {
6870 int count = ffecom_concat_list_count_ (catlist);
6871 int i;
6872 tree lengths;
6873 tree items;
6874 tree length_array;
6875 tree item_array;
6876 tree citem;
6877 tree clength;
5ff904cd 6878
c7e4ee3a
CB
6879#ifdef HOHO
6880 length_array
6881 = lengths
6882 = ffecom_push_tempvar (ffecom_f2c_ftnlen_type_node,
6883 FFETARGET_charactersizeNONE, count, TRUE);
6884 item_array = items = ffecom_push_tempvar (ffecom_f2c_address_type_node,
6885 FFETARGET_charactersizeNONE,
6886 count, TRUE);
6887#else
6888 {
6889 tree hook;
6890
6891 hook = ffebld_nonter_hook (source);
6892 assert (hook);
6893 assert (TREE_CODE (hook) == TREE_VEC);
6894 assert (TREE_VEC_LENGTH (hook) == 2);
6895 length_array = lengths = TREE_VEC_ELT (hook, 0);
6896 item_array = items = TREE_VEC_ELT (hook, 1);
5ff904cd 6897 }
c7e4ee3a 6898#endif
5ff904cd 6899
c7e4ee3a
CB
6900 for (i = 0; i < count; ++i)
6901 {
6902 ffecom_char_args_ (&citem, &clength,
6903 ffecom_concat_list_expr_ (catlist, i));
6904 if ((citem == error_mark_node)
6905 || (clength == error_mark_node))
6906 {
6907 ffecom_concat_list_kill_ (catlist);
6908 return;
6909 }
5ff904cd 6910
c7e4ee3a
CB
6911 items
6912 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (items),
6913 ffecom_modify (void_type_node,
6914 ffecom_2 (ARRAY_REF,
6915 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array))),
6916 item_array,
6917 build_int_2 (i, 0)),
6918 citem),
6919 items);
6920 lengths
6921 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (lengths),
6922 ffecom_modify (void_type_node,
6923 ffecom_2 (ARRAY_REF,
6924 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array))),
6925 length_array,
6926 build_int_2 (i, 0)),
6927 clength),
6928 lengths);
6929 }
5ff904cd 6930
c7e4ee3a
CB
6931 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6932 TREE_CHAIN (expr_tree)
6933 = build_tree_list (NULL_TREE,
6934 ffecom_1 (ADDR_EXPR,
6935 build_pointer_type (TREE_TYPE (items)),
6936 items));
6937 TREE_CHAIN (TREE_CHAIN (expr_tree))
6938 = build_tree_list (NULL_TREE,
6939 ffecom_1 (ADDR_EXPR,
6940 build_pointer_type (TREE_TYPE (lengths)),
6941 lengths));
6942 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6943 = build_tree_list
6944 (NULL_TREE,
6945 ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
6946 convert (ffecom_f2c_ftnlen_type_node,
6947 build_int_2 (count, 0))));
6948 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree))))
6949 = build_tree_list (NULL_TREE, dest_length);
5ff904cd 6950
c7e4ee3a
CB
6951 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCAT, expr_tree, NULL_TREE);
6952 TREE_SIDE_EFFECTS (expr_tree) = 1;
5ff904cd 6953
c7e4ee3a
CB
6954 expand_expr_stmt (expr_tree);
6955 }
5ff904cd 6956
c7e4ee3a
CB
6957 ffecom_concat_list_kill_ (catlist);
6958}
5ff904cd 6959
c7e4ee3a
CB
6960#endif
6961/* ffecom_make_gfrt_ -- Make initial info for run-time routine
5ff904cd 6962
c7e4ee3a
CB
6963 ffecomGfrt ix;
6964 ffecom_make_gfrt_(ix);
5ff904cd 6965
c7e4ee3a
CB
6966 Assumes gfrt_[ix] is NULL_TREE, and replaces it with the FUNCTION_DECL
6967 for the indicated run-time routine (ix). */
5ff904cd 6968
c7e4ee3a
CB
6969#if FFECOM_targetCURRENT == FFECOM_targetGCC
6970static void
6971ffecom_make_gfrt_ (ffecomGfrt ix)
6972{
6973 tree t;
6974 tree ttype;
5ff904cd 6975
c7e4ee3a
CB
6976 push_obstacks_nochange ();
6977 end_temporary_allocation ();
5ff904cd 6978
c7e4ee3a
CB
6979 switch (ffecom_gfrt_type_[ix])
6980 {
6981 case FFECOM_rttypeVOID_:
6982 ttype = void_type_node;
6983 break;
5ff904cd 6984
c7e4ee3a
CB
6985 case FFECOM_rttypeVOIDSTAR_:
6986 ttype = TREE_TYPE (null_pointer_node); /* `void *'. */
6987 break;
5ff904cd 6988
c7e4ee3a
CB
6989 case FFECOM_rttypeFTNINT_:
6990 ttype = ffecom_f2c_ftnint_type_node;
6991 break;
5ff904cd 6992
c7e4ee3a
CB
6993 case FFECOM_rttypeINTEGER_:
6994 ttype = ffecom_f2c_integer_type_node;
6995 break;
5ff904cd 6996
c7e4ee3a
CB
6997 case FFECOM_rttypeLONGINT_:
6998 ttype = ffecom_f2c_longint_type_node;
6999 break;
5ff904cd 7000
c7e4ee3a
CB
7001 case FFECOM_rttypeLOGICAL_:
7002 ttype = ffecom_f2c_logical_type_node;
7003 break;
5ff904cd 7004
c7e4ee3a
CB
7005 case FFECOM_rttypeREAL_F2C_:
7006 ttype = double_type_node;
7007 break;
5ff904cd 7008
c7e4ee3a
CB
7009 case FFECOM_rttypeREAL_GNU_:
7010 ttype = float_type_node;
7011 break;
5ff904cd 7012
c7e4ee3a
CB
7013 case FFECOM_rttypeCOMPLEX_F2C_:
7014 ttype = void_type_node;
7015 break;
5ff904cd 7016
c7e4ee3a
CB
7017 case FFECOM_rttypeCOMPLEX_GNU_:
7018 ttype = ffecom_f2c_complex_type_node;
7019 break;
5ff904cd 7020
c7e4ee3a
CB
7021 case FFECOM_rttypeDOUBLE_:
7022 ttype = double_type_node;
7023 break;
5ff904cd 7024
c7e4ee3a
CB
7025 case FFECOM_rttypeDOUBLEREAL_:
7026 ttype = ffecom_f2c_doublereal_type_node;
7027 break;
5ff904cd 7028
c7e4ee3a
CB
7029 case FFECOM_rttypeDBLCMPLX_F2C_:
7030 ttype = void_type_node;
7031 break;
5ff904cd 7032
c7e4ee3a
CB
7033 case FFECOM_rttypeDBLCMPLX_GNU_:
7034 ttype = ffecom_f2c_doublecomplex_type_node;
7035 break;
5ff904cd 7036
c7e4ee3a
CB
7037 case FFECOM_rttypeCHARACTER_:
7038 ttype = void_type_node;
7039 break;
7040
7041 default:
7042 ttype = NULL;
7043 assert ("bad rttype" == NULL);
7044 break;
5ff904cd 7045 }
5ff904cd 7046
c7e4ee3a
CB
7047 ttype = build_function_type (ttype, NULL_TREE);
7048 t = build_decl (FUNCTION_DECL,
7049 get_identifier (ffecom_gfrt_name_[ix]),
7050 ttype);
7051 DECL_EXTERNAL (t) = 1;
7052 TREE_PUBLIC (t) = 1;
7053 TREE_THIS_VOLATILE (t) = ffecom_gfrt_volatile_[ix] ? 1 : 0;
5ff904cd 7054
c7e4ee3a 7055 t = start_decl (t, TRUE);
5ff904cd 7056
c7e4ee3a 7057 finish_decl (t, NULL_TREE, TRUE);
5ff904cd 7058
c7e4ee3a
CB
7059 resume_temporary_allocation ();
7060 pop_obstacks ();
7061
7062 ffecom_gfrt_[ix] = t;
5ff904cd
JL
7063}
7064
7065#endif
c7e4ee3a
CB
7066/* Phase 1 pass over each member of a COMMON/EQUIVALENCE group. */
7067
5ff904cd 7068#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
7069static void
7070ffecom_member_phase1_ (ffestorag mst UNUSED, ffestorag st)
5ff904cd 7071{
c7e4ee3a 7072 ffesymbol s = ffestorag_symbol (st);
5ff904cd 7073
c7e4ee3a
CB
7074 if (ffesymbol_namelisted (s))
7075 ffecom_member_namelisted_ = TRUE;
7076}
5ff904cd 7077
c7e4ee3a
CB
7078#endif
7079/* Phase 2 pass over each member of a COMMON/EQUIVALENCE group. Declare
7080 the member so debugger will see it. Otherwise nobody should be
7081 referencing the member. */
5ff904cd 7082
c7e4ee3a
CB
7083#if FFECOM_targetCURRENT == FFECOM_targetGCC
7084#ifdef SOMEONE_GETS_DEBUG_SUPPORT_WORKING
7085static void
7086ffecom_member_phase2_ (ffestorag mst, ffestorag st)
7087{
7088 ffesymbol s;
7089 tree t;
7090 tree mt;
7091 tree type;
5ff904cd 7092
c7e4ee3a
CB
7093 if ((mst == NULL)
7094 || ((mt = ffestorag_hook (mst)) == NULL)
7095 || (mt == error_mark_node))
7096 return;
5ff904cd 7097
c7e4ee3a
CB
7098 if ((st == NULL)
7099 || ((s = ffestorag_symbol (st)) == NULL))
7100 return;
5ff904cd 7101
c7e4ee3a
CB
7102 type = ffecom_type_localvar_ (s,
7103 ffesymbol_basictype (s),
7104 ffesymbol_kindtype (s));
7105 if (type == error_mark_node)
7106 return;
5ff904cd 7107
c7e4ee3a
CB
7108 t = build_decl (VAR_DECL,
7109 ffecom_get_identifier_ (ffesymbol_text (s)),
7110 type);
5ff904cd 7111
c7e4ee3a
CB
7112 TREE_STATIC (t) = TREE_STATIC (mt);
7113 DECL_INITIAL (t) = NULL_TREE;
7114 TREE_ASM_WRITTEN (t) = 1;
5ff904cd 7115
c7e4ee3a
CB
7116 DECL_RTL (t)
7117 = gen_rtx (MEM, TYPE_MODE (type),
7118 plus_constant (XEXP (DECL_RTL (mt), 0),
7119 ffestorag_modulo (mst)
7120 + ffestorag_offset (st)
7121 - ffestorag_offset (mst)));
5ff904cd 7122
c7e4ee3a 7123 t = start_decl (t, FALSE);
5ff904cd 7124
c7e4ee3a 7125 finish_decl (t, NULL_TREE, FALSE);
5ff904cd
JL
7126}
7127
7128#endif
c7e4ee3a
CB
7129#endif
7130/* Prepare source expression for assignment into a destination perhaps known
7131 to be of a specific size. */
5ff904cd 7132
c7e4ee3a
CB
7133static void
7134ffecom_prepare_let_char_ (ffetargetCharacterSize dest_size, ffebld source)
5ff904cd 7135{
c7e4ee3a
CB
7136 ffecomConcatList_ catlist;
7137 int count;
7138 int i;
7139 tree ltmp;
7140 tree itmp;
7141 tree tempvar = NULL_TREE;
5ff904cd 7142
c7e4ee3a
CB
7143 while (ffebld_op (source) == FFEBLD_opCONVERT)
7144 source = ffebld_left (source);
5ff904cd 7145
c7e4ee3a
CB
7146 catlist = ffecom_concat_list_new_ (source, dest_size);
7147 count = ffecom_concat_list_count_ (catlist);
5ff904cd 7148
c7e4ee3a
CB
7149 if (count >= 2)
7150 {
7151 ltmp
7152 = ffecom_make_tempvar ("let_char_len", ffecom_f2c_ftnlen_type_node,
7153 FFETARGET_charactersizeNONE, count);
7154 itmp
7155 = ffecom_make_tempvar ("let_char_item", ffecom_f2c_address_type_node,
7156 FFETARGET_charactersizeNONE, count);
7157
7158 tempvar = make_tree_vec (2);
7159 TREE_VEC_ELT (tempvar, 0) = ltmp;
7160 TREE_VEC_ELT (tempvar, 1) = itmp;
7161 }
5ff904cd 7162
c7e4ee3a
CB
7163 for (i = 0; i < count; ++i)
7164 ffecom_prepare_arg_ptr_to_expr (ffecom_concat_list_expr_ (catlist, i));
5ff904cd 7165
c7e4ee3a 7166 ffecom_concat_list_kill_ (catlist);
5ff904cd 7167
c7e4ee3a
CB
7168 if (tempvar)
7169 {
7170 ffebld_nonter_set_hook (source, tempvar);
7171 current_binding_level->prep_state = 1;
7172 }
7173}
5ff904cd 7174
c7e4ee3a 7175/* ffecom_push_dummy_decls_ -- Transform dummy args, push parm decls in order
5ff904cd 7176
c7e4ee3a
CB
7177 Ignores STAR (alternate-return) dummies. All other get exec-transitioned
7178 (which generates their trees) and then their trees get push_parm_decl'd.
5ff904cd 7179
c7e4ee3a
CB
7180 The second arg is TRUE if the dummies are for a statement function, in
7181 which case lengths are not pushed for character arguments (since they are
7182 always known by both the caller and the callee, though the code allows
7183 for someday permitting CHAR*(*) stmtfunc dummies). */
5ff904cd 7184
c7e4ee3a
CB
7185#if FFECOM_targetCURRENT == FFECOM_targetGCC
7186static void
7187ffecom_push_dummy_decls_ (ffebld dummy_list, bool stmtfunc)
7188{
7189 ffebld dummy;
7190 ffebld dumlist;
7191 ffesymbol s;
7192 tree parm;
5ff904cd 7193
c7e4ee3a 7194 ffecom_transform_only_dummies_ = TRUE;
5ff904cd 7195
c7e4ee3a 7196 /* First push the parms corresponding to actual dummy "contents". */
5ff904cd 7197
c7e4ee3a
CB
7198 for (dumlist = dummy_list; dumlist != NULL; dumlist = ffebld_trail (dumlist))
7199 {
7200 dummy = ffebld_head (dumlist);
7201 switch (ffebld_op (dummy))
7202 {
7203 case FFEBLD_opSTAR:
7204 case FFEBLD_opANY:
7205 continue; /* Forget alternate returns. */
5ff904cd 7206
c7e4ee3a
CB
7207 default:
7208 break;
7209 }
7210 assert (ffebld_op (dummy) == FFEBLD_opSYMTER);
7211 s = ffebld_symter (dummy);
7212 parm = ffesymbol_hook (s).decl_tree;
7213 if (parm == NULL_TREE)
7214 {
7215 s = ffecom_sym_transform_ (s);
7216 parm = ffesymbol_hook (s).decl_tree;
7217 assert (parm != NULL_TREE);
7218 }
7219 if (parm != error_mark_node)
7220 push_parm_decl (parm);
5ff904cd
JL
7221 }
7222
c7e4ee3a 7223 /* Then, for CHARACTER dummies, push the parms giving their lengths. */
5ff904cd 7224
c7e4ee3a
CB
7225 for (dumlist = dummy_list; dumlist != NULL; dumlist = ffebld_trail (dumlist))
7226 {
7227 dummy = ffebld_head (dumlist);
7228 switch (ffebld_op (dummy))
7229 {
7230 case FFEBLD_opSTAR:
7231 case FFEBLD_opANY:
7232 continue; /* Forget alternate returns, they mean
7233 NOTHING! */
7234
7235 default:
7236 break;
7237 }
7238 s = ffebld_symter (dummy);
7239 if (ffesymbol_basictype (s) != FFEINFO_basictypeCHARACTER)
7240 continue; /* Only looking for CHARACTER arguments. */
7241 if (stmtfunc && (ffesymbol_size (s) != FFETARGET_charactersizeNONE))
7242 continue; /* Stmtfunc arg with known size needs no
7243 length param. */
7244 if (ffesymbol_kind (s) != FFEINFO_kindENTITY)
7245 continue; /* Only looking for variables and arrays. */
7246 parm = ffesymbol_hook (s).length_tree;
7247 assert (parm != NULL_TREE);
7248 if (parm != error_mark_node)
7249 push_parm_decl (parm);
7250 }
7251
7252 ffecom_transform_only_dummies_ = FALSE;
5ff904cd
JL
7253}
7254
7255#endif
c7e4ee3a 7256/* ffecom_start_progunit_ -- Beginning of program unit
5ff904cd 7257
c7e4ee3a
CB
7258 Does GNU back end stuff necessary to teach it about the start of its
7259 equivalent of a Fortran program unit. */
5ff904cd
JL
7260
7261#if FFECOM_targetCURRENT == FFECOM_targetGCC
7262static void
c7e4ee3a 7263ffecom_start_progunit_ ()
5ff904cd 7264{
c7e4ee3a
CB
7265 ffesymbol fn = ffecom_primary_entry_;
7266 ffebld arglist;
7267 tree id; /* Identifier (name) of function. */
7268 tree type; /* Type of function. */
7269 tree result; /* Result of function. */
7270 ffeinfoBasictype bt;
7271 ffeinfoKindtype kt;
7272 ffeglobal g;
7273 ffeglobalType gt;
7274 ffeglobalType egt = FFEGLOBAL_type;
7275 bool charfunc;
7276 bool cmplxfunc;
7277 bool altentries = (ffecom_num_entrypoints_ != 0);
7278 bool multi
7279 = altentries
7280 && (ffecom_primary_entry_kind_ == FFEINFO_kindFUNCTION)
7281 && (ffecom_master_bt_ == FFEINFO_basictypeNONE);
7282 bool main_program = FALSE;
7283 int old_lineno = lineno;
7284 char *old_input_filename = input_filename;
7285 int yes;
5ff904cd 7286
c7e4ee3a
CB
7287 assert (fn != NULL);
7288 assert (ffesymbol_hook (fn).decl_tree == NULL_TREE);
5ff904cd 7289
c7e4ee3a
CB
7290 input_filename = ffesymbol_where_filename (fn);
7291 lineno = ffesymbol_where_filelinenum (fn);
5ff904cd 7292
c7e4ee3a
CB
7293 /* c-parse.y indeed does call suspend_momentary and not only ignores the
7294 return value, but also never calls resume_momentary, when starting an
7295 outer function (see "fndef:", "setspecs:", and so on). So g77 does the
7296 same thing. It shouldn't be a problem since start_function calls
7297 temporary_allocation, but it might be necessary. If it causes a problem
7298 here, then maybe there's a bug lurking in gcc. NOTE: This identical
7299 comment appears twice in thist file. */
7300
7301 suspend_momentary ();
7302
7303 switch (ffecom_primary_entry_kind_)
7304 {
7305 case FFEINFO_kindPROGRAM:
7306 main_program = TRUE;
7307 gt = FFEGLOBAL_typeMAIN;
7308 bt = FFEINFO_basictypeNONE;
7309 kt = FFEINFO_kindtypeNONE;
7310 type = ffecom_tree_fun_type_void;
7311 charfunc = FALSE;
7312 cmplxfunc = FALSE;
7313 break;
7314
7315 case FFEINFO_kindBLOCKDATA:
7316 gt = FFEGLOBAL_typeBDATA;
7317 bt = FFEINFO_basictypeNONE;
7318 kt = FFEINFO_kindtypeNONE;
7319 type = ffecom_tree_fun_type_void;
7320 charfunc = FALSE;
7321 cmplxfunc = FALSE;
7322 break;
7323
7324 case FFEINFO_kindFUNCTION:
7325 gt = FFEGLOBAL_typeFUNC;
7326 egt = FFEGLOBAL_typeEXT;
7327 bt = ffesymbol_basictype (fn);
7328 kt = ffesymbol_kindtype (fn);
7329 if (bt == FFEINFO_basictypeNONE)
7330 {
7331 ffeimplic_establish_symbol (fn);
7332 if (ffesymbol_funcresult (fn) != NULL)
7333 ffeimplic_establish_symbol (ffesymbol_funcresult (fn));
7334 bt = ffesymbol_basictype (fn);
7335 kt = ffesymbol_kindtype (fn);
7336 }
7337
7338 if (multi)
7339 charfunc = cmplxfunc = FALSE;
7340 else if (bt == FFEINFO_basictypeCHARACTER)
7341 charfunc = TRUE, cmplxfunc = FALSE;
7342 else if ((bt == FFEINFO_basictypeCOMPLEX)
7343 && ffesymbol_is_f2c (fn)
7344 && !altentries)
7345 charfunc = FALSE, cmplxfunc = TRUE;
7346 else
7347 charfunc = cmplxfunc = FALSE;
7348
7349 if (multi || charfunc)
7350 type = ffecom_tree_fun_type_void;
7351 else if (ffesymbol_is_f2c (fn) && !altentries)
7352 type = ffecom_tree_fun_type[bt][kt];
7353 else
7354 type = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
7355
7356 if ((type == NULL_TREE)
7357 || (TREE_TYPE (type) == NULL_TREE))
7358 type = ffecom_tree_fun_type_void; /* _sym_exec_transition. */
7359 break;
7360
7361 case FFEINFO_kindSUBROUTINE:
7362 gt = FFEGLOBAL_typeSUBR;
7363 egt = FFEGLOBAL_typeEXT;
7364 bt = FFEINFO_basictypeNONE;
7365 kt = FFEINFO_kindtypeNONE;
7366 if (ffecom_is_altreturning_)
7367 type = ffecom_tree_subr_type;
7368 else
7369 type = ffecom_tree_fun_type_void;
7370 charfunc = FALSE;
7371 cmplxfunc = FALSE;
7372 break;
5ff904cd 7373
c7e4ee3a
CB
7374 default:
7375 assert ("say what??" == NULL);
7376 /* Fall through. */
7377 case FFEINFO_kindANY:
7378 gt = FFEGLOBAL_typeANY;
7379 bt = FFEINFO_basictypeNONE;
7380 kt = FFEINFO_kindtypeNONE;
7381 type = error_mark_node;
7382 charfunc = FALSE;
7383 cmplxfunc = FALSE;
7384 break;
7385 }
5ff904cd 7386
c7e4ee3a 7387 if (altentries)
5ff904cd 7388 {
c7e4ee3a
CB
7389 id = ffecom_get_invented_identifier ("__g77_masterfun_%s",
7390 ffesymbol_text (fn),
7391 -1);
7392 }
7393#if FFETARGET_isENFORCED_MAIN
7394 else if (main_program)
7395 id = get_identifier (FFETARGET_nameENFORCED_MAIN_NAME);
7396#endif
7397 else
7398 id = ffecom_get_external_identifier_ (fn);
5ff904cd 7399
c7e4ee3a
CB
7400 start_function (id,
7401 type,
7402 0, /* nested/inline */
7403 !altentries); /* TREE_PUBLIC */
5ff904cd 7404
c7e4ee3a 7405 TREE_USED (current_function_decl) = 1; /* Avoid spurious warning if altentries. */
5ff904cd 7406
c7e4ee3a
CB
7407 if (!altentries
7408 && ((g = ffesymbol_global (fn)) != NULL)
7409 && ((ffeglobal_type (g) == gt)
7410 || (ffeglobal_type (g) == egt)))
7411 {
7412 ffeglobal_set_hook (g, current_function_decl);
7413 }
5ff904cd 7414
c7e4ee3a 7415 yes = suspend_momentary ();
5ff904cd 7416
c7e4ee3a
CB
7417 /* Arg handling needs exec-transitioned ffesymbols to work with. But
7418 exec-transitioning needs current_function_decl to be filled in. So we
7419 do these things in two phases. */
5ff904cd 7420
c7e4ee3a
CB
7421 if (altentries)
7422 { /* 1st arg identifies which entrypoint. */
7423 ffecom_which_entrypoint_decl_
7424 = build_decl (PARM_DECL,
7425 ffecom_get_invented_identifier ("__g77_%s",
7426 "which_entrypoint",
7427 -1),
7428 integer_type_node);
7429 push_parm_decl (ffecom_which_entrypoint_decl_);
7430 }
5ff904cd 7431
c7e4ee3a
CB
7432 if (charfunc
7433 || cmplxfunc
7434 || multi)
7435 { /* Arg for result (return value). */
7436 tree type;
7437 tree length;
5ff904cd 7438
c7e4ee3a
CB
7439 if (charfunc)
7440 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
7441 else if (cmplxfunc)
7442 type = ffecom_tree_type[FFEINFO_basictypeCOMPLEX][kt];
7443 else
7444 type = ffecom_multi_type_node_;
5ff904cd 7445
c7e4ee3a
CB
7446 result = ffecom_get_invented_identifier ("__g77_%s",
7447 "result", -1);
5ff904cd 7448
c7e4ee3a 7449 /* Make length arg _and_ enhance type info for CHAR arg itself. */
5ff904cd 7450
c7e4ee3a
CB
7451 if (charfunc)
7452 length = ffecom_char_enhance_arg_ (&type, fn);
7453 else
7454 length = NULL_TREE; /* Not ref'd if !charfunc. */
5ff904cd 7455
c7e4ee3a
CB
7456 type = build_pointer_type (type);
7457 result = build_decl (PARM_DECL, result, type);
5ff904cd 7458
c7e4ee3a
CB
7459 push_parm_decl (result);
7460 if (multi)
7461 ffecom_multi_retval_ = result;
7462 else
7463 ffecom_func_result_ = result;
5ff904cd 7464
c7e4ee3a
CB
7465 if (charfunc)
7466 {
7467 push_parm_decl (length);
7468 ffecom_func_length_ = length;
7469 }
5ff904cd
JL
7470 }
7471
c7e4ee3a
CB
7472 if (ffecom_primary_entry_is_proc_)
7473 {
7474 if (altentries)
7475 arglist = ffecom_master_arglist_;
7476 else
7477 arglist = ffesymbol_dummyargs (fn);
7478 ffecom_push_dummy_decls_ (arglist, FALSE);
7479 }
5ff904cd 7480
c7e4ee3a 7481 resume_momentary (yes);
5ff904cd 7482
c7e4ee3a
CB
7483 if (TREE_CODE (current_function_decl) != ERROR_MARK)
7484 store_parm_decls (main_program ? 1 : 0);
5ff904cd 7485
c7e4ee3a
CB
7486 ffecom_start_compstmt ();
7487 /* Disallow temp vars at this level. */
7488 current_binding_level->prep_state = 2;
5ff904cd 7489
c7e4ee3a
CB
7490 lineno = old_lineno;
7491 input_filename = old_input_filename;
5ff904cd 7492
c7e4ee3a
CB
7493 /* This handles any symbols still untransformed, in case -g specified.
7494 This used to be done in ffecom_finish_progunit, but it turns out to
7495 be necessary to do it here so that statement functions are
7496 expanded before code. But don't bother for BLOCK DATA. */
5ff904cd 7497
c7e4ee3a
CB
7498 if (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA)
7499 ffesymbol_drive (ffecom_finish_symbol_transform_);
5ff904cd
JL
7500}
7501
7502#endif
c7e4ee3a 7503/* ffecom_sym_transform_ -- Transform FFE sym into backend sym
5ff904cd 7504
c7e4ee3a
CB
7505 ffesymbol s;
7506 ffecom_sym_transform_(s);
7507
7508 The ffesymbol_hook info for s is updated with appropriate backend info
7509 on the symbol. */
7510
7511#if FFECOM_targetCURRENT == FFECOM_targetGCC
7512static ffesymbol
7513ffecom_sym_transform_ (ffesymbol s)
7514{
7515 tree t; /* Transformed thingy. */
7516 tree tlen; /* Length if CHAR*(*). */
7517 bool addr; /* Is t the address of the thingy? */
7518 ffeinfoBasictype bt;
7519 ffeinfoKindtype kt;
7520 ffeglobal g;
7521 int yes;
7522 int old_lineno = lineno;
7523 char *old_input_filename = input_filename;
5ff904cd 7524
c7e4ee3a
CB
7525 /* Must ensure special ASSIGN variables are declared at top of outermost
7526 block, else they'll end up in the innermost block when their first
7527 ASSIGN is seen, which leaves them out of scope when they're the
7528 subject of a GOTO or I/O statement.
5ff904cd 7529
c7e4ee3a
CB
7530 We make this variable even if -fugly-assign. Just let it go unused,
7531 in case it turns out there are cases where we really want to use this
7532 variable anyway (e.g. ASSIGN to INTEGER*2 variable). */
5ff904cd 7533
c7e4ee3a
CB
7534 if (! ffecom_transform_only_dummies_
7535 && ffesymbol_assigned (s)
7536 && ! ffesymbol_hook (s).assign_tree)
7537 s = ffecom_sym_transform_assign_ (s);
5ff904cd 7538
c7e4ee3a 7539 if (ffesymbol_sfdummyparent (s) == NULL)
5ff904cd 7540 {
c7e4ee3a
CB
7541 input_filename = ffesymbol_where_filename (s);
7542 lineno = ffesymbol_where_filelinenum (s);
7543 }
7544 else
7545 {
7546 ffesymbol sf = ffesymbol_sfdummyparent (s);
5ff904cd 7547
c7e4ee3a
CB
7548 input_filename = ffesymbol_where_filename (sf);
7549 lineno = ffesymbol_where_filelinenum (sf);
7550 }
6d433196 7551
c7e4ee3a
CB
7552 bt = ffeinfo_basictype (ffebld_info (s));
7553 kt = ffeinfo_kindtype (ffebld_info (s));
5ff904cd 7554
c7e4ee3a
CB
7555 t = NULL_TREE;
7556 tlen = NULL_TREE;
7557 addr = FALSE;
5ff904cd 7558
c7e4ee3a
CB
7559 switch (ffesymbol_kind (s))
7560 {
7561 case FFEINFO_kindNONE:
7562 switch (ffesymbol_where (s))
7563 {
7564 case FFEINFO_whereDUMMY: /* Subroutine or function. */
7565 assert (ffecom_transform_only_dummies_);
5ff904cd 7566
c7e4ee3a
CB
7567 /* Before 0.4, this could be ENTITY/DUMMY, but see
7568 ffestu_sym_end_transition -- no longer true (in particular, if
7569 it could be an ENTITY, it _will_ be made one, so that
7570 possibility won't come through here). So we never make length
7571 arg for CHARACTER type. */
5ff904cd 7572
c7e4ee3a
CB
7573 t = build_decl (PARM_DECL,
7574 ffecom_get_identifier_ (ffesymbol_text (s)),
7575 ffecom_tree_ptr_to_subr_type);
7576#if BUILT_FOR_270
7577 DECL_ARTIFICIAL (t) = 1;
7578#endif
7579 addr = TRUE;
7580 break;
5ff904cd 7581
c7e4ee3a
CB
7582 case FFEINFO_whereGLOBAL: /* Subroutine or function. */
7583 assert (!ffecom_transform_only_dummies_);
5ff904cd 7584
c7e4ee3a
CB
7585 if (((g = ffesymbol_global (s)) != NULL)
7586 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
7587 || (ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
7588 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
7589 && (ffeglobal_hook (g) != NULL_TREE)
7590 && ffe_is_globals ())
7591 {
7592 t = ffeglobal_hook (g);
7593 break;
7594 }
5ff904cd 7595
c7e4ee3a
CB
7596 push_obstacks_nochange ();
7597 end_temporary_allocation ();
5ff904cd 7598
c7e4ee3a
CB
7599 t = build_decl (FUNCTION_DECL,
7600 ffecom_get_external_identifier_ (s),
7601 ffecom_tree_subr_type); /* Assume subr. */
7602 DECL_EXTERNAL (t) = 1;
7603 TREE_PUBLIC (t) = 1;
5ff904cd 7604
c7e4ee3a
CB
7605 t = start_decl (t, FALSE);
7606 finish_decl (t, NULL_TREE, FALSE);
795232f7 7607
c7e4ee3a
CB
7608 if ((g != NULL)
7609 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
7610 || (ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
7611 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
7612 ffeglobal_set_hook (g, t);
5ff904cd 7613
c7e4ee3a
CB
7614 resume_temporary_allocation ();
7615 pop_obstacks ();
5ff904cd 7616
c7e4ee3a 7617 break;
5ff904cd 7618
c7e4ee3a
CB
7619 default:
7620 assert ("NONE where unexpected" == NULL);
7621 /* Fall through. */
7622 case FFEINFO_whereANY:
7623 break;
7624 }
5ff904cd 7625 break;
5ff904cd 7626
c7e4ee3a
CB
7627 case FFEINFO_kindENTITY:
7628 switch (ffeinfo_where (ffesymbol_info (s)))
7629 {
5ff904cd 7630
c7e4ee3a
CB
7631 case FFEINFO_whereCONSTANT:
7632 /* ~~Debugging info needed? */
7633 assert (!ffecom_transform_only_dummies_);
7634 t = error_mark_node; /* Shouldn't ever see this in expr. */
7635 break;
5ff904cd 7636
c7e4ee3a
CB
7637 case FFEINFO_whereLOCAL:
7638 assert (!ffecom_transform_only_dummies_);
5ff904cd 7639
c7e4ee3a
CB
7640 {
7641 ffestorag st = ffesymbol_storage (s);
7642 tree type;
5ff904cd 7643
c7e4ee3a
CB
7644 if ((st != NULL)
7645 && (ffestorag_size (st) == 0))
7646 {
7647 t = error_mark_node;
7648 break;
7649 }
5ff904cd 7650
c7e4ee3a
CB
7651 yes = suspend_momentary ();
7652 type = ffecom_type_localvar_ (s, bt, kt);
7653 resume_momentary (yes);
5ff904cd 7654
c7e4ee3a
CB
7655 if (type == error_mark_node)
7656 {
7657 t = error_mark_node;
7658 break;
7659 }
5ff904cd 7660
c7e4ee3a
CB
7661 if ((st != NULL)
7662 && (ffestorag_parent (st) != NULL))
7663 { /* Child of EQUIVALENCE parent. */
7664 ffestorag est;
7665 tree et;
7666 int yes;
7667 ffetargetOffset offset;
5ff904cd 7668
c7e4ee3a
CB
7669 est = ffestorag_parent (st);
7670 ffecom_transform_equiv_ (est);
5ff904cd 7671
c7e4ee3a
CB
7672 et = ffestorag_hook (est);
7673 assert (et != NULL_TREE);
5ff904cd 7674
c7e4ee3a
CB
7675 if (! TREE_STATIC (et))
7676 put_var_into_stack (et);
5ff904cd 7677
c7e4ee3a 7678 yes = suspend_momentary ();
5ff904cd 7679
c7e4ee3a
CB
7680 offset = ffestorag_modulo (est)
7681 + ffestorag_offset (ffesymbol_storage (s))
7682 - ffestorag_offset (est);
5ff904cd 7683
c7e4ee3a 7684 ffecom_debug_kludge_ (et, "EQUIVALENCE", s, type, offset);
5ff904cd 7685
c7e4ee3a 7686 /* (t_type *) (((char *) &et) + offset) */
5ff904cd 7687
c7e4ee3a
CB
7688 t = convert (string_type_node, /* (char *) */
7689 ffecom_1 (ADDR_EXPR,
7690 build_pointer_type (TREE_TYPE (et)),
7691 et));
7692 t = ffecom_2 (PLUS_EXPR, TREE_TYPE (t),
7693 t,
7694 build_int_2 (offset, 0));
7695 t = convert (build_pointer_type (type),
7696 t);
d50108c7 7697 TREE_CONSTANT (t) = staticp (et);
5ff904cd 7698
c7e4ee3a 7699 addr = TRUE;
5ff904cd 7700
c7e4ee3a
CB
7701 resume_momentary (yes);
7702 }
7703 else
7704 {
7705 tree initexpr;
7706 bool init = ffesymbol_is_init (s);
5ff904cd 7707
c7e4ee3a 7708 yes = suspend_momentary ();
5ff904cd 7709
c7e4ee3a
CB
7710 t = build_decl (VAR_DECL,
7711 ffecom_get_identifier_ (ffesymbol_text (s)),
7712 type);
5ff904cd 7713
c7e4ee3a
CB
7714 if (init
7715 || ffesymbol_namelisted (s)
7716#ifdef FFECOM_sizeMAXSTACKITEM
7717 || ((st != NULL)
7718 && (ffestorag_size (st) > FFECOM_sizeMAXSTACKITEM))
7719#endif
7720 || ((ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
7721 && (ffecom_primary_entry_kind_
7722 != FFEINFO_kindBLOCKDATA)
7723 && (ffesymbol_is_save (s) || ffe_is_saveall ())))
7724 TREE_STATIC (t) = !ffesymbol_attr (s, FFESYMBOL_attrADJUSTABLE);
7725 else
7726 TREE_STATIC (t) = 0; /* No need to make static. */
5ff904cd 7727
c7e4ee3a
CB
7728 if (init || ffe_is_init_local_zero ())
7729 DECL_INITIAL (t) = error_mark_node;
5ff904cd 7730
c7e4ee3a
CB
7731 /* Keep -Wunused from complaining about var if it
7732 is used as sfunc arg or DATA implied-DO. */
7733 if (ffesymbol_attrs (s) & FFESYMBOL_attrsSFARG)
7734 DECL_IN_SYSTEM_HEADER (t) = 1;
5ff904cd 7735
c7e4ee3a 7736 t = start_decl (t, FALSE);
5ff904cd 7737
c7e4ee3a
CB
7738 if (init)
7739 {
7740 if (ffesymbol_init (s) != NULL)
7741 initexpr = ffecom_expr (ffesymbol_init (s));
7742 else
7743 initexpr = ffecom_init_zero_ (t);
7744 }
7745 else if (ffe_is_init_local_zero ())
7746 initexpr = ffecom_init_zero_ (t);
7747 else
7748 initexpr = NULL_TREE; /* Not ref'd if !init. */
5ff904cd 7749
c7e4ee3a 7750 finish_decl (t, initexpr, FALSE);
5ff904cd 7751
c7e4ee3a
CB
7752 if ((st != NULL) && (DECL_SIZE (t) != error_mark_node))
7753 {
7754 tree size_tree;
5ff904cd 7755
c7e4ee3a
CB
7756 size_tree = size_binop (CEIL_DIV_EXPR,
7757 DECL_SIZE (t),
7758 size_int (BITS_PER_UNIT));
7759 assert (TREE_INT_CST_HIGH (size_tree) == 0);
7760 assert (TREE_INT_CST_LOW (size_tree) == ffestorag_size (st));
7761 }
5ff904cd 7762
c7e4ee3a
CB
7763 resume_momentary (yes);
7764 }
7765 }
5ff904cd 7766 break;
5ff904cd 7767
c7e4ee3a
CB
7768 case FFEINFO_whereRESULT:
7769 assert (!ffecom_transform_only_dummies_);
5ff904cd 7770
c7e4ee3a
CB
7771 if (bt == FFEINFO_basictypeCHARACTER)
7772 { /* Result is already in list of dummies, use
7773 it (& length). */
7774 t = ffecom_func_result_;
7775 tlen = ffecom_func_length_;
7776 addr = TRUE;
7777 break;
7778 }
7779 if ((ffecom_num_entrypoints_ == 0)
7780 && (bt == FFEINFO_basictypeCOMPLEX)
7781 && (ffesymbol_is_f2c (ffecom_primary_entry_)))
7782 { /* Result is already in list of dummies, use
7783 it. */
7784 t = ffecom_func_result_;
7785 addr = TRUE;
7786 break;
7787 }
7788 if (ffecom_func_result_ != NULL_TREE)
7789 {
7790 t = ffecom_func_result_;
7791 break;
7792 }
7793 if ((ffecom_num_entrypoints_ != 0)
7794 && (ffecom_master_bt_ == FFEINFO_basictypeNONE))
7795 {
7796 yes = suspend_momentary ();
5ff904cd 7797
c7e4ee3a
CB
7798 assert (ffecom_multi_retval_ != NULL_TREE);
7799 t = ffecom_1 (INDIRECT_REF, ffecom_multi_type_node_,
7800 ffecom_multi_retval_);
7801 t = ffecom_2 (COMPONENT_REF, ffecom_tree_type[bt][kt],
7802 t, ffecom_multi_fields_[bt][kt]);
5ff904cd 7803
c7e4ee3a
CB
7804 resume_momentary (yes);
7805 break;
7806 }
5ff904cd 7807
c7e4ee3a 7808 yes = suspend_momentary ();
5ff904cd 7809
c7e4ee3a
CB
7810 t = build_decl (VAR_DECL,
7811 ffecom_get_identifier_ (ffesymbol_text (s)),
7812 ffecom_tree_type[bt][kt]);
7813 TREE_STATIC (t) = 0; /* Put result on stack. */
7814 t = start_decl (t, FALSE);
7815 finish_decl (t, NULL_TREE, FALSE);
5ff904cd 7816
c7e4ee3a 7817 ffecom_func_result_ = t;
5ff904cd 7818
c7e4ee3a
CB
7819 resume_momentary (yes);
7820 break;
5ff904cd 7821
c7e4ee3a
CB
7822 case FFEINFO_whereDUMMY:
7823 {
7824 tree type;
7825 ffebld dl;
7826 ffebld dim;
7827 tree low;
7828 tree high;
7829 tree old_sizes;
7830 bool adjustable = FALSE; /* Conditionally adjustable? */
5ff904cd 7831
c7e4ee3a
CB
7832 type = ffecom_tree_type[bt][kt];
7833 if (ffesymbol_sfdummyparent (s) != NULL)
7834 {
7835 if (current_function_decl == ffecom_outer_function_decl_)
7836 { /* Exec transition before sfunc
7837 context; get it later. */
7838 break;
7839 }
7840 t = ffecom_get_identifier_ (ffesymbol_text
7841 (ffesymbol_sfdummyparent (s)));
7842 }
7843 else
7844 t = ffecom_get_identifier_ (ffesymbol_text (s));
5ff904cd 7845
c7e4ee3a 7846 assert (ffecom_transform_only_dummies_);
5ff904cd 7847
c7e4ee3a
CB
7848 old_sizes = get_pending_sizes ();
7849 put_pending_sizes (old_sizes);
5ff904cd 7850
c7e4ee3a
CB
7851 if (bt == FFEINFO_basictypeCHARACTER)
7852 tlen = ffecom_char_enhance_arg_ (&type, s);
7853 type = ffecom_check_size_overflow_ (s, type, TRUE);
5ff904cd 7854
c7e4ee3a
CB
7855 for (dl = ffesymbol_dims (s); dl != NULL; dl = ffebld_trail (dl))
7856 {
7857 if (type == error_mark_node)
7858 break;
5ff904cd 7859
c7e4ee3a
CB
7860 dim = ffebld_head (dl);
7861 assert (ffebld_op (dim) == FFEBLD_opBOUNDS);
7862 if ((ffebld_left (dim) == NULL) || ffecom_doing_entry_)
7863 low = ffecom_integer_one_node;
7864 else
7865 low = ffecom_expr (ffebld_left (dim));
7866 assert (ffebld_right (dim) != NULL);
7867 if ((ffebld_op (ffebld_right (dim)) == FFEBLD_opSTAR)
7868 || ffecom_doing_entry_)
7869 {
7870 /* Used to just do high=low. But for ffecom_tree_
7871 canonize_ref_, it probably is important to correctly
7872 assess the size. E.g. given COMPLEX C(*),CFUNC and
7873 C(2)=CFUNC(C), overlap can happen, while it can't
7874 for, say, C(1)=CFUNC(C(2)). */
7875 /* Even more recently used to set to INT_MAX, but that
7876 broke when some overflow checking went into the back
7877 end. Now we just leave the upper bound unspecified. */
7878 high = NULL;
7879 }
7880 else
7881 high = ffecom_expr (ffebld_right (dim));
5ff904cd 7882
c7e4ee3a
CB
7883 /* Determine whether array is conditionally adjustable,
7884 to decide whether back-end magic is needed.
5ff904cd 7885
c7e4ee3a
CB
7886 Normally the front end uses the back-end function
7887 variable_size to wrap SAVE_EXPR's around expressions
7888 affecting the size/shape of an array so that the
7889 size/shape info doesn't change during execution
7890 of the compiled code even though variables and
7891 functions referenced in those expressions might.
5ff904cd 7892
c7e4ee3a
CB
7893 variable_size also makes sure those saved expressions
7894 get evaluated immediately upon entry to the
7895 compiled procedure -- the front end normally doesn't
7896 have to worry about that.
3cf0cea4 7897
c7e4ee3a
CB
7898 However, there is a problem with this that affects
7899 g77's implementation of entry points, and that is
7900 that it is _not_ true that each invocation of the
7901 compiled procedure is permitted to evaluate
7902 array size/shape info -- because it is possible
7903 that, for some invocations, that info is invalid (in
7904 which case it is "promised" -- i.e. a violation of
7905 the Fortran standard -- that the compiled code
7906 won't reference the array or its size/shape
7907 during that particular invocation).
5ff904cd 7908
c7e4ee3a 7909 To phrase this in C terms, consider this gcc function:
5ff904cd 7910
c7e4ee3a
CB
7911 void foo (int *n, float (*a)[*n])
7912 {
7913 // a is "pointer to array ...", fyi.
7914 }
5ff904cd 7915
c7e4ee3a
CB
7916 Suppose that, for some invocations, it is permitted
7917 for a caller of foo to do this:
5ff904cd 7918
c7e4ee3a 7919 foo (NULL, NULL);
5ff904cd 7920
c7e4ee3a
CB
7921 Now the _written_ code for foo can take such a call
7922 into account by either testing explicitly for whether
7923 (a == NULL) || (n == NULL) -- presumably it is
7924 not permitted to reference *a in various fashions
7925 if (n == NULL) I suppose -- or it can avoid it by
7926 looking at other info (other arguments, static/global
7927 data, etc.).
5ff904cd 7928
c7e4ee3a
CB
7929 However, this won't work in gcc 2.5.8 because it'll
7930 automatically emit the code to save the "*n"
7931 expression, which'll yield a NULL dereference for
7932 the "foo (NULL, NULL)" call, something the code
7933 for foo cannot prevent.
5ff904cd 7934
c7e4ee3a
CB
7935 g77 definitely needs to avoid executing such
7936 code anytime the pointer to the adjustable array
7937 is NULL, because even if its bounds expressions
7938 don't have any references to possible "absent"
7939 variables like "*n" -- say all variable references
7940 are to COMMON variables, i.e. global (though in C,
7941 local static could actually make sense) -- the
7942 expressions could yield other run-time problems
7943 for allowably "dead" values in those variables.
5ff904cd 7944
c7e4ee3a
CB
7945 For example, let's consider a more complicated
7946 version of foo:
5ff904cd 7947
c7e4ee3a
CB
7948 extern int i;
7949 extern int j;
5ff904cd 7950
c7e4ee3a
CB
7951 void foo (float (*a)[i/j])
7952 {
7953 ...
7954 }
5ff904cd 7955
c7e4ee3a
CB
7956 The above is (essentially) quite valid for Fortran
7957 but, again, for a call like "foo (NULL);", it is
7958 permitted for i and j to be undefined when the
7959 call is made. If j happened to be zero, for
7960 example, emitting the code to evaluate "i/j"
7961 could result in a run-time error.
5ff904cd 7962
c7e4ee3a
CB
7963 Offhand, though I don't have my F77 or F90
7964 standards handy, it might even be valid for a
7965 bounds expression to contain a function reference,
7966 in which case I doubt it is permitted for an
7967 implementation to invoke that function in the
7968 Fortran case involved here (invocation of an
7969 alternate ENTRY point that doesn't have the adjustable
7970 array as one of its arguments).
5ff904cd 7971
c7e4ee3a
CB
7972 So, the code that the compiler would normally emit
7973 to preevaluate the size/shape info for an
7974 adjustable array _must not_ be executed at run time
7975 in certain cases. Specifically, for Fortran,
7976 the case is when the pointer to the adjustable
7977 array == NULL. (For gnu-ish C, it might be nice
7978 for the source code itself to specify an expression
7979 that, if TRUE, inhibits execution of the code. Or
7980 reverse the sense for elegance.)
5ff904cd 7981
c7e4ee3a
CB
7982 (Note that g77 could use a different test than NULL,
7983 actually, since it happens to always pass an
7984 integer to the called function that specifies which
7985 entry point is being invoked. Hmm, this might
7986 solve the next problem.)
7987
7988 One way a user could, I suppose, write "foo" so
7989 it works is to insert COND_EXPR's for the
7990 size/shape info so the dangerous stuff isn't
7991 actually done, as in:
7992
7993 void foo (int *n, float (*a)[(a == NULL) ? 0 : *n])
7994 {
7995 ...
7996 }
5ff904cd 7997
c7e4ee3a
CB
7998 The next problem is that the front end needs to
7999 be able to tell the back end about the array's
8000 decl _before_ it tells it about the conditional
8001 expression to inhibit evaluation of size/shape info,
8002 as shown above.
5ff904cd 8003
c7e4ee3a
CB
8004 To solve this, the front end needs to be able
8005 to give the back end the expression to inhibit
8006 generation of the preevaluation code _after_
8007 it makes the decl for the adjustable array.
5ff904cd 8008
c7e4ee3a
CB
8009 Until then, the above example using the COND_EXPR
8010 doesn't pass muster with gcc because the "(a == NULL)"
8011 part has a reference to "a", which is still
8012 undefined at that point.
5ff904cd 8013
c7e4ee3a
CB
8014 g77 will therefore use a different mechanism in the
8015 meantime. */
5ff904cd 8016
c7e4ee3a
CB
8017 if (!adjustable
8018 && ((TREE_CODE (low) != INTEGER_CST)
8019 || (high && TREE_CODE (high) != INTEGER_CST)))
8020 adjustable = TRUE;
5ff904cd 8021
c7e4ee3a
CB
8022#if 0 /* Old approach -- see below. */
8023 if (TREE_CODE (low) != INTEGER_CST)
8024 low = ffecom_3 (COND_EXPR, integer_type_node,
8025 ffecom_adjarray_passed_ (s),
8026 low,
8027 ffecom_integer_zero_node);
5ff904cd 8028
c7e4ee3a
CB
8029 if (high && TREE_CODE (high) != INTEGER_CST)
8030 high = ffecom_3 (COND_EXPR, integer_type_node,
8031 ffecom_adjarray_passed_ (s),
8032 high,
8033 ffecom_integer_zero_node);
8034#endif
5ff904cd 8035
c7e4ee3a
CB
8036 /* ~~~gcc/stor-layout.c (layout_type) should do this,
8037 probably. Fixes 950302-1.f. */
5ff904cd 8038
c7e4ee3a
CB
8039 if (TREE_CODE (low) != INTEGER_CST)
8040 low = variable_size (low);
5ff904cd 8041
c7e4ee3a
CB
8042 /* ~~~Similarly, this fixes dumb0.f. The C front end
8043 does this, which is why dumb0.c would work. */
5ff904cd 8044
c7e4ee3a
CB
8045 if (high && TREE_CODE (high) != INTEGER_CST)
8046 high = variable_size (high);
5ff904cd 8047
c7e4ee3a
CB
8048 type
8049 = build_array_type
8050 (type,
8051 build_range_type (ffecom_integer_type_node,
8052 low, high));
8053 type = ffecom_check_size_overflow_ (s, type, TRUE);
8054 }
5ff904cd 8055
c7e4ee3a
CB
8056 if (type == error_mark_node)
8057 {
8058 t = error_mark_node;
8059 break;
8060 }
5ff904cd 8061
c7e4ee3a
CB
8062 if ((ffesymbol_sfdummyparent (s) == NULL)
8063 || (ffesymbol_basictype (s) == FFEINFO_basictypeCHARACTER))
8064 {
8065 type = build_pointer_type (type);
8066 addr = TRUE;
8067 }
5ff904cd 8068
c7e4ee3a 8069 t = build_decl (PARM_DECL, t, type);
5ff904cd 8070#if BUILT_FOR_270
c7e4ee3a 8071 DECL_ARTIFICIAL (t) = 1;
5ff904cd 8072#endif
5ff904cd 8073
c7e4ee3a
CB
8074 /* If this arg is present in every entry point's list of
8075 dummy args, then we're done. */
5ff904cd 8076
c7e4ee3a
CB
8077 if (ffesymbol_numentries (s)
8078 == (ffecom_num_entrypoints_ + 1))
5ff904cd 8079 break;
5ff904cd 8080
c7e4ee3a 8081#if 1
5ff904cd 8082
c7e4ee3a
CB
8083 /* If variable_size in stor-layout has been called during
8084 the above, then get_pending_sizes should have the
8085 yet-to-be-evaluated saved expressions pending.
8086 Make the whole lot of them get emitted, conditionally
8087 on whether the array decl ("t" above) is not NULL. */
5ff904cd 8088
c7e4ee3a
CB
8089 {
8090 tree sizes = get_pending_sizes ();
8091 tree tem;
5ff904cd 8092
c7e4ee3a
CB
8093 for (tem = sizes;
8094 tem != old_sizes;
8095 tem = TREE_CHAIN (tem))
8096 {
8097 tree temv = TREE_VALUE (tem);
5ff904cd 8098
c7e4ee3a
CB
8099 if (sizes == tem)
8100 sizes = temv;
8101 else
8102 sizes
8103 = ffecom_2 (COMPOUND_EXPR,
8104 TREE_TYPE (sizes),
8105 temv,
8106 sizes);
8107 }
5ff904cd 8108
c7e4ee3a
CB
8109 if (sizes != tem)
8110 {
8111 sizes
8112 = ffecom_3 (COND_EXPR,
8113 TREE_TYPE (sizes),
8114 ffecom_2 (NE_EXPR,
8115 integer_type_node,
8116 t,
8117 null_pointer_node),
8118 sizes,
8119 convert (TREE_TYPE (sizes),
8120 integer_zero_node));
8121 sizes = ffecom_save_tree (sizes);
5ff904cd 8122
c7e4ee3a
CB
8123 sizes
8124 = tree_cons (NULL_TREE, sizes, tem);
8125 }
5ff904cd 8126
c7e4ee3a
CB
8127 if (sizes)
8128 put_pending_sizes (sizes);
8129 }
5ff904cd 8130
c7e4ee3a
CB
8131#else
8132#if 0
8133 if (adjustable
8134 && (ffesymbol_numentries (s)
8135 != ffecom_num_entrypoints_ + 1))
8136 DECL_SOMETHING (t)
8137 = ffecom_2 (NE_EXPR, integer_type_node,
8138 t,
8139 null_pointer_node);
8140#else
8141#if 0
8142 if (adjustable
8143 && (ffesymbol_numentries (s)
8144 != ffecom_num_entrypoints_ + 1))
8145 {
8146 ffebad_start (FFEBAD_MISSING_ADJARRAY_UNSUPPORTED);
8147 ffebad_here (0, ffesymbol_where_line (s),
8148 ffesymbol_where_column (s));
8149 ffebad_string (ffesymbol_text (s));
8150 ffebad_finish ();
8151 }
8152#endif
8153#endif
8154#endif
8155 }
5ff904cd
JL
8156 break;
8157
c7e4ee3a 8158 case FFEINFO_whereCOMMON:
5ff904cd 8159 {
c7e4ee3a
CB
8160 ffesymbol cs;
8161 ffeglobal cg;
8162 tree ct;
5ff904cd
JL
8163 ffestorag st = ffesymbol_storage (s);
8164 tree type;
c7e4ee3a 8165 int yes;
5ff904cd 8166
c7e4ee3a
CB
8167 cs = ffesymbol_common (s); /* The COMMON area itself. */
8168 if (st != NULL) /* Else not laid out. */
5ff904cd 8169 {
c7e4ee3a
CB
8170 ffecom_transform_common_ (cs);
8171 st = ffesymbol_storage (s);
5ff904cd
JL
8172 }
8173
c7e4ee3a 8174 yes = suspend_momentary ();
5ff904cd 8175
c7e4ee3a 8176 type = ffecom_type_localvar_ (s, bt, kt);
5ff904cd 8177
c7e4ee3a
CB
8178 cg = ffesymbol_global (cs); /* The global COMMON info. */
8179 if ((cg == NULL)
8180 || (ffeglobal_type (cg) != FFEGLOBAL_typeCOMMON))
8181 ct = NULL_TREE;
8182 else
8183 ct = ffeglobal_hook (cg); /* The common area's tree. */
5ff904cd 8184
c7e4ee3a
CB
8185 if ((ct == NULL_TREE)
8186 || (st == NULL)
8187 || (type == error_mark_node))
8188 t = error_mark_node;
8189 else
8190 {
8191 ffetargetOffset offset;
8192 ffestorag cst;
5ff904cd 8193
c7e4ee3a
CB
8194 cst = ffestorag_parent (st);
8195 assert (cst == ffesymbol_storage (cs));
5ff904cd 8196
c7e4ee3a
CB
8197 offset = ffestorag_modulo (cst)
8198 + ffestorag_offset (st)
8199 - ffestorag_offset (cst);
5ff904cd 8200
c7e4ee3a 8201 ffecom_debug_kludge_ (ct, "COMMON", s, type, offset);
5ff904cd 8202
c7e4ee3a 8203 /* (t_type *) (((char *) &ct) + offset) */
5ff904cd
JL
8204
8205 t = convert (string_type_node, /* (char *) */
8206 ffecom_1 (ADDR_EXPR,
c7e4ee3a
CB
8207 build_pointer_type (TREE_TYPE (ct)),
8208 ct));
5ff904cd
JL
8209 t = ffecom_2 (PLUS_EXPR, TREE_TYPE (t),
8210 t,
8211 build_int_2 (offset, 0));
8212 t = convert (build_pointer_type (type),
8213 t);
d50108c7 8214 TREE_CONSTANT (t) = 1;
5ff904cd
JL
8215
8216 addr = TRUE;
5ff904cd 8217 }
5ff904cd 8218
c7e4ee3a
CB
8219 resume_momentary (yes);
8220 }
8221 break;
5ff904cd 8222
c7e4ee3a
CB
8223 case FFEINFO_whereIMMEDIATE:
8224 case FFEINFO_whereGLOBAL:
8225 case FFEINFO_whereFLEETING:
8226 case FFEINFO_whereFLEETING_CADDR:
8227 case FFEINFO_whereFLEETING_IADDR:
8228 case FFEINFO_whereINTRINSIC:
8229 case FFEINFO_whereCONSTANT_SUBOBJECT:
8230 default:
8231 assert ("ENTITY where unheard of" == NULL);
8232 /* Fall through. */
8233 case FFEINFO_whereANY:
8234 t = error_mark_node;
8235 break;
8236 }
8237 break;
5ff904cd 8238
c7e4ee3a
CB
8239 case FFEINFO_kindFUNCTION:
8240 switch (ffeinfo_where (ffesymbol_info (s)))
8241 {
8242 case FFEINFO_whereLOCAL: /* Me. */
8243 assert (!ffecom_transform_only_dummies_);
8244 t = current_function_decl;
5ff904cd
JL
8245 break;
8246
c7e4ee3a 8247 case FFEINFO_whereGLOBAL:
5ff904cd
JL
8248 assert (!ffecom_transform_only_dummies_);
8249
c7e4ee3a
CB
8250 if (((g = ffesymbol_global (s)) != NULL)
8251 && ((ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
8252 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
8253 && (ffeglobal_hook (g) != NULL_TREE)
8254 && ffe_is_globals ())
5ff904cd 8255 {
c7e4ee3a 8256 t = ffeglobal_hook (g);
5ff904cd
JL
8257 break;
8258 }
5ff904cd 8259
c7e4ee3a
CB
8260 push_obstacks_nochange ();
8261 end_temporary_allocation ();
5ff904cd 8262
c7e4ee3a
CB
8263 if (ffesymbol_is_f2c (s)
8264 && (ffesymbol_where (s) != FFEINFO_whereCONSTANT))
8265 t = ffecom_tree_fun_type[bt][kt];
8266 else
8267 t = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
5ff904cd 8268
c7e4ee3a
CB
8269 t = build_decl (FUNCTION_DECL,
8270 ffecom_get_external_identifier_ (s),
8271 t);
8272 DECL_EXTERNAL (t) = 1;
8273 TREE_PUBLIC (t) = 1;
5ff904cd 8274
5ff904cd
JL
8275 t = start_decl (t, FALSE);
8276 finish_decl (t, NULL_TREE, FALSE);
8277
c7e4ee3a
CB
8278 if ((g != NULL)
8279 && ((ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
8280 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
8281 ffeglobal_set_hook (g, t);
8282
8283 resume_temporary_allocation ();
8284 pop_obstacks ();
5ff904cd 8285
5ff904cd
JL
8286 break;
8287
8288 case FFEINFO_whereDUMMY:
c7e4ee3a 8289 assert (ffecom_transform_only_dummies_);
5ff904cd 8290
c7e4ee3a
CB
8291 if (ffesymbol_is_f2c (s)
8292 && (ffesymbol_where (s) != FFEINFO_whereCONSTANT))
8293 t = ffecom_tree_ptr_to_fun_type[bt][kt];
8294 else
8295 t = build_pointer_type
8296 (build_function_type (ffecom_tree_type[bt][kt], NULL_TREE));
8297
8298 t = build_decl (PARM_DECL,
8299 ffecom_get_identifier_ (ffesymbol_text (s)),
8300 t);
8301#if BUILT_FOR_270
8302 DECL_ARTIFICIAL (t) = 1;
8303#endif
8304 addr = TRUE;
8305 break;
8306
8307 case FFEINFO_whereCONSTANT: /* Statement function. */
8308 assert (!ffecom_transform_only_dummies_);
8309 t = ffecom_gen_sfuncdef_ (s, bt, kt);
8310 break;
8311
8312 case FFEINFO_whereINTRINSIC:
8313 assert (!ffecom_transform_only_dummies_);
8314 break; /* Let actual references generate their
8315 decls. */
8316
8317 default:
8318 assert ("FUNCTION where unheard of" == NULL);
8319 /* Fall through. */
8320 case FFEINFO_whereANY:
8321 t = error_mark_node;
8322 break;
8323 }
8324 break;
8325
8326 case FFEINFO_kindSUBROUTINE:
8327 switch (ffeinfo_where (ffesymbol_info (s)))
8328 {
8329 case FFEINFO_whereLOCAL: /* Me. */
8330 assert (!ffecom_transform_only_dummies_);
8331 t = current_function_decl;
8332 break;
5ff904cd 8333
c7e4ee3a
CB
8334 case FFEINFO_whereGLOBAL:
8335 assert (!ffecom_transform_only_dummies_);
5ff904cd 8336
c7e4ee3a
CB
8337 if (((g = ffesymbol_global (s)) != NULL)
8338 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
8339 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
8340 && (ffeglobal_hook (g) != NULL_TREE)
8341 && ffe_is_globals ())
8342 {
8343 t = ffeglobal_hook (g);
8344 break;
8345 }
5ff904cd 8346
c7e4ee3a
CB
8347 push_obstacks_nochange ();
8348 end_temporary_allocation ();
5ff904cd 8349
c7e4ee3a
CB
8350 t = build_decl (FUNCTION_DECL,
8351 ffecom_get_external_identifier_ (s),
8352 ffecom_tree_subr_type);
8353 DECL_EXTERNAL (t) = 1;
8354 TREE_PUBLIC (t) = 1;
5ff904cd 8355
c7e4ee3a
CB
8356 t = start_decl (t, FALSE);
8357 finish_decl (t, NULL_TREE, FALSE);
5ff904cd 8358
c7e4ee3a
CB
8359 if ((g != NULL)
8360 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
8361 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
8362 ffeglobal_set_hook (g, t);
5ff904cd 8363
c7e4ee3a
CB
8364 resume_temporary_allocation ();
8365 pop_obstacks ();
5ff904cd 8366
c7e4ee3a 8367 break;
5ff904cd 8368
c7e4ee3a
CB
8369 case FFEINFO_whereDUMMY:
8370 assert (ffecom_transform_only_dummies_);
5ff904cd 8371
c7e4ee3a
CB
8372 t = build_decl (PARM_DECL,
8373 ffecom_get_identifier_ (ffesymbol_text (s)),
8374 ffecom_tree_ptr_to_subr_type);
8375#if BUILT_FOR_270
8376 DECL_ARTIFICIAL (t) = 1;
8377#endif
8378 addr = TRUE;
8379 break;
5ff904cd 8380
c7e4ee3a
CB
8381 case FFEINFO_whereINTRINSIC:
8382 assert (!ffecom_transform_only_dummies_);
8383 break; /* Let actual references generate their
8384 decls. */
5ff904cd 8385
c7e4ee3a
CB
8386 default:
8387 assert ("SUBROUTINE where unheard of" == NULL);
8388 /* Fall through. */
8389 case FFEINFO_whereANY:
8390 t = error_mark_node;
8391 break;
8392 }
8393 break;
5ff904cd 8394
c7e4ee3a
CB
8395 case FFEINFO_kindPROGRAM:
8396 switch (ffeinfo_where (ffesymbol_info (s)))
8397 {
8398 case FFEINFO_whereLOCAL: /* Me. */
8399 assert (!ffecom_transform_only_dummies_);
8400 t = current_function_decl;
8401 break;
5ff904cd 8402
c7e4ee3a
CB
8403 case FFEINFO_whereCOMMON:
8404 case FFEINFO_whereDUMMY:
8405 case FFEINFO_whereGLOBAL:
8406 case FFEINFO_whereRESULT:
8407 case FFEINFO_whereFLEETING:
8408 case FFEINFO_whereFLEETING_CADDR:
8409 case FFEINFO_whereFLEETING_IADDR:
8410 case FFEINFO_whereIMMEDIATE:
8411 case FFEINFO_whereINTRINSIC:
8412 case FFEINFO_whereCONSTANT:
8413 case FFEINFO_whereCONSTANT_SUBOBJECT:
8414 default:
8415 assert ("PROGRAM where unheard of" == NULL);
8416 /* Fall through. */
8417 case FFEINFO_whereANY:
8418 t = error_mark_node;
8419 break;
8420 }
8421 break;
5ff904cd 8422
c7e4ee3a
CB
8423 case FFEINFO_kindBLOCKDATA:
8424 switch (ffeinfo_where (ffesymbol_info (s)))
8425 {
8426 case FFEINFO_whereLOCAL: /* Me. */
8427 assert (!ffecom_transform_only_dummies_);
8428 t = current_function_decl;
8429 break;
5ff904cd 8430
c7e4ee3a
CB
8431 case FFEINFO_whereGLOBAL:
8432 assert (!ffecom_transform_only_dummies_);
5ff904cd 8433
c7e4ee3a
CB
8434 push_obstacks_nochange ();
8435 end_temporary_allocation ();
5ff904cd 8436
c7e4ee3a
CB
8437 t = build_decl (FUNCTION_DECL,
8438 ffecom_get_external_identifier_ (s),
8439 ffecom_tree_blockdata_type);
8440 DECL_EXTERNAL (t) = 1;
8441 TREE_PUBLIC (t) = 1;
5ff904cd 8442
c7e4ee3a
CB
8443 t = start_decl (t, FALSE);
8444 finish_decl (t, NULL_TREE, FALSE);
5ff904cd 8445
c7e4ee3a
CB
8446 resume_temporary_allocation ();
8447 pop_obstacks ();
5ff904cd 8448
c7e4ee3a 8449 break;
5ff904cd 8450
c7e4ee3a
CB
8451 case FFEINFO_whereCOMMON:
8452 case FFEINFO_whereDUMMY:
8453 case FFEINFO_whereRESULT:
8454 case FFEINFO_whereFLEETING:
8455 case FFEINFO_whereFLEETING_CADDR:
8456 case FFEINFO_whereFLEETING_IADDR:
8457 case FFEINFO_whereIMMEDIATE:
8458 case FFEINFO_whereINTRINSIC:
8459 case FFEINFO_whereCONSTANT:
8460 case FFEINFO_whereCONSTANT_SUBOBJECT:
8461 default:
8462 assert ("BLOCKDATA where unheard of" == NULL);
8463 /* Fall through. */
8464 case FFEINFO_whereANY:
8465 t = error_mark_node;
8466 break;
8467 }
8468 break;
5ff904cd 8469
c7e4ee3a
CB
8470 case FFEINFO_kindCOMMON:
8471 switch (ffeinfo_where (ffesymbol_info (s)))
8472 {
8473 case FFEINFO_whereLOCAL:
8474 assert (!ffecom_transform_only_dummies_);
8475 ffecom_transform_common_ (s);
8476 break;
8477
8478 case FFEINFO_whereNONE:
8479 case FFEINFO_whereCOMMON:
8480 case FFEINFO_whereDUMMY:
8481 case FFEINFO_whereGLOBAL:
8482 case FFEINFO_whereRESULT:
8483 case FFEINFO_whereFLEETING:
8484 case FFEINFO_whereFLEETING_CADDR:
8485 case FFEINFO_whereFLEETING_IADDR:
8486 case FFEINFO_whereIMMEDIATE:
8487 case FFEINFO_whereINTRINSIC:
8488 case FFEINFO_whereCONSTANT:
8489 case FFEINFO_whereCONSTANT_SUBOBJECT:
8490 default:
8491 assert ("COMMON where unheard of" == NULL);
8492 /* Fall through. */
8493 case FFEINFO_whereANY:
8494 t = error_mark_node;
8495 break;
8496 }
8497 break;
5ff904cd 8498
c7e4ee3a
CB
8499 case FFEINFO_kindCONSTRUCT:
8500 switch (ffeinfo_where (ffesymbol_info (s)))
8501 {
8502 case FFEINFO_whereLOCAL:
8503 assert (!ffecom_transform_only_dummies_);
8504 break;
5ff904cd 8505
c7e4ee3a
CB
8506 case FFEINFO_whereNONE:
8507 case FFEINFO_whereCOMMON:
8508 case FFEINFO_whereDUMMY:
8509 case FFEINFO_whereGLOBAL:
8510 case FFEINFO_whereRESULT:
8511 case FFEINFO_whereFLEETING:
8512 case FFEINFO_whereFLEETING_CADDR:
8513 case FFEINFO_whereFLEETING_IADDR:
8514 case FFEINFO_whereIMMEDIATE:
8515 case FFEINFO_whereINTRINSIC:
8516 case FFEINFO_whereCONSTANT:
8517 case FFEINFO_whereCONSTANT_SUBOBJECT:
8518 default:
8519 assert ("CONSTRUCT where unheard of" == NULL);
8520 /* Fall through. */
8521 case FFEINFO_whereANY:
8522 t = error_mark_node;
8523 break;
8524 }
8525 break;
5ff904cd 8526
c7e4ee3a
CB
8527 case FFEINFO_kindNAMELIST:
8528 switch (ffeinfo_where (ffesymbol_info (s)))
8529 {
8530 case FFEINFO_whereLOCAL:
8531 assert (!ffecom_transform_only_dummies_);
8532 t = ffecom_transform_namelist_ (s);
8533 break;
5ff904cd 8534
c7e4ee3a
CB
8535 case FFEINFO_whereNONE:
8536 case FFEINFO_whereCOMMON:
8537 case FFEINFO_whereDUMMY:
8538 case FFEINFO_whereGLOBAL:
8539 case FFEINFO_whereRESULT:
8540 case FFEINFO_whereFLEETING:
8541 case FFEINFO_whereFLEETING_CADDR:
8542 case FFEINFO_whereFLEETING_IADDR:
8543 case FFEINFO_whereIMMEDIATE:
8544 case FFEINFO_whereINTRINSIC:
8545 case FFEINFO_whereCONSTANT:
8546 case FFEINFO_whereCONSTANT_SUBOBJECT:
8547 default:
8548 assert ("NAMELIST where unheard of" == NULL);
8549 /* Fall through. */
8550 case FFEINFO_whereANY:
8551 t = error_mark_node;
8552 break;
8553 }
8554 break;
5ff904cd 8555
c7e4ee3a
CB
8556 default:
8557 assert ("kind unheard of" == NULL);
8558 /* Fall through. */
8559 case FFEINFO_kindANY:
8560 t = error_mark_node;
8561 break;
8562 }
5ff904cd 8563
c7e4ee3a
CB
8564 ffesymbol_hook (s).decl_tree = t;
8565 ffesymbol_hook (s).length_tree = tlen;
8566 ffesymbol_hook (s).addr = addr;
5ff904cd 8567
c7e4ee3a
CB
8568 lineno = old_lineno;
8569 input_filename = old_input_filename;
5ff904cd 8570
c7e4ee3a
CB
8571 return s;
8572}
5ff904cd 8573
5ff904cd 8574#endif
c7e4ee3a 8575/* Transform into ASSIGNable symbol.
5ff904cd 8576
c7e4ee3a
CB
8577 Symbol has already been transformed, but for whatever reason, the
8578 resulting decl_tree has been deemed not usable for an ASSIGN target.
8579 (E.g. it isn't wide enough to hold a pointer.) So, here we invent
8580 another local symbol of type void * and stuff that in the assign_tree
8581 argument. The F77/F90 standards allow this implementation. */
5ff904cd 8582
c7e4ee3a
CB
8583#if FFECOM_targetCURRENT == FFECOM_targetGCC
8584static ffesymbol
8585ffecom_sym_transform_assign_ (ffesymbol s)
8586{
8587 tree t; /* Transformed thingy. */
8588 int yes;
8589 int old_lineno = lineno;
8590 char *old_input_filename = input_filename;
5ff904cd 8591
c7e4ee3a
CB
8592 if (ffesymbol_sfdummyparent (s) == NULL)
8593 {
8594 input_filename = ffesymbol_where_filename (s);
8595 lineno = ffesymbol_where_filelinenum (s);
8596 }
8597 else
8598 {
8599 ffesymbol sf = ffesymbol_sfdummyparent (s);
5ff904cd 8600
c7e4ee3a
CB
8601 input_filename = ffesymbol_where_filename (sf);
8602 lineno = ffesymbol_where_filelinenum (sf);
8603 }
5ff904cd 8604
c7e4ee3a 8605 assert (!ffecom_transform_only_dummies_);
5ff904cd 8606
c7e4ee3a 8607 yes = suspend_momentary ();
5ff904cd 8608
c7e4ee3a
CB
8609 t = build_decl (VAR_DECL,
8610 ffecom_get_invented_identifier ("__g77_ASSIGN_%s",
8611 ffesymbol_text (s),
8612 -1),
8613 TREE_TYPE (null_pointer_node));
5ff904cd 8614
c7e4ee3a
CB
8615 switch (ffesymbol_where (s))
8616 {
8617 case FFEINFO_whereLOCAL:
8618 /* Unlike for regular vars, SAVE status is easy to determine for
8619 ASSIGNed vars, since there's no initialization, there's no
8620 effective storage association (so "SAVE J" does not apply to
8621 K even given "EQUIVALENCE (J,K)"), there's no size issue
8622 to worry about, etc. */
8623 if ((ffesymbol_is_save (s) || ffe_is_saveall ())
8624 && (ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
8625 && (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA))
8626 TREE_STATIC (t) = 1; /* SAVEd in proc, make static. */
8627 else
8628 TREE_STATIC (t) = 0; /* No need to make static. */
8629 break;
5ff904cd 8630
c7e4ee3a
CB
8631 case FFEINFO_whereCOMMON:
8632 TREE_STATIC (t) = 1; /* Assume COMMONs always SAVEd. */
8633 break;
5ff904cd 8634
c7e4ee3a
CB
8635 case FFEINFO_whereDUMMY:
8636 /* Note that twinning a DUMMY means the caller won't see
8637 the ASSIGNed value. But both F77 and F90 allow implementations
8638 to do this, i.e. disallow Fortran code that would try and
8639 take advantage of actually putting a label into a variable
8640 via a dummy argument (or any other storage association, for
8641 that matter). */
8642 TREE_STATIC (t) = 0;
8643 break;
5ff904cd 8644
c7e4ee3a
CB
8645 default:
8646 TREE_STATIC (t) = 0;
8647 break;
8648 }
5ff904cd 8649
c7e4ee3a
CB
8650 t = start_decl (t, FALSE);
8651 finish_decl (t, NULL_TREE, FALSE);
5ff904cd 8652
c7e4ee3a 8653 resume_momentary (yes);
5ff904cd 8654
c7e4ee3a 8655 ffesymbol_hook (s).assign_tree = t;
5ff904cd 8656
c7e4ee3a
CB
8657 lineno = old_lineno;
8658 input_filename = old_input_filename;
5ff904cd 8659
c7e4ee3a
CB
8660 return s;
8661}
5ff904cd 8662
c7e4ee3a
CB
8663#endif
8664/* Implement COMMON area in back end.
5ff904cd 8665
c7e4ee3a
CB
8666 Because COMMON-based variables can be referenced in the dimension
8667 expressions of dummy (adjustable) arrays, and because dummies
8668 (in the gcc back end) need to be put in the outer binding level
8669 of a function (which has two binding levels, the outer holding
8670 the dummies and the inner holding the other vars), special care
8671 must be taken to handle COMMON areas.
5ff904cd 8672
c7e4ee3a
CB
8673 The current strategy is basically to always tell the back end about
8674 the COMMON area as a top-level external reference to just a block
8675 of storage of the master type of that area (e.g. integer, real,
8676 character, whatever -- not a structure). As a distinct action,
8677 if initial values are provided, tell the back end about the area
8678 as a top-level non-external (initialized) area and remember not to
8679 allow further initialization or expansion of the area. Meanwhile,
8680 if no initialization happens at all, tell the back end about
8681 the largest size we've seen declared so the space does get reserved.
8682 (This function doesn't handle all that stuff, but it does some
8683 of the important things.)
5ff904cd 8684
c7e4ee3a
CB
8685 Meanwhile, for COMMON variables themselves, just keep creating
8686 references like *((float *) (&common_area + offset)) each time
8687 we reference the variable. In other words, don't make a VAR_DECL
8688 or any kind of component reference (like we used to do before 0.4),
8689 though we might do that as well just for debugging purposes (and
8690 stuff the rtl with the appropriate offset expression). */
5ff904cd 8691
c7e4ee3a
CB
8692#if FFECOM_targetCURRENT == FFECOM_targetGCC
8693static void
8694ffecom_transform_common_ (ffesymbol s)
8695{
8696 ffestorag st = ffesymbol_storage (s);
8697 ffeglobal g = ffesymbol_global (s);
8698 tree cbt;
8699 tree cbtype;
8700 tree init;
8701 tree high;
8702 bool is_init = ffestorag_is_init (st);
5ff904cd 8703
c7e4ee3a 8704 assert (st != NULL);
5ff904cd 8705
c7e4ee3a
CB
8706 if ((g == NULL)
8707 || (ffeglobal_type (g) != FFEGLOBAL_typeCOMMON))
8708 return;
5ff904cd 8709
c7e4ee3a 8710 /* First update the size of the area in global terms. */
5ff904cd 8711
c7e4ee3a 8712 ffeglobal_size_common (s, ffestorag_size (st));
5ff904cd 8713
c7e4ee3a
CB
8714 if (!ffeglobal_common_init (g))
8715 is_init = FALSE; /* No explicit init, don't let erroneous joins init. */
5ff904cd 8716
c7e4ee3a 8717 cbt = ffeglobal_hook (g);
5ff904cd 8718
c7e4ee3a
CB
8719 /* If we already have declared this common block for a previous program
8720 unit, and either we already initialized it or we don't have new
8721 initialization for it, just return what we have without changing it. */
5ff904cd 8722
c7e4ee3a
CB
8723 if ((cbt != NULL_TREE)
8724 && (!is_init
8725 || !DECL_EXTERNAL (cbt)))
8726 return;
5ff904cd 8727
c7e4ee3a 8728 /* Process inits. */
5ff904cd 8729
c7e4ee3a
CB
8730 if (is_init)
8731 {
8732 if (ffestorag_init (st) != NULL)
5ff904cd 8733 {
c7e4ee3a 8734 ffebld sexp;
5ff904cd 8735
c7e4ee3a
CB
8736 /* Set the padding for the expression, so ffecom_expr
8737 knows to insert that many zeros. */
8738 switch (ffebld_op (sexp = ffestorag_init (st)))
5ff904cd 8739 {
c7e4ee3a
CB
8740 case FFEBLD_opCONTER:
8741 ffebld_conter_set_pad (sexp, ffestorag_modulo (st));
5ff904cd 8742 break;
5ff904cd 8743
c7e4ee3a
CB
8744 case FFEBLD_opARRTER:
8745 ffebld_arrter_set_pad (sexp, ffestorag_modulo (st));
8746 break;
5ff904cd 8747
c7e4ee3a
CB
8748 case FFEBLD_opACCTER:
8749 ffebld_accter_set_pad (sexp, ffestorag_modulo (st));
8750 break;
5ff904cd 8751
c7e4ee3a
CB
8752 default:
8753 assert ("bad op for cmn init (pad)" == NULL);
8754 break;
8755 }
5ff904cd 8756
c7e4ee3a
CB
8757 init = ffecom_expr (sexp);
8758 if (init == error_mark_node)
8759 { /* Hopefully the back end complained! */
8760 init = NULL_TREE;
8761 if (cbt != NULL_TREE)
8762 return;
8763 }
8764 }
8765 else
8766 init = error_mark_node;
8767 }
8768 else
8769 init = NULL_TREE;
5ff904cd 8770
c7e4ee3a
CB
8771 push_obstacks_nochange ();
8772 end_temporary_allocation ();
5ff904cd 8773
c7e4ee3a 8774 /* cbtype must be permanently allocated! */
5ff904cd 8775
c7e4ee3a
CB
8776 /* Allocate the MAX of the areas so far, seen filewide. */
8777 high = build_int_2 ((ffeglobal_common_size (g)
8778 + ffeglobal_common_pad (g)) - 1, 0);
8779 TREE_TYPE (high) = ffecom_integer_type_node;
5ff904cd 8780
c7e4ee3a
CB
8781 if (init)
8782 cbtype = build_array_type (char_type_node,
8783 build_range_type (integer_type_node,
8784 integer_zero_node,
8785 high));
8786 else
8787 cbtype = build_array_type (char_type_node, NULL_TREE);
5ff904cd 8788
c7e4ee3a
CB
8789 if (cbt == NULL_TREE)
8790 {
8791 cbt
8792 = build_decl (VAR_DECL,
8793 ffecom_get_external_identifier_ (s),
8794 cbtype);
8795 TREE_STATIC (cbt) = 1;
8796 TREE_PUBLIC (cbt) = 1;
8797 }
8798 else
8799 {
8800 assert (is_init);
8801 TREE_TYPE (cbt) = cbtype;
8802 }
8803 DECL_EXTERNAL (cbt) = init ? 0 : 1;
8804 DECL_INITIAL (cbt) = init ? error_mark_node : NULL_TREE;
5ff904cd 8805
c7e4ee3a
CB
8806 cbt = start_decl (cbt, TRUE);
8807 if (ffeglobal_hook (g) != NULL)
8808 assert (cbt == ffeglobal_hook (g));
5ff904cd 8809
c7e4ee3a 8810 assert (!init || !DECL_EXTERNAL (cbt));
5ff904cd 8811
c7e4ee3a
CB
8812 /* Make sure that any type can live in COMMON and be referenced
8813 without getting a bus error. We could pick the most restrictive
8814 alignment of all entities actually placed in the COMMON, but
8815 this seems easy enough. */
5ff904cd 8816
c7e4ee3a 8817 DECL_ALIGN (cbt) = BIGGEST_ALIGNMENT;
5ff904cd 8818
c7e4ee3a
CB
8819 if (is_init && (ffestorag_init (st) == NULL))
8820 init = ffecom_init_zero_ (cbt);
5ff904cd 8821
c7e4ee3a 8822 finish_decl (cbt, init, TRUE);
5ff904cd 8823
c7e4ee3a
CB
8824 if (is_init)
8825 ffestorag_set_init (st, ffebld_new_any ());
5ff904cd 8826
c7e4ee3a
CB
8827 if (init)
8828 {
8829 tree size_tree;
5ff904cd 8830
c7e4ee3a
CB
8831 assert (DECL_SIZE (cbt) != NULL_TREE);
8832 assert (TREE_CODE (DECL_SIZE (cbt)) == INTEGER_CST);
8833 size_tree = size_binop (CEIL_DIV_EXPR,
8834 DECL_SIZE (cbt),
8835 size_int (BITS_PER_UNIT));
8836 assert (TREE_INT_CST_HIGH (size_tree) == 0);
8837 assert (TREE_INT_CST_LOW (size_tree)
8838 == ffeglobal_common_size (g) + ffeglobal_common_pad (g));
8839 }
5ff904cd 8840
c7e4ee3a 8841 ffeglobal_set_hook (g, cbt);
5ff904cd 8842
c7e4ee3a 8843 ffestorag_set_hook (st, cbt);
5ff904cd 8844
c7e4ee3a
CB
8845 resume_temporary_allocation ();
8846 pop_obstacks ();
8847}
5ff904cd 8848
c7e4ee3a
CB
8849#endif
8850/* Make master area for local EQUIVALENCE. */
5ff904cd 8851
c7e4ee3a
CB
8852#if FFECOM_targetCURRENT == FFECOM_targetGCC
8853static void
8854ffecom_transform_equiv_ (ffestorag eqst)
8855{
8856 tree eqt;
8857 tree eqtype;
8858 tree init;
8859 tree high;
8860 bool is_init = ffestorag_is_init (eqst);
8861 int yes;
5ff904cd 8862
c7e4ee3a 8863 assert (eqst != NULL);
5ff904cd 8864
c7e4ee3a 8865 eqt = ffestorag_hook (eqst);
5ff904cd 8866
c7e4ee3a
CB
8867 if (eqt != NULL_TREE)
8868 return;
5ff904cd 8869
c7e4ee3a
CB
8870 /* Process inits. */
8871
8872 if (is_init)
8873 {
8874 if (ffestorag_init (eqst) != NULL)
5ff904cd 8875 {
c7e4ee3a 8876 ffebld sexp;
5ff904cd 8877
c7e4ee3a
CB
8878 /* Set the padding for the expression, so ffecom_expr
8879 knows to insert that many zeros. */
8880 switch (ffebld_op (sexp = ffestorag_init (eqst)))
8881 {
8882 case FFEBLD_opCONTER:
8883 ffebld_conter_set_pad (sexp, ffestorag_modulo (eqst));
8884 break;
5ff904cd 8885
c7e4ee3a
CB
8886 case FFEBLD_opARRTER:
8887 ffebld_arrter_set_pad (sexp, ffestorag_modulo (eqst));
8888 break;
5ff904cd 8889
c7e4ee3a
CB
8890 case FFEBLD_opACCTER:
8891 ffebld_accter_set_pad (sexp, ffestorag_modulo (eqst));
8892 break;
5ff904cd 8893
c7e4ee3a
CB
8894 default:
8895 assert ("bad op for eqv init (pad)" == NULL);
8896 break;
8897 }
5ff904cd 8898
c7e4ee3a
CB
8899 init = ffecom_expr (sexp);
8900 if (init == error_mark_node)
8901 init = NULL_TREE; /* Hopefully the back end complained! */
8902 }
8903 else
8904 init = error_mark_node;
8905 }
8906 else if (ffe_is_init_local_zero ())
8907 init = error_mark_node;
8908 else
8909 init = NULL_TREE;
5ff904cd 8910
c7e4ee3a
CB
8911 ffecom_member_namelisted_ = FALSE;
8912 ffestorag_drive (ffestorag_list_equivs (eqst),
8913 &ffecom_member_phase1_,
8914 eqst);
5ff904cd 8915
c7e4ee3a 8916 yes = suspend_momentary ();
5ff904cd 8917
c7e4ee3a
CB
8918 high = build_int_2 ((ffestorag_size (eqst)
8919 + ffestorag_modulo (eqst)) - 1, 0);
8920 TREE_TYPE (high) = ffecom_integer_type_node;
5ff904cd 8921
c7e4ee3a
CB
8922 eqtype = build_array_type (char_type_node,
8923 build_range_type (ffecom_integer_type_node,
8924 ffecom_integer_zero_node,
8925 high));
8926
8927 eqt = build_decl (VAR_DECL,
8928 ffecom_get_invented_identifier ("__g77_equiv_%s",
8929 ffesymbol_text
8930 (ffestorag_symbol
8931 (eqst)),
8932 -1),
8933 eqtype);
8934 DECL_EXTERNAL (eqt) = 0;
8935 if (is_init
8936 || ffecom_member_namelisted_
8937#ifdef FFECOM_sizeMAXSTACKITEM
8938 || (ffestorag_size (eqst) > FFECOM_sizeMAXSTACKITEM)
8939#endif
8940 || ((ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
8941 && (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA)
8942 && (ffestorag_is_save (eqst) || ffe_is_saveall ())))
8943 TREE_STATIC (eqt) = 1;
8944 else
8945 TREE_STATIC (eqt) = 0;
8946 TREE_PUBLIC (eqt) = 0;
8947 DECL_CONTEXT (eqt) = current_function_decl;
8948 if (init)
8949 DECL_INITIAL (eqt) = error_mark_node;
8950 else
8951 DECL_INITIAL (eqt) = NULL_TREE;
5ff904cd 8952
c7e4ee3a 8953 eqt = start_decl (eqt, FALSE);
5ff904cd 8954
c7e4ee3a
CB
8955 /* Make sure that any type can live in EQUIVALENCE and be referenced
8956 without getting a bus error. We could pick the most restrictive
8957 alignment of all entities actually placed in the EQUIVALENCE, but
8958 this seems easy enough. */
5ff904cd 8959
c7e4ee3a 8960 DECL_ALIGN (eqt) = BIGGEST_ALIGNMENT;
5ff904cd 8961
c7e4ee3a
CB
8962 if ((!is_init && ffe_is_init_local_zero ())
8963 || (is_init && (ffestorag_init (eqst) == NULL)))
8964 init = ffecom_init_zero_ (eqt);
5ff904cd 8965
c7e4ee3a 8966 finish_decl (eqt, init, FALSE);
5ff904cd 8967
c7e4ee3a
CB
8968 if (is_init)
8969 ffestorag_set_init (eqst, ffebld_new_any ());
5ff904cd 8970
c7e4ee3a
CB
8971 {
8972 tree size_tree;
5ff904cd 8973
c7e4ee3a
CB
8974 size_tree = size_binop (CEIL_DIV_EXPR,
8975 DECL_SIZE (eqt),
8976 size_int (BITS_PER_UNIT));
8977 assert (TREE_INT_CST_HIGH (size_tree) == 0);
8978 assert (TREE_INT_CST_LOW (size_tree)
8979 == ffestorag_size (eqst) + ffestorag_modulo (eqst));
8980 }
5ff904cd 8981
c7e4ee3a 8982 ffestorag_set_hook (eqst, eqt);
5ff904cd 8983
c7e4ee3a
CB
8984#ifdef SOMEONE_GETS_DEBUG_SUPPORT_WORKING
8985 ffestorag_drive (ffestorag_list_equivs (eqst),
8986 &ffecom_member_phase2_,
8987 eqst);
8988#endif
8989
8990 resume_momentary (yes);
5ff904cd
JL
8991}
8992
8993#endif
c7e4ee3a 8994/* Implement NAMELIST in back end. See f2c/format.c for more info. */
5ff904cd
JL
8995
8996#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
8997static tree
8998ffecom_transform_namelist_ (ffesymbol s)
5ff904cd 8999{
c7e4ee3a
CB
9000 tree nmlt;
9001 tree nmltype = ffecom_type_namelist_ ();
9002 tree nmlinits;
9003 tree nameinit;
9004 tree varsinit;
9005 tree nvarsinit;
9006 tree field;
9007 tree high;
5ff904cd 9008 int yes;
c7e4ee3a
CB
9009 int i;
9010 static int mynumber = 0;
5ff904cd 9011
c7e4ee3a 9012 yes = suspend_momentary ();
5ff904cd 9013
c7e4ee3a
CB
9014 nmlt = build_decl (VAR_DECL,
9015 ffecom_get_invented_identifier ("__g77_namelist_%d",
9016 NULL, mynumber++),
9017 nmltype);
9018 TREE_STATIC (nmlt) = 1;
9019 DECL_INITIAL (nmlt) = error_mark_node;
5ff904cd 9020
c7e4ee3a 9021 nmlt = start_decl (nmlt, FALSE);
5ff904cd 9022
c7e4ee3a 9023 /* Process inits. */
5ff904cd 9024
c7e4ee3a 9025 i = strlen (ffesymbol_text (s));
5ff904cd 9026
c7e4ee3a
CB
9027 high = build_int_2 (i, 0);
9028 TREE_TYPE (high) = ffecom_f2c_ftnlen_type_node;
9029
9030 nameinit = ffecom_build_f2c_string_ (i + 1,
9031 ffesymbol_text (s));
9032 TREE_TYPE (nameinit)
9033 = build_type_variant
9034 (build_array_type
9035 (char_type_node,
9036 build_range_type (ffecom_f2c_ftnlen_type_node,
9037 ffecom_f2c_ftnlen_one_node,
9038 high)),
9039 1, 0);
9040 TREE_CONSTANT (nameinit) = 1;
9041 TREE_STATIC (nameinit) = 1;
9042 nameinit = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (nameinit)),
9043 nameinit);
9044
9045 varsinit = ffecom_vardesc_array_ (s);
9046 varsinit = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (varsinit)),
9047 varsinit);
9048 TREE_CONSTANT (varsinit) = 1;
9049 TREE_STATIC (varsinit) = 1;
9050
9051 {
9052 ffebld b;
9053
9054 for (i = 0, b = ffesymbol_namelist (s); b != NULL; b = ffebld_trail (b))
9055 ++i;
9056 }
9057 nvarsinit = build_int_2 (i, 0);
9058 TREE_TYPE (nvarsinit) = integer_type_node;
9059 TREE_CONSTANT (nvarsinit) = 1;
9060 TREE_STATIC (nvarsinit) = 1;
9061
9062 nmlinits = build_tree_list ((field = TYPE_FIELDS (nmltype)), nameinit);
9063 TREE_CHAIN (nmlinits) = build_tree_list ((field = TREE_CHAIN (field)),
9064 varsinit);
9065 TREE_CHAIN (TREE_CHAIN (nmlinits))
9066 = build_tree_list ((field = TREE_CHAIN (field)), nvarsinit);
9067
9068 nmlinits = build (CONSTRUCTOR, nmltype, NULL_TREE, nmlinits);
9069 TREE_CONSTANT (nmlinits) = 1;
9070 TREE_STATIC (nmlinits) = 1;
9071
9072 finish_decl (nmlt, nmlinits, FALSE);
9073
9074 nmlt = ffecom_1 (ADDR_EXPR, build_pointer_type (nmltype), nmlt);
9075
9076 resume_momentary (yes);
9077
9078 return nmlt;
9079}
9080
9081#endif
9082
9083/* A subroutine of ffecom_tree_canonize_ref_. The incoming tree is
9084 analyzed on the assumption it is calculating a pointer to be
9085 indirected through. It must return the proper decl and offset,
9086 taking into account different units of measurements for offsets. */
9087
9088#if FFECOM_targetCURRENT == FFECOM_targetGCC
9089static void
9090ffecom_tree_canonize_ptr_ (tree *decl, tree *offset,
9091 tree t)
9092{
9093 switch (TREE_CODE (t))
9094 {
9095 case NOP_EXPR:
9096 case CONVERT_EXPR:
9097 case NON_LVALUE_EXPR:
9098 ffecom_tree_canonize_ptr_ (decl, offset, TREE_OPERAND (t, 0));
5ff904cd
JL
9099 break;
9100
c7e4ee3a
CB
9101 case PLUS_EXPR:
9102 ffecom_tree_canonize_ptr_ (decl, offset, TREE_OPERAND (t, 0));
9103 if ((*decl == NULL_TREE)
9104 || (*decl == error_mark_node))
9105 break;
9106
9107 if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST)
9108 {
9109 /* An offset into COMMON. */
9110 *offset = size_binop (PLUS_EXPR,
9111 *offset,
9112 TREE_OPERAND (t, 1));
9113 /* Convert offset (presumably in bytes) into canonical units
9114 (presumably bits). */
9115 *offset = size_binop (MULT_EXPR,
9116 TYPE_SIZE (TREE_TYPE (TREE_TYPE (t))),
9117 *offset);
9118 break;
9119 }
9120 /* Not a COMMON reference, so an unrecognized pattern. */
9121 *decl = error_mark_node;
5ff904cd
JL
9122 break;
9123
c7e4ee3a
CB
9124 case PARM_DECL:
9125 *decl = t;
9126 *offset = bitsize_int (0L, 0L);
5ff904cd
JL
9127 break;
9128
c7e4ee3a
CB
9129 case ADDR_EXPR:
9130 if (TREE_CODE (TREE_OPERAND (t, 0)) == VAR_DECL)
9131 {
9132 /* A reference to COMMON. */
9133 *decl = TREE_OPERAND (t, 0);
9134 *offset = bitsize_int (0L, 0L);
9135 break;
9136 }
9137 /* Fall through. */
5ff904cd 9138 default:
c7e4ee3a
CB
9139 /* Not a COMMON reference, so an unrecognized pattern. */
9140 *decl = error_mark_node;
5ff904cd
JL
9141 break;
9142 }
c7e4ee3a
CB
9143}
9144#endif
5ff904cd 9145
c7e4ee3a
CB
9146/* Given a tree that is possibly intended for use as an lvalue, return
9147 information representing a canonical view of that tree as a decl, an
9148 offset into that decl, and a size for the lvalue.
5ff904cd 9149
c7e4ee3a
CB
9150 If there's no applicable decl, NULL_TREE is returned for the decl,
9151 and the other fields are left undefined.
5ff904cd 9152
c7e4ee3a
CB
9153 If the tree doesn't fit the recognizable forms, an ERROR_MARK node
9154 is returned for the decl, and the other fields are left undefined.
5ff904cd 9155
c7e4ee3a
CB
9156 Otherwise, the decl returned currently is either a VAR_DECL or a
9157 PARM_DECL.
5ff904cd 9158
c7e4ee3a
CB
9159 The offset returned is always valid, but of course not necessarily
9160 a constant, and not necessarily converted into the appropriate
9161 type, leaving that up to the caller (so as to avoid that overhead
9162 if the decls being looked at are different anyway).
5ff904cd 9163
c7e4ee3a
CB
9164 If the size cannot be determined (e.g. an adjustable array),
9165 an ERROR_MARK node is returned for the size. Otherwise, the
9166 size returned is valid, not necessarily a constant, and not
9167 necessarily converted into the appropriate type as with the
9168 offset.
5ff904cd 9169
c7e4ee3a
CB
9170 Note that the offset and size expressions are expressed in the
9171 base storage units (usually bits) rather than in the units of
9172 the type of the decl, because two decls with different types
9173 might overlap but with apparently non-overlapping array offsets,
9174 whereas converting the array offsets to consistant offsets will
9175 reveal the overlap. */
5ff904cd
JL
9176
9177#if FFECOM_targetCURRENT == FFECOM_targetGCC
9178static void
c7e4ee3a
CB
9179ffecom_tree_canonize_ref_ (tree *decl, tree *offset,
9180 tree *size, tree t)
5ff904cd 9181{
c7e4ee3a
CB
9182 /* The default path is to report a nonexistant decl. */
9183 *decl = NULL_TREE;
5ff904cd 9184
c7e4ee3a 9185 if (t == NULL_TREE)
5ff904cd
JL
9186 return;
9187
c7e4ee3a
CB
9188 switch (TREE_CODE (t))
9189 {
9190 case ERROR_MARK:
9191 case IDENTIFIER_NODE:
9192 case INTEGER_CST:
9193 case REAL_CST:
9194 case COMPLEX_CST:
9195 case STRING_CST:
9196 case CONST_DECL:
9197 case PLUS_EXPR:
9198 case MINUS_EXPR:
9199 case MULT_EXPR:
9200 case TRUNC_DIV_EXPR:
9201 case CEIL_DIV_EXPR:
9202 case FLOOR_DIV_EXPR:
9203 case ROUND_DIV_EXPR:
9204 case TRUNC_MOD_EXPR:
9205 case CEIL_MOD_EXPR:
9206 case FLOOR_MOD_EXPR:
9207 case ROUND_MOD_EXPR:
9208 case RDIV_EXPR:
9209 case EXACT_DIV_EXPR:
9210 case FIX_TRUNC_EXPR:
9211 case FIX_CEIL_EXPR:
9212 case FIX_FLOOR_EXPR:
9213 case FIX_ROUND_EXPR:
9214 case FLOAT_EXPR:
9215 case EXPON_EXPR:
9216 case NEGATE_EXPR:
9217 case MIN_EXPR:
9218 case MAX_EXPR:
9219 case ABS_EXPR:
9220 case FFS_EXPR:
9221 case LSHIFT_EXPR:
9222 case RSHIFT_EXPR:
9223 case LROTATE_EXPR:
9224 case RROTATE_EXPR:
9225 case BIT_IOR_EXPR:
9226 case BIT_XOR_EXPR:
9227 case BIT_AND_EXPR:
9228 case BIT_ANDTC_EXPR:
9229 case BIT_NOT_EXPR:
9230 case TRUTH_ANDIF_EXPR:
9231 case TRUTH_ORIF_EXPR:
9232 case TRUTH_AND_EXPR:
9233 case TRUTH_OR_EXPR:
9234 case TRUTH_XOR_EXPR:
9235 case TRUTH_NOT_EXPR:
9236 case LT_EXPR:
9237 case LE_EXPR:
9238 case GT_EXPR:
9239 case GE_EXPR:
9240 case EQ_EXPR:
9241 case NE_EXPR:
9242 case COMPLEX_EXPR:
9243 case CONJ_EXPR:
9244 case REALPART_EXPR:
9245 case IMAGPART_EXPR:
9246 case LABEL_EXPR:
9247 case COMPONENT_REF:
9248 case COMPOUND_EXPR:
9249 case ADDR_EXPR:
9250 return;
5ff904cd 9251
c7e4ee3a
CB
9252 case VAR_DECL:
9253 case PARM_DECL:
9254 *decl = t;
9255 *offset = bitsize_int (0L, 0L);
9256 *size = TYPE_SIZE (TREE_TYPE (t));
9257 return;
5ff904cd 9258
c7e4ee3a
CB
9259 case ARRAY_REF:
9260 {
9261 tree array = TREE_OPERAND (t, 0);
9262 tree element = TREE_OPERAND (t, 1);
9263 tree init_offset;
9264
9265 if ((array == NULL_TREE)
9266 || (element == NULL_TREE))
9267 {
9268 *decl = error_mark_node;
9269 return;
9270 }
9271
9272 ffecom_tree_canonize_ref_ (decl, &init_offset, size,
9273 array);
9274 if ((*decl == NULL_TREE)
9275 || (*decl == error_mark_node))
9276 return;
9277
9278 *offset = size_binop (MULT_EXPR,
9279 TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))),
9280 size_binop (MINUS_EXPR,
9281 element,
9282 TYPE_MIN_VALUE
9283 (TYPE_DOMAIN
9284 (TREE_TYPE (array)))));
9285
9286 *offset = size_binop (PLUS_EXPR,
9287 init_offset,
9288 *offset);
9289
9290 *size = TYPE_SIZE (TREE_TYPE (t));
9291 return;
9292 }
9293
9294 case INDIRECT_REF:
9295
9296 /* Most of this code is to handle references to COMMON. And so
9297 far that is useful only for calling library functions, since
9298 external (user) functions might reference common areas. But
9299 even calling an external function, it's worthwhile to decode
9300 COMMON references because if not storing into COMMON, we don't
9301 want COMMON-based arguments to gratuitously force use of a
9302 temporary. */
9303
9304 *size = TYPE_SIZE (TREE_TYPE (t));
5ff904cd 9305
c7e4ee3a
CB
9306 ffecom_tree_canonize_ptr_ (decl, offset,
9307 TREE_OPERAND (t, 0));
5ff904cd 9308
c7e4ee3a 9309 return;
5ff904cd 9310
c7e4ee3a
CB
9311 case CONVERT_EXPR:
9312 case NOP_EXPR:
9313 case MODIFY_EXPR:
9314 case NON_LVALUE_EXPR:
9315 case RESULT_DECL:
9316 case FIELD_DECL:
9317 case COND_EXPR: /* More cases than we can handle. */
9318 case SAVE_EXPR:
9319 case REFERENCE_EXPR:
9320 case PREDECREMENT_EXPR:
9321 case PREINCREMENT_EXPR:
9322 case POSTDECREMENT_EXPR:
9323 case POSTINCREMENT_EXPR:
9324 case CALL_EXPR:
9325 default:
9326 *decl = error_mark_node;
9327 return;
9328 }
9329}
9330#endif
5ff904cd 9331
c7e4ee3a 9332/* Do divide operation appropriate to type of operands. */
5ff904cd 9333
c7e4ee3a
CB
9334#if FFECOM_targetCURRENT == FFECOM_targetGCC
9335static tree
9336ffecom_tree_divide_ (tree tree_type, tree left, tree right,
9337 tree dest_tree, ffebld dest, bool *dest_used,
9338 tree hook)
9339{
9340 if ((left == error_mark_node)
9341 || (right == error_mark_node))
9342 return error_mark_node;
a6fa6420 9343
c7e4ee3a
CB
9344 switch (TREE_CODE (tree_type))
9345 {
9346 case INTEGER_TYPE:
9347 return ffecom_2 (TRUNC_DIV_EXPR, tree_type,
9348 left,
9349 right);
a6fa6420 9350
c7e4ee3a 9351 case COMPLEX_TYPE:
c64f913e
CB
9352 if (! optimize_size)
9353 return ffecom_2 (RDIV_EXPR, tree_type,
9354 left,
9355 right);
c7e4ee3a
CB
9356 {
9357 ffecomGfrt ix;
a6fa6420 9358
c7e4ee3a
CB
9359 if (TREE_TYPE (tree_type)
9360 == ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1])
9361 ix = FFECOM_gfrtDIV_CC; /* Overlapping result okay. */
9362 else
9363 ix = FFECOM_gfrtDIV_ZZ; /* Overlapping result okay. */
a6fa6420 9364
c7e4ee3a
CB
9365 left = ffecom_1 (ADDR_EXPR,
9366 build_pointer_type (TREE_TYPE (left)),
9367 left);
9368 left = build_tree_list (NULL_TREE, left);
9369 right = ffecom_1 (ADDR_EXPR,
9370 build_pointer_type (TREE_TYPE (right)),
9371 right);
9372 right = build_tree_list (NULL_TREE, right);
9373 TREE_CHAIN (left) = right;
a6fa6420 9374
c7e4ee3a
CB
9375 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
9376 ffecom_gfrt_kindtype (ix),
9377 ffe_is_f2c_library (),
9378 tree_type,
9379 left,
9380 dest_tree, dest, dest_used,
9381 NULL_TREE, TRUE, hook);
9382 }
9383 break;
5ff904cd 9384
c7e4ee3a
CB
9385 case RECORD_TYPE:
9386 {
9387 ffecomGfrt ix;
5ff904cd 9388
c7e4ee3a
CB
9389 if (TREE_TYPE (TYPE_FIELDS (tree_type))
9390 == ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1])
9391 ix = FFECOM_gfrtDIV_CC; /* Overlapping result okay. */
9392 else
9393 ix = FFECOM_gfrtDIV_ZZ; /* Overlapping result okay. */
5ff904cd 9394
c7e4ee3a
CB
9395 left = ffecom_1 (ADDR_EXPR,
9396 build_pointer_type (TREE_TYPE (left)),
9397 left);
9398 left = build_tree_list (NULL_TREE, left);
9399 right = ffecom_1 (ADDR_EXPR,
9400 build_pointer_type (TREE_TYPE (right)),
9401 right);
9402 right = build_tree_list (NULL_TREE, right);
9403 TREE_CHAIN (left) = right;
a6fa6420 9404
c7e4ee3a
CB
9405 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
9406 ffecom_gfrt_kindtype (ix),
9407 ffe_is_f2c_library (),
9408 tree_type,
9409 left,
9410 dest_tree, dest, dest_used,
9411 NULL_TREE, TRUE, hook);
9412 }
9413 break;
5ff904cd 9414
c7e4ee3a
CB
9415 default:
9416 return ffecom_2 (RDIV_EXPR, tree_type,
9417 left,
9418 right);
5ff904cd 9419 }
c7e4ee3a 9420}
5ff904cd 9421
c7e4ee3a
CB
9422#endif
9423/* Build type info for non-dummy variable. */
5ff904cd 9424
c7e4ee3a
CB
9425#if FFECOM_targetCURRENT == FFECOM_targetGCC
9426static tree
9427ffecom_type_localvar_ (ffesymbol s, ffeinfoBasictype bt,
9428 ffeinfoKindtype kt)
9429{
9430 tree type;
9431 ffebld dl;
9432 ffebld dim;
9433 tree lowt;
9434 tree hight;
5ff904cd 9435
c7e4ee3a
CB
9436 type = ffecom_tree_type[bt][kt];
9437 if (bt == FFEINFO_basictypeCHARACTER)
9438 {
9439 hight = build_int_2 (ffesymbol_size (s), 0);
9440 TREE_TYPE (hight) = ffecom_f2c_ftnlen_type_node;
5ff904cd 9441
c7e4ee3a
CB
9442 type
9443 = build_array_type
9444 (type,
9445 build_range_type (ffecom_f2c_ftnlen_type_node,
9446 ffecom_f2c_ftnlen_one_node,
9447 hight));
9448 type = ffecom_check_size_overflow_ (s, type, FALSE);
9449 }
5ff904cd 9450
c7e4ee3a
CB
9451 for (dl = ffesymbol_dims (s); dl != NULL; dl = ffebld_trail (dl))
9452 {
9453 if (type == error_mark_node)
9454 break;
5ff904cd 9455
c7e4ee3a
CB
9456 dim = ffebld_head (dl);
9457 assert (ffebld_op (dim) == FFEBLD_opBOUNDS);
5ff904cd 9458
c7e4ee3a
CB
9459 if (ffebld_left (dim) == NULL)
9460 lowt = integer_one_node;
9461 else
9462 lowt = ffecom_expr (ffebld_left (dim));
5ff904cd 9463
c7e4ee3a
CB
9464 if (TREE_CODE (lowt) != INTEGER_CST)
9465 lowt = variable_size (lowt);
5ff904cd 9466
c7e4ee3a
CB
9467 assert (ffebld_right (dim) != NULL);
9468 hight = ffecom_expr (ffebld_right (dim));
5ff904cd 9469
c7e4ee3a
CB
9470 if (TREE_CODE (hight) != INTEGER_CST)
9471 hight = variable_size (hight);
5ff904cd 9472
c7e4ee3a
CB
9473 type = build_array_type (type,
9474 build_range_type (ffecom_integer_type_node,
9475 lowt, hight));
9476 type = ffecom_check_size_overflow_ (s, type, FALSE);
9477 }
5ff904cd 9478
c7e4ee3a 9479 return type;
5ff904cd
JL
9480}
9481
9482#endif
c7e4ee3a 9483/* Build Namelist type. */
5ff904cd 9484
c7e4ee3a
CB
9485#if FFECOM_targetCURRENT == FFECOM_targetGCC
9486static tree
9487ffecom_type_namelist_ ()
9488{
9489 static tree type = NULL_TREE;
5ff904cd 9490
c7e4ee3a
CB
9491 if (type == NULL_TREE)
9492 {
9493 static tree namefield, varsfield, nvarsfield;
9494 tree vardesctype;
5ff904cd 9495
c7e4ee3a 9496 vardesctype = ffecom_type_vardesc_ ();
5ff904cd 9497
c7e4ee3a
CB
9498 push_obstacks_nochange ();
9499 end_temporary_allocation ();
a6fa6420 9500
c7e4ee3a 9501 type = make_node (RECORD_TYPE);
a6fa6420 9502
c7e4ee3a 9503 vardesctype = build_pointer_type (build_pointer_type (vardesctype));
a6fa6420 9504
c7e4ee3a
CB
9505 namefield = ffecom_decl_field (type, NULL_TREE, "name",
9506 string_type_node);
9507 varsfield = ffecom_decl_field (type, namefield, "vars", vardesctype);
9508 nvarsfield = ffecom_decl_field (type, varsfield, "nvars",
9509 integer_type_node);
a6fa6420 9510
c7e4ee3a
CB
9511 TYPE_FIELDS (type) = namefield;
9512 layout_type (type);
a6fa6420 9513
c7e4ee3a
CB
9514 resume_temporary_allocation ();
9515 pop_obstacks ();
5ff904cd 9516 }
5ff904cd 9517
c7e4ee3a
CB
9518 return type;
9519}
5ff904cd 9520
c7e4ee3a 9521#endif
5ff904cd 9522
c7e4ee3a
CB
9523/* Make a copy of a type, assuming caller has switched to the permanent
9524 obstacks and that the type is for an aggregate (array) initializer. */
5ff904cd 9525
c7e4ee3a
CB
9526#if FFECOM_targetCURRENT == FFECOM_targetGCC && 0 /* Not used now. */
9527static tree
9528ffecom_type_permanent_copy_ (tree t)
9529{
9530 tree domain;
9531 tree max;
5ff904cd 9532
c7e4ee3a 9533 assert (TREE_TYPE (t) != NULL_TREE);
5ff904cd 9534
c7e4ee3a 9535 domain = TYPE_DOMAIN (t);
5ff904cd 9536
c7e4ee3a
CB
9537 assert (TREE_CODE (t) == ARRAY_TYPE);
9538 assert (TREE_PERMANENT (TREE_TYPE (t)));
9539 assert (TREE_PERMANENT (TREE_TYPE (domain)));
9540 assert (TREE_PERMANENT (TYPE_MIN_VALUE (domain)));
5ff904cd 9541
c7e4ee3a
CB
9542 max = TYPE_MAX_VALUE (domain);
9543 if (!TREE_PERMANENT (max))
9544 {
9545 assert (TREE_CODE (max) == INTEGER_CST);
5ff904cd 9546
c7e4ee3a
CB
9547 max = build_int_2 (TREE_INT_CST_LOW (max), TREE_INT_CST_HIGH (max));
9548 TREE_TYPE (max) = TREE_TYPE (TYPE_MIN_VALUE (domain));
9549 }
5ff904cd 9550
c7e4ee3a
CB
9551 return build_array_type (TREE_TYPE (t),
9552 build_range_type (TREE_TYPE (domain),
9553 TYPE_MIN_VALUE (domain),
9554 max));
9555}
9556#endif
5ff904cd 9557
c7e4ee3a 9558/* Build Vardesc type. */
5ff904cd 9559
c7e4ee3a
CB
9560#if FFECOM_targetCURRENT == FFECOM_targetGCC
9561static tree
9562ffecom_type_vardesc_ ()
9563{
9564 static tree type = NULL_TREE;
9565 static tree namefield, addrfield, dimsfield, typefield;
5ff904cd 9566
c7e4ee3a
CB
9567 if (type == NULL_TREE)
9568 {
9569 push_obstacks_nochange ();
9570 end_temporary_allocation ();
5ff904cd 9571
c7e4ee3a 9572 type = make_node (RECORD_TYPE);
5ff904cd 9573
c7e4ee3a
CB
9574 namefield = ffecom_decl_field (type, NULL_TREE, "name",
9575 string_type_node);
9576 addrfield = ffecom_decl_field (type, namefield, "addr",
9577 string_type_node);
9578 dimsfield = ffecom_decl_field (type, addrfield, "dims",
9579 ffecom_f2c_ptr_to_ftnlen_type_node);
9580 typefield = ffecom_decl_field (type, dimsfield, "type",
9581 integer_type_node);
5ff904cd 9582
c7e4ee3a
CB
9583 TYPE_FIELDS (type) = namefield;
9584 layout_type (type);
9585
9586 resume_temporary_allocation ();
9587 pop_obstacks ();
9588 }
9589
9590 return type;
5ff904cd
JL
9591}
9592
9593#endif
5ff904cd
JL
9594
9595#if FFECOM_targetCURRENT == FFECOM_targetGCC
9596static tree
c7e4ee3a 9597ffecom_vardesc_ (ffebld expr)
5ff904cd 9598{
c7e4ee3a 9599 ffesymbol s;
5ff904cd 9600
c7e4ee3a
CB
9601 assert (ffebld_op (expr) == FFEBLD_opSYMTER);
9602 s = ffebld_symter (expr);
5ff904cd 9603
c7e4ee3a
CB
9604 if (ffesymbol_hook (s).vardesc_tree == NULL_TREE)
9605 {
9606 int i;
9607 tree vardesctype = ffecom_type_vardesc_ ();
9608 tree var;
9609 tree nameinit;
9610 tree dimsinit;
9611 tree addrinit;
9612 tree typeinit;
9613 tree field;
9614 tree varinits;
9615 int yes;
9616 static int mynumber = 0;
5ff904cd 9617
c7e4ee3a 9618 yes = suspend_momentary ();
5ff904cd 9619
c7e4ee3a
CB
9620 var = build_decl (VAR_DECL,
9621 ffecom_get_invented_identifier ("__g77_vardesc_%d",
9622 NULL, mynumber++),
9623 vardesctype);
9624 TREE_STATIC (var) = 1;
9625 DECL_INITIAL (var) = error_mark_node;
5ff904cd 9626
c7e4ee3a 9627 var = start_decl (var, FALSE);
5ff904cd 9628
c7e4ee3a 9629 /* Process inits. */
5ff904cd 9630
c7e4ee3a
CB
9631 nameinit = ffecom_build_f2c_string_ ((i = strlen (ffesymbol_text (s)))
9632 + 1,
9633 ffesymbol_text (s));
9634 TREE_TYPE (nameinit)
9635 = build_type_variant
9636 (build_array_type
9637 (char_type_node,
9638 build_range_type (integer_type_node,
9639 integer_one_node,
9640 build_int_2 (i, 0))),
9641 1, 0);
9642 TREE_CONSTANT (nameinit) = 1;
9643 TREE_STATIC (nameinit) = 1;
9644 nameinit = ffecom_1 (ADDR_EXPR,
9645 build_pointer_type (TREE_TYPE (nameinit)),
9646 nameinit);
5ff904cd 9647
c7e4ee3a 9648 addrinit = ffecom_arg_ptr_to_expr (expr, &typeinit);
5ff904cd 9649
c7e4ee3a 9650 dimsinit = ffecom_vardesc_dims_ (s);
5ff904cd 9651
c7e4ee3a
CB
9652 if (typeinit == NULL_TREE)
9653 {
9654 ffeinfoBasictype bt = ffesymbol_basictype (s);
9655 ffeinfoKindtype kt = ffesymbol_kindtype (s);
9656 int tc = ffecom_f2c_typecode (bt, kt);
5ff904cd 9657
c7e4ee3a
CB
9658 assert (tc != -1);
9659 typeinit = build_int_2 (tc, (tc < 0) ? -1 : 0);
9660 }
9661 else
9662 typeinit = ffecom_1 (NEGATE_EXPR, TREE_TYPE (typeinit), typeinit);
5ff904cd 9663
c7e4ee3a
CB
9664 varinits = build_tree_list ((field = TYPE_FIELDS (vardesctype)),
9665 nameinit);
9666 TREE_CHAIN (varinits) = build_tree_list ((field = TREE_CHAIN (field)),
9667 addrinit);
9668 TREE_CHAIN (TREE_CHAIN (varinits))
9669 = build_tree_list ((field = TREE_CHAIN (field)), dimsinit);
9670 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (varinits)))
9671 = build_tree_list ((field = TREE_CHAIN (field)), typeinit);
5ff904cd 9672
c7e4ee3a
CB
9673 varinits = build (CONSTRUCTOR, vardesctype, NULL_TREE, varinits);
9674 TREE_CONSTANT (varinits) = 1;
9675 TREE_STATIC (varinits) = 1;
5ff904cd 9676
c7e4ee3a 9677 finish_decl (var, varinits, FALSE);
5ff904cd 9678
c7e4ee3a 9679 var = ffecom_1 (ADDR_EXPR, build_pointer_type (vardesctype), var);
5ff904cd 9680
c7e4ee3a 9681 resume_momentary (yes);
5ff904cd 9682
c7e4ee3a
CB
9683 ffesymbol_hook (s).vardesc_tree = var;
9684 }
5ff904cd 9685
c7e4ee3a
CB
9686 return ffesymbol_hook (s).vardesc_tree;
9687}
5ff904cd 9688
c7e4ee3a 9689#endif
5ff904cd 9690#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
9691static tree
9692ffecom_vardesc_array_ (ffesymbol s)
5ff904cd 9693{
c7e4ee3a
CB
9694 ffebld b;
9695 tree list;
9696 tree item = NULL_TREE;
9697 tree var;
9698 int i;
9699 int yes;
9700 static int mynumber = 0;
5ff904cd 9701
c7e4ee3a
CB
9702 for (i = 0, list = NULL_TREE, b = ffesymbol_namelist (s);
9703 b != NULL;
9704 b = ffebld_trail (b), ++i)
9705 {
9706 tree t;
5ff904cd 9707
c7e4ee3a 9708 t = ffecom_vardesc_ (ffebld_head (b));
5ff904cd 9709
c7e4ee3a
CB
9710 if (list == NULL_TREE)
9711 list = item = build_tree_list (NULL_TREE, t);
9712 else
5ff904cd 9713 {
c7e4ee3a
CB
9714 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
9715 item = TREE_CHAIN (item);
5ff904cd 9716 }
5ff904cd 9717 }
5ff904cd 9718
c7e4ee3a 9719 yes = suspend_momentary ();
5ff904cd 9720
c7e4ee3a
CB
9721 item = build_array_type (build_pointer_type (ffecom_type_vardesc_ ()),
9722 build_range_type (integer_type_node,
9723 integer_one_node,
9724 build_int_2 (i, 0)));
9725 list = build (CONSTRUCTOR, item, NULL_TREE, list);
9726 TREE_CONSTANT (list) = 1;
9727 TREE_STATIC (list) = 1;
5ff904cd 9728
c7e4ee3a
CB
9729 var = ffecom_get_invented_identifier ("__g77_vardesc_array_%d", NULL,
9730 mynumber++);
9731 var = build_decl (VAR_DECL, var, item);
9732 TREE_STATIC (var) = 1;
9733 DECL_INITIAL (var) = error_mark_node;
9734 var = start_decl (var, FALSE);
9735 finish_decl (var, list, FALSE);
5ff904cd 9736
c7e4ee3a 9737 resume_momentary (yes);
5ff904cd 9738
c7e4ee3a
CB
9739 return var;
9740}
5ff904cd 9741
c7e4ee3a
CB
9742#endif
9743#if FFECOM_targetCURRENT == FFECOM_targetGCC
9744static tree
9745ffecom_vardesc_dims_ (ffesymbol s)
9746{
9747 if (ffesymbol_dims (s) == NULL)
9748 return convert (ffecom_f2c_ptr_to_ftnlen_type_node,
9749 integer_zero_node);
5ff904cd 9750
c7e4ee3a
CB
9751 {
9752 ffebld b;
9753 ffebld e;
9754 tree list;
9755 tree backlist;
9756 tree item = NULL_TREE;
9757 tree var;
9758 int yes;
9759 tree numdim;
9760 tree numelem;
9761 tree baseoff = NULL_TREE;
9762 static int mynumber = 0;
9763
9764 numdim = build_int_2 ((int) ffesymbol_rank (s), 0);
9765 TREE_TYPE (numdim) = ffecom_f2c_ftnlen_type_node;
9766
9767 numelem = ffecom_expr (ffesymbol_arraysize (s));
9768 TREE_TYPE (numelem) = ffecom_f2c_ftnlen_type_node;
9769
9770 list = NULL_TREE;
9771 backlist = NULL_TREE;
9772 for (b = ffesymbol_dims (s), e = ffesymbol_extents (s);
9773 b != NULL;
9774 b = ffebld_trail (b), e = ffebld_trail (e))
5ff904cd 9775 {
c7e4ee3a
CB
9776 tree t;
9777 tree low;
9778 tree back;
5ff904cd 9779
c7e4ee3a
CB
9780 if (ffebld_trail (b) == NULL)
9781 t = NULL_TREE;
9782 else
5ff904cd 9783 {
c7e4ee3a
CB
9784 t = convert (ffecom_f2c_ftnlen_type_node,
9785 ffecom_expr (ffebld_head (e)));
5ff904cd 9786
c7e4ee3a
CB
9787 if (list == NULL_TREE)
9788 list = item = build_tree_list (NULL_TREE, t);
9789 else
9790 {
9791 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
9792 item = TREE_CHAIN (item);
9793 }
9794 }
5ff904cd 9795
c7e4ee3a
CB
9796 if (ffebld_left (ffebld_head (b)) == NULL)
9797 low = ffecom_integer_one_node;
9798 else
9799 low = ffecom_expr (ffebld_left (ffebld_head (b)));
9800 low = convert (ffecom_f2c_ftnlen_type_node, low);
5ff904cd 9801
c7e4ee3a
CB
9802 back = build_tree_list (low, t);
9803 TREE_CHAIN (back) = backlist;
9804 backlist = back;
9805 }
5ff904cd 9806
c7e4ee3a
CB
9807 for (item = backlist; item != NULL_TREE; item = TREE_CHAIN (item))
9808 {
9809 if (TREE_VALUE (item) == NULL_TREE)
9810 baseoff = TREE_PURPOSE (item);
9811 else
9812 baseoff = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
9813 TREE_PURPOSE (item),
9814 ffecom_2 (MULT_EXPR,
9815 ffecom_f2c_ftnlen_type_node,
9816 TREE_VALUE (item),
9817 baseoff));
5ff904cd
JL
9818 }
9819
c7e4ee3a 9820 /* backlist now dead, along with all TREE_PURPOSEs on it. */
5ff904cd 9821
c7e4ee3a
CB
9822 baseoff = build_tree_list (NULL_TREE, baseoff);
9823 TREE_CHAIN (baseoff) = list;
5ff904cd 9824
c7e4ee3a
CB
9825 numelem = build_tree_list (NULL_TREE, numelem);
9826 TREE_CHAIN (numelem) = baseoff;
5ff904cd 9827
c7e4ee3a
CB
9828 numdim = build_tree_list (NULL_TREE, numdim);
9829 TREE_CHAIN (numdim) = numelem;
5ff904cd 9830
c7e4ee3a 9831 yes = suspend_momentary ();
5ff904cd 9832
c7e4ee3a
CB
9833 item = build_array_type (ffecom_f2c_ftnlen_type_node,
9834 build_range_type (integer_type_node,
9835 integer_zero_node,
9836 build_int_2
9837 ((int) ffesymbol_rank (s)
9838 + 2, 0)));
9839 list = build (CONSTRUCTOR, item, NULL_TREE, numdim);
9840 TREE_CONSTANT (list) = 1;
9841 TREE_STATIC (list) = 1;
9842
9843 var = ffecom_get_invented_identifier ("__g77_dims_%d", NULL,
9844 mynumber++);
9845 var = build_decl (VAR_DECL, var, item);
9846 TREE_STATIC (var) = 1;
9847 DECL_INITIAL (var) = error_mark_node;
9848 var = start_decl (var, FALSE);
9849 finish_decl (var, list, FALSE);
9850
9851 var = ffecom_1 (ADDR_EXPR, build_pointer_type (item), var);
9852
9853 resume_momentary (yes);
9854
9855 return var;
9856 }
5ff904cd 9857}
c7e4ee3a 9858
5ff904cd 9859#endif
c7e4ee3a
CB
9860/* Essentially does a "fold (build1 (code, type, node))" while checking
9861 for certain housekeeping things.
5ff904cd 9862
c7e4ee3a
CB
9863 NOTE: for building an ADDR_EXPR around a FUNCTION_DECL, use
9864 ffecom_1_fn instead. */
5ff904cd
JL
9865
9866#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
9867tree
9868ffecom_1 (enum tree_code code, tree type, tree node)
5ff904cd 9869{
c7e4ee3a
CB
9870 tree item;
9871
9872 if ((node == error_mark_node)
9873 || (type == error_mark_node))
5ff904cd
JL
9874 return error_mark_node;
9875
c7e4ee3a 9876 if (code == ADDR_EXPR)
5ff904cd 9877 {
c7e4ee3a
CB
9878 if (!mark_addressable (node))
9879 assert ("can't mark_addressable this node!" == NULL);
9880 }
5ff904cd 9881
c7e4ee3a
CB
9882 switch (ffe_is_emulate_complex () ? code : NOP_EXPR)
9883 {
9884 tree realtype;
5ff904cd 9885
c7e4ee3a
CB
9886 case REALPART_EXPR:
9887 item = build (COMPONENT_REF, type, node, TYPE_FIELDS (TREE_TYPE (node)));
5ff904cd
JL
9888 break;
9889
c7e4ee3a
CB
9890 case IMAGPART_EXPR:
9891 item = build (COMPONENT_REF, type, node, TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (node))));
9892 break;
5ff904cd 9893
5ff904cd 9894
c7e4ee3a
CB
9895 case NEGATE_EXPR:
9896 if (TREE_CODE (type) != RECORD_TYPE)
9897 {
9898 item = build1 (code, type, node);
9899 break;
9900 }
9901 node = ffecom_stabilize_aggregate_ (node);
9902 realtype = TREE_TYPE (TYPE_FIELDS (type));
9903 item =
9904 ffecom_2 (COMPLEX_EXPR, type,
9905 ffecom_1 (NEGATE_EXPR, realtype,
9906 ffecom_1 (REALPART_EXPR, realtype,
9907 node)),
9908 ffecom_1 (NEGATE_EXPR, realtype,
9909 ffecom_1 (IMAGPART_EXPR, realtype,
9910 node)));
5ff904cd
JL
9911 break;
9912
9913 default:
c7e4ee3a
CB
9914 item = build1 (code, type, node);
9915 break;
5ff904cd 9916 }
5ff904cd 9917
c7e4ee3a
CB
9918 if (TREE_SIDE_EFFECTS (node))
9919 TREE_SIDE_EFFECTS (item) = 1;
9920 if ((code == ADDR_EXPR) && staticp (node))
9921 TREE_CONSTANT (item) = 1;
9922 return fold (item);
9923}
5ff904cd 9924#endif
5ff904cd 9925
c7e4ee3a
CB
9926/* Like ffecom_1 (ADDR_EXPR, TREE_TYPE (node), node), except
9927 handles TREE_CODE (node) == FUNCTION_DECL. In particular,
9928 does not set TREE_ADDRESSABLE (because calling an inline
9929 function does not mean the function needs to be separately
9930 compiled). */
5ff904cd
JL
9931
9932#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
9933tree
9934ffecom_1_fn (tree node)
5ff904cd 9935{
c7e4ee3a 9936 tree item;
5ff904cd 9937 tree type;
5ff904cd 9938
c7e4ee3a
CB
9939 if (node == error_mark_node)
9940 return error_mark_node;
5ff904cd 9941
c7e4ee3a
CB
9942 type = build_type_variant (TREE_TYPE (node),
9943 TREE_READONLY (node),
9944 TREE_THIS_VOLATILE (node));
9945 item = build1 (ADDR_EXPR,
9946 build_pointer_type (type), node);
9947 if (TREE_SIDE_EFFECTS (node))
9948 TREE_SIDE_EFFECTS (item) = 1;
9949 if (staticp (node))
9950 TREE_CONSTANT (item) = 1;
9951 return fold (item);
5ff904cd 9952}
5ff904cd 9953#endif
c7e4ee3a
CB
9954
9955/* Essentially does a "fold (build (code, type, node1, node2))" while
9956 checking for certain housekeeping things. */
5ff904cd
JL
9957
9958#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
9959tree
9960ffecom_2 (enum tree_code code, tree type, tree node1,
9961 tree node2)
5ff904cd 9962{
c7e4ee3a 9963 tree item;
5ff904cd 9964
c7e4ee3a
CB
9965 if ((node1 == error_mark_node)
9966 || (node2 == error_mark_node)
9967 || (type == error_mark_node))
9968 return error_mark_node;
9969
9970 switch (ffe_is_emulate_complex () ? code : NOP_EXPR)
5ff904cd 9971 {
c7e4ee3a 9972 tree a, b, c, d, realtype;
5ff904cd 9973
c7e4ee3a
CB
9974 case CONJ_EXPR:
9975 assert ("no CONJ_EXPR support yet" == NULL);
9976 return error_mark_node;
5ff904cd 9977
c7e4ee3a
CB
9978 case COMPLEX_EXPR:
9979 item = build_tree_list (TYPE_FIELDS (type), node1);
9980 TREE_CHAIN (item) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), node2);
9981 item = build (CONSTRUCTOR, type, NULL_TREE, item);
9982 break;
5ff904cd 9983
c7e4ee3a
CB
9984 case PLUS_EXPR:
9985 if (TREE_CODE (type) != RECORD_TYPE)
9986 {
9987 item = build (code, type, node1, node2);
9988 break;
9989 }
9990 node1 = ffecom_stabilize_aggregate_ (node1);
9991 node2 = ffecom_stabilize_aggregate_ (node2);
9992 realtype = TREE_TYPE (TYPE_FIELDS (type));
9993 item =
9994 ffecom_2 (COMPLEX_EXPR, type,
9995 ffecom_2 (PLUS_EXPR, realtype,
9996 ffecom_1 (REALPART_EXPR, realtype,
9997 node1),
9998 ffecom_1 (REALPART_EXPR, realtype,
9999 node2)),
10000 ffecom_2 (PLUS_EXPR, realtype,
10001 ffecom_1 (IMAGPART_EXPR, realtype,
10002 node1),
10003 ffecom_1 (IMAGPART_EXPR, realtype,
10004 node2)));
10005 break;
5ff904cd 10006
c7e4ee3a
CB
10007 case MINUS_EXPR:
10008 if (TREE_CODE (type) != RECORD_TYPE)
10009 {
10010 item = build (code, type, node1, node2);
10011 break;
10012 }
10013 node1 = ffecom_stabilize_aggregate_ (node1);
10014 node2 = ffecom_stabilize_aggregate_ (node2);
10015 realtype = TREE_TYPE (TYPE_FIELDS (type));
10016 item =
10017 ffecom_2 (COMPLEX_EXPR, type,
10018 ffecom_2 (MINUS_EXPR, realtype,
10019 ffecom_1 (REALPART_EXPR, realtype,
10020 node1),
10021 ffecom_1 (REALPART_EXPR, realtype,
10022 node2)),
10023 ffecom_2 (MINUS_EXPR, realtype,
10024 ffecom_1 (IMAGPART_EXPR, realtype,
10025 node1),
10026 ffecom_1 (IMAGPART_EXPR, realtype,
10027 node2)));
10028 break;
5ff904cd 10029
c7e4ee3a
CB
10030 case MULT_EXPR:
10031 if (TREE_CODE (type) != RECORD_TYPE)
10032 {
10033 item = build (code, type, node1, node2);
10034 break;
10035 }
10036 node1 = ffecom_stabilize_aggregate_ (node1);
10037 node2 = ffecom_stabilize_aggregate_ (node2);
10038 realtype = TREE_TYPE (TYPE_FIELDS (type));
10039 a = save_expr (ffecom_1 (REALPART_EXPR, realtype,
10040 node1));
10041 b = save_expr (ffecom_1 (IMAGPART_EXPR, realtype,
10042 node1));
10043 c = save_expr (ffecom_1 (REALPART_EXPR, realtype,
10044 node2));
10045 d = save_expr (ffecom_1 (IMAGPART_EXPR, realtype,
10046 node2));
10047 item =
10048 ffecom_2 (COMPLEX_EXPR, type,
10049 ffecom_2 (MINUS_EXPR, realtype,
10050 ffecom_2 (MULT_EXPR, realtype,
10051 a,
10052 c),
10053 ffecom_2 (MULT_EXPR, realtype,
10054 b,
10055 d)),
10056 ffecom_2 (PLUS_EXPR, realtype,
10057 ffecom_2 (MULT_EXPR, realtype,
10058 a,
10059 d),
10060 ffecom_2 (MULT_EXPR, realtype,
10061 c,
10062 b)));
10063 break;
5ff904cd 10064
c7e4ee3a
CB
10065 case EQ_EXPR:
10066 if ((TREE_CODE (node1) != RECORD_TYPE)
10067 && (TREE_CODE (node2) != RECORD_TYPE))
10068 {
10069 item = build (code, type, node1, node2);
10070 break;
10071 }
10072 assert (TREE_CODE (node1) == RECORD_TYPE);
10073 assert (TREE_CODE (node2) == RECORD_TYPE);
10074 node1 = ffecom_stabilize_aggregate_ (node1);
10075 node2 = ffecom_stabilize_aggregate_ (node2);
10076 realtype = TREE_TYPE (TYPE_FIELDS (type));
10077 item =
10078 ffecom_2 (TRUTH_ANDIF_EXPR, type,
10079 ffecom_2 (code, type,
10080 ffecom_1 (REALPART_EXPR, realtype,
10081 node1),
10082 ffecom_1 (REALPART_EXPR, realtype,
10083 node2)),
10084 ffecom_2 (code, type,
10085 ffecom_1 (IMAGPART_EXPR, realtype,
10086 node1),
10087 ffecom_1 (IMAGPART_EXPR, realtype,
10088 node2)));
10089 break;
10090
10091 case NE_EXPR:
10092 if ((TREE_CODE (node1) != RECORD_TYPE)
10093 && (TREE_CODE (node2) != RECORD_TYPE))
10094 {
10095 item = build (code, type, node1, node2);
10096 break;
10097 }
10098 assert (TREE_CODE (node1) == RECORD_TYPE);
10099 assert (TREE_CODE (node2) == RECORD_TYPE);
10100 node1 = ffecom_stabilize_aggregate_ (node1);
10101 node2 = ffecom_stabilize_aggregate_ (node2);
10102 realtype = TREE_TYPE (TYPE_FIELDS (type));
10103 item =
10104 ffecom_2 (TRUTH_ORIF_EXPR, type,
10105 ffecom_2 (code, type,
10106 ffecom_1 (REALPART_EXPR, realtype,
10107 node1),
10108 ffecom_1 (REALPART_EXPR, realtype,
10109 node2)),
10110 ffecom_2 (code, type,
10111 ffecom_1 (IMAGPART_EXPR, realtype,
10112 node1),
10113 ffecom_1 (IMAGPART_EXPR, realtype,
10114 node2)));
10115 break;
5ff904cd 10116
c7e4ee3a
CB
10117 default:
10118 item = build (code, type, node1, node2);
10119 break;
5ff904cd
JL
10120 }
10121
c7e4ee3a
CB
10122 if (TREE_SIDE_EFFECTS (node1) || TREE_SIDE_EFFECTS (node2))
10123 TREE_SIDE_EFFECTS (item) = 1;
10124 return fold (item);
5ff904cd
JL
10125}
10126
10127#endif
c7e4ee3a 10128/* ffecom_2pass_advise_entrypoint -- Advise that there's this entrypoint
5ff904cd 10129
c7e4ee3a
CB
10130 ffesymbol s; // the ENTRY point itself
10131 if (ffecom_2pass_advise_entrypoint(s))
10132 // the ENTRY point has been accepted
5ff904cd 10133
c7e4ee3a
CB
10134 Does whatever compiler needs to do when it learns about the entrypoint,
10135 like determine the return type of the master function, count the
10136 number of entrypoints, etc. Returns FALSE if the return type is
10137 not compatible with the return type(s) of other entrypoint(s).
5ff904cd 10138
c7e4ee3a
CB
10139 NOTE: for every call to this fn that returns TRUE, _do_entrypoint must
10140 later (after _finish_progunit) be called with the same entrypoint(s)
10141 as passed to this fn for which TRUE was returned.
5ff904cd 10142
c7e4ee3a
CB
10143 03-Jan-92 JCB 2.0
10144 Return FALSE if the return type conflicts with previous entrypoints. */
5ff904cd
JL
10145
10146#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
10147bool
10148ffecom_2pass_advise_entrypoint (ffesymbol entry)
5ff904cd 10149{
c7e4ee3a
CB
10150 ffebld list; /* opITEM. */
10151 ffebld mlist; /* opITEM. */
10152 ffebld plist; /* opITEM. */
10153 ffebld arg; /* ffebld_head(opITEM). */
10154 ffebld item; /* opITEM. */
10155 ffesymbol s; /* ffebld_symter(arg). */
10156 ffeinfoBasictype bt = ffesymbol_basictype (entry);
10157 ffeinfoKindtype kt = ffesymbol_kindtype (entry);
10158 ffetargetCharacterSize size = ffesymbol_size (entry);
10159 bool ok;
5ff904cd 10160
c7e4ee3a
CB
10161 if (ffecom_num_entrypoints_ == 0)
10162 { /* First entrypoint, make list of main
10163 arglist's dummies. */
10164 assert (ffecom_primary_entry_ != NULL);
5ff904cd 10165
c7e4ee3a
CB
10166 ffecom_master_bt_ = ffesymbol_basictype (ffecom_primary_entry_);
10167 ffecom_master_kt_ = ffesymbol_kindtype (ffecom_primary_entry_);
10168 ffecom_master_size_ = ffesymbol_size (ffecom_primary_entry_);
5ff904cd 10169
c7e4ee3a
CB
10170 for (plist = NULL, list = ffesymbol_dummyargs (ffecom_primary_entry_);
10171 list != NULL;
10172 list = ffebld_trail (list))
10173 {
10174 arg = ffebld_head (list);
10175 if (ffebld_op (arg) != FFEBLD_opSYMTER)
10176 continue; /* Alternate return or some such thing. */
10177 item = ffebld_new_item (arg, NULL);
10178 if (plist == NULL)
10179 ffecom_master_arglist_ = item;
10180 else
10181 ffebld_set_trail (plist, item);
10182 plist = item;
10183 }
5ff904cd
JL
10184 }
10185
c7e4ee3a
CB
10186 /* If necessary, scan entry arglist for alternate returns. Do this scan
10187 apparently redundantly (it's done below to UNIONize the arglists) so
10188 that we don't complain about RETURN 1 if an offending ENTRY is the only
10189 one with an alternate return. */
5ff904cd 10190
c7e4ee3a 10191 if (!ffecom_is_altreturning_)
5ff904cd 10192 {
c7e4ee3a
CB
10193 for (list = ffesymbol_dummyargs (entry);
10194 list != NULL;
10195 list = ffebld_trail (list))
10196 {
10197 arg = ffebld_head (list);
10198 if (ffebld_op (arg) == FFEBLD_opSTAR)
10199 {
10200 ffecom_is_altreturning_ = TRUE;
10201 break;
10202 }
10203 }
10204 }
5ff904cd 10205
c7e4ee3a 10206 /* Now check type compatibility. */
5ff904cd 10207
c7e4ee3a
CB
10208 switch (ffecom_master_bt_)
10209 {
10210 case FFEINFO_basictypeNONE:
10211 ok = (bt != FFEINFO_basictypeCHARACTER);
10212 break;
5ff904cd 10213
c7e4ee3a
CB
10214 case FFEINFO_basictypeCHARACTER:
10215 ok
10216 = (bt == FFEINFO_basictypeCHARACTER)
10217 && (kt == ffecom_master_kt_)
10218 && (size == ffecom_master_size_);
10219 break;
5ff904cd 10220
c7e4ee3a
CB
10221 case FFEINFO_basictypeANY:
10222 return FALSE; /* Just don't bother. */
5ff904cd 10223
c7e4ee3a
CB
10224 default:
10225 if (bt == FFEINFO_basictypeCHARACTER)
5ff904cd 10226 {
c7e4ee3a
CB
10227 ok = FALSE;
10228 break;
5ff904cd 10229 }
c7e4ee3a
CB
10230 ok = TRUE;
10231 if ((bt != ffecom_master_bt_) || (kt != ffecom_master_kt_))
10232 {
10233 ffecom_master_bt_ = FFEINFO_basictypeNONE;
10234 ffecom_master_kt_ = FFEINFO_kindtypeNONE;
10235 }
10236 break;
10237 }
5ff904cd 10238
c7e4ee3a
CB
10239 if (!ok)
10240 {
10241 ffebad_start (FFEBAD_ENTRY_CONFLICTS);
10242 ffest_ffebad_here_current_stmt (0);
10243 ffebad_finish ();
10244 return FALSE; /* Can't handle entrypoint. */
10245 }
5ff904cd 10246
c7e4ee3a 10247 /* Entrypoint type compatible with previous types. */
5ff904cd 10248
c7e4ee3a 10249 ++ffecom_num_entrypoints_;
5ff904cd 10250
c7e4ee3a
CB
10251 /* Master-arg-list = UNION(Master-arg-list,entry-arg-list). */
10252
10253 for (list = ffesymbol_dummyargs (entry);
10254 list != NULL;
10255 list = ffebld_trail (list))
10256 {
10257 arg = ffebld_head (list);
10258 if (ffebld_op (arg) != FFEBLD_opSYMTER)
10259 continue; /* Alternate return or some such thing. */
10260 s = ffebld_symter (arg);
10261 for (plist = NULL, mlist = ffecom_master_arglist_;
10262 mlist != NULL;
10263 plist = mlist, mlist = ffebld_trail (mlist))
10264 { /* plist points to previous item for easy
10265 appending of arg. */
10266 if (ffebld_symter (ffebld_head (mlist)) == s)
10267 break; /* Already have this arg in the master list. */
10268 }
10269 if (mlist != NULL)
10270 continue; /* Already have this arg in the master list. */
5ff904cd 10271
c7e4ee3a 10272 /* Append this arg to the master list. */
5ff904cd 10273
c7e4ee3a
CB
10274 item = ffebld_new_item (arg, NULL);
10275 if (plist == NULL)
10276 ffecom_master_arglist_ = item;
10277 else
10278 ffebld_set_trail (plist, item);
5ff904cd
JL
10279 }
10280
c7e4ee3a 10281 return TRUE;
5ff904cd
JL
10282}
10283
10284#endif
c7e4ee3a
CB
10285/* ffecom_2pass_do_entrypoint -- Do compilation of entrypoint
10286
10287 ffesymbol s; // the ENTRY point itself
10288 ffecom_2pass_do_entrypoint(s);
10289
10290 Does whatever compiler needs to do to make the entrypoint actually
10291 happen. Must be called for each entrypoint after
10292 ffecom_finish_progunit is called. */
10293
5ff904cd 10294#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
10295void
10296ffecom_2pass_do_entrypoint (ffesymbol entry)
5ff904cd 10297{
c7e4ee3a
CB
10298 static int mfn_num = 0;
10299 static int ent_num;
5ff904cd 10300
c7e4ee3a
CB
10301 if (mfn_num != ffecom_num_fns_)
10302 { /* First entrypoint for this program unit. */
10303 ent_num = 1;
10304 mfn_num = ffecom_num_fns_;
10305 ffecom_do_entry_ (ffecom_primary_entry_, 0);
10306 }
10307 else
10308 ++ent_num;
5ff904cd 10309
c7e4ee3a 10310 --ffecom_num_entrypoints_;
5ff904cd 10311
c7e4ee3a
CB
10312 ffecom_do_entry_ (entry, ent_num);
10313}
5ff904cd 10314
c7e4ee3a 10315#endif
5ff904cd 10316
c7e4ee3a
CB
10317/* Essentially does a "fold (build (code, type, node1, node2))" while
10318 checking for certain housekeeping things. Always sets
10319 TREE_SIDE_EFFECTS. */
5ff904cd 10320
c7e4ee3a
CB
10321#if FFECOM_targetCURRENT == FFECOM_targetGCC
10322tree
10323ffecom_2s (enum tree_code code, tree type, tree node1,
10324 tree node2)
10325{
10326 tree item;
5ff904cd 10327
c7e4ee3a
CB
10328 if ((node1 == error_mark_node)
10329 || (node2 == error_mark_node)
10330 || (type == error_mark_node))
10331 return error_mark_node;
5ff904cd 10332
c7e4ee3a
CB
10333 item = build (code, type, node1, node2);
10334 TREE_SIDE_EFFECTS (item) = 1;
10335 return fold (item);
5ff904cd
JL
10336}
10337
10338#endif
c7e4ee3a
CB
10339/* Essentially does a "fold (build (code, type, node1, node2, node3))" while
10340 checking for certain housekeeping things. */
10341
5ff904cd 10342#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
10343tree
10344ffecom_3 (enum tree_code code, tree type, tree node1,
10345 tree node2, tree node3)
5ff904cd 10346{
c7e4ee3a 10347 tree item;
5ff904cd 10348
c7e4ee3a
CB
10349 if ((node1 == error_mark_node)
10350 || (node2 == error_mark_node)
10351 || (node3 == error_mark_node)
10352 || (type == error_mark_node))
10353 return error_mark_node;
5ff904cd 10354
c7e4ee3a
CB
10355 item = build (code, type, node1, node2, node3);
10356 if (TREE_SIDE_EFFECTS (node1) || TREE_SIDE_EFFECTS (node2)
10357 || (node3 != NULL_TREE && TREE_SIDE_EFFECTS (node3)))
10358 TREE_SIDE_EFFECTS (item) = 1;
10359 return fold (item);
10360}
5ff904cd 10361
c7e4ee3a
CB
10362#endif
10363/* Essentially does a "fold (build (code, type, node1, node2, node3))" while
10364 checking for certain housekeeping things. Always sets
10365 TREE_SIDE_EFFECTS. */
5ff904cd 10366
c7e4ee3a
CB
10367#if FFECOM_targetCURRENT == FFECOM_targetGCC
10368tree
10369ffecom_3s (enum tree_code code, tree type, tree node1,
10370 tree node2, tree node3)
10371{
10372 tree item;
5ff904cd 10373
c7e4ee3a
CB
10374 if ((node1 == error_mark_node)
10375 || (node2 == error_mark_node)
10376 || (node3 == error_mark_node)
10377 || (type == error_mark_node))
10378 return error_mark_node;
5ff904cd 10379
c7e4ee3a
CB
10380 item = build (code, type, node1, node2, node3);
10381 TREE_SIDE_EFFECTS (item) = 1;
10382 return fold (item);
10383}
5ff904cd 10384
c7e4ee3a 10385#endif
5ff904cd 10386
c7e4ee3a 10387/* ffecom_arg_expr -- Transform argument expr into gcc tree
5ff904cd 10388
c7e4ee3a 10389 See use by ffecom_list_expr.
5ff904cd 10390
c7e4ee3a
CB
10391 If expression is NULL, returns an integer zero tree. If it is not
10392 a CHARACTER expression, returns whatever ffecom_expr
10393 returns and sets the length return value to NULL_TREE. Otherwise
10394 generates code to evaluate the character expression, returns the proper
10395 pointer to the result, but does NOT set the length return value to a tree
10396 that specifies the length of the result. (In other words, the length
10397 variable is always set to NULL_TREE, because a length is never passed.)
5ff904cd 10398
c7e4ee3a
CB
10399 21-Dec-91 JCB 1.1
10400 Don't set returned length, since nobody needs it (yet; someday if
10401 we allow CHARACTER*(*) dummies to statement functions, we'll need
10402 it). */
5ff904cd 10403
c7e4ee3a
CB
10404#if FFECOM_targetCURRENT == FFECOM_targetGCC
10405tree
10406ffecom_arg_expr (ffebld expr, tree *length)
10407{
10408 tree ign;
5ff904cd 10409
c7e4ee3a 10410 *length = NULL_TREE;
5ff904cd 10411
c7e4ee3a
CB
10412 if (expr == NULL)
10413 return integer_zero_node;
5ff904cd 10414
c7e4ee3a
CB
10415 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10416 return ffecom_expr (expr);
5ff904cd 10417
c7e4ee3a
CB
10418 return ffecom_arg_ptr_to_expr (expr, &ign);
10419}
10420
10421#endif
10422/* Transform expression into constant argument-pointer-to-expression tree.
10423
10424 If the expression can be transformed into a argument-pointer-to-expression
10425 tree that is constant, that is done, and the tree returned. Else
10426 NULL_TREE is returned.
5ff904cd 10427
c7e4ee3a
CB
10428 That way, a caller can attempt to provide compile-time initialization
10429 of a variable and, if that fails, *then* choose to start a new block
10430 and resort to using temporaries, as appropriate. */
5ff904cd 10431
c7e4ee3a
CB
10432tree
10433ffecom_arg_ptr_to_const_expr (ffebld expr, tree *length)
10434{
10435 if (! expr)
10436 return integer_zero_node;
5ff904cd 10437
c7e4ee3a
CB
10438 if (ffebld_op (expr) == FFEBLD_opANY)
10439 {
10440 if (length)
10441 *length = error_mark_node;
10442 return error_mark_node;
10443 }
10444
10445 if (ffebld_arity (expr) == 0
10446 && (ffebld_op (expr) != FFEBLD_opSYMTER
10447 || ffebld_where (expr) == FFEINFO_whereCOMMON
10448 || ffebld_where (expr) == FFEINFO_whereGLOBAL
10449 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
10450 {
10451 tree t;
10452
10453 t = ffecom_arg_ptr_to_expr (expr, length);
10454 assert (TREE_CONSTANT (t));
10455 assert (! length || TREE_CONSTANT (*length));
10456 return t;
10457 }
10458
10459 if (length
10460 && ffebld_size (expr) != FFETARGET_charactersizeNONE)
10461 *length = build_int_2 (ffebld_size (expr), 0);
10462 else if (length)
10463 *length = NULL_TREE;
10464 return NULL_TREE;
5ff904cd
JL
10465}
10466
c7e4ee3a 10467/* ffecom_arg_ptr_to_expr -- Transform argument expr into gcc tree
5ff904cd 10468
c7e4ee3a
CB
10469 See use by ffecom_list_ptr_to_expr.
10470
10471 If expression is NULL, returns an integer zero tree. If it is not
10472 a CHARACTER expression, returns whatever ffecom_ptr_to_expr
10473 returns and sets the length return value to NULL_TREE. Otherwise
10474 generates code to evaluate the character expression, returns the proper
10475 pointer to the result, AND sets the length return value to a tree that
10476 specifies the length of the result.
10477
10478 If the length argument is NULL, this is a slightly special
10479 case of building a FORMAT expression, that is, an expression that
10480 will be used at run time without regard to length. For the current
10481 implementation, which uses the libf2c library, this means it is nice
10482 to append a null byte to the end of the expression, where feasible,
10483 to make sure any diagnostic about the FORMAT string terminates at
10484 some useful point.
10485
10486 For now, treat %REF(char-expr) as the same as char-expr with a NULL
10487 length argument. This might even be seen as a feature, if a null
10488 byte can always be appended. */
5ff904cd
JL
10489
10490#if FFECOM_targetCURRENT == FFECOM_targetGCC
10491tree
c7e4ee3a 10492ffecom_arg_ptr_to_expr (ffebld expr, tree *length)
5ff904cd
JL
10493{
10494 tree item;
c7e4ee3a
CB
10495 tree ign_length;
10496 ffecomConcatList_ catlist;
5ff904cd 10497
c7e4ee3a
CB
10498 if (length != NULL)
10499 *length = NULL_TREE;
5ff904cd 10500
c7e4ee3a
CB
10501 if (expr == NULL)
10502 return integer_zero_node;
5ff904cd 10503
c7e4ee3a 10504 switch (ffebld_op (expr))
5ff904cd 10505 {
c7e4ee3a
CB
10506 case FFEBLD_opPERCENT_VAL:
10507 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10508 return ffecom_expr (ffebld_left (expr));
10509 {
10510 tree temp_exp;
10511 tree temp_length;
5ff904cd 10512
c7e4ee3a
CB
10513 temp_exp = ffecom_arg_ptr_to_expr (ffebld_left (expr), &temp_length);
10514 if (temp_exp == error_mark_node)
10515 return error_mark_node;
5ff904cd 10516
c7e4ee3a
CB
10517 return ffecom_1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (temp_exp)),
10518 temp_exp);
10519 }
5ff904cd 10520
c7e4ee3a
CB
10521 case FFEBLD_opPERCENT_REF:
10522 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10523 return ffecom_ptr_to_expr (ffebld_left (expr));
10524 if (length != NULL)
10525 {
10526 ign_length = NULL_TREE;
10527 length = &ign_length;
10528 }
10529 expr = ffebld_left (expr);
10530 break;
5ff904cd 10531
c7e4ee3a
CB
10532 case FFEBLD_opPERCENT_DESCR:
10533 switch (ffeinfo_basictype (ffebld_info (expr)))
5ff904cd 10534 {
c7e4ee3a
CB
10535#ifdef PASS_HOLLERITH_BY_DESCRIPTOR
10536 case FFEINFO_basictypeHOLLERITH:
10537#endif
10538 case FFEINFO_basictypeCHARACTER:
10539 break; /* Passed by descriptor anyway. */
10540
10541 default:
10542 item = ffecom_ptr_to_expr (expr);
10543 if (item != error_mark_node)
10544 *length = TYPE_SIZE (TREE_TYPE (TREE_TYPE (item)));
5ff904cd
JL
10545 break;
10546 }
5ff904cd
JL
10547 break;
10548
10549 default:
5ff904cd
JL
10550 break;
10551 }
10552
c7e4ee3a
CB
10553#ifdef PASS_HOLLERITH_BY_DESCRIPTOR
10554 if ((ffeinfo_basictype (ffebld_info (expr)) == FFEINFO_basictypeHOLLERITH)
10555 && (length != NULL))
10556 { /* Pass Hollerith by descriptor. */
10557 ffetargetHollerith h;
10558
10559 assert (ffebld_op (expr) == FFEBLD_opCONTER);
10560 h = ffebld_cu_val_hollerith (ffebld_constant_union
10561 (ffebld_conter (expr)));
10562 *length
10563 = build_int_2 (h.length, 0);
10564 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
10565 }
10566#endif
10567
10568 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10569 return ffecom_ptr_to_expr (expr);
10570
10571 assert (ffeinfo_kindtype (ffebld_info (expr))
10572 == FFEINFO_kindtypeCHARACTER1);
10573
47d98fa2
CB
10574 while (ffebld_op (expr) == FFEBLD_opPAREN)
10575 expr = ffebld_left (expr);
10576
c7e4ee3a
CB
10577 catlist = ffecom_concat_list_new_ (expr, FFETARGET_charactersizeNONE);
10578 switch (ffecom_concat_list_count_ (catlist))
10579 {
10580 case 0: /* Shouldn't happen, but in case it does... */
10581 if (length != NULL)
10582 {
10583 *length = ffecom_f2c_ftnlen_zero_node;
10584 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
10585 }
10586 ffecom_concat_list_kill_ (catlist);
10587 return null_pointer_node;
10588
10589 case 1: /* The (fairly) easy case. */
10590 if (length == NULL)
10591 ffecom_char_args_with_null_ (&item, &ign_length,
10592 ffecom_concat_list_expr_ (catlist, 0));
10593 else
10594 ffecom_char_args_ (&item, length,
10595 ffecom_concat_list_expr_ (catlist, 0));
10596 ffecom_concat_list_kill_ (catlist);
10597 assert (item != NULL_TREE);
10598 return item;
10599
10600 default: /* Must actually concatenate things. */
10601 break;
10602 }
10603
10604 {
10605 int count = ffecom_concat_list_count_ (catlist);
10606 int i;
10607 tree lengths;
10608 tree items;
10609 tree length_array;
10610 tree item_array;
10611 tree citem;
10612 tree clength;
10613 tree temporary;
10614 tree num;
10615 tree known_length;
10616 ffetargetCharacterSize sz;
10617
10618 sz = ffecom_concat_list_maxlen_ (catlist);
10619 /* ~~Kludge! */
10620 assert (sz != FFETARGET_charactersizeNONE);
10621
10622#ifdef HOHO
10623 length_array
10624 = lengths
10625 = ffecom_push_tempvar (ffecom_f2c_ftnlen_type_node,
10626 FFETARGET_charactersizeNONE, count, TRUE);
10627 item_array
10628 = items
10629 = ffecom_push_tempvar (ffecom_f2c_address_type_node,
10630 FFETARGET_charactersizeNONE, count, TRUE);
10631 temporary = ffecom_push_tempvar (char_type_node,
10632 sz, -1, TRUE);
10633#else
10634 {
10635 tree hook;
10636
10637 hook = ffebld_nonter_hook (expr);
10638 assert (hook);
10639 assert (TREE_CODE (hook) == TREE_VEC);
10640 assert (TREE_VEC_LENGTH (hook) == 3);
10641 length_array = lengths = TREE_VEC_ELT (hook, 0);
10642 item_array = items = TREE_VEC_ELT (hook, 1);
10643 temporary = TREE_VEC_ELT (hook, 2);
10644 }
10645#endif
10646
10647 known_length = ffecom_f2c_ftnlen_zero_node;
10648
10649 for (i = 0; i < count; ++i)
10650 {
10651 if ((i == count)
10652 && (length == NULL))
10653 ffecom_char_args_with_null_ (&citem, &clength,
10654 ffecom_concat_list_expr_ (catlist, i));
10655 else
10656 ffecom_char_args_ (&citem, &clength,
10657 ffecom_concat_list_expr_ (catlist, i));
10658 if ((citem == error_mark_node)
10659 || (clength == error_mark_node))
10660 {
10661 ffecom_concat_list_kill_ (catlist);
10662 *length = error_mark_node;
10663 return error_mark_node;
10664 }
10665
10666 items
10667 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (items),
10668 ffecom_modify (void_type_node,
10669 ffecom_2 (ARRAY_REF,
10670 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array))),
10671 item_array,
10672 build_int_2 (i, 0)),
10673 citem),
10674 items);
10675 clength = ffecom_save_tree (clength);
10676 if (length != NULL)
10677 known_length
10678 = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
10679 known_length,
10680 clength);
10681 lengths
10682 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (lengths),
10683 ffecom_modify (void_type_node,
10684 ffecom_2 (ARRAY_REF,
10685 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array))),
10686 length_array,
10687 build_int_2 (i, 0)),
10688 clength),
10689 lengths);
10690 }
10691
10692 temporary = ffecom_1 (ADDR_EXPR,
10693 build_pointer_type (TREE_TYPE (temporary)),
10694 temporary);
10695
10696 item = build_tree_list (NULL_TREE, temporary);
10697 TREE_CHAIN (item)
10698 = build_tree_list (NULL_TREE,
10699 ffecom_1 (ADDR_EXPR,
10700 build_pointer_type (TREE_TYPE (items)),
10701 items));
10702 TREE_CHAIN (TREE_CHAIN (item))
10703 = build_tree_list (NULL_TREE,
10704 ffecom_1 (ADDR_EXPR,
10705 build_pointer_type (TREE_TYPE (lengths)),
10706 lengths));
10707 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item)))
10708 = build_tree_list
10709 (NULL_TREE,
10710 ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
10711 convert (ffecom_f2c_ftnlen_type_node,
10712 build_int_2 (count, 0))));
10713 num = build_int_2 (sz, 0);
10714 TREE_TYPE (num) = ffecom_f2c_ftnlen_type_node;
10715 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item))))
10716 = build_tree_list (NULL_TREE, num);
10717
10718 item = ffecom_call_gfrt (FFECOM_gfrtCAT, item, NULL_TREE);
5ff904cd 10719 TREE_SIDE_EFFECTS (item) = 1;
c7e4ee3a
CB
10720 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (temporary),
10721 item,
10722 temporary);
10723
10724 if (length != NULL)
10725 *length = known_length;
10726 }
10727
10728 ffecom_concat_list_kill_ (catlist);
10729 assert (item != NULL_TREE);
10730 return item;
5ff904cd 10731}
c7e4ee3a 10732
5ff904cd 10733#endif
c7e4ee3a 10734/* Generate call to run-time function.
5ff904cd 10735
c7e4ee3a
CB
10736 The first arg is the GNU Fortran Run-Time function index, the second
10737 arg is the list of arguments to pass to it. Returned is the expression
10738 (WITHOUT TREE_SIDE_EFFECTS set!) that makes the call and returns the
10739 result (which may be void). */
5ff904cd
JL
10740
10741#if FFECOM_targetCURRENT == FFECOM_targetGCC
10742tree
c7e4ee3a 10743ffecom_call_gfrt (ffecomGfrt ix, tree args, tree hook)
5ff904cd 10744{
c7e4ee3a
CB
10745 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
10746 ffecom_gfrt_kindtype (ix),
10747 ffe_is_f2c_library () && ffecom_gfrt_complex_[ix],
10748 NULL_TREE, args, NULL_TREE, NULL,
10749 NULL, NULL_TREE, TRUE, hook);
5ff904cd
JL
10750}
10751#endif
10752
c7e4ee3a 10753/* Transform constant-union to tree. */
5ff904cd
JL
10754
10755#if FFECOM_targetCURRENT == FFECOM_targetGCC
10756tree
c7e4ee3a
CB
10757ffecom_constantunion (ffebldConstantUnion *cu, ffeinfoBasictype bt,
10758 ffeinfoKindtype kt, tree tree_type)
5ff904cd
JL
10759{
10760 tree item;
10761
c7e4ee3a 10762 switch (bt)
5ff904cd 10763 {
c7e4ee3a
CB
10764 case FFEINFO_basictypeINTEGER:
10765 {
10766 int val;
5ff904cd 10767
c7e4ee3a
CB
10768 switch (kt)
10769 {
10770#if FFETARGET_okINTEGER1
10771 case FFEINFO_kindtypeINTEGER1:
10772 val = ffebld_cu_val_integer1 (*cu);
10773 break;
10774#endif
5ff904cd 10775
c7e4ee3a
CB
10776#if FFETARGET_okINTEGER2
10777 case FFEINFO_kindtypeINTEGER2:
10778 val = ffebld_cu_val_integer2 (*cu);
10779 break;
10780#endif
5ff904cd 10781
c7e4ee3a
CB
10782#if FFETARGET_okINTEGER3
10783 case FFEINFO_kindtypeINTEGER3:
10784 val = ffebld_cu_val_integer3 (*cu);
10785 break;
10786#endif
5ff904cd 10787
c7e4ee3a
CB
10788#if FFETARGET_okINTEGER4
10789 case FFEINFO_kindtypeINTEGER4:
10790 val = ffebld_cu_val_integer4 (*cu);
10791 break;
10792#endif
5ff904cd 10793
c7e4ee3a
CB
10794 default:
10795 assert ("bad INTEGER constant kind type" == NULL);
10796 /* Fall through. */
10797 case FFEINFO_kindtypeANY:
10798 return error_mark_node;
10799 }
10800 item = build_int_2 (val, (val < 0) ? -1 : 0);
10801 TREE_TYPE (item) = tree_type;
10802 }
5ff904cd 10803 break;
5ff904cd 10804
c7e4ee3a
CB
10805 case FFEINFO_basictypeLOGICAL:
10806 {
10807 int val;
5ff904cd 10808
c7e4ee3a
CB
10809 switch (kt)
10810 {
10811#if FFETARGET_okLOGICAL1
10812 case FFEINFO_kindtypeLOGICAL1:
10813 val = ffebld_cu_val_logical1 (*cu);
10814 break;
5ff904cd 10815#endif
5ff904cd 10816
c7e4ee3a
CB
10817#if FFETARGET_okLOGICAL2
10818 case FFEINFO_kindtypeLOGICAL2:
10819 val = ffebld_cu_val_logical2 (*cu);
10820 break;
10821#endif
5ff904cd 10822
c7e4ee3a
CB
10823#if FFETARGET_okLOGICAL3
10824 case FFEINFO_kindtypeLOGICAL3:
10825 val = ffebld_cu_val_logical3 (*cu);
10826 break;
10827#endif
5ff904cd 10828
c7e4ee3a
CB
10829#if FFETARGET_okLOGICAL4
10830 case FFEINFO_kindtypeLOGICAL4:
10831 val = ffebld_cu_val_logical4 (*cu);
10832 break;
10833#endif
5ff904cd 10834
c7e4ee3a
CB
10835 default:
10836 assert ("bad LOGICAL constant kind type" == NULL);
10837 /* Fall through. */
10838 case FFEINFO_kindtypeANY:
10839 return error_mark_node;
10840 }
10841 item = build_int_2 (val, (val < 0) ? -1 : 0);
10842 TREE_TYPE (item) = tree_type;
10843 }
10844 break;
5ff904cd 10845
c7e4ee3a
CB
10846 case FFEINFO_basictypeREAL:
10847 {
10848 REAL_VALUE_TYPE val;
5ff904cd 10849
c7e4ee3a
CB
10850 switch (kt)
10851 {
10852#if FFETARGET_okREAL1
10853 case FFEINFO_kindtypeREAL1:
10854 val = ffetarget_value_real1 (ffebld_cu_val_real1 (*cu));
10855 break;
10856#endif
5ff904cd 10857
c7e4ee3a
CB
10858#if FFETARGET_okREAL2
10859 case FFEINFO_kindtypeREAL2:
10860 val = ffetarget_value_real2 (ffebld_cu_val_real2 (*cu));
10861 break;
10862#endif
5ff904cd 10863
c7e4ee3a
CB
10864#if FFETARGET_okREAL3
10865 case FFEINFO_kindtypeREAL3:
10866 val = ffetarget_value_real3 (ffebld_cu_val_real3 (*cu));
10867 break;
10868#endif
5ff904cd 10869
c7e4ee3a
CB
10870#if FFETARGET_okREAL4
10871 case FFEINFO_kindtypeREAL4:
10872 val = ffetarget_value_real4 (ffebld_cu_val_real4 (*cu));
10873 break;
10874#endif
5ff904cd 10875
c7e4ee3a
CB
10876 default:
10877 assert ("bad REAL constant kind type" == NULL);
10878 /* Fall through. */
10879 case FFEINFO_kindtypeANY:
10880 return error_mark_node;
10881 }
10882 item = build_real (tree_type, val);
10883 }
5ff904cd
JL
10884 break;
10885
c7e4ee3a
CB
10886 case FFEINFO_basictypeCOMPLEX:
10887 {
10888 REAL_VALUE_TYPE real;
10889 REAL_VALUE_TYPE imag;
10890 tree el_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
5ff904cd 10891
c7e4ee3a
CB
10892 switch (kt)
10893 {
10894#if FFETARGET_okCOMPLEX1
10895 case FFEINFO_kindtypeREAL1:
10896 real = ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu).real);
10897 imag = ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu).imaginary);
10898 break;
10899#endif
5ff904cd 10900
c7e4ee3a
CB
10901#if FFETARGET_okCOMPLEX2
10902 case FFEINFO_kindtypeREAL2:
10903 real = ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu).real);
10904 imag = ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu).imaginary);
10905 break;
10906#endif
5ff904cd 10907
c7e4ee3a
CB
10908#if FFETARGET_okCOMPLEX3
10909 case FFEINFO_kindtypeREAL3:
10910 real = ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu).real);
10911 imag = ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu).imaginary);
10912 break;
10913#endif
5ff904cd 10914
c7e4ee3a
CB
10915#if FFETARGET_okCOMPLEX4
10916 case FFEINFO_kindtypeREAL4:
10917 real = ffetarget_value_real4 (ffebld_cu_val_complex4 (*cu).real);
10918 imag = ffetarget_value_real4 (ffebld_cu_val_complex4 (*cu).imaginary);
10919 break;
10920#endif
5ff904cd 10921
c7e4ee3a
CB
10922 default:
10923 assert ("bad REAL constant kind type" == NULL);
10924 /* Fall through. */
10925 case FFEINFO_kindtypeANY:
10926 return error_mark_node;
10927 }
10928 item = ffecom_build_complex_constant_ (tree_type,
10929 build_real (el_type, real),
10930 build_real (el_type, imag));
10931 }
10932 break;
5ff904cd 10933
c7e4ee3a
CB
10934 case FFEINFO_basictypeCHARACTER:
10935 { /* Happens only in DATA and similar contexts. */
10936 ffetargetCharacter1 val;
5ff904cd 10937
c7e4ee3a
CB
10938 switch (kt)
10939 {
10940#if FFETARGET_okCHARACTER1
10941 case FFEINFO_kindtypeLOGICAL1:
10942 val = ffebld_cu_val_character1 (*cu);
10943 break;
10944#endif
10945
10946 default:
10947 assert ("bad CHARACTER constant kind type" == NULL);
10948 /* Fall through. */
10949 case FFEINFO_kindtypeANY:
10950 return error_mark_node;
10951 }
10952 item = build_string (ffetarget_length_character1 (val),
10953 ffetarget_text_character1 (val));
10954 TREE_TYPE (item)
10955 = build_type_variant (build_array_type (char_type_node,
10956 build_range_type
10957 (integer_type_node,
10958 integer_one_node,
10959 build_int_2
10960 (ffetarget_length_character1
10961 (val), 0))),
10962 1, 0);
10963 }
10964 break;
5ff904cd 10965
c7e4ee3a
CB
10966 case FFEINFO_basictypeHOLLERITH:
10967 {
10968 ffetargetHollerith h;
5ff904cd 10969
c7e4ee3a 10970 h = ffebld_cu_val_hollerith (*cu);
5ff904cd 10971
c7e4ee3a
CB
10972 /* If not at least as wide as default INTEGER, widen it. */
10973 if (h.length >= FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE)
10974 item = build_string (h.length, h.text);
10975 else
10976 {
10977 char str[FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE];
5ff904cd 10978
c7e4ee3a
CB
10979 memcpy (str, h.text, h.length);
10980 memset (&str[h.length], ' ',
10981 FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE
10982 - h.length);
10983 item = build_string (FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE,
10984 str);
10985 }
10986 TREE_TYPE (item)
10987 = build_type_variant (build_array_type (char_type_node,
10988 build_range_type
10989 (integer_type_node,
10990 integer_one_node,
10991 build_int_2
10992 (h.length, 0))),
10993 1, 0);
10994 }
10995 break;
5ff904cd 10996
c7e4ee3a
CB
10997 case FFEINFO_basictypeTYPELESS:
10998 {
10999 ffetargetInteger1 ival;
11000 ffetargetTypeless tless;
11001 ffebad error;
5ff904cd 11002
c7e4ee3a
CB
11003 tless = ffebld_cu_val_typeless (*cu);
11004 error = ffetarget_convert_integer1_typeless (&ival, tless);
11005 assert (error == FFEBAD);
5ff904cd 11006
c7e4ee3a
CB
11007 item = build_int_2 ((int) ival, 0);
11008 }
11009 break;
5ff904cd 11010
c7e4ee3a
CB
11011 default:
11012 assert ("not yet on constant type" == NULL);
11013 /* Fall through. */
11014 case FFEINFO_basictypeANY:
11015 return error_mark_node;
5ff904cd 11016 }
5ff904cd 11017
c7e4ee3a 11018 TREE_CONSTANT (item) = 1;
5ff904cd 11019
c7e4ee3a 11020 return item;
5ff904cd
JL
11021}
11022
11023#endif
11024
c7e4ee3a
CB
11025/* Transform expression into constant tree.
11026
11027 If the expression can be transformed into a tree that is constant,
11028 that is done, and the tree returned. Else NULL_TREE is returned.
11029
11030 That way, a caller can attempt to provide compile-time initialization
11031 of a variable and, if that fails, *then* choose to start a new block
11032 and resort to using temporaries, as appropriate. */
5ff904cd 11033
5ff904cd 11034tree
c7e4ee3a 11035ffecom_const_expr (ffebld expr)
5ff904cd 11036{
c7e4ee3a
CB
11037 if (! expr)
11038 return integer_zero_node;
5ff904cd 11039
c7e4ee3a 11040 if (ffebld_op (expr) == FFEBLD_opANY)
5ff904cd
JL
11041 return error_mark_node;
11042
c7e4ee3a
CB
11043 if (ffebld_arity (expr) == 0
11044 && (ffebld_op (expr) != FFEBLD_opSYMTER
11045#if NEWCOMMON
11046 /* ~~Enable once common/equivalence is handled properly? */
11047 || ffebld_where (expr) == FFEINFO_whereCOMMON
5ff904cd 11048#endif
c7e4ee3a
CB
11049 || ffebld_where (expr) == FFEINFO_whereGLOBAL
11050 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
11051 {
11052 tree t;
5ff904cd 11053
c7e4ee3a
CB
11054 t = ffecom_expr (expr);
11055 assert (TREE_CONSTANT (t));
11056 return t;
11057 }
5ff904cd 11058
c7e4ee3a 11059 return NULL_TREE;
5ff904cd
JL
11060}
11061
c7e4ee3a 11062/* Handy way to make a field in a struct/union. */
5ff904cd
JL
11063
11064#if FFECOM_targetCURRENT == FFECOM_targetGCC
11065tree
c7e4ee3a
CB
11066ffecom_decl_field (tree context, tree prevfield,
11067 const char *name, tree type)
5ff904cd 11068{
c7e4ee3a 11069 tree field;
5ff904cd 11070
c7e4ee3a
CB
11071 field = build_decl (FIELD_DECL, get_identifier (name), type);
11072 DECL_CONTEXT (field) = context;
11073 DECL_FRAME_SIZE (field) = 0;
11074 if (prevfield != NULL_TREE)
11075 TREE_CHAIN (prevfield) = field;
5ff904cd 11076
c7e4ee3a 11077 return field;
5ff904cd
JL
11078}
11079
11080#endif
5ff904cd 11081
c7e4ee3a
CB
11082void
11083ffecom_close_include (FILE *f)
11084{
11085#if FFECOM_GCC_INCLUDE
11086 ffecom_close_include_ (f);
11087#endif
11088}
5ff904cd 11089
c7e4ee3a
CB
11090int
11091ffecom_decode_include_option (char *spec)
11092{
11093#if FFECOM_GCC_INCLUDE
11094 return ffecom_decode_include_option_ (spec);
11095#else
11096 return 1;
11097#endif
11098}
5ff904cd 11099
c7e4ee3a 11100/* End a compound statement (block). */
5ff904cd
JL
11101
11102#if FFECOM_targetCURRENT == FFECOM_targetGCC
11103tree
c7e4ee3a 11104ffecom_end_compstmt (void)
5ff904cd 11105{
c7e4ee3a
CB
11106 return bison_rule_compstmt_ ();
11107}
11108#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
5ff904cd 11109
c7e4ee3a 11110/* ffecom_end_transition -- Perform end transition on all symbols
5ff904cd 11111
c7e4ee3a 11112 ffecom_end_transition();
5ff904cd 11113
c7e4ee3a 11114 Calls ffecom_sym_end_transition for each global and local symbol. */
5ff904cd 11115
c7e4ee3a
CB
11116void
11117ffecom_end_transition ()
11118{
11119#if FFECOM_targetCURRENT == FFECOM_targetGCC
11120 ffebld item;
5ff904cd 11121#endif
5ff904cd 11122
c7e4ee3a
CB
11123 if (ffe_is_ffedebug ())
11124 fprintf (dmpout, "; end_stmt_transition\n");
86fc7a6c 11125
c7e4ee3a
CB
11126#if FFECOM_targetCURRENT == FFECOM_targetGCC
11127 ffecom_list_blockdata_ = NULL;
11128 ffecom_list_common_ = NULL;
11129#endif
86fc7a6c 11130
c7e4ee3a
CB
11131 ffesymbol_drive (ffecom_sym_end_transition);
11132 if (ffe_is_ffedebug ())
11133 {
11134 ffestorag_report ();
11135#if FFECOM_targetCURRENT == FFECOM_targetFFE
11136 ffesymbol_report_all ();
11137#endif
11138 }
5ff904cd
JL
11139
11140#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
11141 ffecom_start_progunit_ ();
11142
11143 for (item = ffecom_list_blockdata_;
11144 item != NULL;
11145 item = ffebld_trail (item))
11146 {
11147 ffebld callee;
11148 ffesymbol s;
11149 tree dt;
11150 tree t;
11151 tree var;
11152 int yes;
11153 static int number = 0;
11154
11155 callee = ffebld_head (item);
11156 s = ffebld_symter (callee);
11157 t = ffesymbol_hook (s).decl_tree;
11158 if (t == NULL_TREE)
11159 {
11160 s = ffecom_sym_transform_ (s);
11161 t = ffesymbol_hook (s).decl_tree;
11162 }
5ff904cd 11163
c7e4ee3a 11164 yes = suspend_momentary ();
5ff904cd 11165
c7e4ee3a 11166 dt = build_pointer_type (TREE_TYPE (t));
5ff904cd 11167
c7e4ee3a
CB
11168 var = build_decl (VAR_DECL,
11169 ffecom_get_invented_identifier ("__g77_forceload_%d",
11170 NULL, number++),
11171 dt);
11172 DECL_EXTERNAL (var) = 0;
11173 TREE_STATIC (var) = 1;
11174 TREE_PUBLIC (var) = 0;
11175 DECL_INITIAL (var) = error_mark_node;
11176 TREE_USED (var) = 1;
5ff904cd 11177
c7e4ee3a 11178 var = start_decl (var, FALSE);
702edf1d 11179
c7e4ee3a 11180 t = ffecom_1 (ADDR_EXPR, dt, t);
5ff904cd 11181
c7e4ee3a 11182 finish_decl (var, t, FALSE);
5ff904cd 11183
c7e4ee3a
CB
11184 resume_momentary (yes);
11185 }
11186
11187 /* This handles any COMMON areas that weren't referenced but have, for
11188 example, important initial data. */
11189
11190 for (item = ffecom_list_common_;
11191 item != NULL;
11192 item = ffebld_trail (item))
11193 ffecom_transform_common_ (ffebld_symter (ffebld_head (item)));
11194
11195 ffecom_list_common_ = NULL;
5ff904cd 11196#endif
c7e4ee3a 11197}
5ff904cd 11198
c7e4ee3a 11199/* ffecom_exec_transition -- Perform exec transition on all symbols
5ff904cd 11200
c7e4ee3a 11201 ffecom_exec_transition();
5ff904cd 11202
c7e4ee3a
CB
11203 Calls ffecom_sym_exec_transition for each global and local symbol.
11204 Make sure error updating not inhibited. */
5ff904cd 11205
c7e4ee3a
CB
11206void
11207ffecom_exec_transition ()
11208{
11209 bool inhibited;
5ff904cd 11210
c7e4ee3a
CB
11211 if (ffe_is_ffedebug ())
11212 fprintf (dmpout, "; exec_stmt_transition\n");
5ff904cd 11213
c7e4ee3a
CB
11214 inhibited = ffebad_inhibit ();
11215 ffebad_set_inhibit (FALSE);
5ff904cd 11216
c7e4ee3a
CB
11217 ffesymbol_drive (ffecom_sym_exec_transition); /* Don't retract! */
11218 ffeequiv_exec_transition (); /* Handle all pending EQUIVALENCEs. */
11219 if (ffe_is_ffedebug ())
5ff904cd 11220 {
c7e4ee3a
CB
11221 ffestorag_report ();
11222#if FFECOM_targetCURRENT == FFECOM_targetFFE
11223 ffesymbol_report_all ();
11224#endif
11225 }
5ff904cd 11226
c7e4ee3a
CB
11227 if (inhibited)
11228 ffebad_set_inhibit (TRUE);
11229}
5ff904cd 11230
c7e4ee3a 11231/* Handle assignment statement.
5ff904cd 11232
c7e4ee3a
CB
11233 Convert dest and source using ffecom_expr, then join them
11234 with an ASSIGN op and pass the whole thing to expand_expr_stmt. */
5ff904cd 11235
c7e4ee3a
CB
11236#if FFECOM_targetCURRENT == FFECOM_targetGCC
11237void
11238ffecom_expand_let_stmt (ffebld dest, ffebld source)
11239{
11240 tree dest_tree;
11241 tree dest_length;
11242 tree source_tree;
11243 tree expr_tree;
5ff904cd 11244
c7e4ee3a
CB
11245 if (ffeinfo_basictype (ffebld_info (dest)) != FFEINFO_basictypeCHARACTER)
11246 {
11247 bool dest_used;
d6cd84e0 11248 tree assign_temp;
5ff904cd 11249
c7e4ee3a
CB
11250 /* This attempts to replicate the test below, but must not be
11251 true when the test below is false. (Always err on the side
11252 of creating unused temporaries, to avoid ICEs.) */
11253 if (ffebld_op (dest) != FFEBLD_opSYMTER
11254 || ((dest_tree = ffesymbol_hook (ffebld_symter (dest)).decl_tree)
11255 && (TREE_CODE (dest_tree) != VAR_DECL
11256 || TREE_ADDRESSABLE (dest_tree))))
11257 {
11258 ffecom_prepare_expr_ (source, dest);
11259 dest_used = TRUE;
11260 }
11261 else
11262 {
11263 ffecom_prepare_expr_ (source, NULL);
11264 dest_used = FALSE;
11265 }
5ff904cd 11266
c7e4ee3a 11267 ffecom_prepare_expr_w (NULL_TREE, dest);
5ff904cd 11268
d6cd84e0
CB
11269 /* For COMPLEX assignment like C1=C2, if partial overlap is possible,
11270 create a temporary through which the assignment is to take place,
11271 since MODIFY_EXPR doesn't handle partial overlap properly. */
11272 if (ffebld_basictype (dest) == FFEINFO_basictypeCOMPLEX
11273 && ffecom_possible_partial_overlap_ (dest, source))
11274 {
11275 assign_temp = ffecom_make_tempvar ("complex_let",
11276 ffecom_tree_type
11277 [ffebld_basictype (dest)]
11278 [ffebld_kindtype (dest)],
11279 FFETARGET_charactersizeNONE,
11280 -1);
11281 }
11282 else
11283 assign_temp = NULL_TREE;
11284
c7e4ee3a 11285 ffecom_prepare_end ();
5ff904cd 11286
c7e4ee3a
CB
11287 dest_tree = ffecom_expr_w (NULL_TREE, dest);
11288 if (dest_tree == error_mark_node)
11289 return;
5ff904cd 11290
c7e4ee3a
CB
11291 if ((TREE_CODE (dest_tree) != VAR_DECL)
11292 || TREE_ADDRESSABLE (dest_tree))
11293 source_tree = ffecom_expr_ (source, dest_tree, dest, &dest_used,
11294 FALSE, FALSE);
11295 else
11296 {
11297 assert (! dest_used);
11298 dest_used = FALSE;
11299 source_tree = ffecom_expr (source);
11300 }
11301 if (source_tree == error_mark_node)
11302 return;
5ff904cd 11303
c7e4ee3a
CB
11304 if (dest_used)
11305 expr_tree = source_tree;
d6cd84e0
CB
11306 else if (assign_temp)
11307 {
11308#ifdef MOVE_EXPR
11309 /* The back end understands a conceptual move (evaluate source;
11310 store into dest), so use that, in case it can determine
11311 that it is going to use, say, two registers as temporaries
11312 anyway. So don't use the temp (and someday avoid generating
11313 it, once this code starts triggering regularly). */
11314 expr_tree = ffecom_2s (MOVE_EXPR, void_type_node,
11315 dest_tree,
11316 source_tree);
11317#else
11318 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
11319 assign_temp,
11320 source_tree);
11321 expand_expr_stmt (expr_tree);
11322 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
11323 dest_tree,
11324 assign_temp);
11325#endif
11326 }
c7e4ee3a
CB
11327 else
11328 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
11329 dest_tree,
11330 source_tree);
5ff904cd 11331
c7e4ee3a
CB
11332 expand_expr_stmt (expr_tree);
11333 return;
11334 }
5ff904cd 11335
c7e4ee3a
CB
11336 ffecom_prepare_let_char_ (ffebld_size_known (dest), source);
11337 ffecom_prepare_expr_w (NULL_TREE, dest);
11338
11339 ffecom_prepare_end ();
11340
11341 ffecom_char_args_ (&dest_tree, &dest_length, dest);
11342 ffecom_let_char_ (dest_tree, dest_length, ffebld_size_known (dest),
11343 source);
5ff904cd
JL
11344}
11345
11346#endif
c7e4ee3a 11347/* ffecom_expr -- Transform expr into gcc tree
5ff904cd 11348
c7e4ee3a
CB
11349 tree t;
11350 ffebld expr; // FFE expression.
11351 tree = ffecom_expr(expr);
5ff904cd 11352
c7e4ee3a
CB
11353 Recursive descent on expr while making corresponding tree nodes and
11354 attaching type info and such. */
5ff904cd
JL
11355
11356#if FFECOM_targetCURRENT == FFECOM_targetGCC
11357tree
c7e4ee3a 11358ffecom_expr (ffebld expr)
5ff904cd 11359{
c7e4ee3a 11360 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, FALSE, FALSE);
5ff904cd 11361}
c7e4ee3a 11362
5ff904cd 11363#endif
c7e4ee3a 11364/* Like ffecom_expr, but return tree usable for assigned GOTO or FORMAT. */
5ff904cd 11365
c7e4ee3a
CB
11366#if FFECOM_targetCURRENT == FFECOM_targetGCC
11367tree
11368ffecom_expr_assign (ffebld expr)
11369{
11370 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, TRUE, FALSE);
11371}
5ff904cd 11372
c7e4ee3a
CB
11373#endif
11374/* Like ffecom_expr_rw, but return tree usable for ASSIGN. */
5ff904cd
JL
11375
11376#if FFECOM_targetCURRENT == FFECOM_targetGCC
11377tree
c7e4ee3a 11378ffecom_expr_assign_w (ffebld expr)
5ff904cd 11379{
c7e4ee3a
CB
11380 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, TRUE, FALSE);
11381}
5ff904cd 11382
5ff904cd 11383#endif
c7e4ee3a
CB
11384/* Transform expr for use as into read/write tree and stabilize the
11385 reference. Not for use on CHARACTER expressions.
5ff904cd 11386
c7e4ee3a
CB
11387 Recursive descent on expr while making corresponding tree nodes and
11388 attaching type info and such. */
5ff904cd 11389
c7e4ee3a
CB
11390#if FFECOM_targetCURRENT == FFECOM_targetGCC
11391tree
11392ffecom_expr_rw (tree type, ffebld expr)
11393{
11394 assert (expr != NULL);
11395 /* Different target types not yet supported. */
11396 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
11397
11398 return stabilize_reference (ffecom_expr (expr));
11399}
5ff904cd 11400
5ff904cd 11401#endif
c7e4ee3a
CB
11402/* Transform expr for use as into write tree and stabilize the
11403 reference. Not for use on CHARACTER expressions.
5ff904cd 11404
c7e4ee3a
CB
11405 Recursive descent on expr while making corresponding tree nodes and
11406 attaching type info and such. */
5ff904cd 11407
c7e4ee3a
CB
11408#if FFECOM_targetCURRENT == FFECOM_targetGCC
11409tree
11410ffecom_expr_w (tree type, ffebld expr)
11411{
11412 assert (expr != NULL);
11413 /* Different target types not yet supported. */
11414 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
11415
11416 return stabilize_reference (ffecom_expr (expr));
11417}
5ff904cd 11418
5ff904cd 11419#endif
c7e4ee3a
CB
11420/* Do global stuff. */
11421
11422#if FFECOM_targetCURRENT == FFECOM_targetGCC
11423void
11424ffecom_finish_compile ()
11425{
11426 assert (ffecom_outer_function_decl_ == NULL_TREE);
11427 assert (current_function_decl == NULL_TREE);
11428
11429 ffeglobal_drive (ffecom_finish_global_);
11430}
5ff904cd 11431
5ff904cd 11432#endif
c7e4ee3a
CB
11433/* Public entry point for front end to access finish_decl. */
11434
11435#if FFECOM_targetCURRENT == FFECOM_targetGCC
11436void
11437ffecom_finish_decl (tree decl, tree init, bool is_top_level)
11438{
11439 assert (!is_top_level);
11440 finish_decl (decl, init, FALSE);
11441}
5ff904cd 11442
5ff904cd 11443#endif
c7e4ee3a
CB
11444/* Finish a program unit. */
11445
11446#if FFECOM_targetCURRENT == FFECOM_targetGCC
11447void
11448ffecom_finish_progunit ()
11449{
11450 ffecom_end_compstmt ();
11451
11452 ffecom_previous_function_decl_ = current_function_decl;
11453 ffecom_which_entrypoint_decl_ = NULL_TREE;
11454
11455 finish_function (0);
11456}
5ff904cd 11457
5ff904cd 11458#endif
c7e4ee3a
CB
11459/* Wrapper for get_identifier. pattern is sprintf-like, assumed to contain
11460 one %s if text is not NULL, assumed to contain one %d if number is
11461 not -1. If both are assumed, the %s is assumed to precede the %d. */
11462
11463#if FFECOM_targetCURRENT == FFECOM_targetGCC
11464tree
11465ffecom_get_invented_identifier (const char *pattern, const char *text,
11466 int number)
11467{
11468 tree decl;
11469 char *nam;
11470 mallocSize lenlen;
11471 char space[66];
11472
11473 lenlen = 0;
11474 if (text)
11475 lenlen += strlen (text);
11476 if (number != -1)
11477 lenlen += 20;
11478 if (text || number != -1)
11479 {
11480 lenlen += strlen (pattern);
11481 if (lenlen > ARRAY_SIZE (space))
11482 nam = malloc_new_ks (malloc_pool_image (), pattern, lenlen);
11483 else
11484 nam = &space[0];
11485 }
11486 else
11487 {
11488 lenlen = 0;
11489 nam = (char *) pattern;
11490 }
11491
11492 if (text == NULL)
11493 {
11494 if (number != -1)
11495 sprintf (&nam[0], pattern, number);
11496 }
11497 else
11498 {
11499 if (number == -1)
11500 sprintf (&nam[0], pattern, text);
11501 else
11502 sprintf (&nam[0], pattern, text, number);
11503 }
11504
11505 decl = get_identifier (nam);
11506
11507 if (lenlen > ARRAY_SIZE (space))
11508 malloc_kill_ks (malloc_pool_image (), nam, lenlen);
11509
11510 IDENTIFIER_INVENTED (decl) = 1;
11511
11512 return decl;
11513}
11514
11515ffeinfoBasictype
11516ffecom_gfrt_basictype (ffecomGfrt gfrt)
11517{
11518 assert (gfrt < FFECOM_gfrt);
11519
11520 switch (ffecom_gfrt_type_[gfrt])
11521 {
11522 case FFECOM_rttypeVOID_:
11523 case FFECOM_rttypeVOIDSTAR_:
11524 return FFEINFO_basictypeNONE;
11525
11526 case FFECOM_rttypeFTNINT_:
11527 return FFEINFO_basictypeINTEGER;
11528
11529 case FFECOM_rttypeINTEGER_:
11530 return FFEINFO_basictypeINTEGER;
11531
11532 case FFECOM_rttypeLONGINT_:
11533 return FFEINFO_basictypeINTEGER;
11534
11535 case FFECOM_rttypeLOGICAL_:
11536 return FFEINFO_basictypeLOGICAL;
11537
11538 case FFECOM_rttypeREAL_F2C_:
11539 case FFECOM_rttypeREAL_GNU_:
11540 return FFEINFO_basictypeREAL;
11541
11542 case FFECOM_rttypeCOMPLEX_F2C_:
11543 case FFECOM_rttypeCOMPLEX_GNU_:
11544 return FFEINFO_basictypeCOMPLEX;
11545
11546 case FFECOM_rttypeDOUBLE_:
11547 case FFECOM_rttypeDOUBLEREAL_:
11548 return FFEINFO_basictypeREAL;
11549
11550 case FFECOM_rttypeDBLCMPLX_F2C_:
11551 case FFECOM_rttypeDBLCMPLX_GNU_:
11552 return FFEINFO_basictypeCOMPLEX;
11553
11554 case FFECOM_rttypeCHARACTER_:
11555 return FFEINFO_basictypeCHARACTER;
11556
11557 default:
11558 return FFEINFO_basictypeANY;
11559 }
11560}
11561
11562ffeinfoKindtype
11563ffecom_gfrt_kindtype (ffecomGfrt gfrt)
11564{
11565 assert (gfrt < FFECOM_gfrt);
11566
11567 switch (ffecom_gfrt_type_[gfrt])
11568 {
11569 case FFECOM_rttypeVOID_:
11570 case FFECOM_rttypeVOIDSTAR_:
11571 return FFEINFO_kindtypeNONE;
5ff904cd 11572
c7e4ee3a
CB
11573 case FFECOM_rttypeFTNINT_:
11574 return FFEINFO_kindtypeINTEGER1;
5ff904cd 11575
c7e4ee3a
CB
11576 case FFECOM_rttypeINTEGER_:
11577 return FFEINFO_kindtypeINTEGER1;
5ff904cd 11578
c7e4ee3a
CB
11579 case FFECOM_rttypeLONGINT_:
11580 return FFEINFO_kindtypeINTEGER4;
5ff904cd 11581
c7e4ee3a
CB
11582 case FFECOM_rttypeLOGICAL_:
11583 return FFEINFO_kindtypeLOGICAL1;
5ff904cd 11584
c7e4ee3a
CB
11585 case FFECOM_rttypeREAL_F2C_:
11586 case FFECOM_rttypeREAL_GNU_:
11587 return FFEINFO_kindtypeREAL1;
5ff904cd 11588
c7e4ee3a
CB
11589 case FFECOM_rttypeCOMPLEX_F2C_:
11590 case FFECOM_rttypeCOMPLEX_GNU_:
11591 return FFEINFO_kindtypeREAL1;
5ff904cd 11592
c7e4ee3a
CB
11593 case FFECOM_rttypeDOUBLE_:
11594 case FFECOM_rttypeDOUBLEREAL_:
11595 return FFEINFO_kindtypeREAL2;
5ff904cd 11596
c7e4ee3a
CB
11597 case FFECOM_rttypeDBLCMPLX_F2C_:
11598 case FFECOM_rttypeDBLCMPLX_GNU_:
11599 return FFEINFO_kindtypeREAL2;
5ff904cd 11600
c7e4ee3a
CB
11601 case FFECOM_rttypeCHARACTER_:
11602 return FFEINFO_kindtypeCHARACTER1;
5ff904cd 11603
c7e4ee3a
CB
11604 default:
11605 return FFEINFO_kindtypeANY;
11606 }
11607}
5ff904cd 11608
c7e4ee3a
CB
11609void
11610ffecom_init_0 ()
11611{
11612 tree endlink;
11613 int i;
11614 int j;
11615 tree t;
11616 tree field;
11617 ffetype type;
11618 ffetype base_type;
5ff904cd 11619
c7e4ee3a
CB
11620 /* This block of code comes from the now-obsolete cktyps.c. It checks
11621 whether the compiler environment is buggy in known ways, some of which
11622 would, if not explicitly checked here, result in subtle bugs in g77. */
5ff904cd 11623
c7e4ee3a
CB
11624 if (ffe_is_do_internal_checks ())
11625 {
11626 static char names[][12]
11627 =
11628 {"bar", "bletch", "foo", "foobar"};
11629 char *name;
11630 unsigned long ul;
11631 double fl;
5ff904cd 11632
c7e4ee3a
CB
11633 name = bsearch ("foo", &names[0], ARRAY_SIZE (names), sizeof (names[0]),
11634 (int (*)()) strcmp);
11635 if (name != (char *) &names[2])
11636 {
11637 assert ("bsearch doesn't work, #define FFEPROJ_BSEARCH 0 in proj.h"
11638 == NULL);
11639 abort ();
11640 }
5ff904cd 11641
c7e4ee3a
CB
11642 ul = strtoul ("123456789", NULL, 10);
11643 if (ul != 123456789L)
11644 {
11645 assert ("strtoul doesn't have enough range, #define FFEPROJ_STRTOUL 0\
11646 in proj.h" == NULL);
11647 abort ();
11648 }
5ff904cd 11649
c7e4ee3a
CB
11650 fl = atof ("56.789");
11651 if ((fl < 56.788) || (fl > 56.79))
11652 {
11653 assert ("atof not type double, fix your #include <stdio.h>"
11654 == NULL);
11655 abort ();
11656 }
11657 }
5ff904cd 11658
c7e4ee3a
CB
11659#if FFECOM_GCC_INCLUDE
11660 ffecom_initialize_char_syntax_ ();
11661#endif
5ff904cd 11662
c7e4ee3a
CB
11663 ffecom_outer_function_decl_ = NULL_TREE;
11664 current_function_decl = NULL_TREE;
11665 named_labels = NULL_TREE;
11666 current_binding_level = NULL_BINDING_LEVEL;
11667 free_binding_level = NULL_BINDING_LEVEL;
11668 /* Make the binding_level structure for global names. */
11669 pushlevel (0);
11670 global_binding_level = current_binding_level;
11671 current_binding_level->prep_state = 2;
5ff904cd 11672
81b3411c 11673 build_common_tree_nodes (1);
5ff904cd 11674
81b3411c 11675 /* Define `int' and `char' first so that dbx will output them first. */
c7e4ee3a
CB
11676 pushdecl (build_decl (TYPE_DECL, get_identifier ("int"),
11677 integer_type_node));
c7e4ee3a
CB
11678 pushdecl (build_decl (TYPE_DECL, get_identifier ("char"),
11679 char_type_node));
c7e4ee3a
CB
11680 pushdecl (build_decl (TYPE_DECL, get_identifier ("long int"),
11681 long_integer_type_node));
c7e4ee3a
CB
11682 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned int"),
11683 unsigned_type_node));
c7e4ee3a
CB
11684 pushdecl (build_decl (TYPE_DECL, get_identifier ("long unsigned int"),
11685 long_unsigned_type_node));
c7e4ee3a
CB
11686 pushdecl (build_decl (TYPE_DECL, get_identifier ("long long int"),
11687 long_long_integer_type_node));
c7e4ee3a
CB
11688 pushdecl (build_decl (TYPE_DECL, get_identifier ("long long unsigned int"),
11689 long_long_unsigned_type_node));
c7e4ee3a
CB
11690 pushdecl (build_decl (TYPE_DECL, get_identifier ("short int"),
11691 short_integer_type_node));
c7e4ee3a
CB
11692 pushdecl (build_decl (TYPE_DECL, get_identifier ("short unsigned int"),
11693 short_unsigned_type_node));
5ff904cd 11694
ff852b44
CB
11695 /* Set the sizetype before we make other types. This *should* be the
11696 first type we create. */
11697
11698 set_sizetype
11699 (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE))));
11700 ffecom_typesize_pointer_
11701 = TREE_INT_CST_LOW (TYPE_SIZE (sizetype)) / BITS_PER_UNIT;
11702
81b3411c 11703 build_common_tree_nodes_2 (0);
ff852b44 11704
c7e4ee3a 11705 /* Define both `signed char' and `unsigned char'. */
c7e4ee3a
CB
11706 pushdecl (build_decl (TYPE_DECL, get_identifier ("signed char"),
11707 signed_char_type_node));
5ff904cd 11708
c7e4ee3a
CB
11709 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned char"),
11710 unsigned_char_type_node));
5ff904cd 11711
c7e4ee3a
CB
11712 pushdecl (build_decl (TYPE_DECL, get_identifier ("float"),
11713 float_type_node));
c7e4ee3a
CB
11714 pushdecl (build_decl (TYPE_DECL, get_identifier ("double"),
11715 double_type_node));
c7e4ee3a
CB
11716 pushdecl (build_decl (TYPE_DECL, get_identifier ("long double"),
11717 long_double_type_node));
5ff904cd 11718
81b3411c 11719 /* For now, override what build_common_tree_nodes has done. */
c7e4ee3a 11720 complex_integer_type_node = ffecom_make_complex_type_ (integer_type_node);
81b3411c
BS
11721 complex_float_type_node = ffecom_make_complex_type_ (float_type_node);
11722 complex_double_type_node = ffecom_make_complex_type_ (double_type_node);
11723 complex_long_double_type_node
11724 = ffecom_make_complex_type_ (long_double_type_node);
11725
c7e4ee3a
CB
11726 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex int"),
11727 complex_integer_type_node));
c7e4ee3a
CB
11728 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex float"),
11729 complex_float_type_node));
c7e4ee3a
CB
11730 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex double"),
11731 complex_double_type_node));
c7e4ee3a
CB
11732 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex long double"),
11733 complex_long_double_type_node));
5ff904cd 11734
c7e4ee3a
CB
11735 pushdecl (build_decl (TYPE_DECL, get_identifier ("void"),
11736 void_type_node));
c7e4ee3a
CB
11737 /* We are not going to have real types in C with less than byte alignment,
11738 so we might as well not have any types that claim to have it. */
11739 TYPE_ALIGN (void_type_node) = BITS_PER_UNIT;
5ff904cd 11740
c7e4ee3a 11741 string_type_node = build_pointer_type (char_type_node);
5ff904cd 11742
c7e4ee3a
CB
11743 ffecom_tree_fun_type_void
11744 = build_function_type (void_type_node, NULL_TREE);
5ff904cd 11745
c7e4ee3a
CB
11746 ffecom_tree_ptr_to_fun_type_void
11747 = build_pointer_type (ffecom_tree_fun_type_void);
5ff904cd 11748
c7e4ee3a 11749 endlink = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
5ff904cd 11750
c7e4ee3a
CB
11751 float_ftype_float
11752 = build_function_type (float_type_node,
11753 tree_cons (NULL_TREE, float_type_node, endlink));
5ff904cd 11754
c7e4ee3a
CB
11755 double_ftype_double
11756 = build_function_type (double_type_node,
11757 tree_cons (NULL_TREE, double_type_node, endlink));
5ff904cd 11758
c7e4ee3a
CB
11759 ldouble_ftype_ldouble
11760 = build_function_type (long_double_type_node,
11761 tree_cons (NULL_TREE, long_double_type_node,
11762 endlink));
5ff904cd 11763
c7e4ee3a
CB
11764 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11765 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11766 {
11767 ffecom_tree_type[i][j] = NULL_TREE;
11768 ffecom_tree_fun_type[i][j] = NULL_TREE;
11769 ffecom_tree_ptr_to_fun_type[i][j] = NULL_TREE;
11770 ffecom_f2c_typecode_[i][j] = -1;
11771 }
5ff904cd 11772
c7e4ee3a
CB
11773 /* Set up standard g77 types. Note that INTEGER and LOGICAL are set
11774 to size FLOAT_TYPE_SIZE because they have to be the same size as
11775 REAL, which also is FLOAT_TYPE_SIZE, according to the standard.
11776 Compiler options and other such stuff that change the ways these
11777 types are set should not affect this particular setup. */
5ff904cd 11778
c7e4ee3a
CB
11779 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER1]
11780 = t = make_signed_type (FLOAT_TYPE_SIZE);
11781 pushdecl (build_decl (TYPE_DECL, get_identifier ("integer"),
11782 t));
11783 type = ffetype_new ();
11784 base_type = type;
11785 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER1,
11786 type);
11787 ffetype_set_ams (type,
11788 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11789 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11790 ffetype_set_star (base_type,
11791 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11792 type);
11793 ffetype_set_kind (base_type, 1, type);
ff852b44 11794 ffecom_typesize_integer1_ = ffetype_size (type);
c7e4ee3a 11795 assert (ffetype_size (type) == sizeof (ffetargetInteger1));
5ff904cd 11796
c7e4ee3a
CB
11797 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER1]
11798 = t = make_unsigned_type (FLOAT_TYPE_SIZE); /* HOLLERITH means unsigned. */
11799 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned"),
11800 t));
5ff904cd 11801
c7e4ee3a
CB
11802 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER2]
11803 = t = make_signed_type (CHAR_TYPE_SIZE);
11804 pushdecl (build_decl (TYPE_DECL, get_identifier ("byte"),
11805 t));
11806 type = ffetype_new ();
11807 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER2,
11808 type);
11809 ffetype_set_ams (type,
11810 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11811 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11812 ffetype_set_star (base_type,
11813 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11814 type);
11815 ffetype_set_kind (base_type, 3, type);
11816 assert (ffetype_size (type) == sizeof (ffetargetInteger2));
5ff904cd 11817
c7e4ee3a
CB
11818 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER2]
11819 = t = make_unsigned_type (CHAR_TYPE_SIZE);
11820 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned byte"),
11821 t));
11822
11823 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER3]
11824 = t = make_signed_type (CHAR_TYPE_SIZE * 2);
11825 pushdecl (build_decl (TYPE_DECL, get_identifier ("word"),
11826 t));
11827 type = ffetype_new ();
11828 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER3,
11829 type);
11830 ffetype_set_ams (type,
11831 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11832 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11833 ffetype_set_star (base_type,
11834 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11835 type);
11836 ffetype_set_kind (base_type, 6, type);
11837 assert (ffetype_size (type) == sizeof (ffetargetInteger3));
5ff904cd 11838
c7e4ee3a
CB
11839 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER3]
11840 = t = make_unsigned_type (CHAR_TYPE_SIZE * 2);
11841 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned word"),
11842 t));
5ff904cd 11843
c7e4ee3a
CB
11844 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER4]
11845 = t = make_signed_type (FLOAT_TYPE_SIZE * 2);
11846 pushdecl (build_decl (TYPE_DECL, get_identifier ("integer4"),
11847 t));
11848 type = ffetype_new ();
11849 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER4,
11850 type);
11851 ffetype_set_ams (type,
11852 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11853 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11854 ffetype_set_star (base_type,
11855 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11856 type);
11857 ffetype_set_kind (base_type, 2, type);
11858 assert (ffetype_size (type) == sizeof (ffetargetInteger4));
5ff904cd 11859
c7e4ee3a
CB
11860 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER4]
11861 = t = make_unsigned_type (FLOAT_TYPE_SIZE * 2);
11862 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned4"),
11863 t));
5ff904cd 11864
c7e4ee3a
CB
11865#if 0
11866 if (ffe_is_do_internal_checks ()
11867 && LONG_TYPE_SIZE != FLOAT_TYPE_SIZE
11868 && LONG_TYPE_SIZE != CHAR_TYPE_SIZE
11869 && LONG_TYPE_SIZE != SHORT_TYPE_SIZE
11870 && LONG_TYPE_SIZE != LONG_LONG_TYPE_SIZE)
5ff904cd 11871 {
c7e4ee3a
CB
11872 fprintf (stderr, "Sorry, no g77 support for LONG_TYPE_SIZE (%d bits) yet.\n",
11873 LONG_TYPE_SIZE);
5ff904cd 11874 }
c7e4ee3a 11875#endif
5ff904cd 11876
c7e4ee3a
CB
11877 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL1]
11878 = t = make_signed_type (FLOAT_TYPE_SIZE);
11879 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical"),
11880 t));
11881 type = ffetype_new ();
11882 base_type = type;
11883 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL1,
11884 type);
11885 ffetype_set_ams (type,
11886 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11887 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11888 ffetype_set_star (base_type,
11889 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11890 type);
11891 ffetype_set_kind (base_type, 1, type);
11892 assert (ffetype_size (type) == sizeof (ffetargetLogical1));
5ff904cd 11893
c7e4ee3a
CB
11894 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL2]
11895 = t = make_signed_type (CHAR_TYPE_SIZE);
11896 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical2"),
11897 t));
11898 type = ffetype_new ();
11899 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL2,
11900 type);
11901 ffetype_set_ams (type,
11902 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11903 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11904 ffetype_set_star (base_type,
11905 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11906 type);
11907 ffetype_set_kind (base_type, 3, type);
11908 assert (ffetype_size (type) == sizeof (ffetargetLogical2));
5ff904cd 11909
c7e4ee3a
CB
11910 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL3]
11911 = t = make_signed_type (CHAR_TYPE_SIZE * 2);
11912 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical3"),
11913 t));
11914 type = ffetype_new ();
11915 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL3,
11916 type);
11917 ffetype_set_ams (type,
11918 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11919 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11920 ffetype_set_star (base_type,
11921 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11922 type);
11923 ffetype_set_kind (base_type, 6, type);
11924 assert (ffetype_size (type) == sizeof (ffetargetLogical3));
5ff904cd 11925
c7e4ee3a
CB
11926 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL4]
11927 = t = make_signed_type (FLOAT_TYPE_SIZE * 2);
11928 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical4"),
11929 t));
11930 type = ffetype_new ();
11931 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL4,
11932 type);
11933 ffetype_set_ams (type,
11934 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11935 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11936 ffetype_set_star (base_type,
11937 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11938 type);
11939 ffetype_set_kind (base_type, 2, type);
11940 assert (ffetype_size (type) == sizeof (ffetargetLogical4));
5ff904cd 11941
c7e4ee3a
CB
11942 ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]
11943 = t = make_node (REAL_TYPE);
11944 TYPE_PRECISION (t) = FLOAT_TYPE_SIZE;
11945 pushdecl (build_decl (TYPE_DECL, get_identifier ("real"),
11946 t));
11947 layout_type (t);
11948 type = ffetype_new ();
11949 base_type = type;
11950 ffeinfo_set_type (FFEINFO_basictypeREAL, FFEINFO_kindtypeREAL1,
11951 type);
11952 ffetype_set_ams (type,
11953 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11954 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11955 ffetype_set_star (base_type,
11956 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11957 type);
11958 ffetype_set_kind (base_type, 1, type);
11959 ffecom_f2c_typecode_[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]
11960 = FFETARGET_f2cTYREAL;
11961 assert (ffetype_size (type) == sizeof (ffetargetReal1));
5ff904cd 11962
c7e4ee3a
CB
11963 ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREALDOUBLE]
11964 = t = make_node (REAL_TYPE);
11965 TYPE_PRECISION (t) = FLOAT_TYPE_SIZE * 2; /* Always twice REAL. */
11966 pushdecl (build_decl (TYPE_DECL, get_identifier ("double precision"),
11967 t));
11968 layout_type (t);
11969 type = ffetype_new ();
11970 ffeinfo_set_type (FFEINFO_basictypeREAL, FFEINFO_kindtypeREALDOUBLE,
11971 type);
11972 ffetype_set_ams (type,
11973 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11974 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11975 ffetype_set_star (base_type,
11976 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11977 type);
11978 ffetype_set_kind (base_type, 2, type);
11979 ffecom_f2c_typecode_[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2]
11980 = FFETARGET_f2cTYDREAL;
11981 assert (ffetype_size (type) == sizeof (ffetargetReal2));
5ff904cd 11982
c7e4ee3a
CB
11983 ffecom_tree_type[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL1]
11984 = t = ffecom_make_complex_type_ (ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]);
11985 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex"),
11986 t));
11987 type = ffetype_new ();
11988 base_type = type;
11989 ffeinfo_set_type (FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREAL1,
11990 type);
11991 ffetype_set_ams (type,
11992 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11993 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11994 ffetype_set_star (base_type,
11995 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11996 type);
11997 ffetype_set_kind (base_type, 1, type);
11998 ffecom_f2c_typecode_[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL1]
11999 = FFETARGET_f2cTYCOMPLEX;
12000 assert (ffetype_size (type) == sizeof (ffetargetComplex1));
5ff904cd 12001
c7e4ee3a
CB
12002 ffecom_tree_type[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREALDOUBLE]
12003 = t = ffecom_make_complex_type_ (ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2]);
12004 pushdecl (build_decl (TYPE_DECL, get_identifier ("double complex"),
12005 t));
12006 type = ffetype_new ();
12007 ffeinfo_set_type (FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREALDOUBLE,
12008 type);
12009 ffetype_set_ams (type,
12010 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
12011 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
12012 ffetype_set_star (base_type,
12013 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
12014 type);
12015 ffetype_set_kind (base_type, 2,
12016 type);
12017 ffecom_f2c_typecode_[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL2]
12018 = FFETARGET_f2cTYDCOMPLEX;
12019 assert (ffetype_size (type) == sizeof (ffetargetComplex2));
5ff904cd 12020
c7e4ee3a 12021 /* Make function and ptr-to-function types for non-CHARACTER types. */
5ff904cd 12022
c7e4ee3a
CB
12023 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
12024 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
12025 {
12026 if ((t = ffecom_tree_type[i][j]) != NULL_TREE)
12027 {
12028 if (i == FFEINFO_basictypeINTEGER)
12029 {
12030 /* Figure out the smallest INTEGER type that can hold
12031 a pointer on this machine. */
12032 if (GET_MODE_SIZE (TYPE_MODE (t))
12033 >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
12034 {
12035 if ((ffecom_pointer_kind_ == FFEINFO_kindtypeNONE)
12036 || (GET_MODE_SIZE (TYPE_MODE (ffecom_tree_type[i][ffecom_pointer_kind_]))
12037 > GET_MODE_SIZE (TYPE_MODE (t))))
12038 ffecom_pointer_kind_ = j;
12039 }
12040 }
12041 else if (i == FFEINFO_basictypeCOMPLEX)
12042 t = void_type_node;
12043 /* For f2c compatibility, REAL functions are really
12044 implemented as DOUBLE PRECISION. */
12045 else if ((i == FFEINFO_basictypeREAL)
12046 && (j == FFEINFO_kindtypeREAL1))
12047 t = ffecom_tree_type
12048 [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2];
5ff904cd 12049
c7e4ee3a
CB
12050 t = ffecom_tree_fun_type[i][j] = build_function_type (t,
12051 NULL_TREE);
12052 ffecom_tree_ptr_to_fun_type[i][j] = build_pointer_type (t);
12053 }
12054 }
5ff904cd 12055
c7e4ee3a 12056 /* Set up pointer types. */
5ff904cd 12057
c7e4ee3a
CB
12058 if (ffecom_pointer_kind_ == FFEINFO_basictypeNONE)
12059 fatal ("no INTEGER type can hold a pointer on this configuration");
12060 else if (0 && ffe_is_do_internal_checks ())
12061 fprintf (stderr, "Pointer type kt=%d\n", ffecom_pointer_kind_);
12062 ffetype_set_kind (ffeinfo_type (FFEINFO_basictypeINTEGER,
12063 FFEINFO_kindtypeINTEGERDEFAULT),
12064 7,
12065 ffeinfo_type (FFEINFO_basictypeINTEGER,
12066 ffecom_pointer_kind_));
5ff904cd 12067
c7e4ee3a
CB
12068 if (ffe_is_ugly_assign ())
12069 ffecom_label_kind_ = ffecom_pointer_kind_; /* Require ASSIGN etc to this. */
12070 else
12071 ffecom_label_kind_ = FFEINFO_kindtypeINTEGERDEFAULT;
12072 if (0 && ffe_is_do_internal_checks ())
12073 fprintf (stderr, "Label type kt=%d\n", ffecom_label_kind_);
5ff904cd 12074
c7e4ee3a
CB
12075 ffecom_integer_type_node
12076 = ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER1];
12077 ffecom_integer_zero_node = convert (ffecom_integer_type_node,
12078 integer_zero_node);
12079 ffecom_integer_one_node = convert (ffecom_integer_type_node,
12080 integer_one_node);
5ff904cd 12081
c7e4ee3a
CB
12082 /* Yes, the "FLOAT_TYPE_SIZE" references below are intentional.
12083 Turns out that by TYLONG, runtime/libI77/lio.h really means
12084 "whatever size an ftnint is". For consistency and sanity,
12085 com.h and runtime/f2c.h.in agree that flag, ftnint, and ftlen
12086 all are INTEGER, which we also make out of whatever back-end
12087 integer type is FLOAT_TYPE_SIZE bits wide. This change, from
12088 LONG_TYPE_SIZE, for TYLONG and TYLOGICAL, was necessary to
12089 accommodate machines like the Alpha. Note that this suggests
12090 f2c and libf2c are missing a distinction perhaps needed on
12091 some machines between "int" and "long int". -- burley 0.5.5 950215 */
5ff904cd 12092
c7e4ee3a
CB
12093 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, FLOAT_TYPE_SIZE,
12094 FFETARGET_f2cTYLONG);
12095 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, SHORT_TYPE_SIZE,
12096 FFETARGET_f2cTYSHORT);
12097 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, CHAR_TYPE_SIZE,
12098 FFETARGET_f2cTYINT1);
12099 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, LONG_LONG_TYPE_SIZE,
12100 FFETARGET_f2cTYQUAD);
12101 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, FLOAT_TYPE_SIZE,
12102 FFETARGET_f2cTYLOGICAL);
12103 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, SHORT_TYPE_SIZE,
12104 FFETARGET_f2cTYLOGICAL2);
12105 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, CHAR_TYPE_SIZE,
12106 FFETARGET_f2cTYLOGICAL1);
12107 /* ~~~Not really such a type in libf2c, e.g. I/O support? */
12108 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, LONG_LONG_TYPE_SIZE,
12109 FFETARGET_f2cTYQUAD);
5ff904cd 12110
c7e4ee3a
CB
12111 /* CHARACTER stuff is all special-cased, so it is not handled in the above
12112 loop. CHARACTER items are built as arrays of unsigned char. */
5ff904cd 12113
c7e4ee3a
CB
12114 ffecom_tree_type[FFEINFO_basictypeCHARACTER]
12115 [FFEINFO_kindtypeCHARACTER1] = t = char_type_node;
12116 type = ffetype_new ();
12117 base_type = type;
12118 ffeinfo_set_type (FFEINFO_basictypeCHARACTER,
12119 FFEINFO_kindtypeCHARACTER1,
12120 type);
12121 ffetype_set_ams (type,
12122 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
12123 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
12124 ffetype_set_kind (base_type, 1, type);
12125 assert (ffetype_size (type)
12126 == sizeof (((ffetargetCharacter1) { 0, NULL }).text[0]));
5ff904cd 12127
c7e4ee3a
CB
12128 ffecom_tree_fun_type[FFEINFO_basictypeCHARACTER]
12129 [FFEINFO_kindtypeCHARACTER1] = ffecom_tree_fun_type_void;
12130 ffecom_tree_ptr_to_fun_type[FFEINFO_basictypeCHARACTER]
12131 [FFEINFO_kindtypeCHARACTER1]
12132 = ffecom_tree_ptr_to_fun_type_void;
12133 ffecom_f2c_typecode_[FFEINFO_basictypeCHARACTER][FFEINFO_kindtypeCHARACTER1]
12134 = FFETARGET_f2cTYCHAR;
5ff904cd 12135
c7e4ee3a
CB
12136 ffecom_f2c_typecode_[FFEINFO_basictypeANY][FFEINFO_kindtypeANY]
12137 = 0;
5ff904cd 12138
c7e4ee3a 12139 /* Make multi-return-value type and fields. */
5ff904cd 12140
c7e4ee3a 12141 ffecom_multi_type_node_ = make_node (UNION_TYPE);
5ff904cd 12142
c7e4ee3a 12143 field = NULL_TREE;
5ff904cd 12144
c7e4ee3a
CB
12145 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
12146 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
12147 {
12148 char name[30];
5ff904cd 12149
c7e4ee3a
CB
12150 if (ffecom_tree_type[i][j] == NULL_TREE)
12151 continue; /* Not supported. */
12152 sprintf (&name[0], "bt_%s_kt_%s",
12153 ffeinfo_basictype_string ((ffeinfoBasictype) i),
12154 ffeinfo_kindtype_string ((ffeinfoKindtype) j));
12155 ffecom_multi_fields_[i][j] = build_decl (FIELD_DECL,
12156 get_identifier (name),
12157 ffecom_tree_type[i][j]);
12158 DECL_CONTEXT (ffecom_multi_fields_[i][j])
12159 = ffecom_multi_type_node_;
12160 DECL_FRAME_SIZE (ffecom_multi_fields_[i][j]) = 0;
12161 TREE_CHAIN (ffecom_multi_fields_[i][j]) = field;
12162 field = ffecom_multi_fields_[i][j];
12163 }
5ff904cd 12164
c7e4ee3a
CB
12165 TYPE_FIELDS (ffecom_multi_type_node_) = field;
12166 layout_type (ffecom_multi_type_node_);
5ff904cd 12167
c7e4ee3a
CB
12168 /* Subroutines usually return integer because they might have alternate
12169 returns. */
5ff904cd 12170
c7e4ee3a
CB
12171 ffecom_tree_subr_type
12172 = build_function_type (integer_type_node, NULL_TREE);
12173 ffecom_tree_ptr_to_subr_type
12174 = build_pointer_type (ffecom_tree_subr_type);
12175 ffecom_tree_blockdata_type
12176 = build_function_type (void_type_node, NULL_TREE);
5ff904cd 12177
c7e4ee3a
CB
12178 builtin_function ("__builtin_sqrtf", float_ftype_float,
12179 BUILT_IN_FSQRT, "sqrtf");
12180 builtin_function ("__builtin_fsqrt", double_ftype_double,
12181 BUILT_IN_FSQRT, "sqrt");
12182 builtin_function ("__builtin_sqrtl", ldouble_ftype_ldouble,
12183 BUILT_IN_FSQRT, "sqrtl");
12184 builtin_function ("__builtin_sinf", float_ftype_float,
12185 BUILT_IN_SIN, "sinf");
12186 builtin_function ("__builtin_sin", double_ftype_double,
12187 BUILT_IN_SIN, "sin");
12188 builtin_function ("__builtin_sinl", ldouble_ftype_ldouble,
12189 BUILT_IN_SIN, "sinl");
12190 builtin_function ("__builtin_cosf", float_ftype_float,
12191 BUILT_IN_COS, "cosf");
12192 builtin_function ("__builtin_cos", double_ftype_double,
12193 BUILT_IN_COS, "cos");
12194 builtin_function ("__builtin_cosl", ldouble_ftype_ldouble,
12195 BUILT_IN_COS, "cosl");
5ff904cd 12196
c7e4ee3a
CB
12197#if BUILT_FOR_270
12198 pedantic_lvalues = FALSE;
5ff904cd 12199#endif
5ff904cd 12200
c7e4ee3a
CB
12201 ffecom_f2c_make_type_ (&ffecom_f2c_integer_type_node,
12202 FFECOM_f2cINTEGER,
12203 "integer");
12204 ffecom_f2c_make_type_ (&ffecom_f2c_address_type_node,
12205 FFECOM_f2cADDRESS,
12206 "address");
12207 ffecom_f2c_make_type_ (&ffecom_f2c_real_type_node,
12208 FFECOM_f2cREAL,
12209 "real");
12210 ffecom_f2c_make_type_ (&ffecom_f2c_doublereal_type_node,
12211 FFECOM_f2cDOUBLEREAL,
12212 "doublereal");
12213 ffecom_f2c_make_type_ (&ffecom_f2c_complex_type_node,
12214 FFECOM_f2cCOMPLEX,
12215 "complex");
12216 ffecom_f2c_make_type_ (&ffecom_f2c_doublecomplex_type_node,
12217 FFECOM_f2cDOUBLECOMPLEX,
12218 "doublecomplex");
12219 ffecom_f2c_make_type_ (&ffecom_f2c_longint_type_node,
12220 FFECOM_f2cLONGINT,
12221 "longint");
12222 ffecom_f2c_make_type_ (&ffecom_f2c_logical_type_node,
12223 FFECOM_f2cLOGICAL,
12224 "logical");
12225 ffecom_f2c_make_type_ (&ffecom_f2c_flag_type_node,
12226 FFECOM_f2cFLAG,
12227 "flag");
12228 ffecom_f2c_make_type_ (&ffecom_f2c_ftnlen_type_node,
12229 FFECOM_f2cFTNLEN,
12230 "ftnlen");
12231 ffecom_f2c_make_type_ (&ffecom_f2c_ftnint_type_node,
12232 FFECOM_f2cFTNINT,
12233 "ftnint");
5ff904cd 12234
c7e4ee3a
CB
12235 ffecom_f2c_ftnlen_zero_node
12236 = convert (ffecom_f2c_ftnlen_type_node, integer_zero_node);
5ff904cd 12237
c7e4ee3a
CB
12238 ffecom_f2c_ftnlen_one_node
12239 = convert (ffecom_f2c_ftnlen_type_node, integer_one_node);
5ff904cd 12240
c7e4ee3a
CB
12241 ffecom_f2c_ftnlen_two_node = build_int_2 (2, 0);
12242 TREE_TYPE (ffecom_f2c_ftnlen_two_node) = ffecom_integer_type_node;
5ff904cd 12243
c7e4ee3a
CB
12244 ffecom_f2c_ptr_to_ftnlen_type_node
12245 = build_pointer_type (ffecom_f2c_ftnlen_type_node);
5ff904cd 12246
c7e4ee3a
CB
12247 ffecom_f2c_ptr_to_ftnint_type_node
12248 = build_pointer_type (ffecom_f2c_ftnint_type_node);
5ff904cd 12249
c7e4ee3a
CB
12250 ffecom_f2c_ptr_to_integer_type_node
12251 = build_pointer_type (ffecom_f2c_integer_type_node);
5ff904cd 12252
c7e4ee3a
CB
12253 ffecom_f2c_ptr_to_real_type_node
12254 = build_pointer_type (ffecom_f2c_real_type_node);
5ff904cd 12255
c7e4ee3a
CB
12256 ffecom_float_zero_ = build_real (float_type_node, dconst0);
12257 ffecom_double_zero_ = build_real (double_type_node, dconst0);
12258 {
12259 REAL_VALUE_TYPE point_5;
5ff904cd 12260
c7e4ee3a
CB
12261#ifdef REAL_ARITHMETIC
12262 REAL_ARITHMETIC (point_5, RDIV_EXPR, dconst1, dconst2);
12263#else
12264 point_5 = .5;
12265#endif
12266 ffecom_float_half_ = build_real (float_type_node, point_5);
12267 ffecom_double_half_ = build_real (double_type_node, point_5);
12268 }
5ff904cd 12269
c7e4ee3a 12270 /* Do "extern int xargc;". */
5ff904cd 12271
c7e4ee3a
CB
12272 ffecom_tree_xargc_ = build_decl (VAR_DECL,
12273 get_identifier ("f__xargc"),
12274 integer_type_node);
12275 DECL_EXTERNAL (ffecom_tree_xargc_) = 1;
12276 TREE_STATIC (ffecom_tree_xargc_) = 1;
12277 TREE_PUBLIC (ffecom_tree_xargc_) = 1;
12278 ffecom_tree_xargc_ = start_decl (ffecom_tree_xargc_, FALSE);
12279 finish_decl (ffecom_tree_xargc_, NULL_TREE, FALSE);
5ff904cd 12280
c7e4ee3a
CB
12281#if 0 /* This is being fixed, and seems to be working now. */
12282 if ((FLOAT_TYPE_SIZE != 32)
12283 || (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node))) != 32))
5ff904cd 12284 {
c7e4ee3a
CB
12285 warning ("configuration: REAL, INTEGER, and LOGICAL are %d bits wide,",
12286 (int) FLOAT_TYPE_SIZE);
12287 warning ("and pointers are %d bits wide, but g77 doesn't yet work",
12288 (int) TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node))));
12289 warning ("properly unless they all are 32 bits wide.");
12290 warning ("Please keep this in mind before you report bugs. g77 should");
12291 warning ("support non-32-bit machines better as of version 0.6.");
12292 }
12293#endif
5ff904cd 12294
c7e4ee3a
CB
12295#if 0 /* Code in ste.c that would crash has been commented out. */
12296 if (TYPE_PRECISION (ffecom_f2c_ftnlen_type_node)
12297 < TYPE_PRECISION (string_type_node))
12298 /* I/O will probably crash. */
12299 warning ("configuration: char * holds %d bits, but ftnlen only %d",
12300 TYPE_PRECISION (string_type_node),
12301 TYPE_PRECISION (ffecom_f2c_ftnlen_type_node));
12302#endif
5ff904cd 12303
c7e4ee3a
CB
12304#if 0 /* ASSIGN-related stuff has been changed to accommodate this. */
12305 if (TYPE_PRECISION (ffecom_integer_type_node)
12306 < TYPE_PRECISION (string_type_node))
12307 /* ASSIGN 10 TO I will crash. */
12308 warning ("configuration: char * holds %d bits, but INTEGER only %d --\n\
12309 ASSIGN statement might fail",
12310 TYPE_PRECISION (string_type_node),
12311 TYPE_PRECISION (ffecom_integer_type_node));
12312#endif
12313}
5ff904cd 12314
c7e4ee3a
CB
12315#endif
12316/* ffecom_init_2 -- Initialize
5ff904cd 12317
c7e4ee3a 12318 ffecom_init_2(); */
5ff904cd 12319
c7e4ee3a
CB
12320#if FFECOM_targetCURRENT == FFECOM_targetGCC
12321void
12322ffecom_init_2 ()
12323{
12324 assert (ffecom_outer_function_decl_ == NULL_TREE);
12325 assert (current_function_decl == NULL_TREE);
12326 assert (ffecom_which_entrypoint_decl_ == NULL_TREE);
5ff904cd 12327
c7e4ee3a
CB
12328 ffecom_master_arglist_ = NULL;
12329 ++ffecom_num_fns_;
12330 ffecom_primary_entry_ = NULL;
12331 ffecom_is_altreturning_ = FALSE;
12332 ffecom_func_result_ = NULL_TREE;
12333 ffecom_multi_retval_ = NULL_TREE;
12334}
5ff904cd 12335
c7e4ee3a
CB
12336#endif
12337/* ffecom_list_expr -- Transform list of exprs into gcc tree
5ff904cd 12338
c7e4ee3a
CB
12339 tree t;
12340 ffebld expr; // FFE opITEM list.
12341 tree = ffecom_list_expr(expr);
5ff904cd 12342
c7e4ee3a 12343 List of actual args is transformed into corresponding gcc backend list. */
5ff904cd 12344
c7e4ee3a
CB
12345#if FFECOM_targetCURRENT == FFECOM_targetGCC
12346tree
12347ffecom_list_expr (ffebld expr)
5ff904cd 12348{
c7e4ee3a
CB
12349 tree list;
12350 tree *plist = &list;
12351 tree trail = NULL_TREE; /* Append char length args here. */
12352 tree *ptrail = &trail;
12353 tree length;
5ff904cd 12354
c7e4ee3a 12355 while (expr != NULL)
5ff904cd 12356 {
c7e4ee3a 12357 tree texpr = ffecom_arg_expr (ffebld_head (expr), &length);
5ff904cd 12358
c7e4ee3a
CB
12359 if (texpr == error_mark_node)
12360 return error_mark_node;
5ff904cd 12361
c7e4ee3a
CB
12362 *plist = build_tree_list (NULL_TREE, texpr);
12363 plist = &TREE_CHAIN (*plist);
12364 expr = ffebld_trail (expr);
12365 if (length != NULL_TREE)
5ff904cd 12366 {
c7e4ee3a
CB
12367 *ptrail = build_tree_list (NULL_TREE, length);
12368 ptrail = &TREE_CHAIN (*ptrail);
5ff904cd
JL
12369 }
12370 }
12371
c7e4ee3a 12372 *plist = trail;
5ff904cd 12373
c7e4ee3a
CB
12374 return list;
12375}
5ff904cd 12376
c7e4ee3a
CB
12377#endif
12378/* ffecom_list_ptr_to_expr -- Transform list of exprs into gcc tree
5ff904cd 12379
c7e4ee3a
CB
12380 tree t;
12381 ffebld expr; // FFE opITEM list.
12382 tree = ffecom_list_ptr_to_expr(expr);
5ff904cd 12383
c7e4ee3a
CB
12384 List of actual args is transformed into corresponding gcc backend list for
12385 use in calling an external procedure (vs. a statement function). */
5ff904cd 12386
c7e4ee3a
CB
12387#if FFECOM_targetCURRENT == FFECOM_targetGCC
12388tree
12389ffecom_list_ptr_to_expr (ffebld expr)
12390{
12391 tree list;
12392 tree *plist = &list;
12393 tree trail = NULL_TREE; /* Append char length args here. */
12394 tree *ptrail = &trail;
12395 tree length;
5ff904cd 12396
c7e4ee3a
CB
12397 while (expr != NULL)
12398 {
12399 tree texpr = ffecom_arg_ptr_to_expr (ffebld_head (expr), &length);
5ff904cd 12400
c7e4ee3a
CB
12401 if (texpr == error_mark_node)
12402 return error_mark_node;
5ff904cd 12403
c7e4ee3a
CB
12404 *plist = build_tree_list (NULL_TREE, texpr);
12405 plist = &TREE_CHAIN (*plist);
12406 expr = ffebld_trail (expr);
12407 if (length != NULL_TREE)
12408 {
12409 *ptrail = build_tree_list (NULL_TREE, length);
12410 ptrail = &TREE_CHAIN (*ptrail);
12411 }
12412 }
5ff904cd 12413
c7e4ee3a 12414 *plist = trail;
5ff904cd 12415
c7e4ee3a
CB
12416 return list;
12417}
5ff904cd 12418
c7e4ee3a
CB
12419#endif
12420/* Obtain gcc's LABEL_DECL tree for label. */
5ff904cd 12421
c7e4ee3a
CB
12422#if FFECOM_targetCURRENT == FFECOM_targetGCC
12423tree
12424ffecom_lookup_label (ffelab label)
12425{
12426 tree glabel;
5ff904cd 12427
c7e4ee3a
CB
12428 if (ffelab_hook (label) == NULL_TREE)
12429 {
12430 char labelname[16];
5ff904cd 12431
c7e4ee3a
CB
12432 switch (ffelab_type (label))
12433 {
12434 case FFELAB_typeLOOPEND:
12435 case FFELAB_typeNOTLOOP:
12436 case FFELAB_typeENDIF:
12437 sprintf (labelname, "%" ffelabValue_f "u", ffelab_value (label));
12438 glabel = build_decl (LABEL_DECL, get_identifier (labelname),
12439 void_type_node);
12440 DECL_CONTEXT (glabel) = current_function_decl;
12441 DECL_MODE (glabel) = VOIDmode;
12442 break;
5ff904cd 12443
c7e4ee3a
CB
12444 case FFELAB_typeFORMAT:
12445 push_obstacks_nochange ();
12446 end_temporary_allocation ();
5ff904cd 12447
c7e4ee3a
CB
12448 glabel = build_decl (VAR_DECL,
12449 ffecom_get_invented_identifier
12450 ("__g77_format_%d", NULL,
12451 (int) ffelab_value (label)),
12452 build_type_variant (build_array_type
12453 (char_type_node,
12454 NULL_TREE),
12455 1, 0));
12456 TREE_CONSTANT (glabel) = 1;
12457 TREE_STATIC (glabel) = 1;
12458 DECL_CONTEXT (glabel) = 0;
12459 DECL_INITIAL (glabel) = NULL;
12460 make_decl_rtl (glabel, NULL, 0);
12461 expand_decl (glabel);
5ff904cd 12462
c7e4ee3a
CB
12463 resume_temporary_allocation ();
12464 pop_obstacks ();
5ff904cd 12465
c7e4ee3a 12466 break;
5ff904cd 12467
c7e4ee3a
CB
12468 case FFELAB_typeANY:
12469 glabel = error_mark_node;
12470 break;
5ff904cd 12471
c7e4ee3a
CB
12472 default:
12473 assert ("bad label type" == NULL);
12474 glabel = NULL;
12475 break;
12476 }
12477 ffelab_set_hook (label, glabel);
12478 }
12479 else
12480 {
12481 glabel = ffelab_hook (label);
12482 }
5ff904cd 12483
c7e4ee3a
CB
12484 return glabel;
12485}
5ff904cd 12486
c7e4ee3a
CB
12487#endif
12488/* Stabilizes the arguments. Don't use this if the lhs and rhs come from
12489 a single source specification (as in the fourth argument of MVBITS).
12490 If the type is NULL_TREE, the type of lhs is used to make the type of
12491 the MODIFY_EXPR. */
5ff904cd 12492
c7e4ee3a
CB
12493#if FFECOM_targetCURRENT == FFECOM_targetGCC
12494tree
12495ffecom_modify (tree newtype, tree lhs,
12496 tree rhs)
12497{
12498 if (lhs == error_mark_node || rhs == error_mark_node)
12499 return error_mark_node;
5ff904cd 12500
c7e4ee3a
CB
12501 if (newtype == NULL_TREE)
12502 newtype = TREE_TYPE (lhs);
5ff904cd 12503
c7e4ee3a
CB
12504 if (TREE_SIDE_EFFECTS (lhs))
12505 lhs = stabilize_reference (lhs);
5ff904cd 12506
c7e4ee3a
CB
12507 return ffecom_2s (MODIFY_EXPR, newtype, lhs, rhs);
12508}
5ff904cd 12509
c7e4ee3a 12510#endif
5ff904cd 12511
c7e4ee3a 12512/* Register source file name. */
5ff904cd 12513
c7e4ee3a
CB
12514void
12515ffecom_file (char *name)
12516{
12517#if FFECOM_GCC_INCLUDE
12518 ffecom_file_ (name);
12519#endif
12520}
5ff904cd 12521
c7e4ee3a 12522/* ffecom_notify_init_storage -- An aggregate storage is now fully init'ed
5ff904cd 12523
c7e4ee3a
CB
12524 ffestorag st;
12525 ffecom_notify_init_storage(st);
5ff904cd 12526
c7e4ee3a
CB
12527 Gets called when all possible units in an aggregate storage area (a LOCAL
12528 with equivalences or a COMMON) have been initialized. The initialization
12529 info either is in ffestorag_init or, if that is NULL,
12530 ffestorag_accretion:
5ff904cd 12531
c7e4ee3a
CB
12532 ffestorag_init may contain an opCONTER or opARRTER. opCONTER may occur
12533 even for an array if the array is one element in length!
5ff904cd 12534
c7e4ee3a
CB
12535 ffestorag_accretion will contain an opACCTER. It is much like an
12536 opARRTER except it has an ffebit object in it instead of just a size.
12537 The back end can use the info in the ffebit object, if it wants, to
12538 reduce the amount of actual initialization, but in any case it should
12539 kill the ffebit object when done. Also, set accretion to NULL but
12540 init to a non-NULL value.
5ff904cd 12541
c7e4ee3a
CB
12542 After performing initialization, DO NOT set init to NULL, because that'll
12543 tell the front end it is ok for more initialization to happen. Instead,
12544 set init to an opANY expression or some such thing that you can use to
12545 tell that you've already initialized the object.
5ff904cd 12546
c7e4ee3a
CB
12547 27-Oct-91 JCB 1.1
12548 Support two-pass FFE. */
5ff904cd 12549
c7e4ee3a
CB
12550void
12551ffecom_notify_init_storage (ffestorag st)
12552{
12553 ffebld init; /* The initialization expression. */
12554#if 0 && FFECOM_targetCURRENT == FFECOM_targetGCC
12555 ffetargetOffset size; /* The size of the entity. */
12556 ffetargetAlign pad; /* Its initial padding. */
12557#endif
12558
12559 if (ffestorag_init (st) == NULL)
5ff904cd 12560 {
c7e4ee3a
CB
12561 init = ffestorag_accretion (st);
12562 assert (init != NULL);
12563 ffestorag_set_accretion (st, NULL);
12564 ffestorag_set_accretes (st, 0);
12565
12566#if 0 && FFECOM_targetCURRENT == FFECOM_targetGCC
12567 /* For GNU backend, just turn ACCTER into ARRTER and proceed. */
12568 size = ffebld_accter_size (init);
12569 pad = ffebld_accter_pad (init);
12570 ffebit_kill (ffebld_accter_bits (init));
12571 ffebld_set_op (init, FFEBLD_opARRTER);
12572 ffebld_set_arrter (init, ffebld_accter (init));
12573 ffebld_arrter_set_size (init, size);
12574 ffebld_arrter_set_pad (init, size);
12575#endif
12576
12577#if FFECOM_TWOPASS
12578 ffestorag_set_init (st, init);
12579#endif
5ff904cd 12580 }
c7e4ee3a
CB
12581#if FFECOM_ONEPASS
12582 else
12583 init = ffestorag_init (st);
5ff904cd
JL
12584#endif
12585
c7e4ee3a
CB
12586#if FFECOM_ONEPASS /* Process the inits, wipe 'em out. */
12587 ffestorag_set_init (st, ffebld_new_any ());
5ff904cd 12588
c7e4ee3a
CB
12589 if (ffebld_op (init) == FFEBLD_opANY)
12590 return; /* Oh, we already did this! */
5ff904cd 12591
c7e4ee3a
CB
12592#if FFECOM_targetCURRENT == FFECOM_targetFFE
12593 {
12594 ffesymbol s;
5ff904cd 12595
c7e4ee3a
CB
12596 if (ffestorag_symbol (st) != NULL)
12597 s = ffestorag_symbol (st);
12598 else
12599 s = ffestorag_typesymbol (st);
5ff904cd 12600
c7e4ee3a
CB
12601 fprintf (dmpout, "= initialize_storage \"%s\" ",
12602 (s != NULL) ? ffesymbol_text (s) : "(unnamed)");
12603 ffebld_dump (init);
12604 fputc ('\n', dmpout);
12605 }
12606#endif
5ff904cd 12607
c7e4ee3a
CB
12608#endif /* if FFECOM_ONEPASS */
12609}
5ff904cd 12610
c7e4ee3a 12611/* ffecom_notify_init_symbol -- A symbol is now fully init'ed
5ff904cd 12612
c7e4ee3a
CB
12613 ffesymbol s;
12614 ffecom_notify_init_symbol(s);
5ff904cd 12615
c7e4ee3a
CB
12616 Gets called when all possible units in a symbol (not placed in COMMON
12617 or involved in EQUIVALENCE, unless it as yet has no ffestorag object)
12618 have been initialized. The initialization info either is in
12619 ffesymbol_init or, if that is NULL, ffesymbol_accretion:
5ff904cd 12620
c7e4ee3a
CB
12621 ffesymbol_init may contain an opCONTER or opARRTER. opCONTER may occur
12622 even for an array if the array is one element in length!
5ff904cd 12623
c7e4ee3a
CB
12624 ffesymbol_accretion will contain an opACCTER. It is much like an
12625 opARRTER except it has an ffebit object in it instead of just a size.
12626 The back end can use the info in the ffebit object, if it wants, to
12627 reduce the amount of actual initialization, but in any case it should
12628 kill the ffebit object when done. Also, set accretion to NULL but
12629 init to a non-NULL value.
5ff904cd 12630
c7e4ee3a
CB
12631 After performing initialization, DO NOT set init to NULL, because that'll
12632 tell the front end it is ok for more initialization to happen. Instead,
12633 set init to an opANY expression or some such thing that you can use to
12634 tell that you've already initialized the object.
5ff904cd 12635
c7e4ee3a
CB
12636 27-Oct-91 JCB 1.1
12637 Support two-pass FFE. */
5ff904cd 12638
c7e4ee3a
CB
12639void
12640ffecom_notify_init_symbol (ffesymbol s)
12641{
12642 ffebld init; /* The initialization expression. */
12643#if 0 && FFECOM_targetCURRENT == FFECOM_targetGCC
12644 ffetargetOffset size; /* The size of the entity. */
12645 ffetargetAlign pad; /* Its initial padding. */
12646#endif
5ff904cd 12647
c7e4ee3a
CB
12648 if (ffesymbol_storage (s) == NULL)
12649 return; /* Do nothing until COMMON/EQUIVALENCE
12650 possibilities checked. */
5ff904cd 12651
c7e4ee3a
CB
12652 if ((ffesymbol_init (s) == NULL)
12653 && ((init = ffesymbol_accretion (s)) != NULL))
12654 {
12655 ffesymbol_set_accretion (s, NULL);
12656 ffesymbol_set_accretes (s, 0);
5ff904cd 12657
c7e4ee3a
CB
12658#if 0 && FFECOM_targetCURRENT == FFECOM_targetGCC
12659 /* For GNU backend, just turn ACCTER into ARRTER and proceed. */
12660 size = ffebld_accter_size (init);
12661 pad = ffebld_accter_pad (init);
12662 ffebit_kill (ffebld_accter_bits (init));
12663 ffebld_set_op (init, FFEBLD_opARRTER);
12664 ffebld_set_arrter (init, ffebld_accter (init));
12665 ffebld_arrter_set_size (init, size);
12666 ffebld_arrter_set_pad (init, size);
12667#endif
5ff904cd 12668
c7e4ee3a
CB
12669#if FFECOM_TWOPASS
12670 ffesymbol_set_init (s, init);
12671#endif
12672 }
12673#if FFECOM_ONEPASS
12674 else
12675 init = ffesymbol_init (s);
12676#endif
5ff904cd 12677
c7e4ee3a
CB
12678#if FFECOM_ONEPASS
12679 ffesymbol_set_init (s, ffebld_new_any ());
5ff904cd 12680
c7e4ee3a
CB
12681 if (ffebld_op (init) == FFEBLD_opANY)
12682 return; /* Oh, we already did this! */
5ff904cd 12683
c7e4ee3a
CB
12684#if FFECOM_targetCURRENT == FFECOM_targetFFE
12685 fprintf (dmpout, "= initialize_symbol \"%s\" ", ffesymbol_text (s));
12686 ffebld_dump (init);
12687 fputc ('\n', dmpout);
12688#endif
5ff904cd 12689
c7e4ee3a
CB
12690#endif /* if FFECOM_ONEPASS */
12691}
5ff904cd 12692
c7e4ee3a 12693/* ffecom_notify_primary_entry -- Learn which is the primary entry point
5ff904cd 12694
c7e4ee3a
CB
12695 ffesymbol s;
12696 ffecom_notify_primary_entry(s);
5ff904cd 12697
c7e4ee3a
CB
12698 Gets called when implicit or explicit PROGRAM statement seen or when
12699 FUNCTION, SUBROUTINE, or BLOCK DATA statement seen, with the primary
12700 global symbol that serves as the entry point. */
5ff904cd 12701
c7e4ee3a
CB
12702void
12703ffecom_notify_primary_entry (ffesymbol s)
12704{
12705 ffecom_primary_entry_ = s;
12706 ffecom_primary_entry_kind_ = ffesymbol_kind (s);
5ff904cd 12707
c7e4ee3a
CB
12708 if ((ffecom_primary_entry_kind_ == FFEINFO_kindFUNCTION)
12709 || (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE))
12710 ffecom_primary_entry_is_proc_ = TRUE;
12711 else
12712 ffecom_primary_entry_is_proc_ = FALSE;
5ff904cd 12713
c7e4ee3a
CB
12714 if (!ffe_is_silent ())
12715 {
12716 if (ffecom_primary_entry_kind_ == FFEINFO_kindPROGRAM)
12717 fprintf (stderr, "%s:\n", ffesymbol_text (s));
12718 else
12719 fprintf (stderr, " %s:\n", ffesymbol_text (s));
12720 }
5ff904cd 12721
c7e4ee3a
CB
12722#if FFECOM_targetCURRENT == FFECOM_targetGCC
12723 if (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE)
12724 {
12725 ffebld list;
12726 ffebld arg;
5ff904cd 12727
c7e4ee3a
CB
12728 for (list = ffesymbol_dummyargs (s);
12729 list != NULL;
12730 list = ffebld_trail (list))
12731 {
12732 arg = ffebld_head (list);
12733 if (ffebld_op (arg) == FFEBLD_opSTAR)
12734 {
12735 ffecom_is_altreturning_ = TRUE;
12736 break;
12737 }
12738 }
12739 }
12740#endif
12741}
5ff904cd 12742
c7e4ee3a
CB
12743FILE *
12744ffecom_open_include (char *name, ffewhereLine l, ffewhereColumn c)
12745{
12746#if FFECOM_GCC_INCLUDE
12747 return ffecom_open_include_ (name, l, c);
12748#else
12749 return fopen (name, "r");
5ff904cd 12750#endif
c7e4ee3a 12751}
5ff904cd 12752
c7e4ee3a 12753/* ffecom_ptr_to_expr -- Transform expr into gcc tree with & in front
5ff904cd 12754
c7e4ee3a
CB
12755 tree t;
12756 ffebld expr; // FFE expression.
12757 tree = ffecom_ptr_to_expr(expr);
5ff904cd 12758
c7e4ee3a 12759 Like ffecom_expr, but sticks address-of in front of most things. */
5ff904cd 12760
c7e4ee3a
CB
12761#if FFECOM_targetCURRENT == FFECOM_targetGCC
12762tree
12763ffecom_ptr_to_expr (ffebld expr)
12764{
12765 tree item;
12766 ffeinfoBasictype bt;
12767 ffeinfoKindtype kt;
12768 ffesymbol s;
5ff904cd 12769
c7e4ee3a 12770 assert (expr != NULL);
5ff904cd 12771
c7e4ee3a
CB
12772 switch (ffebld_op (expr))
12773 {
12774 case FFEBLD_opSYMTER:
12775 s = ffebld_symter (expr);
12776 if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC)
12777 {
12778 ffecomGfrt ix;
5ff904cd 12779
c7e4ee3a
CB
12780 ix = ffeintrin_gfrt_indirect (ffebld_symter_implementation (expr));
12781 assert (ix != FFECOM_gfrt);
12782 if ((item = ffecom_gfrt_[ix]) == NULL_TREE)
12783 {
12784 ffecom_make_gfrt_ (ix);
12785 item = ffecom_gfrt_[ix];
12786 }
12787 }
12788 else
12789 {
12790 item = ffesymbol_hook (s).decl_tree;
12791 if (item == NULL_TREE)
12792 {
12793 s = ffecom_sym_transform_ (s);
12794 item = ffesymbol_hook (s).decl_tree;
12795 }
12796 }
12797 assert (item != NULL);
12798 if (item == error_mark_node)
12799 return item;
12800 if (!ffesymbol_hook (s).addr)
12801 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12802 item);
12803 return item;
5ff904cd 12804
c7e4ee3a 12805 case FFEBLD_opARRAYREF:
ff852b44 12806 return ffecom_arrayref_ (NULL_TREE, expr, 1);
5ff904cd 12807
c7e4ee3a 12808 case FFEBLD_opCONTER:
5ff904cd 12809
c7e4ee3a
CB
12810 bt = ffeinfo_basictype (ffebld_info (expr));
12811 kt = ffeinfo_kindtype (ffebld_info (expr));
5ff904cd 12812
c7e4ee3a
CB
12813 item = ffecom_constantunion (&ffebld_constant_union
12814 (ffebld_conter (expr)), bt, kt,
12815 ffecom_tree_type[bt][kt]);
12816 if (item == error_mark_node)
12817 return error_mark_node;
12818 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12819 item);
12820 return item;
5ff904cd 12821
c7e4ee3a
CB
12822 case FFEBLD_opANY:
12823 return error_mark_node;
5ff904cd 12824
c7e4ee3a
CB
12825 default:
12826 bt = ffeinfo_basictype (ffebld_info (expr));
12827 kt = ffeinfo_kindtype (ffebld_info (expr));
12828
12829 item = ffecom_expr (expr);
12830 if (item == error_mark_node)
12831 return error_mark_node;
12832
12833 /* The back end currently optimizes a bit too zealously for us, in that
12834 we fail JCB001 if the following block of code is omitted. It checks
12835 to see if the transformed expression is a symbol or array reference,
12836 and encloses it in a SAVE_EXPR if that is the case. */
12837
12838 STRIP_NOPS (item);
12839 if ((TREE_CODE (item) == VAR_DECL)
12840 || (TREE_CODE (item) == PARM_DECL)
12841 || (TREE_CODE (item) == RESULT_DECL)
12842 || (TREE_CODE (item) == INDIRECT_REF)
12843 || (TREE_CODE (item) == ARRAY_REF)
12844 || (TREE_CODE (item) == COMPONENT_REF)
12845#ifdef OFFSET_REF
12846 || (TREE_CODE (item) == OFFSET_REF)
12847#endif
12848 || (TREE_CODE (item) == BUFFER_REF)
12849 || (TREE_CODE (item) == REALPART_EXPR)
12850 || (TREE_CODE (item) == IMAGPART_EXPR))
12851 {
12852 item = ffecom_save_tree (item);
12853 }
12854
12855 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12856 item);
12857 return item;
12858 }
12859
12860 assert ("fall-through error" == NULL);
12861 return error_mark_node;
5ff904cd
JL
12862}
12863
12864#endif
c7e4ee3a 12865/* Obtain a temp var with given data type.
5ff904cd 12866
c7e4ee3a
CB
12867 size is FFETARGET_charactersizeNONE for a non-CHARACTER type
12868 or >= 0 for a CHARACTER type.
5ff904cd 12869
c7e4ee3a 12870 elements is -1 for a scalar or > 0 for an array of type. */
5ff904cd
JL
12871
12872#if FFECOM_targetCURRENT == FFECOM_targetGCC
12873tree
c7e4ee3a
CB
12874ffecom_make_tempvar (const char *commentary, tree type,
12875 ffetargetCharacterSize size, int elements)
5ff904cd 12876{
c7e4ee3a
CB
12877 int yes;
12878 tree t;
12879 static int mynumber;
5ff904cd 12880
c7e4ee3a 12881 assert (current_binding_level->prep_state < 2);
702edf1d 12882
c7e4ee3a
CB
12883 if (type == error_mark_node)
12884 return error_mark_node;
702edf1d 12885
c7e4ee3a 12886 yes = suspend_momentary ();
5ff904cd 12887
c7e4ee3a
CB
12888 if (size != FFETARGET_charactersizeNONE)
12889 type = build_array_type (type,
12890 build_range_type (ffecom_f2c_ftnlen_type_node,
12891 ffecom_f2c_ftnlen_one_node,
12892 build_int_2 (size, 0)));
12893 if (elements != -1)
12894 type = build_array_type (type,
12895 build_range_type (integer_type_node,
12896 integer_zero_node,
12897 build_int_2 (elements - 1,
12898 0)));
12899 t = build_decl (VAR_DECL,
12900 ffecom_get_invented_identifier ("__g77_%s_%d",
12901 commentary,
12902 mynumber++),
12903 type);
5ff904cd 12904
c7e4ee3a
CB
12905 t = start_decl (t, FALSE);
12906 finish_decl (t, NULL_TREE, FALSE);
12907
12908 resume_momentary (yes);
5ff904cd 12909
c7e4ee3a
CB
12910 return t;
12911}
5ff904cd 12912#endif
5ff904cd 12913
c7e4ee3a 12914/* Prepare argument pointer to expression.
5ff904cd 12915
c7e4ee3a
CB
12916 Like ffecom_prepare_expr, except for expressions to be evaluated
12917 via ffecom_arg_ptr_to_expr. */
5ff904cd 12918
c7e4ee3a
CB
12919void
12920ffecom_prepare_arg_ptr_to_expr (ffebld expr)
5ff904cd 12921{
c7e4ee3a
CB
12922 /* ~~For now, it seems to be the same thing. */
12923 ffecom_prepare_expr (expr);
12924 return;
12925}
702edf1d 12926
c7e4ee3a 12927/* End of preparations. */
702edf1d 12928
c7e4ee3a
CB
12929bool
12930ffecom_prepare_end (void)
12931{
12932 int prep_state = current_binding_level->prep_state;
5ff904cd 12933
c7e4ee3a
CB
12934 assert (prep_state < 2);
12935 current_binding_level->prep_state = 2;
5ff904cd 12936
c7e4ee3a 12937 return (prep_state == 1) ? TRUE : FALSE;
5ff904cd
JL
12938}
12939
c7e4ee3a 12940/* Prepare expression.
5ff904cd 12941
c7e4ee3a
CB
12942 This is called before any code is generated for the current block.
12943 It scans the expression, declares any temporaries that might be needed
12944 during evaluation of the expression, and stores those temporaries in
12945 the appropriate "hook" fields of the expression. `dest', if not NULL,
12946 specifies the destination that ffecom_expr_ will see, in case that
12947 helps avoid generating unused temporaries.
12948
12949 ~~Improve to avoid allocating unused temporaries by taking `dest'
12950 into account vis-a-vis aliasing requirements of complex/character
12951 functions. */
12952
12953void
12954ffecom_prepare_expr_ (ffebld expr, ffebld dest UNUSED)
5ff904cd 12955{
c7e4ee3a
CB
12956 ffeinfoBasictype bt;
12957 ffeinfoKindtype kt;
12958 ffetargetCharacterSize sz;
12959 tree tempvar = NULL_TREE;
5ff904cd 12960
c7e4ee3a
CB
12961 assert (current_binding_level->prep_state < 2);
12962
12963 if (! expr)
12964 return;
12965
12966 bt = ffeinfo_basictype (ffebld_info (expr));
12967 kt = ffeinfo_kindtype (ffebld_info (expr));
12968 sz = ffeinfo_size (ffebld_info (expr));
12969
12970 /* Generate whatever temporaries are needed to represent the result
12971 of the expression. */
12972
47d98fa2
CB
12973 if (bt == FFEINFO_basictypeCHARACTER)
12974 {
12975 while (ffebld_op (expr) == FFEBLD_opPAREN)
12976 expr = ffebld_left (expr);
12977 }
12978
c7e4ee3a 12979 switch (ffebld_op (expr))
5ff904cd 12980 {
c7e4ee3a
CB
12981 default:
12982 /* Don't make temps for SYMTER, CONTER, etc. */
12983 if (ffebld_arity (expr) == 0)
12984 break;
5ff904cd 12985
c7e4ee3a 12986 switch (bt)
5ff904cd 12987 {
c7e4ee3a
CB
12988 case FFEINFO_basictypeCOMPLEX:
12989 if (ffebld_op (expr) == FFEBLD_opFUNCREF)
12990 {
12991 ffesymbol s;
5ff904cd 12992
c7e4ee3a
CB
12993 if (ffebld_op (ffebld_left (expr)) != FFEBLD_opSYMTER)
12994 break;
5ff904cd 12995
c7e4ee3a
CB
12996 s = ffebld_symter (ffebld_left (expr));
12997 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT
68779408
CB
12998 || (ffesymbol_where (s) != FFEINFO_whereINTRINSIC
12999 && ! ffesymbol_is_f2c (s))
13000 || (ffesymbol_where (s) == FFEINFO_whereINTRINSIC
13001 && ! ffe_is_f2c_library ()))
c7e4ee3a
CB
13002 break;
13003 }
13004 else if (ffebld_op (expr) == FFEBLD_opPOWER)
13005 {
13006 /* Requires special treatment. There's no POW_CC function
13007 in libg2c, so POW_ZZ is used, which means we always
13008 need a double-complex temp, not a single-complex. */
13009 kt = FFEINFO_kindtypeREAL2;
13010 }
13011 else if (ffebld_op (expr) != FFEBLD_opDIVIDE)
13012 /* The other ops don't need temps for complex operands. */
13013 break;
5ff904cd 13014
c7e4ee3a
CB
13015 /* ~~~Avoid making temps for some intrinsics, such as AIMAG(C),
13016 REAL(C). See 19990325-0.f, routine `check', for cases. */
13017 tempvar = ffecom_make_tempvar ("complex",
13018 ffecom_tree_type
13019 [FFEINFO_basictypeCOMPLEX][kt],
13020 FFETARGET_charactersizeNONE,
13021 -1);
5ff904cd
JL
13022 break;
13023
c7e4ee3a
CB
13024 case FFEINFO_basictypeCHARACTER:
13025 if (ffebld_op (expr) != FFEBLD_opFUNCREF)
13026 break;
13027
13028 if (sz == FFETARGET_charactersizeNONE)
13029 /* ~~Kludge alert! This should someday be fixed. */
13030 sz = 24;
13031
13032 tempvar = ffecom_make_tempvar ("char", char_type_node, sz, -1);
5ff904cd
JL
13033 break;
13034
13035 default:
5ff904cd
JL
13036 break;
13037 }
c7e4ee3a 13038 break;
5ff904cd 13039
c7e4ee3a
CB
13040#ifdef HAHA
13041 case FFEBLD_opPOWER:
13042 {
13043 tree rtype, ltype;
13044 tree rtmp, ltmp, result;
5ff904cd 13045
c7e4ee3a
CB
13046 ltype = ffecom_type_expr (ffebld_left (expr));
13047 rtype = ffecom_type_expr (ffebld_right (expr));
5ff904cd 13048
c7e4ee3a
CB
13049 rtmp = ffecom_make_tempvar (rtype, FFETARGET_charactersizeNONE, -1);
13050 ltmp = ffecom_make_tempvar (ltype, FFETARGET_charactersizeNONE, -1);
13051 result = ffecom_make_tempvar (ltype, FFETARGET_charactersizeNONE, -1);
5ff904cd 13052
c7e4ee3a
CB
13053 tempvar = make_tree_vec (3);
13054 TREE_VEC_ELT (tempvar, 0) = rtmp;
13055 TREE_VEC_ELT (tempvar, 1) = ltmp;
13056 TREE_VEC_ELT (tempvar, 2) = result;
13057 }
13058 break;
13059#endif /* HAHA */
5ff904cd 13060
c7e4ee3a
CB
13061 case FFEBLD_opCONCATENATE:
13062 {
13063 /* This gets special handling, because only one set of temps
13064 is needed for a tree of these -- the tree is treated as
13065 a flattened list of concatenations when generating code. */
5ff904cd 13066
c7e4ee3a
CB
13067 ffecomConcatList_ catlist;
13068 tree ltmp, itmp, result;
13069 int count;
13070 int i;
5ff904cd 13071
c7e4ee3a
CB
13072 catlist = ffecom_concat_list_new_ (expr, FFETARGET_charactersizeNONE);
13073 count = ffecom_concat_list_count_ (catlist);
5ff904cd 13074
c7e4ee3a
CB
13075 if (count >= 2)
13076 {
13077 ltmp
13078 = ffecom_make_tempvar ("concat_len",
13079 ffecom_f2c_ftnlen_type_node,
13080 FFETARGET_charactersizeNONE, count);
13081 itmp
13082 = ffecom_make_tempvar ("concat_item",
13083 ffecom_f2c_address_type_node,
13084 FFETARGET_charactersizeNONE, count);
13085 result
13086 = ffecom_make_tempvar ("concat_res",
13087 char_type_node,
13088 ffecom_concat_list_maxlen_ (catlist),
13089 -1);
13090
13091 tempvar = make_tree_vec (3);
13092 TREE_VEC_ELT (tempvar, 0) = ltmp;
13093 TREE_VEC_ELT (tempvar, 1) = itmp;
13094 TREE_VEC_ELT (tempvar, 2) = result;
13095 }
5ff904cd 13096
c7e4ee3a
CB
13097 for (i = 0; i < count; ++i)
13098 ffecom_prepare_arg_ptr_to_expr (ffecom_concat_list_expr_ (catlist,
13099 i));
5ff904cd 13100
c7e4ee3a 13101 ffecom_concat_list_kill_ (catlist);
5ff904cd 13102
c7e4ee3a
CB
13103 if (tempvar)
13104 {
13105 ffebld_nonter_set_hook (expr, tempvar);
13106 current_binding_level->prep_state = 1;
13107 }
13108 }
13109 return;
5ff904cd 13110
c7e4ee3a
CB
13111 case FFEBLD_opCONVERT:
13112 if (bt == FFEINFO_basictypeCHARACTER
13113 && ((ffebld_size_known (ffebld_left (expr))
13114 == FFETARGET_charactersizeNONE)
13115 || (ffebld_size_known (ffebld_left (expr)) >= sz)))
13116 tempvar = ffecom_make_tempvar ("convert", char_type_node, sz, -1);
13117 break;
13118 }
5ff904cd 13119
c7e4ee3a
CB
13120 if (tempvar)
13121 {
13122 ffebld_nonter_set_hook (expr, tempvar);
13123 current_binding_level->prep_state = 1;
13124 }
5ff904cd 13125
c7e4ee3a 13126 /* Prepare subexpressions for this expr. */
5ff904cd 13127
c7e4ee3a 13128 switch (ffebld_op (expr))
5ff904cd 13129 {
c7e4ee3a
CB
13130 case FFEBLD_opPERCENT_LOC:
13131 ffecom_prepare_ptr_to_expr (ffebld_left (expr));
13132 break;
5ff904cd 13133
c7e4ee3a
CB
13134 case FFEBLD_opPERCENT_VAL:
13135 case FFEBLD_opPERCENT_REF:
13136 ffecom_prepare_expr (ffebld_left (expr));
13137 break;
5ff904cd 13138
c7e4ee3a
CB
13139 case FFEBLD_opPERCENT_DESCR:
13140 ffecom_prepare_arg_ptr_to_expr (ffebld_left (expr));
13141 break;
5ff904cd 13142
c7e4ee3a
CB
13143 case FFEBLD_opITEM:
13144 {
13145 ffebld item;
5ff904cd 13146
c7e4ee3a
CB
13147 for (item = expr;
13148 item != NULL;
13149 item = ffebld_trail (item))
13150 if (ffebld_head (item) != NULL)
13151 ffecom_prepare_expr (ffebld_head (item));
13152 }
13153 break;
5ff904cd 13154
c7e4ee3a
CB
13155 default:
13156 /* Need to handle character conversion specially. */
13157 switch (ffebld_arity (expr))
13158 {
13159 case 2:
13160 ffecom_prepare_expr (ffebld_left (expr));
13161 ffecom_prepare_expr (ffebld_right (expr));
13162 break;
5ff904cd 13163
c7e4ee3a
CB
13164 case 1:
13165 ffecom_prepare_expr (ffebld_left (expr));
13166 break;
5ff904cd 13167
c7e4ee3a
CB
13168 default:
13169 break;
13170 }
13171 }
5ff904cd 13172
c7e4ee3a 13173 return;
5ff904cd
JL
13174}
13175
c7e4ee3a 13176/* Prepare expression for reading and writing.
5ff904cd 13177
c7e4ee3a
CB
13178 Like ffecom_prepare_expr, except for expressions to be evaluated
13179 via ffecom_expr_rw. */
5ff904cd 13180
c7e4ee3a
CB
13181void
13182ffecom_prepare_expr_rw (tree type, ffebld expr)
13183{
13184 /* This is all we support for now. */
13185 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
5ff904cd 13186
c7e4ee3a
CB
13187 /* ~~For now, it seems to be the same thing. */
13188 ffecom_prepare_expr (expr);
13189 return;
13190}
5ff904cd 13191
c7e4ee3a 13192/* Prepare expression for writing.
5ff904cd 13193
c7e4ee3a
CB
13194 Like ffecom_prepare_expr, except for expressions to be evaluated
13195 via ffecom_expr_w. */
5ff904cd
JL
13196
13197void
c7e4ee3a 13198ffecom_prepare_expr_w (tree type, ffebld expr)
5ff904cd 13199{
c7e4ee3a
CB
13200 /* This is all we support for now. */
13201 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
5ff904cd 13202
c7e4ee3a
CB
13203 /* ~~For now, it seems to be the same thing. */
13204 ffecom_prepare_expr (expr);
13205 return;
13206}
5ff904cd 13207
c7e4ee3a 13208/* Prepare expression for returning.
5ff904cd 13209
c7e4ee3a
CB
13210 Like ffecom_prepare_expr, except for expressions to be evaluated
13211 via ffecom_return_expr. */
5ff904cd 13212
c7e4ee3a
CB
13213void
13214ffecom_prepare_return_expr (ffebld expr)
13215{
13216 assert (current_binding_level->prep_state < 2);
5ff904cd 13217
c7e4ee3a
CB
13218 if (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE
13219 && ffecom_is_altreturning_
13220 && expr != NULL)
13221 ffecom_prepare_expr (expr);
13222}
5ff904cd 13223
c7e4ee3a 13224/* Prepare pointer to expression.
5ff904cd 13225
c7e4ee3a
CB
13226 Like ffecom_prepare_expr, except for expressions to be evaluated
13227 via ffecom_ptr_to_expr. */
5ff904cd 13228
c7e4ee3a
CB
13229void
13230ffecom_prepare_ptr_to_expr (ffebld expr)
13231{
13232 /* ~~For now, it seems to be the same thing. */
13233 ffecom_prepare_expr (expr);
13234 return;
5ff904cd
JL
13235}
13236
c7e4ee3a 13237/* Transform expression into constant pointer-to-expression tree.
5ff904cd 13238
c7e4ee3a
CB
13239 If the expression can be transformed into a pointer-to-expression tree
13240 that is constant, that is done, and the tree returned. Else NULL_TREE
13241 is returned.
5ff904cd 13242
c7e4ee3a
CB
13243 That way, a caller can attempt to provide compile-time initialization
13244 of a variable and, if that fails, *then* choose to start a new block
13245 and resort to using temporaries, as appropriate. */
5ff904cd 13246
c7e4ee3a
CB
13247tree
13248ffecom_ptr_to_const_expr (ffebld expr)
5ff904cd 13249{
c7e4ee3a
CB
13250 if (! expr)
13251 return integer_zero_node;
5ff904cd 13252
c7e4ee3a
CB
13253 if (ffebld_op (expr) == FFEBLD_opANY)
13254 return error_mark_node;
5ff904cd 13255
c7e4ee3a
CB
13256 if (ffebld_arity (expr) == 0
13257 && (ffebld_op (expr) != FFEBLD_opSYMTER
13258 || ffebld_where (expr) == FFEINFO_whereCOMMON
13259 || ffebld_where (expr) == FFEINFO_whereGLOBAL
13260 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
5ff904cd 13261 {
c7e4ee3a
CB
13262 tree t;
13263
13264 t = ffecom_ptr_to_expr (expr);
13265 assert (TREE_CONSTANT (t));
13266 return t;
5ff904cd
JL
13267 }
13268
c7e4ee3a
CB
13269 return NULL_TREE;
13270}
13271
13272/* ffecom_return_expr -- Returns return-value expr given alt return expr
13273
13274 tree rtn; // NULL_TREE means use expand_null_return()
13275 ffebld expr; // NULL if no alt return expr to RETURN stmt
13276 rtn = ffecom_return_expr(expr);
13277
13278 Based on the program unit type and other info (like return function
13279 type, return master function type when alternate ENTRY points,
13280 whether subroutine has any alternate RETURN points, etc), returns the
13281 appropriate expression to be returned to the caller, or NULL_TREE
13282 meaning no return value or the caller expects it to be returned somewhere
13283 else (which is handled by other parts of this module). */
13284
5ff904cd 13285#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
13286tree
13287ffecom_return_expr (ffebld expr)
13288{
13289 tree rtn;
13290
13291 switch (ffecom_primary_entry_kind_)
5ff904cd 13292 {
c7e4ee3a
CB
13293 case FFEINFO_kindPROGRAM:
13294 case FFEINFO_kindBLOCKDATA:
13295 rtn = NULL_TREE;
13296 break;
5ff904cd 13297
c7e4ee3a
CB
13298 case FFEINFO_kindSUBROUTINE:
13299 if (!ffecom_is_altreturning_)
13300 rtn = NULL_TREE; /* No alt returns, never an expr. */
13301 else if (expr == NULL)
13302 rtn = integer_zero_node;
13303 else
13304 rtn = ffecom_expr (expr);
13305 break;
13306
13307 case FFEINFO_kindFUNCTION:
13308 if ((ffecom_multi_retval_ != NULL_TREE)
13309 || (ffesymbol_basictype (ffecom_primary_entry_)
13310 == FFEINFO_basictypeCHARACTER)
13311 || ((ffesymbol_basictype (ffecom_primary_entry_)
13312 == FFEINFO_basictypeCOMPLEX)
13313 && (ffecom_num_entrypoints_ == 0)
13314 && ffesymbol_is_f2c (ffecom_primary_entry_)))
13315 { /* Value is returned by direct assignment
13316 into (implicit) dummy. */
13317 rtn = NULL_TREE;
13318 break;
5ff904cd 13319 }
c7e4ee3a
CB
13320 rtn = ffecom_func_result_;
13321#if 0
13322 /* Spurious error if RETURN happens before first reference! So elide
13323 this code. In particular, for debugging registry, rtn should always
13324 be non-null after all, but TREE_USED won't be set until we encounter
13325 a reference in the code. Perfectly okay (but weird) code that,
13326 e.g., has "GOTO 20;10 RETURN;20 RTN=0;GOTO 10", would result in
13327 this diagnostic for no reason. Have people use -O -Wuninitialized
13328 and leave it to the back end to find obviously weird cases. */
5ff904cd 13329
c7e4ee3a
CB
13330 /* Used to "assert(rtn != NULL_TREE);" here, but it's kind of a valid
13331 situation; if the return value has never been referenced, it won't
13332 have a tree under 2pass mode. */
13333 if ((rtn == NULL_TREE)
13334 || !TREE_USED (rtn))
13335 {
13336 ffebad_start (FFEBAD_RETURN_VALUE_UNSET);
13337 ffebad_here (0, ffesymbol_where_line (ffecom_primary_entry_),
13338 ffesymbol_where_column (ffecom_primary_entry_));
13339 ffebad_string (ffesymbol_text (ffesymbol_funcresult
13340 (ffecom_primary_entry_)));
13341 ffebad_finish ();
13342 }
5ff904cd 13343#endif
c7e4ee3a 13344 break;
5ff904cd 13345
c7e4ee3a
CB
13346 default:
13347 assert ("bad unit kind" == NULL);
13348 case FFEINFO_kindANY:
13349 rtn = error_mark_node;
13350 break;
13351 }
5ff904cd 13352
c7e4ee3a
CB
13353 return rtn;
13354}
5ff904cd 13355
c7e4ee3a
CB
13356#endif
13357/* Do save_expr only if tree is not error_mark_node. */
5ff904cd
JL
13358
13359#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
13360tree
13361ffecom_save_tree (tree t)
5ff904cd 13362{
c7e4ee3a 13363 return save_expr (t);
5ff904cd 13364}
5ff904cd 13365#endif
c7e4ee3a
CB
13366
13367/* Start a compound statement (block). */
5ff904cd
JL
13368
13369#if FFECOM_targetCURRENT == FFECOM_targetGCC
13370void
c7e4ee3a 13371ffecom_start_compstmt (void)
5ff904cd 13372{
c7e4ee3a 13373 bison_rule_pushlevel_ ();
5ff904cd 13374}
c7e4ee3a 13375#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
5ff904cd 13376
c7e4ee3a 13377/* Public entry point for front end to access start_decl. */
5ff904cd
JL
13378
13379#if FFECOM_targetCURRENT == FFECOM_targetGCC
13380tree
c7e4ee3a 13381ffecom_start_decl (tree decl, bool is_initialized)
5ff904cd 13382{
c7e4ee3a
CB
13383 DECL_INITIAL (decl) = is_initialized ? error_mark_node : NULL_TREE;
13384 return start_decl (decl, FALSE);
13385}
5ff904cd 13386
c7e4ee3a
CB
13387#endif
13388/* ffecom_sym_commit -- Symbol's state being committed to reality
5ff904cd 13389
c7e4ee3a
CB
13390 ffesymbol s;
13391 ffecom_sym_commit(s);
5ff904cd 13392
c7e4ee3a
CB
13393 Does whatever the backend needs when a symbol is committed after having
13394 been backtrackable for a period of time. */
5ff904cd 13395
c7e4ee3a
CB
13396#if FFECOM_targetCURRENT == FFECOM_targetGCC
13397void
13398ffecom_sym_commit (ffesymbol s UNUSED)
13399{
13400 assert (!ffesymbol_retractable ());
13401}
5ff904cd 13402
c7e4ee3a
CB
13403#endif
13404/* ffecom_sym_end_transition -- Perform end transition on all symbols
5ff904cd 13405
c7e4ee3a 13406 ffecom_sym_end_transition();
5ff904cd 13407
c7e4ee3a
CB
13408 Does backend-specific stuff and also calls ffest_sym_end_transition
13409 to do the necessary FFE stuff.
5ff904cd 13410
c7e4ee3a
CB
13411 Backtracking is never enabled when this fn is called, so don't worry
13412 about it. */
5ff904cd 13413
c7e4ee3a
CB
13414ffesymbol
13415ffecom_sym_end_transition (ffesymbol s)
13416{
13417 ffestorag st;
5ff904cd 13418
c7e4ee3a 13419 assert (!ffesymbol_retractable ());
5ff904cd 13420
c7e4ee3a 13421 s = ffest_sym_end_transition (s);
5ff904cd 13422
c7e4ee3a
CB
13423#if FFECOM_targetCURRENT == FFECOM_targetGCC
13424 if ((ffesymbol_kind (s) == FFEINFO_kindBLOCKDATA)
13425 && (ffesymbol_where (s) == FFEINFO_whereGLOBAL))
13426 {
13427 ffecom_list_blockdata_
13428 = ffebld_new_item (ffebld_new_symter (s, FFEINTRIN_genNONE,
13429 FFEINTRIN_specNONE,
13430 FFEINTRIN_impNONE),
13431 ffecom_list_blockdata_);
5ff904cd 13432 }
5ff904cd 13433#endif
5ff904cd 13434
c7e4ee3a
CB
13435 /* This is where we finally notice that a symbol has partial initialization
13436 and finalize it. */
5ff904cd 13437
c7e4ee3a
CB
13438 if (ffesymbol_accretion (s) != NULL)
13439 {
13440 assert (ffesymbol_init (s) == NULL);
13441 ffecom_notify_init_symbol (s);
13442 }
13443 else if (((st = ffesymbol_storage (s)) != NULL)
13444 && ((st = ffestorag_parent (st)) != NULL)
13445 && (ffestorag_accretion (st) != NULL))
13446 {
13447 assert (ffestorag_init (st) == NULL);
13448 ffecom_notify_init_storage (st);
13449 }
5ff904cd
JL
13450
13451#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
13452 if ((ffesymbol_kind (s) == FFEINFO_kindCOMMON)
13453 && (ffesymbol_where (s) == FFEINFO_whereLOCAL)
13454 && (ffesymbol_storage (s) != NULL))
13455 {
13456 ffecom_list_common_
13457 = ffebld_new_item (ffebld_new_symter (s, FFEINTRIN_genNONE,
13458 FFEINTRIN_specNONE,
13459 FFEINTRIN_impNONE),
13460 ffecom_list_common_);
13461 }
13462#endif
5ff904cd 13463
c7e4ee3a
CB
13464 return s;
13465}
5ff904cd 13466
c7e4ee3a 13467/* ffecom_sym_exec_transition -- Perform exec transition on all symbols
5ff904cd 13468
c7e4ee3a 13469 ffecom_sym_exec_transition();
5ff904cd 13470
c7e4ee3a
CB
13471 Does backend-specific stuff and also calls ffest_sym_exec_transition
13472 to do the necessary FFE stuff.
5ff904cd 13473
c7e4ee3a
CB
13474 See the long-winded description in ffecom_sym_learned for info
13475 on handling the situation where backtracking is inhibited. */
5ff904cd 13476
c7e4ee3a
CB
13477ffesymbol
13478ffecom_sym_exec_transition (ffesymbol s)
13479{
13480 s = ffest_sym_exec_transition (s);
5ff904cd 13481
c7e4ee3a
CB
13482 return s;
13483}
5ff904cd 13484
c7e4ee3a 13485/* ffecom_sym_learned -- Initial or more info gained on symbol after exec
5ff904cd 13486
c7e4ee3a
CB
13487 ffesymbol s;
13488 s = ffecom_sym_learned(s);
5ff904cd 13489
c7e4ee3a
CB
13490 Called when a new symbol is seen after the exec transition or when more
13491 info (perhaps) is gained for an UNCERTAIN symbol. The symbol state when
13492 it arrives here is that all its latest info is updated already, so its
13493 state may be UNCERTAIN or UNDERSTOOD, it might already have the hook
13494 field filled in if its gone through here or exec_transition first, and
13495 so on.
5ff904cd 13496
c7e4ee3a
CB
13497 The backend probably wants to check ffesymbol_retractable() to see if
13498 backtracking is in effect. If so, the FFE's changes to the symbol may
13499 be retracted (undone) or committed (ratified), at which time the
13500 appropriate ffecom_sym_retract or _commit function will be called
13501 for that function.
5ff904cd 13502
c7e4ee3a
CB
13503 If the backend has its own backtracking mechanism, great, use it so that
13504 committal is a simple operation. Though it doesn't make much difference,
13505 I suppose: the reason for tentative symbol evolution in the FFE is to
13506 enable error detection in weird incorrect statements early and to disable
13507 incorrect error detection on a correct statement. The backend is not
13508 likely to introduce any information that'll get involved in these
13509 considerations, so it is probably just fine that the implementation
13510 model for this fn and for _exec_transition is to not do anything
13511 (besides the required FFE stuff) if ffesymbol_retractable() returns TRUE
13512 and instead wait until ffecom_sym_commit is called (which it never
13513 will be as long as we're using ambiguity-detecting statement analysis in
13514 the FFE, which we are initially to shake out the code, but don't depend
13515 on this), otherwise go ahead and do whatever is needed.
5ff904cd 13516
c7e4ee3a
CB
13517 In essence, then, when this fn and _exec_transition get called while
13518 backtracking is enabled, a general mechanism would be to flag which (or
13519 both) of these were called (and in what order? neat question as to what
13520 might happen that I'm too lame to think through right now) and then when
13521 _commit is called reproduce the original calling sequence, if any, for
13522 the two fns (at which point backtracking will, of course, be disabled). */
5ff904cd 13523
c7e4ee3a
CB
13524ffesymbol
13525ffecom_sym_learned (ffesymbol s)
13526{
13527 ffestorag_exec_layout (s);
5ff904cd 13528
c7e4ee3a 13529 return s;
5ff904cd
JL
13530}
13531
c7e4ee3a 13532/* ffecom_sym_retract -- Symbol's state being retracted from reality
5ff904cd 13533
c7e4ee3a
CB
13534 ffesymbol s;
13535 ffecom_sym_retract(s);
5ff904cd 13536
c7e4ee3a
CB
13537 Does whatever the backend needs when a symbol is retracted after having
13538 been backtrackable for a period of time. */
5ff904cd
JL
13539
13540#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
13541void
13542ffecom_sym_retract (ffesymbol s UNUSED)
5ff904cd 13543{
c7e4ee3a 13544 assert (!ffesymbol_retractable ());
5ff904cd 13545
c7e4ee3a
CB
13546#if 0 /* GCC doesn't commit any backtrackable sins,
13547 so nothing needed here. */
13548 switch (ffesymbol_hook (s).state)
5ff904cd 13549 {
c7e4ee3a 13550 case 0: /* nothing happened yet. */
5ff904cd
JL
13551 break;
13552
c7e4ee3a 13553 case 1: /* exec transition happened. */
5ff904cd
JL
13554 break;
13555
c7e4ee3a
CB
13556 case 2: /* learned happened. */
13557 break;
5ff904cd 13558
c7e4ee3a
CB
13559 case 3: /* learned then exec. */
13560 break;
13561
13562 case 4: /* exec then learned. */
5ff904cd
JL
13563 break;
13564
13565 default:
c7e4ee3a 13566 assert ("bad hook state" == NULL);
5ff904cd
JL
13567 break;
13568 }
c7e4ee3a
CB
13569#endif
13570}
5ff904cd 13571
c7e4ee3a
CB
13572#endif
13573/* Create temporary gcc label. */
13574
13575#if FFECOM_targetCURRENT == FFECOM_targetGCC
13576tree
13577ffecom_temp_label ()
13578{
13579 tree glabel;
13580 static int mynumber = 0;
13581
13582 glabel = build_decl (LABEL_DECL,
13583 ffecom_get_invented_identifier ("__g77_label_%d",
13584 NULL,
13585 mynumber++),
13586 void_type_node);
13587 DECL_CONTEXT (glabel) = current_function_decl;
13588 DECL_MODE (glabel) = VOIDmode;
13589
13590 return glabel;
5ff904cd
JL
13591}
13592
13593#endif
c7e4ee3a
CB
13594/* Return an expression that is usable as an arg in a conditional context
13595 (IF, DO WHILE, .NOT., and so on).
13596
13597 Use the one provided for the back end as of >2.6.0. */
5ff904cd
JL
13598
13599#if FFECOM_targetCURRENT == FFECOM_targetGCC
a2977d2d 13600tree
c7e4ee3a 13601ffecom_truth_value (tree expr)
5ff904cd 13602{
c7e4ee3a 13603 return truthvalue_conversion (expr);
5ff904cd 13604}
c7e4ee3a 13605
5ff904cd 13606#endif
c7e4ee3a
CB
13607/* Return the inversion of a truth value (the inversion of what
13608 ffecom_truth_value builds).
5ff904cd 13609
c7e4ee3a
CB
13610 Apparently invert_truthvalue, which is properly in the back end, is
13611 enough for now, so just use it. */
5ff904cd
JL
13612
13613#if FFECOM_targetCURRENT == FFECOM_targetGCC
13614tree
c7e4ee3a 13615ffecom_truth_value_invert (tree expr)
5ff904cd 13616{
c7e4ee3a 13617 return invert_truthvalue (ffecom_truth_value (expr));
5ff904cd
JL
13618}
13619
13620#endif
5ff904cd 13621
c7e4ee3a
CB
13622/* Return the tree that is the type of the expression, as would be
13623 returned in TREE_TYPE(ffecom_expr(expr)), without otherwise
13624 transforming the expression, generating temporaries, etc. */
5ff904cd 13625
c7e4ee3a
CB
13626tree
13627ffecom_type_expr (ffebld expr)
13628{
13629 ffeinfoBasictype bt;
13630 ffeinfoKindtype kt;
13631 tree tree_type;
13632
13633 assert (expr != NULL);
13634
13635 bt = ffeinfo_basictype (ffebld_info (expr));
13636 kt = ffeinfo_kindtype (ffebld_info (expr));
13637 tree_type = ffecom_tree_type[bt][kt];
13638
13639 switch (ffebld_op (expr))
13640 {
13641 case FFEBLD_opCONTER:
13642 case FFEBLD_opSYMTER:
13643 case FFEBLD_opARRAYREF:
13644 case FFEBLD_opUPLUS:
13645 case FFEBLD_opPAREN:
13646 case FFEBLD_opUMINUS:
13647 case FFEBLD_opADD:
13648 case FFEBLD_opSUBTRACT:
13649 case FFEBLD_opMULTIPLY:
13650 case FFEBLD_opDIVIDE:
13651 case FFEBLD_opPOWER:
13652 case FFEBLD_opNOT:
13653 case FFEBLD_opFUNCREF:
13654 case FFEBLD_opSUBRREF:
13655 case FFEBLD_opAND:
13656 case FFEBLD_opOR:
13657 case FFEBLD_opXOR:
13658 case FFEBLD_opNEQV:
13659 case FFEBLD_opEQV:
13660 case FFEBLD_opCONVERT:
13661 case FFEBLD_opLT:
13662 case FFEBLD_opLE:
13663 case FFEBLD_opEQ:
13664 case FFEBLD_opNE:
13665 case FFEBLD_opGT:
13666 case FFEBLD_opGE:
13667 case FFEBLD_opPERCENT_LOC:
13668 return tree_type;
13669
13670 case FFEBLD_opACCTER:
13671 case FFEBLD_opARRTER:
13672 case FFEBLD_opITEM:
13673 case FFEBLD_opSTAR:
13674 case FFEBLD_opBOUNDS:
13675 case FFEBLD_opREPEAT:
13676 case FFEBLD_opLABTER:
13677 case FFEBLD_opLABTOK:
13678 case FFEBLD_opIMPDO:
13679 case FFEBLD_opCONCATENATE:
13680 case FFEBLD_opSUBSTR:
13681 default:
13682 assert ("bad op for ffecom_type_expr" == NULL);
13683 /* Fall through. */
13684 case FFEBLD_opANY:
13685 return error_mark_node;
13686 }
13687}
13688
13689/* Return PARM_DECL for arg#1 of master fn containing alternate ENTRY points
13690
13691 If the PARM_DECL already exists, return it, else create it. It's an
13692 integer_type_node argument for the master function that implements a
13693 subroutine or function with more than one entrypoint and is bound at
13694 run time with the entrypoint number (0 for SUBROUTINE/FUNCTION, 1 for
13695 first ENTRY statement, and so on). */
5ff904cd
JL
13696
13697#if FFECOM_targetCURRENT == FFECOM_targetGCC
c7e4ee3a
CB
13698tree
13699ffecom_which_entrypoint_decl ()
5ff904cd 13700{
c7e4ee3a
CB
13701 assert (ffecom_which_entrypoint_decl_ != NULL_TREE);
13702
13703 return ffecom_which_entrypoint_decl_;
5ff904cd
JL
13704}
13705
13706#endif
c7e4ee3a
CB
13707\f
13708/* The following sections consists of private and public functions
13709 that have the same names and perform roughly the same functions
13710 as counterparts in the C front end. Changes in the C front end
13711 might affect how things should be done here. Only functions
13712 needed by the back end should be public here; the rest should
13713 be private (static in the C sense). Functions needed by other
13714 g77 front-end modules should be accessed by them via public
13715 ffecom_* names, which should themselves call private versions
13716 in this section so the private versions are easy to recognize
13717 when upgrading to a new gcc and finding interesting changes
13718 in the front end.
5ff904cd 13719
c7e4ee3a
CB
13720 Functions named after rule "foo:" in c-parse.y are named
13721 "bison_rule_foo_" so they are easy to find. */
5ff904cd 13722
c7e4ee3a 13723#if FFECOM_targetCURRENT == FFECOM_targetGCC
5ff904cd 13724
c7e4ee3a
CB
13725static void
13726bison_rule_pushlevel_ ()
13727{
13728 emit_line_note (input_filename, lineno);
13729 pushlevel (0);
13730 clear_last_expr ();
13731 push_momentary ();
13732 expand_start_bindings (0);
13733}
5ff904cd 13734
c7e4ee3a
CB
13735static tree
13736bison_rule_compstmt_ ()
5ff904cd 13737{
c7e4ee3a
CB
13738 tree t;
13739 int keep = kept_level_p ();
5ff904cd 13740
c7e4ee3a
CB
13741 /* Make the temps go away. */
13742 if (! keep)
13743 current_binding_level->names = NULL_TREE;
5ff904cd 13744
c7e4ee3a
CB
13745 emit_line_note (input_filename, lineno);
13746 expand_end_bindings (getdecls (), keep, 0);
13747 t = poplevel (keep, 1, 0);
13748 pop_momentary ();
5ff904cd 13749
c7e4ee3a
CB
13750 return t;
13751}
5ff904cd 13752
c7e4ee3a
CB
13753/* Return a definition for a builtin function named NAME and whose data type
13754 is TYPE. TYPE should be a function type with argument types.
13755 FUNCTION_CODE tells later passes how to compile calls to this function.
13756 See tree.h for its possible values.
5ff904cd 13757
c7e4ee3a
CB
13758 If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME,
13759 the name to be called if we can't opencode the function. */
5ff904cd 13760
c7e4ee3a
CB
13761static tree
13762builtin_function (const char *name, tree type,
13763 enum built_in_function function_code,
13764 const char *library_name)
13765{
13766 tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
13767 DECL_EXTERNAL (decl) = 1;
13768 TREE_PUBLIC (decl) = 1;
13769 if (library_name)
13770 DECL_ASSEMBLER_NAME (decl) = get_identifier (library_name);
13771 make_decl_rtl (decl, NULL_PTR, 1);
13772 pushdecl (decl);
13773 if (function_code != NOT_BUILT_IN)
5ff904cd 13774 {
c7e4ee3a
CB
13775 DECL_BUILT_IN (decl) = 1;
13776 DECL_FUNCTION_CODE (decl) = function_code;
5ff904cd 13777 }
5ff904cd 13778
c7e4ee3a 13779 return decl;
5ff904cd
JL
13780}
13781
c7e4ee3a
CB
13782/* Handle when a new declaration NEWDECL
13783 has the same name as an old one OLDDECL
13784 in the same binding contour.
13785 Prints an error message if appropriate.
5ff904cd 13786
c7e4ee3a
CB
13787 If safely possible, alter OLDDECL to look like NEWDECL, and return 1.
13788 Otherwise, return 0. */
5ff904cd 13789
c7e4ee3a
CB
13790static int
13791duplicate_decls (tree newdecl, tree olddecl)
5ff904cd 13792{
c7e4ee3a
CB
13793 int types_match = 1;
13794 int new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL
13795 && DECL_INITIAL (newdecl) != 0);
13796 tree oldtype = TREE_TYPE (olddecl);
13797 tree newtype = TREE_TYPE (newdecl);
5ff904cd 13798
c7e4ee3a
CB
13799 if (olddecl == newdecl)
13800 return 1;
5ff904cd 13801
c7e4ee3a
CB
13802 if (TREE_CODE (newtype) == ERROR_MARK
13803 || TREE_CODE (oldtype) == ERROR_MARK)
13804 types_match = 0;
5ff904cd 13805
c7e4ee3a
CB
13806 /* New decl is completely inconsistent with the old one =>
13807 tell caller to replace the old one.
13808 This is always an error except in the case of shadowing a builtin. */
13809 if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
13810 return 0;
5ff904cd 13811
c7e4ee3a
CB
13812 /* For real parm decl following a forward decl,
13813 return 1 so old decl will be reused. */
13814 if (types_match && TREE_CODE (newdecl) == PARM_DECL
13815 && TREE_ASM_WRITTEN (olddecl) && ! TREE_ASM_WRITTEN (newdecl))
13816 return 1;
5ff904cd 13817
c7e4ee3a
CB
13818 /* The new declaration is the same kind of object as the old one.
13819 The declarations may partially match. Print warnings if they don't
13820 match enough. Ultimately, copy most of the information from the new
13821 decl to the old one, and keep using the old one. */
5ff904cd 13822
c7e4ee3a
CB
13823 if (TREE_CODE (olddecl) == FUNCTION_DECL
13824 && DECL_BUILT_IN (olddecl))
13825 {
13826 /* A function declaration for a built-in function. */
13827 if (!TREE_PUBLIC (newdecl))
13828 return 0;
13829 else if (!types_match)
13830 {
13831 /* Accept the return type of the new declaration if same modes. */
13832 tree oldreturntype = TREE_TYPE (TREE_TYPE (olddecl));
13833 tree newreturntype = TREE_TYPE (TREE_TYPE (newdecl));
5ff904cd 13834
c7e4ee3a
CB
13835 /* Make sure we put the new type in the same obstack as the old ones.
13836 If the old types are not both in the same obstack, use the
13837 permanent one. */
13838 if (TYPE_OBSTACK (oldtype) == TYPE_OBSTACK (newtype))
13839 push_obstacks (TYPE_OBSTACK (oldtype), TYPE_OBSTACK (oldtype));
13840 else
13841 {
13842 push_obstacks_nochange ();
13843 end_temporary_allocation ();
13844 }
5ff904cd 13845
c7e4ee3a
CB
13846 if (TYPE_MODE (oldreturntype) == TYPE_MODE (newreturntype))
13847 {
13848 /* Function types may be shared, so we can't just modify
13849 the return type of olddecl's function type. */
13850 tree newtype
13851 = build_function_type (newreturntype,
13852 TYPE_ARG_TYPES (TREE_TYPE (olddecl)));
5ff904cd 13853
c7e4ee3a
CB
13854 types_match = 1;
13855 if (types_match)
13856 TREE_TYPE (olddecl) = newtype;
13857 }
5ff904cd 13858
c7e4ee3a
CB
13859 pop_obstacks ();
13860 }
13861 if (!types_match)
13862 return 0;
13863 }
13864 else if (TREE_CODE (olddecl) == FUNCTION_DECL
13865 && DECL_SOURCE_LINE (olddecl) == 0)
5ff904cd 13866 {
c7e4ee3a
CB
13867 /* A function declaration for a predeclared function
13868 that isn't actually built in. */
13869 if (!TREE_PUBLIC (newdecl))
13870 return 0;
13871 else if (!types_match)
13872 {
13873 /* If the types don't match, preserve volatility indication.
13874 Later on, we will discard everything else about the
13875 default declaration. */
13876 TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
13877 }
13878 }
5ff904cd 13879
c7e4ee3a
CB
13880 /* Copy all the DECL_... slots specified in the new decl
13881 except for any that we copy here from the old type.
5ff904cd 13882
c7e4ee3a
CB
13883 Past this point, we don't change OLDTYPE and NEWTYPE
13884 even if we change the types of NEWDECL and OLDDECL. */
5ff904cd 13885
c7e4ee3a
CB
13886 if (types_match)
13887 {
13888 /* Make sure we put the new type in the same obstack as the old ones.
13889 If the old types are not both in the same obstack, use the permanent
13890 one. */
13891 if (TYPE_OBSTACK (oldtype) == TYPE_OBSTACK (newtype))
13892 push_obstacks (TYPE_OBSTACK (oldtype), TYPE_OBSTACK (oldtype));
13893 else
13894 {
13895 push_obstacks_nochange ();
13896 end_temporary_allocation ();
13897 }
5ff904cd 13898
c7e4ee3a
CB
13899 /* Merge the data types specified in the two decls. */
13900 if (TREE_CODE (newdecl) != FUNCTION_DECL || !DECL_BUILT_IN (olddecl))
13901 TREE_TYPE (newdecl)
13902 = TREE_TYPE (olddecl)
13903 = TREE_TYPE (newdecl);
5ff904cd 13904
c7e4ee3a
CB
13905 /* Lay the type out, unless already done. */
13906 if (oldtype != TREE_TYPE (newdecl))
13907 {
13908 if (TREE_TYPE (newdecl) != error_mark_node)
13909 layout_type (TREE_TYPE (newdecl));
13910 if (TREE_CODE (newdecl) != FUNCTION_DECL
13911 && TREE_CODE (newdecl) != TYPE_DECL
13912 && TREE_CODE (newdecl) != CONST_DECL)
13913 layout_decl (newdecl, 0);
13914 }
13915 else
13916 {
13917 /* Since the type is OLDDECL's, make OLDDECL's size go with. */
13918 DECL_SIZE (newdecl) = DECL_SIZE (olddecl);
13919 if (TREE_CODE (olddecl) != FUNCTION_DECL)
13920 if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl))
13921 DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl);
13922 }
5ff904cd 13923
c7e4ee3a
CB
13924 /* Keep the old rtl since we can safely use it. */
13925 DECL_RTL (newdecl) = DECL_RTL (olddecl);
5ff904cd 13926
c7e4ee3a
CB
13927 /* Merge the type qualifiers. */
13928 if (DECL_BUILT_IN_NONANSI (olddecl) && TREE_THIS_VOLATILE (olddecl)
13929 && !TREE_THIS_VOLATILE (newdecl))
13930 TREE_THIS_VOLATILE (olddecl) = 0;
13931 if (TREE_READONLY (newdecl))
13932 TREE_READONLY (olddecl) = 1;
13933 if (TREE_THIS_VOLATILE (newdecl))
13934 {
13935 TREE_THIS_VOLATILE (olddecl) = 1;
13936 if (TREE_CODE (newdecl) == VAR_DECL)
13937 make_var_volatile (newdecl);
13938 }
5ff904cd 13939
c7e4ee3a
CB
13940 /* Keep source location of definition rather than declaration.
13941 Likewise, keep decl at outer scope. */
13942 if ((DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0)
13943 || (DECL_CONTEXT (newdecl) != 0 && DECL_CONTEXT (olddecl) == 0))
13944 {
13945 DECL_SOURCE_LINE (newdecl) = DECL_SOURCE_LINE (olddecl);
13946 DECL_SOURCE_FILE (newdecl) = DECL_SOURCE_FILE (olddecl);
5ff904cd 13947
c7e4ee3a
CB
13948 if (DECL_CONTEXT (olddecl) == 0
13949 && TREE_CODE (newdecl) != FUNCTION_DECL)
13950 DECL_CONTEXT (newdecl) = 0;
13951 }
5ff904cd 13952
c7e4ee3a
CB
13953 /* Merge the unused-warning information. */
13954 if (DECL_IN_SYSTEM_HEADER (olddecl))
13955 DECL_IN_SYSTEM_HEADER (newdecl) = 1;
13956 else if (DECL_IN_SYSTEM_HEADER (newdecl))
13957 DECL_IN_SYSTEM_HEADER (olddecl) = 1;
5ff904cd 13958
c7e4ee3a
CB
13959 /* Merge the initialization information. */
13960 if (DECL_INITIAL (newdecl) == 0)
13961 DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
5ff904cd 13962
c7e4ee3a
CB
13963 /* Merge the section attribute.
13964 We want to issue an error if the sections conflict but that must be
13965 done later in decl_attributes since we are called before attributes
13966 are assigned. */
13967 if (DECL_SECTION_NAME (newdecl) == NULL_TREE)
13968 DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl);
5ff904cd 13969
c7e4ee3a
CB
13970#if BUILT_FOR_270
13971 if (TREE_CODE (newdecl) == FUNCTION_DECL)
13972 {
13973 DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl);
13974 DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
13975 }
5ff904cd 13976#endif
5ff904cd 13977
c7e4ee3a
CB
13978 pop_obstacks ();
13979 }
13980 /* If cannot merge, then use the new type and qualifiers,
13981 and don't preserve the old rtl. */
13982 else
13983 {
13984 TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
13985 TREE_READONLY (olddecl) = TREE_READONLY (newdecl);
13986 TREE_THIS_VOLATILE (olddecl) = TREE_THIS_VOLATILE (newdecl);
13987 TREE_SIDE_EFFECTS (olddecl) = TREE_SIDE_EFFECTS (newdecl);
13988 }
5ff904cd 13989
c7e4ee3a
CB
13990 /* Merge the storage class information. */
13991 /* For functions, static overrides non-static. */
13992 if (TREE_CODE (newdecl) == FUNCTION_DECL)
13993 {
13994 TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl);
13995 /* This is since we don't automatically
13996 copy the attributes of NEWDECL into OLDDECL. */
13997 TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
13998 /* If this clears `static', clear it in the identifier too. */
13999 if (! TREE_PUBLIC (olddecl))
14000 TREE_PUBLIC (DECL_NAME (olddecl)) = 0;
14001 }
14002 if (DECL_EXTERNAL (newdecl))
14003 {
14004 TREE_STATIC (newdecl) = TREE_STATIC (olddecl);
14005 DECL_EXTERNAL (newdecl) = DECL_EXTERNAL (olddecl);
14006 /* An extern decl does not override previous storage class. */
14007 TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
14008 }
14009 else
14010 {
14011 TREE_STATIC (olddecl) = TREE_STATIC (newdecl);
14012 TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
14013 }
5ff904cd 14014
c7e4ee3a
CB
14015 /* If either decl says `inline', this fn is inline,
14016 unless its definition was passed already. */
14017 if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == 0)
14018 DECL_INLINE (olddecl) = 1;
14019 DECL_INLINE (newdecl) = DECL_INLINE (olddecl);
5ff904cd 14020
c7e4ee3a
CB
14021 /* Get rid of any built-in function if new arg types don't match it
14022 or if we have a function definition. */
14023 if (TREE_CODE (newdecl) == FUNCTION_DECL
14024 && DECL_BUILT_IN (olddecl)
14025 && (!types_match || new_is_definition))
14026 {
14027 TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
14028 DECL_BUILT_IN (olddecl) = 0;
14029 }
5ff904cd 14030
c7e4ee3a
CB
14031 /* If redeclaring a builtin function, and not a definition,
14032 it stays built in.
14033 Also preserve various other info from the definition. */
14034 if (TREE_CODE (newdecl) == FUNCTION_DECL && !new_is_definition)
14035 {
14036 if (DECL_BUILT_IN (olddecl))
14037 {
14038 DECL_BUILT_IN (newdecl) = 1;
14039 DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
14040 }
14041 else
14042 DECL_FRAME_SIZE (newdecl) = DECL_FRAME_SIZE (olddecl);
5ff904cd 14043
c7e4ee3a
CB
14044 DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
14045 DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
14046 DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl);
14047 DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
14048 }
5ff904cd 14049
c7e4ee3a
CB
14050 /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
14051 But preserve olddecl's DECL_UID. */
14052 {
14053 register unsigned olddecl_uid = DECL_UID (olddecl);
5ff904cd 14054
c7e4ee3a
CB
14055 memcpy ((char *) olddecl + sizeof (struct tree_common),
14056 (char *) newdecl + sizeof (struct tree_common),
14057 sizeof (struct tree_decl) - sizeof (struct tree_common));
14058 DECL_UID (olddecl) = olddecl_uid;
14059 }
5ff904cd 14060
c7e4ee3a 14061 return 1;
5ff904cd
JL
14062}
14063
c7e4ee3a
CB
14064/* Finish processing of a declaration;
14065 install its initial value.
14066 If the length of an array type is not known before,
14067 it must be determined now, from the initial value, or it is an error. */
14068
5ff904cd 14069static void
c7e4ee3a 14070finish_decl (tree decl, tree init, bool is_top_level)
5ff904cd 14071{
c7e4ee3a
CB
14072 register tree type = TREE_TYPE (decl);
14073 int was_incomplete = (DECL_SIZE (decl) == 0);
14074 int temporary = allocation_temporary_p ();
14075 bool at_top_level = (current_binding_level == global_binding_level);
14076 bool top_level = is_top_level || at_top_level;
5ff904cd 14077
c7e4ee3a
CB
14078 /* Caller should pass TRUE for is_top_level only if we wouldn't be at top
14079 level anyway. */
14080 assert (!is_top_level || !at_top_level);
5ff904cd 14081
c7e4ee3a
CB
14082 if (TREE_CODE (decl) == PARM_DECL)
14083 assert (init == NULL_TREE);
14084 /* Remember that PARM_DECL doesn't have a DECL_INITIAL field per se -- it
14085 overlaps DECL_ARG_TYPE. */
14086 else if (init == NULL_TREE)
14087 assert (DECL_INITIAL (decl) == NULL_TREE);
14088 else
14089 assert (DECL_INITIAL (decl) == error_mark_node);
5ff904cd 14090
c7e4ee3a 14091 if (init != NULL_TREE)
5ff904cd 14092 {
c7e4ee3a
CB
14093 if (TREE_CODE (decl) != TYPE_DECL)
14094 DECL_INITIAL (decl) = init;
14095 else
14096 {
14097 /* typedef foo = bar; store the type of bar as the type of foo. */
14098 TREE_TYPE (decl) = TREE_TYPE (init);
14099 DECL_INITIAL (decl) = init = 0;
14100 }
5ff904cd
JL
14101 }
14102
c7e4ee3a
CB
14103 /* Pop back to the obstack that is current for this binding level. This is
14104 because MAXINDEX, rtl, etc. to be made below must go in the permanent
14105 obstack. But don't discard the temporary data yet. */
14106 pop_obstacks ();
5ff904cd 14107
c7e4ee3a 14108 /* Deduce size of array from initialization, if not already known */
5ff904cd 14109
c7e4ee3a
CB
14110 if (TREE_CODE (type) == ARRAY_TYPE
14111 && TYPE_DOMAIN (type) == 0
14112 && TREE_CODE (decl) != TYPE_DECL)
14113 {
14114 assert (top_level);
14115 assert (was_incomplete);
5ff904cd 14116
c7e4ee3a
CB
14117 layout_decl (decl, 0);
14118 }
5ff904cd 14119
c7e4ee3a
CB
14120 if (TREE_CODE (decl) == VAR_DECL)
14121 {
14122 if (DECL_SIZE (decl) == NULL_TREE
14123 && TYPE_SIZE (TREE_TYPE (decl)) != NULL_TREE)
14124 layout_decl (decl, 0);
5ff904cd 14125
c7e4ee3a
CB
14126 if (DECL_SIZE (decl) == NULL_TREE
14127 && (TREE_STATIC (decl)
14128 ?
14129 /* A static variable with an incomplete type is an error if it is
14130 initialized. Also if it is not file scope. Otherwise, let it
14131 through, but if it is not `extern' then it may cause an error
14132 message later. */
14133 (DECL_INITIAL (decl) != 0 || DECL_CONTEXT (decl) != 0)
14134 :
14135 /* An automatic variable with an incomplete type is an error. */
14136 !DECL_EXTERNAL (decl)))
14137 {
14138 assert ("storage size not known" == NULL);
14139 abort ();
14140 }
5ff904cd 14141
c7e4ee3a
CB
14142 if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl))
14143 && (DECL_SIZE (decl) != 0)
14144 && (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST))
14145 {
14146 assert ("storage size not constant" == NULL);
14147 abort ();
14148 }
14149 }
5ff904cd 14150
c7e4ee3a
CB
14151 /* Output the assembler code and/or RTL code for variables and functions,
14152 unless the type is an undefined structure or union. If not, it will get
14153 done when the type is completed. */
5ff904cd 14154
c7e4ee3a 14155 if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)
5ff904cd 14156 {
c7e4ee3a
CB
14157 rest_of_decl_compilation (decl, NULL,
14158 DECL_CONTEXT (decl) == 0,
14159 0);
5ff904cd 14160
c7e4ee3a
CB
14161 if (DECL_CONTEXT (decl) != 0)
14162 {
14163 /* Recompute the RTL of a local array now if it used to be an
14164 incomplete type. */
14165 if (was_incomplete
14166 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
5ff904cd 14167 {
c7e4ee3a
CB
14168 /* If we used it already as memory, it must stay in memory. */
14169 TREE_ADDRESSABLE (decl) = TREE_USED (decl);
14170 /* If it's still incomplete now, no init will save it. */
14171 if (DECL_SIZE (decl) == 0)
14172 DECL_INITIAL (decl) = 0;
14173 expand_decl (decl);
5ff904cd 14174 }
c7e4ee3a
CB
14175 /* Compute and store the initial value. */
14176 if (TREE_CODE (decl) != FUNCTION_DECL)
14177 expand_decl_init (decl);
14178 }
14179 }
14180 else if (TREE_CODE (decl) == TYPE_DECL)
14181 {
14182 rest_of_decl_compilation (decl, NULL_PTR,
14183 DECL_CONTEXT (decl) == 0,
14184 0);
14185 }
5ff904cd 14186
c7e4ee3a
CB
14187 /* This test used to include TREE_PERMANENT, however, we have the same
14188 problem with initializers at the function level. Such initializers get
14189 saved until the end of the function on the momentary_obstack. */
14190 if (!(TREE_CODE (decl) == FUNCTION_DECL && DECL_INLINE (decl))
14191 && temporary
14192 /* DECL_INITIAL is not defined in PARM_DECLs, since it shares space with
14193 DECL_ARG_TYPE. */
14194 && TREE_CODE (decl) != PARM_DECL)
14195 {
14196 /* We need to remember that this array HAD an initialization, but
14197 discard the actual temporary nodes, since we can't have a permanent
14198 node keep pointing to them. */
14199 /* We make an exception for inline functions, since it's normal for a
14200 local extern redeclaration of an inline function to have a copy of
14201 the top-level decl's DECL_INLINE. */
14202 if ((DECL_INITIAL (decl) != 0)
14203 && (DECL_INITIAL (decl) != error_mark_node))
14204 {
14205 /* If this is a const variable, then preserve the
14206 initializer instead of discarding it so that we can optimize
14207 references to it. */
14208 /* This test used to include TREE_STATIC, but this won't be set
14209 for function level initializers. */
14210 if (TREE_READONLY (decl))
5ff904cd 14211 {
c7e4ee3a
CB
14212 preserve_initializer ();
14213 /* Hack? Set the permanent bit for something that is
14214 permanent, but not on the permenent obstack, so as to
14215 convince output_constant_def to make its rtl on the
14216 permanent obstack. */
14217 TREE_PERMANENT (DECL_INITIAL (decl)) = 1;
5ff904cd 14218
c7e4ee3a
CB
14219 /* The initializer and DECL must have the same (or equivalent
14220 types), but if the initializer is a STRING_CST, its type
14221 might not be on the right obstack, so copy the type
14222 of DECL. */
14223 TREE_TYPE (DECL_INITIAL (decl)) = type;
5ff904cd 14224 }
c7e4ee3a
CB
14225 else
14226 DECL_INITIAL (decl) = error_mark_node;
5ff904cd 14227 }
5ff904cd 14228 }
c7e4ee3a
CB
14229
14230 /* If requested, warn about definitions of large data objects. */
14231
14232 if (warn_larger_than
14233 && (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL)
14234 && !DECL_EXTERNAL (decl))
5ff904cd 14235 {
c7e4ee3a
CB
14236 register tree decl_size = DECL_SIZE (decl);
14237
14238 if (decl_size && TREE_CODE (decl_size) == INTEGER_CST)
5ff904cd 14239 {
c7e4ee3a
CB
14240 unsigned units = TREE_INT_CST_LOW (decl_size) / BITS_PER_UNIT;
14241
14242 if (units > larger_than_size)
14243 warning_with_decl (decl, "size of `%s' is %u bytes", units);
5ff904cd
JL
14244 }
14245 }
14246
c7e4ee3a
CB
14247 /* If we have gone back from temporary to permanent allocation, actually
14248 free the temporary space that we no longer need. */
14249 if (temporary && !allocation_temporary_p ())
14250 permanent_allocation (0);
5ff904cd 14251
c7e4ee3a
CB
14252 /* At the end of a declaration, throw away any variable type sizes of types
14253 defined inside that declaration. There is no use computing them in the
14254 following function definition. */
14255 if (current_binding_level == global_binding_level)
14256 get_pending_sizes ();
14257}
5ff904cd 14258
c7e4ee3a
CB
14259/* Finish up a function declaration and compile that function
14260 all the way to assembler language output. The free the storage
14261 for the function definition.
5ff904cd 14262
c7e4ee3a 14263 This is called after parsing the body of the function definition.
5ff904cd 14264
c7e4ee3a
CB
14265 NESTED is nonzero if the function being finished is nested in another. */
14266
14267static void
14268finish_function (int nested)
14269{
14270 register tree fndecl = current_function_decl;
14271
14272 assert (fndecl != NULL_TREE);
14273 if (TREE_CODE (fndecl) != ERROR_MARK)
14274 {
14275 if (nested)
14276 assert (DECL_CONTEXT (fndecl) != NULL_TREE);
5ff904cd 14277 else
c7e4ee3a
CB
14278 assert (DECL_CONTEXT (fndecl) == NULL_TREE);
14279 }
5ff904cd 14280
c7e4ee3a
CB
14281/* TREE_READONLY (fndecl) = 1;
14282 This caused &foo to be of type ptr-to-const-function
14283 which then got a warning when stored in a ptr-to-function variable. */
5ff904cd 14284
c7e4ee3a 14285 poplevel (1, 0, 1);
5ff904cd 14286
c7e4ee3a
CB
14287 if (TREE_CODE (fndecl) != ERROR_MARK)
14288 {
14289 BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
5ff904cd 14290
c7e4ee3a 14291 /* Must mark the RESULT_DECL as being in this function. */
5ff904cd 14292
c7e4ee3a 14293 DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;
5ff904cd 14294
c7e4ee3a
CB
14295 /* Obey `register' declarations if `setjmp' is called in this fn. */
14296 /* Generate rtl for function exit. */
14297 expand_function_end (input_filename, lineno, 0);
5ff904cd 14298
c7e4ee3a
CB
14299 /* So we can tell if jump_optimize sets it to 1. */
14300 can_reach_end = 0;
5ff904cd 14301
c7e4ee3a
CB
14302 /* Run the optimizers and output the assembler code for this function. */
14303 rest_of_compilation (fndecl);
14304 }
5ff904cd 14305
c7e4ee3a
CB
14306 /* Free all the tree nodes making up this function. */
14307 /* Switch back to allocating nodes permanently until we start another
14308 function. */
14309 if (!nested)
14310 permanent_allocation (1);
14311
14312 if (TREE_CODE (fndecl) != ERROR_MARK
14313 && !nested
14314 && DECL_SAVED_INSNS (fndecl) == 0)
14315 {
14316 /* Stop pointing to the local nodes about to be freed. */
14317 /* But DECL_INITIAL must remain nonzero so we know this was an actual
14318 function definition. */
14319 /* For a nested function, this is done in pop_f_function_context. */
14320 /* If rest_of_compilation set this to 0, leave it 0. */
14321 if (DECL_INITIAL (fndecl) != 0)
14322 DECL_INITIAL (fndecl) = error_mark_node;
14323 DECL_ARGUMENTS (fndecl) = 0;
5ff904cd 14324 }
c7e4ee3a
CB
14325
14326 if (!nested)
5ff904cd 14327 {
c7e4ee3a
CB
14328 /* Let the error reporting routines know that we're outside a function.
14329 For a nested function, this value is used in pop_c_function_context
14330 and then reset via pop_function_context. */
14331 ffecom_outer_function_decl_ = current_function_decl = NULL;
5ff904cd 14332 }
c7e4ee3a 14333}
5ff904cd 14334
c7e4ee3a
CB
14335/* Plug-in replacement for identifying the name of a decl and, for a
14336 function, what we call it in diagnostics. For now, "program unit"
14337 should suffice, since it's a bit of a hassle to figure out which
14338 of several kinds of things it is. Note that it could conceivably
14339 be a statement function, which probably isn't really a program unit
14340 per se, but if that comes up, it should be easy to check (being a
14341 nested function and all). */
14342
4b731ffa 14343static const char *
c7e4ee3a
CB
14344lang_printable_name (tree decl, int v)
14345{
14346 /* Just to keep GCC quiet about the unused variable.
14347 In theory, differing values of V should produce different
14348 output. */
14349 switch (v)
5ff904cd 14350 {
c7e4ee3a
CB
14351 default:
14352 if (TREE_CODE (decl) == ERROR_MARK)
14353 return "erroneous code";
14354 return IDENTIFIER_POINTER (DECL_NAME (decl));
5ff904cd 14355 }
c7e4ee3a
CB
14356}
14357
14358/* g77's function to print out name of current function that caused
14359 an error. */
14360
14361#if BUILT_FOR_270
14362void
14363lang_print_error_function (file)
dafbd854 14364 const char *file;
c7e4ee3a
CB
14365{
14366 static ffeglobal last_g = NULL;
14367 static ffesymbol last_s = NULL;
14368 ffeglobal g;
14369 ffesymbol s;
14370 const char *kind;
14371
14372 if ((ffecom_primary_entry_ == NULL)
14373 || (ffesymbol_global (ffecom_primary_entry_) == NULL))
5ff904cd 14374 {
c7e4ee3a
CB
14375 g = NULL;
14376 s = NULL;
14377 kind = NULL;
5ff904cd
JL
14378 }
14379 else
14380 {
c7e4ee3a
CB
14381 g = ffesymbol_global (ffecom_primary_entry_);
14382 if (ffecom_nested_entry_ == NULL)
14383 {
14384 s = ffecom_primary_entry_;
14385 switch (ffesymbol_kind (s))
14386 {
14387 case FFEINFO_kindFUNCTION:
14388 kind = "function";
14389 break;
5ff904cd 14390
c7e4ee3a
CB
14391 case FFEINFO_kindSUBROUTINE:
14392 kind = "subroutine";
14393 break;
5ff904cd 14394
c7e4ee3a
CB
14395 case FFEINFO_kindPROGRAM:
14396 kind = "program";
14397 break;
14398
14399 case FFEINFO_kindBLOCKDATA:
14400 kind = "block-data";
14401 break;
14402
14403 default:
14404 kind = ffeinfo_kind_message (ffesymbol_kind (s));
14405 break;
14406 }
14407 }
14408 else
14409 {
14410 s = ffecom_nested_entry_;
14411 kind = "statement function";
14412 }
5ff904cd
JL
14413 }
14414
c7e4ee3a 14415 if ((last_g != g) || (last_s != s))
5ff904cd 14416 {
c7e4ee3a
CB
14417 if (file)
14418 fprintf (stderr, "%s: ", file);
14419
14420 if (s == NULL)
14421 fprintf (stderr, "Outside of any program unit:\n");
14422 else
5ff904cd 14423 {
c7e4ee3a
CB
14424 const char *name = ffesymbol_text (s);
14425
14426 fprintf (stderr, "In %s `%s':\n", kind, name);
5ff904cd 14427 }
5ff904cd 14428
c7e4ee3a
CB
14429 last_g = g;
14430 last_s = s;
5ff904cd 14431 }
c7e4ee3a
CB
14432}
14433#endif
5ff904cd 14434
c7e4ee3a 14435/* Similar to `lookup_name' but look only at current binding level. */
5ff904cd 14436
c7e4ee3a
CB
14437static tree
14438lookup_name_current_level (tree name)
14439{
14440 register tree t;
5ff904cd 14441
c7e4ee3a
CB
14442 if (current_binding_level == global_binding_level)
14443 return IDENTIFIER_GLOBAL_VALUE (name);
14444
14445 if (IDENTIFIER_LOCAL_VALUE (name) == 0)
14446 return 0;
14447
14448 for (t = current_binding_level->names; t; t = TREE_CHAIN (t))
14449 if (DECL_NAME (t) == name)
14450 break;
14451
14452 return t;
5ff904cd
JL
14453}
14454
c7e4ee3a 14455/* Create a new `struct binding_level'. */
5ff904cd 14456
c7e4ee3a
CB
14457static struct binding_level *
14458make_binding_level ()
5ff904cd 14459{
c7e4ee3a
CB
14460 /* NOSTRICT */
14461 return (struct binding_level *) xmalloc (sizeof (struct binding_level));
14462}
5ff904cd 14463
c7e4ee3a
CB
14464/* Save and restore the variables in this file and elsewhere
14465 that keep track of the progress of compilation of the current function.
14466 Used for nested functions. */
5ff904cd 14467
c7e4ee3a
CB
14468struct f_function
14469{
14470 struct f_function *next;
14471 tree named_labels;
14472 tree shadowed_labels;
14473 struct binding_level *binding_level;
14474};
5ff904cd 14475
c7e4ee3a 14476struct f_function *f_function_chain;
5ff904cd 14477
c7e4ee3a 14478/* Restore the variables used during compilation of a C function. */
5ff904cd 14479
c7e4ee3a
CB
14480static void
14481pop_f_function_context ()
14482{
14483 struct f_function *p = f_function_chain;
14484 tree link;
5ff904cd 14485
c7e4ee3a
CB
14486 /* Bring back all the labels that were shadowed. */
14487 for (link = shadowed_labels; link; link = TREE_CHAIN (link))
14488 if (DECL_NAME (TREE_VALUE (link)) != 0)
14489 IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link)))
14490 = TREE_VALUE (link);
5ff904cd 14491
c7e4ee3a
CB
14492 if (current_function_decl != error_mark_node
14493 && DECL_SAVED_INSNS (current_function_decl) == 0)
14494 {
14495 /* Stop pointing to the local nodes about to be freed. */
14496 /* But DECL_INITIAL must remain nonzero so we know this was an actual
14497 function definition. */
14498 DECL_INITIAL (current_function_decl) = error_mark_node;
14499 DECL_ARGUMENTS (current_function_decl) = 0;
5ff904cd
JL
14500 }
14501
c7e4ee3a 14502 pop_function_context ();
5ff904cd 14503
c7e4ee3a 14504 f_function_chain = p->next;
5ff904cd 14505
c7e4ee3a
CB
14506 named_labels = p->named_labels;
14507 shadowed_labels = p->shadowed_labels;
14508 current_binding_level = p->binding_level;
5ff904cd 14509
c7e4ee3a
CB
14510 free (p);
14511}
5ff904cd 14512
c7e4ee3a
CB
14513/* Save and reinitialize the variables
14514 used during compilation of a C function. */
5ff904cd 14515
c7e4ee3a
CB
14516static void
14517push_f_function_context ()
14518{
14519 struct f_function *p
14520 = (struct f_function *) xmalloc (sizeof (struct f_function));
5ff904cd 14521
c7e4ee3a
CB
14522 push_function_context ();
14523
14524 p->next = f_function_chain;
14525 f_function_chain = p;
14526
14527 p->named_labels = named_labels;
14528 p->shadowed_labels = shadowed_labels;
14529 p->binding_level = current_binding_level;
14530}
5ff904cd 14531
c7e4ee3a
CB
14532static void
14533push_parm_decl (tree parm)
14534{
14535 int old_immediate_size_expand = immediate_size_expand;
5ff904cd 14536
c7e4ee3a 14537 /* Don't try computing parm sizes now -- wait till fn is called. */
5ff904cd 14538
c7e4ee3a 14539 immediate_size_expand = 0;
5ff904cd 14540
c7e4ee3a 14541 push_obstacks_nochange ();
5ff904cd 14542
c7e4ee3a 14543 /* Fill in arg stuff. */
5ff904cd 14544
c7e4ee3a
CB
14545 DECL_ARG_TYPE (parm) = TREE_TYPE (parm);
14546 DECL_ARG_TYPE_AS_WRITTEN (parm) = TREE_TYPE (parm);
14547 TREE_READONLY (parm) = 1; /* All implementation args are read-only. */
5ff904cd 14548
c7e4ee3a
CB
14549 parm = pushdecl (parm);
14550
14551 immediate_size_expand = old_immediate_size_expand;
14552
14553 finish_decl (parm, NULL_TREE, FALSE);
5ff904cd
JL
14554}
14555
c7e4ee3a 14556/* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL, if appropriate. */
5ff904cd 14557
c7e4ee3a
CB
14558static tree
14559pushdecl_top_level (x)
14560 tree x;
14561{
14562 register tree t;
14563 register struct binding_level *b = current_binding_level;
14564 register tree f = current_function_decl;
5ff904cd 14565
c7e4ee3a
CB
14566 current_binding_level = global_binding_level;
14567 current_function_decl = NULL_TREE;
14568 t = pushdecl (x);
14569 current_binding_level = b;
14570 current_function_decl = f;
14571 return t;
14572}
14573
14574/* Store the list of declarations of the current level.
14575 This is done for the parameter declarations of a function being defined,
14576 after they are modified in the light of any missing parameters. */
14577
14578static tree
14579storedecls (decls)
14580 tree decls;
14581{
14582 return current_binding_level->names = decls;
14583}
14584
14585/* Store the parameter declarations into the current function declaration.
14586 This is called after parsing the parameter declarations, before
14587 digesting the body of the function.
14588
14589 For an old-style definition, modify the function's type
14590 to specify at least the number of arguments. */
5ff904cd
JL
14591
14592static void
c7e4ee3a 14593store_parm_decls (int is_main_program UNUSED)
5ff904cd
JL
14594{
14595 register tree fndecl = current_function_decl;
14596
c7e4ee3a
CB
14597 if (fndecl == error_mark_node)
14598 return;
5ff904cd 14599
c7e4ee3a
CB
14600 /* This is a chain of PARM_DECLs from old-style parm declarations. */
14601 DECL_ARGUMENTS (fndecl) = storedecls (nreverse (getdecls ()));
5ff904cd 14602
c7e4ee3a 14603 /* Initialize the RTL code for the function. */
5ff904cd 14604
c7e4ee3a 14605 init_function_start (fndecl, input_filename, lineno);
56a0044b 14606
c7e4ee3a 14607 /* Set up parameters and prepare for return, for the function. */
5ff904cd 14608
c7e4ee3a
CB
14609 expand_function_start (fndecl, 0);
14610}
5ff904cd 14611
c7e4ee3a
CB
14612static tree
14613start_decl (tree decl, bool is_top_level)
14614{
14615 register tree tem;
14616 bool at_top_level = (current_binding_level == global_binding_level);
14617 bool top_level = is_top_level || at_top_level;
5ff904cd 14618
c7e4ee3a
CB
14619 /* Caller should pass TRUE for is_top_level only if we wouldn't be at top
14620 level anyway. */
14621 assert (!is_top_level || !at_top_level);
5ff904cd 14622
c7e4ee3a
CB
14623 /* The corresponding pop_obstacks is in finish_decl. */
14624 push_obstacks_nochange ();
14625
14626 if (DECL_INITIAL (decl) != NULL_TREE)
14627 {
14628 assert (DECL_INITIAL (decl) == error_mark_node);
14629 assert (!DECL_EXTERNAL (decl));
56a0044b 14630 }
c7e4ee3a
CB
14631 else if (top_level)
14632 assert ((TREE_STATIC (decl) == 1) || DECL_EXTERNAL (decl) == 1);
5ff904cd 14633
c7e4ee3a
CB
14634 /* For Fortran, we by default put things in .common when possible. */
14635 DECL_COMMON (decl) = 1;
5ff904cd 14636
c7e4ee3a
CB
14637 /* Add this decl to the current binding level. TEM may equal DECL or it may
14638 be a previous decl of the same name. */
14639 if (is_top_level)
14640 tem = pushdecl_top_level (decl);
14641 else
14642 tem = pushdecl (decl);
14643
14644 /* For a local variable, define the RTL now. */
14645 if (!top_level
14646 /* But not if this is a duplicate decl and we preserved the rtl from the
14647 previous one (which may or may not happen). */
14648 && DECL_RTL (tem) == 0)
5ff904cd 14649 {
c7e4ee3a
CB
14650 if (TYPE_SIZE (TREE_TYPE (tem)) != 0)
14651 expand_decl (tem);
14652 else if (TREE_CODE (TREE_TYPE (tem)) == ARRAY_TYPE
14653 && DECL_INITIAL (tem) != 0)
14654 expand_decl (tem);
5ff904cd
JL
14655 }
14656
c7e4ee3a 14657 if (DECL_INITIAL (tem) != NULL_TREE)
5ff904cd 14658 {
c7e4ee3a
CB
14659 /* When parsing and digesting the initializer, use temporary storage.
14660 Do this even if we will ignore the value. */
14661 if (at_top_level)
14662 temporary_allocation ();
5ff904cd 14663 }
c7e4ee3a
CB
14664
14665 return tem;
5ff904cd
JL
14666}
14667
c7e4ee3a
CB
14668/* Create the FUNCTION_DECL for a function definition.
14669 DECLSPECS and DECLARATOR are the parts of the declaration;
14670 they describe the function's name and the type it returns,
14671 but twisted together in a fashion that parallels the syntax of C.
5ff904cd 14672
c7e4ee3a
CB
14673 This function creates a binding context for the function body
14674 as well as setting up the FUNCTION_DECL in current_function_decl.
5ff904cd 14675
c7e4ee3a
CB
14676 Returns 1 on success. If the DECLARATOR is not suitable for a function
14677 (it defines a datum instead), we return 0, which tells
14678 yyparse to report a parse error.
5ff904cd 14679
c7e4ee3a
CB
14680 NESTED is nonzero for a function nested within another function. */
14681
14682static void
14683start_function (tree name, tree type, int nested, int public)
5ff904cd 14684{
c7e4ee3a
CB
14685 tree decl1;
14686 tree restype;
14687 int old_immediate_size_expand = immediate_size_expand;
5ff904cd 14688
c7e4ee3a
CB
14689 named_labels = 0;
14690 shadowed_labels = 0;
14691
14692 /* Don't expand any sizes in the return type of the function. */
14693 immediate_size_expand = 0;
14694
14695 if (nested)
5ff904cd 14696 {
c7e4ee3a
CB
14697 assert (!public);
14698 assert (current_function_decl != NULL_TREE);
14699 assert (DECL_CONTEXT (current_function_decl) == NULL_TREE);
14700 }
14701 else
14702 {
14703 assert (current_function_decl == NULL_TREE);
5ff904cd 14704 }
c7e4ee3a
CB
14705
14706 if (TREE_CODE (type) == ERROR_MARK)
14707 decl1 = current_function_decl = error_mark_node;
56a0044b 14708 else
5ff904cd 14709 {
c7e4ee3a
CB
14710 decl1 = build_decl (FUNCTION_DECL,
14711 name,
14712 type);
14713 TREE_PUBLIC (decl1) = public ? 1 : 0;
14714 if (nested)
14715 DECL_INLINE (decl1) = 1;
14716 TREE_STATIC (decl1) = 1;
14717 DECL_EXTERNAL (decl1) = 0;
5ff904cd 14718
c7e4ee3a 14719 announce_function (decl1);
5ff904cd 14720
c7e4ee3a
CB
14721 /* Make the init_value nonzero so pushdecl knows this is not tentative.
14722 error_mark_node is replaced below (in poplevel) with the BLOCK. */
14723 DECL_INITIAL (decl1) = error_mark_node;
5ff904cd 14724
c7e4ee3a
CB
14725 /* Record the decl so that the function name is defined. If we already have
14726 a decl for this name, and it is a FUNCTION_DECL, use the old decl. */
5ff904cd 14727
c7e4ee3a 14728 current_function_decl = pushdecl (decl1);
5ff904cd
JL
14729 }
14730
c7e4ee3a
CB
14731 if (!nested)
14732 ffecom_outer_function_decl_ = current_function_decl;
5ff904cd 14733
c7e4ee3a
CB
14734 pushlevel (0);
14735 current_binding_level->prep_state = 2;
5ff904cd 14736
c7e4ee3a
CB
14737 if (TREE_CODE (current_function_decl) != ERROR_MARK)
14738 {
14739 make_function_rtl (current_function_decl);
5ff904cd 14740
c7e4ee3a
CB
14741 restype = TREE_TYPE (TREE_TYPE (current_function_decl));
14742 DECL_RESULT (current_function_decl)
14743 = build_decl (RESULT_DECL, NULL_TREE, restype);
5ff904cd 14744 }
5ff904cd 14745
c7e4ee3a
CB
14746 if (!nested)
14747 /* Allocate further tree nodes temporarily during compilation of this
14748 function only. */
14749 temporary_allocation ();
5ff904cd 14750
c7e4ee3a
CB
14751 if (!nested && (TREE_CODE (current_function_decl) != ERROR_MARK))
14752 TREE_ADDRESSABLE (current_function_decl) = 1;
14753
14754 immediate_size_expand = old_immediate_size_expand;
14755}
14756\f
14757/* Here are the public functions the GNU back end needs. */
14758
14759tree
14760convert (type, expr)
14761 tree type, expr;
5ff904cd 14762{
c7e4ee3a
CB
14763 register tree e = expr;
14764 register enum tree_code code = TREE_CODE (type);
5ff904cd 14765
c7e4ee3a
CB
14766 if (type == TREE_TYPE (e)
14767 || TREE_CODE (e) == ERROR_MARK)
14768 return e;
14769 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
14770 return fold (build1 (NOP_EXPR, type, e));
14771 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
14772 || code == ERROR_MARK)
14773 return error_mark_node;
14774 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
14775 {
14776 assert ("void value not ignored as it ought to be" == NULL);
14777 return error_mark_node;
14778 }
14779 if (code == VOID_TYPE)
14780 return build1 (CONVERT_EXPR, type, e);
14781 if ((code != RECORD_TYPE)
14782 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
14783 e = ffecom_1 (REALPART_EXPR, TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e))),
14784 e);
14785 if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)
14786 return fold (convert_to_integer (type, e));
14787 if (code == POINTER_TYPE)
14788 return fold (convert_to_pointer (type, e));
14789 if (code == REAL_TYPE)
14790 return fold (convert_to_real (type, e));
14791 if (code == COMPLEX_TYPE)
14792 return fold (convert_to_complex (type, e));
14793 if (code == RECORD_TYPE)
14794 return fold (ffecom_convert_to_complex_ (type, e));
5ff904cd 14795
c7e4ee3a
CB
14796 assert ("conversion to non-scalar type requested" == NULL);
14797 return error_mark_node;
14798}
5ff904cd 14799
c7e4ee3a
CB
14800/* integrate_decl_tree calls this function, but since we don't use the
14801 DECL_LANG_SPECIFIC field, this is a no-op. */
5ff904cd 14802
c7e4ee3a
CB
14803void
14804copy_lang_decl (node)
14805 tree node UNUSED;
14806{
5ff904cd
JL
14807}
14808
c7e4ee3a
CB
14809/* Return the list of declarations of the current level.
14810 Note that this list is in reverse order unless/until
14811 you nreverse it; and when you do nreverse it, you must
14812 store the result back using `storedecls' or you will lose. */
5ff904cd 14813
c7e4ee3a
CB
14814tree
14815getdecls ()
5ff904cd 14816{
c7e4ee3a 14817 return current_binding_level->names;
5ff904cd
JL
14818}
14819
c7e4ee3a 14820/* Nonzero if we are currently in the global binding level. */
5ff904cd 14821
c7e4ee3a
CB
14822int
14823global_bindings_p ()
5ff904cd 14824{
c7e4ee3a
CB
14825 return current_binding_level == global_binding_level;
14826}
5ff904cd 14827
c7e4ee3a
CB
14828/* Print an error message for invalid use of an incomplete type.
14829 VALUE is the expression that was used (or 0 if that isn't known)
14830 and TYPE is the type that was invalid. */
5ff904cd 14831
c7e4ee3a
CB
14832void
14833incomplete_type_error (value, type)
14834 tree value UNUSED;
14835 tree type;
14836{
14837 if (TREE_CODE (type) == ERROR_MARK)
14838 return;
5ff904cd 14839
c7e4ee3a
CB
14840 assert ("incomplete type?!?" == NULL);
14841}
14842
14843void
14844init_decl_processing ()
5ff904cd 14845{
c7e4ee3a
CB
14846 malloc_init ();
14847 ffe_init_0 ();
14848}
5ff904cd 14849
c7e4ee3a
CB
14850char *
14851init_parse (filename)
14852 char *filename;
14853{
c7e4ee3a
CB
14854 /* Open input file. */
14855 if (filename == 0 || !strcmp (filename, "-"))
5ff904cd 14856 {
c7e4ee3a
CB
14857 finput = stdin;
14858 filename = "stdin";
5ff904cd 14859 }
c7e4ee3a
CB
14860 else
14861 finput = fopen (filename, "r");
14862 if (finput == 0)
14863 pfatal_with_name (filename);
5ff904cd 14864
c7e4ee3a
CB
14865#ifdef IO_BUFFER_SIZE
14866 setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
14867#endif
5ff904cd 14868
c7e4ee3a
CB
14869 /* Make identifier nodes long enough for the language-specific slots. */
14870 set_identifier_size (sizeof (struct lang_identifier));
14871 decl_printable_name = lang_printable_name;
14872#if BUILT_FOR_270
14873 print_error_function = lang_print_error_function;
14874#endif
5ff904cd 14875
c7e4ee3a
CB
14876 return filename;
14877}
5ff904cd 14878
c7e4ee3a
CB
14879void
14880finish_parse ()
14881{
14882 fclose (finput);
14883}
14884
14885/* Delete the node BLOCK from the current binding level.
14886 This is used for the block inside a stmt expr ({...})
14887 so that the block can be reinserted where appropriate. */
14888
14889static void
14890delete_block (block)
14891 tree block;
14892{
14893 tree t;
14894 if (current_binding_level->blocks == block)
14895 current_binding_level->blocks = TREE_CHAIN (block);
14896 for (t = current_binding_level->blocks; t;)
14897 {
14898 if (TREE_CHAIN (t) == block)
14899 TREE_CHAIN (t) = TREE_CHAIN (block);
14900 else
14901 t = TREE_CHAIN (t);
14902 }
14903 TREE_CHAIN (block) = NULL;
14904 /* Clear TREE_USED which is always set by poplevel.
14905 The flag is set again if insert_block is called. */
14906 TREE_USED (block) = 0;
14907}
14908
14909void
14910insert_block (block)
14911 tree block;
14912{
14913 TREE_USED (block) = 1;
14914 current_binding_level->blocks
14915 = chainon (current_binding_level->blocks, block);
14916}
14917
14918int
14919lang_decode_option (argc, argv)
14920 int argc;
14921 char **argv;
14922{
14923 return ffe_decode_option (argc, argv);
5ff904cd
JL
14924}
14925
c7e4ee3a 14926/* used by print-tree.c */
5ff904cd 14927
c7e4ee3a
CB
14928void
14929lang_print_xnode (file, node, indent)
14930 FILE *file UNUSED;
14931 tree node UNUSED;
14932 int indent UNUSED;
5ff904cd 14933{
c7e4ee3a 14934}
5ff904cd 14935
c7e4ee3a
CB
14936void
14937lang_finish ()
14938{
14939 ffe_terminate_0 ();
5ff904cd 14940
c7e4ee3a
CB
14941 if (ffe_is_ffedebug ())
14942 malloc_pool_display (malloc_pool_image ());
5ff904cd
JL
14943}
14944
dafbd854 14945const char *
c7e4ee3a 14946lang_identify ()
5ff904cd 14947{
c7e4ee3a
CB
14948 return "f77";
14949}
5ff904cd 14950
c7e4ee3a
CB
14951void
14952lang_init_options ()
14953{
14954 /* Set default options for Fortran. */
14955 flag_move_all_movables = 1;
14956 flag_reduce_all_givs = 1;
14957 flag_argument_noalias = 2;
41af162c 14958 flag_errno_math = 0;
c64f913e 14959 flag_complex_divide_method = 1;
c7e4ee3a 14960}
5ff904cd 14961
c7e4ee3a
CB
14962void
14963lang_init ()
14964{
14965 /* If the file is output from cpp, it should contain a first line
14966 `# 1 "real-filename"', and the current design of gcc (toplev.c
14967 in particular and the way it sets up information relied on by
14968 INCLUDE) requires that we read this now, and store the
14969 "real-filename" info in master_input_filename. Ask the lexer
14970 to try doing this. */
14971 ffelex_hash_kludge (finput);
14972}
5ff904cd 14973
c7e4ee3a
CB
14974int
14975mark_addressable (exp)
14976 tree exp;
14977{
14978 register tree x = exp;
14979 while (1)
14980 switch (TREE_CODE (x))
14981 {
14982 case ADDR_EXPR:
14983 case COMPONENT_REF:
14984 case ARRAY_REF:
14985 x = TREE_OPERAND (x, 0);
14986 break;
5ff904cd 14987
c7e4ee3a
CB
14988 case CONSTRUCTOR:
14989 TREE_ADDRESSABLE (x) = 1;
14990 return 1;
5ff904cd 14991
c7e4ee3a
CB
14992 case VAR_DECL:
14993 case CONST_DECL:
14994 case PARM_DECL:
14995 case RESULT_DECL:
14996 if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
14997 && DECL_NONLOCAL (x))
14998 {
14999 if (TREE_PUBLIC (x))
15000 {
15001 assert ("address of global register var requested" == NULL);
15002 return 0;
15003 }
15004 assert ("address of register variable requested" == NULL);
15005 }
15006 else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x))
15007 {
15008 if (TREE_PUBLIC (x))
15009 {
15010 assert ("address of global register var requested" == NULL);
15011 return 0;
15012 }
15013 assert ("address of register var requested" == NULL);
15014 }
15015 put_var_into_stack (x);
5ff904cd 15016
c7e4ee3a
CB
15017 /* drops in */
15018 case FUNCTION_DECL:
15019 TREE_ADDRESSABLE (x) = 1;
15020#if 0 /* poplevel deals with this now. */
15021 if (DECL_CONTEXT (x) == 0)
15022 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (x)) = 1;
15023#endif
5ff904cd 15024
c7e4ee3a
CB
15025 default:
15026 return 1;
15027 }
5ff904cd
JL
15028}
15029
c7e4ee3a
CB
15030/* If DECL has a cleanup, build and return that cleanup here.
15031 This is a callback called by expand_expr. */
5ff904cd 15032
c7e4ee3a
CB
15033tree
15034maybe_build_cleanup (decl)
15035 tree decl UNUSED;
5ff904cd 15036{
c7e4ee3a
CB
15037 /* There are no cleanups in Fortran. */
15038 return NULL_TREE;
5ff904cd
JL
15039}
15040
c7e4ee3a
CB
15041/* Exit a binding level.
15042 Pop the level off, and restore the state of the identifier-decl mappings
15043 that were in effect when this level was entered.
5ff904cd 15044
c7e4ee3a
CB
15045 If KEEP is nonzero, this level had explicit declarations, so
15046 and create a "block" (a BLOCK node) for the level
15047 to record its declarations and subblocks for symbol table output.
5ff904cd 15048
c7e4ee3a
CB
15049 If FUNCTIONBODY is nonzero, this level is the body of a function,
15050 so create a block as if KEEP were set and also clear out all
15051 label names.
5ff904cd 15052
c7e4ee3a
CB
15053 If REVERSE is nonzero, reverse the order of decls before putting
15054 them into the BLOCK. */
5ff904cd 15055
c7e4ee3a
CB
15056tree
15057poplevel (keep, reverse, functionbody)
15058 int keep;
15059 int reverse;
15060 int functionbody;
5ff904cd 15061{
c7e4ee3a
CB
15062 register tree link;
15063 /* The chain of decls was accumulated in reverse order.
15064 Put it into forward order, just for cleanliness. */
15065 tree decls;
15066 tree subblocks = current_binding_level->blocks;
15067 tree block = 0;
15068 tree decl;
15069 int block_previously_created;
5ff904cd 15070
c7e4ee3a
CB
15071 /* Get the decls in the order they were written.
15072 Usually current_binding_level->names is in reverse order.
15073 But parameter decls were previously put in forward order. */
702edf1d 15074
c7e4ee3a
CB
15075 if (reverse)
15076 current_binding_level->names
15077 = decls = nreverse (current_binding_level->names);
15078 else
15079 decls = current_binding_level->names;
5ff904cd 15080
c7e4ee3a
CB
15081 /* Output any nested inline functions within this block
15082 if they weren't already output. */
5ff904cd 15083
c7e4ee3a
CB
15084 for (decl = decls; decl; decl = TREE_CHAIN (decl))
15085 if (TREE_CODE (decl) == FUNCTION_DECL
15086 && ! TREE_ASM_WRITTEN (decl)
15087 && DECL_INITIAL (decl) != 0
15088 && TREE_ADDRESSABLE (decl))
15089 {
15090 /* If this decl was copied from a file-scope decl
15091 on account of a block-scope extern decl,
15092 propagate TREE_ADDRESSABLE to the file-scope decl.
15093
15094 DECL_ABSTRACT_ORIGIN can be set to itself if warn_return_type is
15095 true, since then the decl goes through save_for_inline_copying. */
15096 if (DECL_ABSTRACT_ORIGIN (decl) != 0
15097 && DECL_ABSTRACT_ORIGIN (decl) != decl)
15098 TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1;
15099 else if (DECL_SAVED_INSNS (decl) != 0)
15100 {
15101 push_function_context ();
15102 output_inline_function (decl);
15103 pop_function_context ();
15104 }
15105 }
5ff904cd 15106
c7e4ee3a
CB
15107 /* If there were any declarations or structure tags in that level,
15108 or if this level is a function body,
15109 create a BLOCK to record them for the life of this function. */
5ff904cd 15110
c7e4ee3a
CB
15111 block = 0;
15112 block_previously_created = (current_binding_level->this_block != 0);
15113 if (block_previously_created)
15114 block = current_binding_level->this_block;
15115 else if (keep || functionbody)
15116 block = make_node (BLOCK);
15117 if (block != 0)
15118 {
15119 BLOCK_VARS (block) = decls;
15120 BLOCK_SUBBLOCKS (block) = subblocks;
15121 remember_end_note (block);
15122 }
5ff904cd 15123
c7e4ee3a 15124 /* In each subblock, record that this is its superior. */
5ff904cd 15125
c7e4ee3a
CB
15126 for (link = subblocks; link; link = TREE_CHAIN (link))
15127 BLOCK_SUPERCONTEXT (link) = block;
5ff904cd 15128
c7e4ee3a 15129 /* Clear out the meanings of the local variables of this level. */
5ff904cd 15130
c7e4ee3a 15131 for (link = decls; link; link = TREE_CHAIN (link))
5ff904cd 15132 {
c7e4ee3a
CB
15133 if (DECL_NAME (link) != 0)
15134 {
15135 /* If the ident. was used or addressed via a local extern decl,
15136 don't forget that fact. */
15137 if (DECL_EXTERNAL (link))
15138 {
15139 if (TREE_USED (link))
15140 TREE_USED (DECL_NAME (link)) = 1;
15141 if (TREE_ADDRESSABLE (link))
15142 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (link)) = 1;
15143 }
15144 IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = 0;
15145 }
5ff904cd 15146 }
5ff904cd 15147
c7e4ee3a
CB
15148 /* If the level being exited is the top level of a function,
15149 check over all the labels, and clear out the current
15150 (function local) meanings of their names. */
5ff904cd 15151
c7e4ee3a 15152 if (functionbody)
5ff904cd 15153 {
c7e4ee3a
CB
15154 /* If this is the top level block of a function,
15155 the vars are the function's parameters.
15156 Don't leave them in the BLOCK because they are
15157 found in the FUNCTION_DECL instead. */
15158
15159 BLOCK_VARS (block) = 0;
5ff904cd
JL
15160 }
15161
c7e4ee3a
CB
15162 /* Pop the current level, and free the structure for reuse. */
15163
15164 {
15165 register struct binding_level *level = current_binding_level;
15166 current_binding_level = current_binding_level->level_chain;
15167
15168 level->level_chain = free_binding_level;
15169 free_binding_level = level;
15170 }
15171
15172 /* Dispose of the block that we just made inside some higher level. */
15173 if (functionbody
15174 && current_function_decl != error_mark_node)
15175 DECL_INITIAL (current_function_decl) = block;
15176 else if (block)
5ff904cd 15177 {
c7e4ee3a
CB
15178 if (!block_previously_created)
15179 current_binding_level->blocks
15180 = chainon (current_binding_level->blocks, block);
5ff904cd 15181 }
c7e4ee3a
CB
15182 /* If we did not make a block for the level just exited,
15183 any blocks made for inner levels
15184 (since they cannot be recorded as subblocks in that level)
15185 must be carried forward so they will later become subblocks
15186 of something else. */
15187 else if (subblocks)
15188 current_binding_level->blocks
15189 = chainon (current_binding_level->blocks, subblocks);
5ff904cd 15190
c7e4ee3a
CB
15191 if (block)
15192 TREE_USED (block) = 1;
15193 return block;
5ff904cd
JL
15194}
15195
c7e4ee3a
CB
15196void
15197print_lang_decl (file, node, indent)
15198 FILE *file UNUSED;
15199 tree node UNUSED;
15200 int indent UNUSED;
15201{
15202}
5ff904cd 15203
c7e4ee3a
CB
15204void
15205print_lang_identifier (file, node, indent)
15206 FILE *file;
15207 tree node;
15208 int indent;
15209{
15210 print_node (file, "global", IDENTIFIER_GLOBAL_VALUE (node), indent + 4);
15211 print_node (file, "local", IDENTIFIER_LOCAL_VALUE (node), indent + 4);
15212}
5ff904cd 15213
c7e4ee3a
CB
15214void
15215print_lang_statistics ()
15216{
15217}
5ff904cd 15218
c7e4ee3a
CB
15219void
15220print_lang_type (file, node, indent)
15221 FILE *file UNUSED;
15222 tree node UNUSED;
15223 int indent UNUSED;
5ff904cd 15224{
c7e4ee3a 15225}
5ff904cd 15226
c7e4ee3a
CB
15227/* Record a decl-node X as belonging to the current lexical scope.
15228 Check for errors (such as an incompatible declaration for the same
15229 name already seen in the same scope).
5ff904cd 15230
c7e4ee3a
CB
15231 Returns either X or an old decl for the same name.
15232 If an old decl is returned, it may have been smashed
15233 to agree with what X says. */
5ff904cd 15234
c7e4ee3a
CB
15235tree
15236pushdecl (x)
15237 tree x;
15238{
15239 register tree t;
15240 register tree name = DECL_NAME (x);
15241 register struct binding_level *b = current_binding_level;
5ff904cd 15242
c7e4ee3a
CB
15243 if ((TREE_CODE (x) == FUNCTION_DECL)
15244 && (DECL_INITIAL (x) == 0)
15245 && DECL_EXTERNAL (x))
15246 DECL_CONTEXT (x) = NULL_TREE;
56a0044b 15247 else
c7e4ee3a
CB
15248 DECL_CONTEXT (x) = current_function_decl;
15249
15250 if (name)
56a0044b 15251 {
c7e4ee3a
CB
15252 if (IDENTIFIER_INVENTED (name))
15253 {
15254#if BUILT_FOR_270
15255 DECL_ARTIFICIAL (x) = 1;
15256#endif
15257 DECL_IN_SYSTEM_HEADER (x) = 1;
15258 }
5ff904cd 15259
c7e4ee3a 15260 t = lookup_name_current_level (name);
5ff904cd 15261
c7e4ee3a 15262 assert ((t == NULL_TREE) || (DECL_CONTEXT (x) == NULL_TREE));
5ff904cd 15263
c7e4ee3a
CB
15264 /* Don't push non-parms onto list for parms until we understand
15265 why we're doing this and whether it works. */
56a0044b 15266
c7e4ee3a
CB
15267 assert ((b == global_binding_level)
15268 || !ffecom_transform_only_dummies_
15269 || TREE_CODE (x) == PARM_DECL);
5ff904cd 15270
c7e4ee3a
CB
15271 if ((t != NULL_TREE) && duplicate_decls (x, t))
15272 return t;
5ff904cd 15273
c7e4ee3a
CB
15274 /* If we are processing a typedef statement, generate a whole new
15275 ..._TYPE node (which will be just an variant of the existing
15276 ..._TYPE node with identical properties) and then install the
15277 TYPE_DECL node generated to represent the typedef name as the
15278 TYPE_NAME of this brand new (duplicate) ..._TYPE node.
5ff904cd 15279
c7e4ee3a
CB
15280 The whole point here is to end up with a situation where each and every
15281 ..._TYPE node the compiler creates will be uniquely associated with
15282 AT MOST one node representing a typedef name. This way, even though
15283 the compiler substitutes corresponding ..._TYPE nodes for TYPE_DECL
15284 (i.e. "typedef name") nodes very early on, later parts of the
15285 compiler can always do the reverse translation and get back the
15286 corresponding typedef name. For example, given:
5ff904cd 15287
c7e4ee3a 15288 typedef struct S MY_TYPE; MY_TYPE object;
5ff904cd 15289
c7e4ee3a
CB
15290 Later parts of the compiler might only know that `object' was of type
15291 `struct S' if it were not for code just below. With this code
15292 however, later parts of the compiler see something like:
5ff904cd 15293
c7e4ee3a 15294 struct S' == struct S typedef struct S' MY_TYPE; struct S' object;
5ff904cd 15295
c7e4ee3a
CB
15296 And they can then deduce (from the node for type struct S') that the
15297 original object declaration was:
5ff904cd 15298
c7e4ee3a 15299 MY_TYPE object;
5ff904cd 15300
c7e4ee3a
CB
15301 Being able to do this is important for proper support of protoize, and
15302 also for generating precise symbolic debugging information which
15303 takes full account of the programmer's (typedef) vocabulary.
5ff904cd 15304
c7e4ee3a
CB
15305 Obviously, we don't want to generate a duplicate ..._TYPE node if the
15306 TYPE_DECL node that we are now processing really represents a
15307 standard built-in type.
5ff904cd 15308
c7e4ee3a
CB
15309 Since all standard types are effectively declared at line zero in the
15310 source file, we can easily check to see if we are working on a
15311 standard type by checking the current value of lineno. */
15312
15313 if (TREE_CODE (x) == TYPE_DECL)
15314 {
15315 if (DECL_SOURCE_LINE (x) == 0)
15316 {
15317 if (TYPE_NAME (TREE_TYPE (x)) == 0)
15318 TYPE_NAME (TREE_TYPE (x)) = x;
15319 }
15320 else if (TREE_TYPE (x) != error_mark_node)
15321 {
15322 tree tt = TREE_TYPE (x);
15323
15324 tt = build_type_copy (tt);
15325 TYPE_NAME (tt) = x;
15326 TREE_TYPE (x) = tt;
15327 }
15328 }
5ff904cd 15329
c7e4ee3a
CB
15330 /* This name is new in its binding level. Install the new declaration
15331 and return it. */
15332 if (b == global_binding_level)
15333 IDENTIFIER_GLOBAL_VALUE (name) = x;
15334 else
15335 IDENTIFIER_LOCAL_VALUE (name) = x;
15336 }
5ff904cd 15337
c7e4ee3a
CB
15338 /* Put decls on list in reverse order. We will reverse them later if
15339 necessary. */
15340 TREE_CHAIN (x) = b->names;
15341 b->names = x;
5ff904cd 15342
c7e4ee3a 15343 return x;
5ff904cd
JL
15344}
15345
c7e4ee3a 15346/* Nonzero if the current level needs to have a BLOCK made. */
5ff904cd 15347
c7e4ee3a
CB
15348static int
15349kept_level_p ()
5ff904cd 15350{
c7e4ee3a
CB
15351 tree decl;
15352
15353 for (decl = current_binding_level->names;
15354 decl;
15355 decl = TREE_CHAIN (decl))
15356 {
15357 if (TREE_USED (decl) || TREE_CODE (decl) != VAR_DECL
15358 || (DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl)))
15359 /* Currently, there aren't supposed to be non-artificial names
15360 at other than the top block for a function -- they're
15361 believed to always be temps. But it's wise to check anyway. */
15362 return 1;
15363 }
15364 return 0;
5ff904cd
JL
15365}
15366
c7e4ee3a
CB
15367/* Enter a new binding level.
15368 If TAG_TRANSPARENT is nonzero, do so only for the name space of variables,
15369 not for that of tags. */
5ff904cd
JL
15370
15371void
c7e4ee3a
CB
15372pushlevel (tag_transparent)
15373 int tag_transparent;
5ff904cd 15374{
c7e4ee3a 15375 register struct binding_level *newlevel = NULL_BINDING_LEVEL;
5ff904cd 15376
c7e4ee3a 15377 assert (! tag_transparent);
5ff904cd 15378
c7e4ee3a
CB
15379 if (current_binding_level == global_binding_level)
15380 {
15381 named_labels = 0;
15382 }
5ff904cd 15383
c7e4ee3a 15384 /* Reuse or create a struct for this binding level. */
5ff904cd 15385
c7e4ee3a 15386 if (free_binding_level)
77f77701 15387 {
c7e4ee3a
CB
15388 newlevel = free_binding_level;
15389 free_binding_level = free_binding_level->level_chain;
77f77701
DB
15390 }
15391 else
c7e4ee3a
CB
15392 {
15393 newlevel = make_binding_level ();
15394 }
77f77701 15395
c7e4ee3a
CB
15396 /* Add this level to the front of the chain (stack) of levels that
15397 are active. */
71b5e532 15398
c7e4ee3a
CB
15399 *newlevel = clear_binding_level;
15400 newlevel->level_chain = current_binding_level;
15401 current_binding_level = newlevel;
5ff904cd
JL
15402}
15403
c7e4ee3a
CB
15404/* Set the BLOCK node for the innermost scope
15405 (the one we are currently in). */
77f77701 15406
5ff904cd 15407void
c7e4ee3a
CB
15408set_block (block)
15409 register tree block;
5ff904cd 15410{
c7e4ee3a 15411 current_binding_level->this_block = block;
5ff904cd
JL
15412}
15413
c7e4ee3a 15414/* ~~gcc/tree.h *should* declare this, because toplev.c references it. */
5ff904cd 15415
c7e4ee3a 15416/* Can't 'yydebug' a front end not generated by yacc/bison! */
bc289659
ML
15417
15418void
c7e4ee3a
CB
15419set_yydebug (value)
15420 int value;
bc289659 15421{
c7e4ee3a
CB
15422 if (value)
15423 fprintf (stderr, "warning: no yacc/bison-generated output to debug!\n");
bc289659
ML
15424}
15425
c7e4ee3a
CB
15426tree
15427signed_or_unsigned_type (unsignedp, type)
15428 int unsignedp;
15429 tree type;
5ff904cd 15430{
c7e4ee3a 15431 tree type2;
5ff904cd 15432
c7e4ee3a
CB
15433 if (! INTEGRAL_TYPE_P (type))
15434 return type;
15435 if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node))
15436 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
15437 if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
15438 return unsignedp ? unsigned_type_node : integer_type_node;
15439 if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node))
15440 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
15441 if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node))
15442 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
15443 if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node))
15444 return (unsignedp ? long_long_unsigned_type_node
15445 : long_long_integer_type_node);
5ff904cd 15446
c7e4ee3a
CB
15447 type2 = type_for_size (TYPE_PRECISION (type), unsignedp);
15448 if (type2 == NULL_TREE)
15449 return type;
f84639ba 15450
c7e4ee3a 15451 return type2;
5ff904cd
JL
15452}
15453
c7e4ee3a
CB
15454tree
15455signed_type (type)
15456 tree type;
5ff904cd 15457{
c7e4ee3a
CB
15458 tree type1 = TYPE_MAIN_VARIANT (type);
15459 ffeinfoKindtype kt;
15460 tree type2;
5ff904cd 15461
c7e4ee3a
CB
15462 if (type1 == unsigned_char_type_node || type1 == char_type_node)
15463 return signed_char_type_node;
15464 if (type1 == unsigned_type_node)
15465 return integer_type_node;
15466 if (type1 == short_unsigned_type_node)
15467 return short_integer_type_node;
15468 if (type1 == long_unsigned_type_node)
15469 return long_integer_type_node;
15470 if (type1 == long_long_unsigned_type_node)
15471 return long_long_integer_type_node;
15472#if 0 /* gcc/c-* files only */
15473 if (type1 == unsigned_intDI_type_node)
15474 return intDI_type_node;
15475 if (type1 == unsigned_intSI_type_node)
15476 return intSI_type_node;
15477 if (type1 == unsigned_intHI_type_node)
15478 return intHI_type_node;
15479 if (type1 == unsigned_intQI_type_node)
15480 return intQI_type_node;
15481#endif
5ff904cd 15482
c7e4ee3a
CB
15483 type2 = type_for_size (TYPE_PRECISION (type1), 0);
15484 if (type2 != NULL_TREE)
15485 return type2;
5ff904cd 15486
c7e4ee3a
CB
15487 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
15488 {
15489 type2 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
5ff904cd 15490
c7e4ee3a
CB
15491 if (type1 == type2)
15492 return ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
15493 }
15494
15495 return type;
5ff904cd
JL
15496}
15497
c7e4ee3a
CB
15498/* Prepare expr to be an argument of a TRUTH_NOT_EXPR,
15499 or validate its data type for an `if' or `while' statement or ?..: exp.
15500
15501 This preparation consists of taking the ordinary
15502 representation of an expression expr and producing a valid tree
15503 boolean expression describing whether expr is nonzero. We could
15504 simply always do build_binary_op (NE_EXPR, expr, integer_zero_node, 1),
15505 but we optimize comparisons, &&, ||, and !.
15506
15507 The resulting type should always be `integer_type_node'. */
5ff904cd
JL
15508
15509tree
c7e4ee3a
CB
15510truthvalue_conversion (expr)
15511 tree expr;
5ff904cd 15512{
c7e4ee3a
CB
15513 if (TREE_CODE (expr) == ERROR_MARK)
15514 return expr;
5ff904cd 15515
c7e4ee3a
CB
15516#if 0 /* This appears to be wrong for C++. */
15517 /* These really should return error_mark_node after 2.4 is stable.
15518 But not all callers handle ERROR_MARK properly. */
15519 switch (TREE_CODE (TREE_TYPE (expr)))
15520 {
15521 case RECORD_TYPE:
15522 error ("struct type value used where scalar is required");
15523 return integer_zero_node;
5ff904cd 15524
c7e4ee3a
CB
15525 case UNION_TYPE:
15526 error ("union type value used where scalar is required");
15527 return integer_zero_node;
5ff904cd 15528
c7e4ee3a
CB
15529 case ARRAY_TYPE:
15530 error ("array type value used where scalar is required");
15531 return integer_zero_node;
5ff904cd 15532
c7e4ee3a
CB
15533 default:
15534 break;
15535 }
15536#endif /* 0 */
5ff904cd 15537
c7e4ee3a
CB
15538 switch (TREE_CODE (expr))
15539 {
15540 /* It is simpler and generates better code to have only TRUTH_*_EXPR
15541 or comparison expressions as truth values at this level. */
15542#if 0
15543 case COMPONENT_REF:
15544 /* A one-bit unsigned bit-field is already acceptable. */
15545 if (1 == TREE_INT_CST_LOW (DECL_SIZE (TREE_OPERAND (expr, 1)))
15546 && TREE_UNSIGNED (TREE_OPERAND (expr, 1)))
15547 return expr;
15548 break;
15549#endif
15550
15551 case EQ_EXPR:
15552 /* It is simpler and generates better code to have only TRUTH_*_EXPR
15553 or comparison expressions as truth values at this level. */
15554#if 0
15555 if (integer_zerop (TREE_OPERAND (expr, 1)))
15556 return build_unary_op (TRUTH_NOT_EXPR, TREE_OPERAND (expr, 0), 0);
15557#endif
15558 case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
15559 case TRUTH_ANDIF_EXPR:
15560 case TRUTH_ORIF_EXPR:
15561 case TRUTH_AND_EXPR:
15562 case TRUTH_OR_EXPR:
15563 case TRUTH_XOR_EXPR:
15564 TREE_TYPE (expr) = integer_type_node;
15565 return expr;
5ff904cd 15566
c7e4ee3a
CB
15567 case ERROR_MARK:
15568 return expr;
5ff904cd 15569
c7e4ee3a
CB
15570 case INTEGER_CST:
15571 return integer_zerop (expr) ? integer_zero_node : integer_one_node;
5ff904cd 15572
c7e4ee3a
CB
15573 case REAL_CST:
15574 return real_zerop (expr) ? integer_zero_node : integer_one_node;
5ff904cd 15575
c7e4ee3a
CB
15576 case ADDR_EXPR:
15577 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 0)))
15578 return build (COMPOUND_EXPR, integer_type_node,
15579 TREE_OPERAND (expr, 0), integer_one_node);
15580 else
15581 return integer_one_node;
5ff904cd 15582
c7e4ee3a
CB
15583 case COMPLEX_EXPR:
15584 return ffecom_2 ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))
15585 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
15586 integer_type_node,
15587 truthvalue_conversion (TREE_OPERAND (expr, 0)),
15588 truthvalue_conversion (TREE_OPERAND (expr, 1)));
5ff904cd 15589
c7e4ee3a
CB
15590 case NEGATE_EXPR:
15591 case ABS_EXPR:
15592 case FLOAT_EXPR:
15593 case FFS_EXPR:
15594 /* These don't change whether an object is non-zero or zero. */
15595 return truthvalue_conversion (TREE_OPERAND (expr, 0));
5ff904cd 15596
c7e4ee3a
CB
15597 case LROTATE_EXPR:
15598 case RROTATE_EXPR:
15599 /* These don't change whether an object is zero or non-zero, but
15600 we can't ignore them if their second arg has side-effects. */
15601 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)))
15602 return build (COMPOUND_EXPR, integer_type_node, TREE_OPERAND (expr, 1),
15603 truthvalue_conversion (TREE_OPERAND (expr, 0)));
15604 else
15605 return truthvalue_conversion (TREE_OPERAND (expr, 0));
5ff904cd 15606
c7e4ee3a
CB
15607 case COND_EXPR:
15608 /* Distribute the conversion into the arms of a COND_EXPR. */
15609 return fold (build (COND_EXPR, integer_type_node, TREE_OPERAND (expr, 0),
15610 truthvalue_conversion (TREE_OPERAND (expr, 1)),
15611 truthvalue_conversion (TREE_OPERAND (expr, 2))));
5ff904cd 15612
c7e4ee3a
CB
15613 case CONVERT_EXPR:
15614 /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
15615 since that affects how `default_conversion' will behave. */
15616 if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE
15617 || TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)
15618 break;
15619 /* fall through... */
15620 case NOP_EXPR:
15621 /* If this is widening the argument, we can ignore it. */
15622 if (TYPE_PRECISION (TREE_TYPE (expr))
15623 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
15624 return truthvalue_conversion (TREE_OPERAND (expr, 0));
15625 break;
5ff904cd 15626
c7e4ee3a
CB
15627 case MINUS_EXPR:
15628 /* With IEEE arithmetic, x - x may not equal 0, so we can't optimize
15629 this case. */
15630 if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
15631 && TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE)
15632 break;
15633 /* fall through... */
15634 case BIT_XOR_EXPR:
15635 /* This and MINUS_EXPR can be changed into a comparison of the
15636 two objects. */
15637 if (TREE_TYPE (TREE_OPERAND (expr, 0))
15638 == TREE_TYPE (TREE_OPERAND (expr, 1)))
15639 return ffecom_2 (NE_EXPR, integer_type_node,
15640 TREE_OPERAND (expr, 0),
15641 TREE_OPERAND (expr, 1));
15642 return ffecom_2 (NE_EXPR, integer_type_node,
15643 TREE_OPERAND (expr, 0),
15644 fold (build1 (NOP_EXPR,
15645 TREE_TYPE (TREE_OPERAND (expr, 0)),
15646 TREE_OPERAND (expr, 1))));
15647
15648 case BIT_AND_EXPR:
15649 if (integer_onep (TREE_OPERAND (expr, 1)))
15650 return expr;
15651 break;
15652
15653 case MODIFY_EXPR:
15654#if 0 /* No such thing in Fortran. */
15655 if (warn_parentheses && C_EXP_ORIGINAL_CODE (expr) == MODIFY_EXPR)
15656 warning ("suggest parentheses around assignment used as truth value");
15657#endif
15658 break;
15659
15660 default:
15661 break;
5ff904cd
JL
15662 }
15663
c7e4ee3a
CB
15664 if (TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE)
15665 return (ffecom_2
15666 ((TREE_SIDE_EFFECTS (expr)
15667 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
15668 integer_type_node,
15669 truthvalue_conversion (ffecom_1 (REALPART_EXPR,
15670 TREE_TYPE (TREE_TYPE (expr)),
15671 expr)),
15672 truthvalue_conversion (ffecom_1 (IMAGPART_EXPR,
15673 TREE_TYPE (TREE_TYPE (expr)),
15674 expr))));
15675
15676 return ffecom_2 (NE_EXPR, integer_type_node,
15677 expr,
15678 convert (TREE_TYPE (expr), integer_zero_node));
15679}
15680
15681tree
15682type_for_mode (mode, unsignedp)
15683 enum machine_mode mode;
15684 int unsignedp;
15685{
15686 int i;
15687 int j;
15688 tree t;
5ff904cd 15689
c7e4ee3a
CB
15690 if (mode == TYPE_MODE (integer_type_node))
15691 return unsignedp ? unsigned_type_node : integer_type_node;
5ff904cd 15692
c7e4ee3a
CB
15693 if (mode == TYPE_MODE (signed_char_type_node))
15694 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
5ff904cd 15695
c7e4ee3a
CB
15696 if (mode == TYPE_MODE (short_integer_type_node))
15697 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
5ff904cd 15698
c7e4ee3a
CB
15699 if (mode == TYPE_MODE (long_integer_type_node))
15700 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
5ff904cd 15701
c7e4ee3a
CB
15702 if (mode == TYPE_MODE (long_long_integer_type_node))
15703 return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node;
5ff904cd 15704
c7e4ee3a
CB
15705 if (mode == TYPE_MODE (float_type_node))
15706 return float_type_node;
5ff904cd 15707
c7e4ee3a
CB
15708 if (mode == TYPE_MODE (double_type_node))
15709 return double_type_node;
5ff904cd 15710
c7e4ee3a
CB
15711 if (mode == TYPE_MODE (build_pointer_type (char_type_node)))
15712 return build_pointer_type (char_type_node);
5ff904cd 15713
c7e4ee3a
CB
15714 if (mode == TYPE_MODE (build_pointer_type (integer_type_node)))
15715 return build_pointer_type (integer_type_node);
5ff904cd 15716
c7e4ee3a
CB
15717 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
15718 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
15719 {
15720 if (((t = ffecom_tree_type[i][j]) != NULL_TREE)
15721 && (mode == TYPE_MODE (t)))
15722 {
15723 if ((i == FFEINFO_basictypeINTEGER) && unsignedp)
15724 return ffecom_tree_type[FFEINFO_basictypeHOLLERITH][j];
15725 else
15726 return t;
15727 }
15728 }
5ff904cd 15729
c7e4ee3a 15730 return 0;
5ff904cd
JL
15731}
15732
c7e4ee3a
CB
15733tree
15734type_for_size (bits, unsignedp)
15735 unsigned bits;
15736 int unsignedp;
5ff904cd 15737{
c7e4ee3a
CB
15738 ffeinfoKindtype kt;
15739 tree type_node;
5ff904cd 15740
c7e4ee3a
CB
15741 if (bits == TYPE_PRECISION (integer_type_node))
15742 return unsignedp ? unsigned_type_node : integer_type_node;
5ff904cd 15743
c7e4ee3a
CB
15744 if (bits == TYPE_PRECISION (signed_char_type_node))
15745 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
5ff904cd 15746
c7e4ee3a
CB
15747 if (bits == TYPE_PRECISION (short_integer_type_node))
15748 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
5ff904cd 15749
c7e4ee3a
CB
15750 if (bits == TYPE_PRECISION (long_integer_type_node))
15751 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
5ff904cd 15752
c7e4ee3a
CB
15753 if (bits == TYPE_PRECISION (long_long_integer_type_node))
15754 return (unsignedp ? long_long_unsigned_type_node
15755 : long_long_integer_type_node);
5ff904cd 15756
c7e4ee3a 15757 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
5ff904cd 15758 {
c7e4ee3a 15759 type_node = ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
5ff904cd 15760
c7e4ee3a
CB
15761 if ((type_node != NULL_TREE) && (bits == TYPE_PRECISION (type_node)))
15762 return unsignedp ? ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt]
15763 : type_node;
15764 }
5ff904cd 15765
c7e4ee3a
CB
15766 return 0;
15767}
5ff904cd 15768
c7e4ee3a
CB
15769tree
15770unsigned_type (type)
15771 tree type;
15772{
15773 tree type1 = TYPE_MAIN_VARIANT (type);
15774 ffeinfoKindtype kt;
15775 tree type2;
5ff904cd 15776
c7e4ee3a
CB
15777 if (type1 == signed_char_type_node || type1 == char_type_node)
15778 return unsigned_char_type_node;
15779 if (type1 == integer_type_node)
15780 return unsigned_type_node;
15781 if (type1 == short_integer_type_node)
15782 return short_unsigned_type_node;
15783 if (type1 == long_integer_type_node)
15784 return long_unsigned_type_node;
15785 if (type1 == long_long_integer_type_node)
15786 return long_long_unsigned_type_node;
15787#if 0 /* gcc/c-* files only */
15788 if (type1 == intDI_type_node)
15789 return unsigned_intDI_type_node;
15790 if (type1 == intSI_type_node)
15791 return unsigned_intSI_type_node;
15792 if (type1 == intHI_type_node)
15793 return unsigned_intHI_type_node;
15794 if (type1 == intQI_type_node)
15795 return unsigned_intQI_type_node;
15796#endif
5ff904cd 15797
c7e4ee3a
CB
15798 type2 = type_for_size (TYPE_PRECISION (type1), 1);
15799 if (type2 != NULL_TREE)
15800 return type2;
5ff904cd 15801
c7e4ee3a
CB
15802 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
15803 {
15804 type2 = ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
5ff904cd 15805
c7e4ee3a
CB
15806 if (type1 == type2)
15807 return ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
15808 }
5ff904cd 15809
c7e4ee3a
CB
15810 return type;
15811}
5ff904cd 15812
c7e4ee3a
CB
15813#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
15814\f
15815#if FFECOM_GCC_INCLUDE
5ff904cd 15816
c7e4ee3a 15817/* From gcc/cccp.c, the code to handle -I. */
5ff904cd 15818
c7e4ee3a
CB
15819/* Skip leading "./" from a directory name.
15820 This may yield the empty string, which represents the current directory. */
5ff904cd 15821
c7e4ee3a
CB
15822static const char *
15823skip_redundant_dir_prefix (const char *dir)
15824{
15825 while (dir[0] == '.' && dir[1] == '/')
15826 for (dir += 2; *dir == '/'; dir++)
15827 continue;
15828 if (dir[0] == '.' && !dir[1])
15829 dir++;
15830 return dir;
15831}
5ff904cd 15832
c7e4ee3a
CB
15833/* The file_name_map structure holds a mapping of file names for a
15834 particular directory. This mapping is read from the file named
15835 FILE_NAME_MAP_FILE in that directory. Such a file can be used to
15836 map filenames on a file system with severe filename restrictions,
15837 such as DOS. The format of the file name map file is just a series
15838 of lines with two tokens on each line. The first token is the name
15839 to map, and the second token is the actual name to use. */
5ff904cd 15840
c7e4ee3a
CB
15841struct file_name_map
15842{
15843 struct file_name_map *map_next;
15844 char *map_from;
15845 char *map_to;
15846};
5ff904cd 15847
c7e4ee3a 15848#define FILE_NAME_MAP_FILE "header.gcc"
5ff904cd 15849
c7e4ee3a
CB
15850/* Current maximum length of directory names in the search path
15851 for include files. (Altered as we get more of them.) */
5ff904cd 15852
c7e4ee3a 15853static int max_include_len = 0;
5ff904cd 15854
c7e4ee3a
CB
15855struct file_name_list
15856 {
15857 struct file_name_list *next;
15858 char *fname;
15859 /* Mapping of file names for this directory. */
15860 struct file_name_map *name_map;
15861 /* Non-zero if name_map is valid. */
15862 int got_name_map;
15863 };
5ff904cd 15864
c7e4ee3a
CB
15865static struct file_name_list *include = NULL; /* First dir to search */
15866static struct file_name_list *last_include = NULL; /* Last in chain */
5ff904cd 15867
c7e4ee3a
CB
15868/* I/O buffer structure.
15869 The `fname' field is nonzero for source files and #include files
15870 and for the dummy text used for -D and -U.
15871 It is zero for rescanning results of macro expansion
15872 and for expanding macro arguments. */
15873#define INPUT_STACK_MAX 400
15874static struct file_buf {
15875 char *fname;
15876 /* Filename specified with #line command. */
15877 char *nominal_fname;
15878 /* Record where in the search path this file was found.
15879 For #include_next. */
15880 struct file_name_list *dir;
15881 ffewhereLine line;
15882 ffewhereColumn column;
15883} instack[INPUT_STACK_MAX];
5ff904cd 15884
c7e4ee3a
CB
15885static int last_error_tick = 0; /* Incremented each time we print it. */
15886static int input_file_stack_tick = 0; /* Incremented when status changes. */
5ff904cd 15887
c7e4ee3a
CB
15888/* Current nesting level of input sources.
15889 `instack[indepth]' is the level currently being read. */
15890static int indepth = -1;
5ff904cd 15891
c7e4ee3a 15892typedef struct file_buf FILE_BUF;
5ff904cd 15893
c7e4ee3a 15894typedef unsigned char U_CHAR;
5ff904cd 15895
c7e4ee3a
CB
15896/* table to tell if char can be part of a C identifier. */
15897U_CHAR is_idchar[256];
15898/* table to tell if char can be first char of a c identifier. */
15899U_CHAR is_idstart[256];
15900/* table to tell if c is horizontal space. */
15901U_CHAR is_hor_space[256];
15902/* table to tell if c is horizontal or vertical space. */
15903static U_CHAR is_space[256];
5ff904cd 15904
c7e4ee3a
CB
15905#define SKIP_WHITE_SPACE(p) do { while (is_hor_space[*p]) p++; } while (0)
15906#define SKIP_ALL_WHITE_SPACE(p) do { while (is_space[*p]) p++; } while (0)
5ff904cd 15907
c7e4ee3a
CB
15908/* Nonzero means -I- has been seen,
15909 so don't look for #include "foo" the source-file directory. */
15910static int ignore_srcdir;
5ff904cd 15911
c7e4ee3a
CB
15912#ifndef INCLUDE_LEN_FUDGE
15913#define INCLUDE_LEN_FUDGE 0
15914#endif
5ff904cd 15915
c7e4ee3a
CB
15916static void append_include_chain (struct file_name_list *first,
15917 struct file_name_list *last);
15918static FILE *open_include_file (char *filename,
15919 struct file_name_list *searchptr);
15920static void print_containing_files (ffebadSeverity sev);
15921static const char *skip_redundant_dir_prefix (const char *);
15922static char *read_filename_string (int ch, FILE *f);
15923static struct file_name_map *read_name_map (const char *dirname);
5ff904cd 15924
c7e4ee3a
CB
15925/* Append a chain of `struct file_name_list's
15926 to the end of the main include chain.
15927 FIRST is the beginning of the chain to append, and LAST is the end. */
5ff904cd 15928
c7e4ee3a
CB
15929static void
15930append_include_chain (first, last)
15931 struct file_name_list *first, *last;
5ff904cd 15932{
c7e4ee3a 15933 struct file_name_list *dir;
5ff904cd 15934
c7e4ee3a
CB
15935 if (!first || !last)
15936 return;
5ff904cd 15937
c7e4ee3a
CB
15938 if (include == 0)
15939 include = first;
15940 else
15941 last_include->next = first;
5ff904cd 15942
c7e4ee3a
CB
15943 for (dir = first; ; dir = dir->next) {
15944 int len = strlen (dir->fname) + INCLUDE_LEN_FUDGE;
15945 if (len > max_include_len)
15946 max_include_len = len;
15947 if (dir == last)
15948 break;
15949 }
15950
15951 last->next = NULL;
15952 last_include = last;
5ff904cd
JL
15953}
15954
c7e4ee3a
CB
15955/* Try to open include file FILENAME. SEARCHPTR is the directory
15956 being tried from the include file search path. This function maps
15957 filenames on file systems based on information read by
15958 read_name_map. */
15959
15960static FILE *
15961open_include_file (filename, searchptr)
15962 char *filename;
15963 struct file_name_list *searchptr;
5ff904cd 15964{
c7e4ee3a
CB
15965 register struct file_name_map *map;
15966 register char *from;
15967 char *p, *dir;
5ff904cd 15968
c7e4ee3a
CB
15969 if (searchptr && ! searchptr->got_name_map)
15970 {
15971 searchptr->name_map = read_name_map (searchptr->fname
15972 ? searchptr->fname : ".");
15973 searchptr->got_name_map = 1;
15974 }
5ff904cd 15975
c7e4ee3a
CB
15976 /* First check the mapping for the directory we are using. */
15977 if (searchptr && searchptr->name_map)
15978 {
15979 from = filename;
15980 if (searchptr->fname)
15981 from += strlen (searchptr->fname) + 1;
15982 for (map = searchptr->name_map; map; map = map->map_next)
15983 {
15984 if (! strcmp (map->map_from, from))
15985 {
15986 /* Found a match. */
15987 return fopen (map->map_to, "r");
15988 }
15989 }
15990 }
5ff904cd 15991
c7e4ee3a
CB
15992 /* Try to find a mapping file for the particular directory we are
15993 looking in. Thus #include <sys/types.h> will look up sys/types.h
15994 in /usr/include/header.gcc and look up types.h in
15995 /usr/include/sys/header.gcc. */
15996 p = rindex (filename, '/');
15997#ifdef DIR_SEPARATOR
15998 if (! p) p = rindex (filename, DIR_SEPARATOR);
15999 else {
16000 char *tmp = rindex (filename, DIR_SEPARATOR);
16001 if (tmp != NULL && tmp > p) p = tmp;
16002 }
16003#endif
16004 if (! p)
16005 p = filename;
16006 if (searchptr
16007 && searchptr->fname
16008 && strlen (searchptr->fname) == (size_t) (p - filename)
16009 && ! strncmp (searchptr->fname, filename, (int) (p - filename)))
16010 {
16011 /* FILENAME is in SEARCHPTR, which we've already checked. */
16012 return fopen (filename, "r");
16013 }
16014
16015 if (p == filename)
16016 {
16017 from = filename;
16018 map = read_name_map (".");
16019 }
16020 else
5ff904cd 16021 {
c7e4ee3a
CB
16022 dir = (char *) xmalloc (p - filename + 1);
16023 memcpy (dir, filename, p - filename);
16024 dir[p - filename] = '\0';
16025 from = p + 1;
16026 map = read_name_map (dir);
16027 free (dir);
5ff904cd 16028 }
c7e4ee3a
CB
16029 for (; map; map = map->map_next)
16030 if (! strcmp (map->map_from, from))
16031 return fopen (map->map_to, "r");
5ff904cd 16032
c7e4ee3a 16033 return fopen (filename, "r");
5ff904cd
JL
16034}
16035
c7e4ee3a
CB
16036/* Print the file names and line numbers of the #include
16037 commands which led to the current file. */
5ff904cd 16038
c7e4ee3a
CB
16039static void
16040print_containing_files (ffebadSeverity sev)
16041{
16042 FILE_BUF *ip = NULL;
16043 int i;
16044 int first = 1;
16045 const char *str1;
16046 const char *str2;
5ff904cd 16047
c7e4ee3a
CB
16048 /* If stack of files hasn't changed since we last printed
16049 this info, don't repeat it. */
16050 if (last_error_tick == input_file_stack_tick)
16051 return;
5ff904cd 16052
c7e4ee3a
CB
16053 for (i = indepth; i >= 0; i--)
16054 if (instack[i].fname != NULL) {
16055 ip = &instack[i];
16056 break;
16057 }
5ff904cd 16058
c7e4ee3a
CB
16059 /* Give up if we don't find a source file. */
16060 if (ip == NULL)
16061 return;
5ff904cd 16062
c7e4ee3a
CB
16063 /* Find the other, outer source files. */
16064 for (i--; i >= 0; i--)
16065 if (instack[i].fname != NULL)
16066 {
16067 ip = &instack[i];
16068 if (first)
16069 {
16070 first = 0;
16071 str1 = "In file included";
16072 }
16073 else
16074 {
16075 str1 = "... ...";
16076 }
5ff904cd 16077
c7e4ee3a
CB
16078 if (i == 1)
16079 str2 = ":";
16080 else
16081 str2 = "";
5ff904cd 16082
c7e4ee3a
CB
16083 ffebad_start_msg ("%A from %B at %0%C", sev);
16084 ffebad_here (0, ip->line, ip->column);
16085 ffebad_string (str1);
16086 ffebad_string (ip->nominal_fname);
16087 ffebad_string (str2);
16088 ffebad_finish ();
16089 }
5ff904cd 16090
c7e4ee3a
CB
16091 /* Record we have printed the status as of this time. */
16092 last_error_tick = input_file_stack_tick;
16093}
5ff904cd 16094
c7e4ee3a
CB
16095/* Read a space delimited string of unlimited length from a stdio
16096 file. */
5ff904cd 16097
c7e4ee3a
CB
16098static char *
16099read_filename_string (ch, f)
16100 int ch;
16101 FILE *f;
16102{
16103 char *alloc, *set;
16104 int len;
5ff904cd 16105
c7e4ee3a
CB
16106 len = 20;
16107 set = alloc = xmalloc (len + 1);
16108 if (! is_space[ch])
16109 {
16110 *set++ = ch;
16111 while ((ch = getc (f)) != EOF && ! is_space[ch])
16112 {
16113 if (set - alloc == len)
16114 {
16115 len *= 2;
16116 alloc = xrealloc (alloc, len + 1);
16117 set = alloc + len / 2;
16118 }
16119 *set++ = ch;
16120 }
16121 }
16122 *set = '\0';
16123 ungetc (ch, f);
16124 return alloc;
16125}
5ff904cd 16126
c7e4ee3a 16127/* Read the file name map file for DIRNAME. */
5ff904cd 16128
c7e4ee3a
CB
16129static struct file_name_map *
16130read_name_map (dirname)
16131 const char *dirname;
16132{
16133 /* This structure holds a linked list of file name maps, one per
16134 directory. */
16135 struct file_name_map_list
16136 {
16137 struct file_name_map_list *map_list_next;
16138 char *map_list_name;
16139 struct file_name_map *map_list_map;
16140 };
16141 static struct file_name_map_list *map_list;
16142 register struct file_name_map_list *map_list_ptr;
16143 char *name;
16144 FILE *f;
16145 size_t dirlen;
16146 int separator_needed;
5ff904cd 16147
c7e4ee3a 16148 dirname = skip_redundant_dir_prefix (dirname);
5ff904cd 16149
c7e4ee3a
CB
16150 for (map_list_ptr = map_list; map_list_ptr;
16151 map_list_ptr = map_list_ptr->map_list_next)
16152 if (! strcmp (map_list_ptr->map_list_name, dirname))
16153 return map_list_ptr->map_list_map;
5ff904cd 16154
c7e4ee3a
CB
16155 map_list_ptr = ((struct file_name_map_list *)
16156 xmalloc (sizeof (struct file_name_map_list)));
16157 map_list_ptr->map_list_name = xstrdup (dirname);
16158 map_list_ptr->map_list_map = NULL;
5ff904cd 16159
c7e4ee3a
CB
16160 dirlen = strlen (dirname);
16161 separator_needed = dirlen != 0 && dirname[dirlen - 1] != '/';
16162 name = (char *) xmalloc (dirlen + strlen (FILE_NAME_MAP_FILE) + 2);
16163 strcpy (name, dirname);
16164 name[dirlen] = '/';
16165 strcpy (name + dirlen + separator_needed, FILE_NAME_MAP_FILE);
16166 f = fopen (name, "r");
16167 free (name);
16168 if (!f)
16169 map_list_ptr->map_list_map = NULL;
16170 else
16171 {
16172 int ch;
5ff904cd 16173
c7e4ee3a
CB
16174 while ((ch = getc (f)) != EOF)
16175 {
16176 char *from, *to;
16177 struct file_name_map *ptr;
16178
16179 if (is_space[ch])
16180 continue;
16181 from = read_filename_string (ch, f);
16182 while ((ch = getc (f)) != EOF && is_hor_space[ch])
16183 ;
16184 to = read_filename_string (ch, f);
5ff904cd 16185
c7e4ee3a
CB
16186 ptr = ((struct file_name_map *)
16187 xmalloc (sizeof (struct file_name_map)));
16188 ptr->map_from = from;
5ff904cd 16189
c7e4ee3a
CB
16190 /* Make the real filename absolute. */
16191 if (*to == '/')
16192 ptr->map_to = to;
16193 else
16194 {
16195 ptr->map_to = xmalloc (dirlen + strlen (to) + 2);
16196 strcpy (ptr->map_to, dirname);
16197 ptr->map_to[dirlen] = '/';
16198 strcpy (ptr->map_to + dirlen + separator_needed, to);
16199 free (to);
16200 }
5ff904cd 16201
c7e4ee3a
CB
16202 ptr->map_next = map_list_ptr->map_list_map;
16203 map_list_ptr->map_list_map = ptr;
5ff904cd 16204
c7e4ee3a
CB
16205 while ((ch = getc (f)) != '\n')
16206 if (ch == EOF)
16207 break;
16208 }
16209 fclose (f);
5ff904cd
JL
16210 }
16211
c7e4ee3a
CB
16212 map_list_ptr->map_list_next = map_list;
16213 map_list = map_list_ptr;
5ff904cd 16214
c7e4ee3a 16215 return map_list_ptr->map_list_map;
5ff904cd
JL
16216}
16217
c7e4ee3a
CB
16218static void
16219ffecom_file_ (char *name)
5ff904cd 16220{
c7e4ee3a 16221 FILE_BUF *fp;
5ff904cd 16222
c7e4ee3a
CB
16223 /* Do partial setup of input buffer for the sake of generating
16224 early #line directives (when -g is in effect). */
5ff904cd 16225
c7e4ee3a
CB
16226 fp = &instack[++indepth];
16227 memset ((char *) fp, 0, sizeof (FILE_BUF));
16228 if (name == NULL)
16229 name = "";
16230 fp->nominal_fname = fp->fname = name;
16231}
5ff904cd 16232
c7e4ee3a 16233/* Initialize syntactic classifications of characters. */
5ff904cd 16234
c7e4ee3a
CB
16235static void
16236ffecom_initialize_char_syntax_ ()
16237{
16238 register int i;
5ff904cd 16239
c7e4ee3a
CB
16240 /*
16241 * Set up is_idchar and is_idstart tables. These should be
16242 * faster than saying (is_alpha (c) || c == '_'), etc.
16243 * Set up these things before calling any routines tthat
16244 * refer to them.
16245 */
16246 for (i = 'a'; i <= 'z'; i++) {
16247 is_idchar[i - 'a' + 'A'] = 1;
16248 is_idchar[i] = 1;
16249 is_idstart[i - 'a' + 'A'] = 1;
16250 is_idstart[i] = 1;
16251 }
16252 for (i = '0'; i <= '9'; i++)
16253 is_idchar[i] = 1;
16254 is_idchar['_'] = 1;
16255 is_idstart['_'] = 1;
5ff904cd 16256
c7e4ee3a
CB
16257 /* horizontal space table */
16258 is_hor_space[' '] = 1;
16259 is_hor_space['\t'] = 1;
16260 is_hor_space['\v'] = 1;
16261 is_hor_space['\f'] = 1;
16262 is_hor_space['\r'] = 1;
5ff904cd 16263
c7e4ee3a
CB
16264 is_space[' '] = 1;
16265 is_space['\t'] = 1;
16266 is_space['\v'] = 1;
16267 is_space['\f'] = 1;
16268 is_space['\n'] = 1;
16269 is_space['\r'] = 1;
16270}
5ff904cd 16271
c7e4ee3a
CB
16272static void
16273ffecom_close_include_ (FILE *f)
16274{
16275 fclose (f);
5ff904cd 16276
c7e4ee3a
CB
16277 indepth--;
16278 input_file_stack_tick++;
5ff904cd 16279
c7e4ee3a
CB
16280 ffewhere_line_kill (instack[indepth].line);
16281 ffewhere_column_kill (instack[indepth].column);
16282}
5ff904cd 16283
c7e4ee3a
CB
16284static int
16285ffecom_decode_include_option_ (char *spec)
16286{
16287 struct file_name_list *dirtmp;
16288
16289 if (! ignore_srcdir && !strcmp (spec, "-"))
16290 ignore_srcdir = 1;
16291 else
16292 {
16293 dirtmp = (struct file_name_list *)
16294 xmalloc (sizeof (struct file_name_list));
16295 dirtmp->next = 0; /* New one goes on the end */
16296 if (spec[0] != 0)
16297 dirtmp->fname = spec;
16298 else
16299 fatal ("Directory name must immediately follow -I option with no intervening spaces, as in `-Idir', not `-I dir'");
16300 dirtmp->got_name_map = 0;
16301 append_include_chain (dirtmp, dirtmp);
16302 }
16303 return 1;
5ff904cd
JL
16304}
16305
c7e4ee3a
CB
16306/* Open INCLUDEd file. */
16307
16308static FILE *
16309ffecom_open_include_ (char *name, ffewhereLine l, ffewhereColumn c)
5ff904cd 16310{
c7e4ee3a
CB
16311 char *fbeg = name;
16312 size_t flen = strlen (fbeg);
16313 struct file_name_list *search_start = include; /* Chain of dirs to search */
16314 struct file_name_list dsp[1]; /* First in chain, if #include "..." */
16315 struct file_name_list *searchptr = 0;
16316 char *fname; /* Dynamically allocated fname buffer */
16317 FILE *f;
16318 FILE_BUF *fp;
5ff904cd 16319
c7e4ee3a
CB
16320 if (flen == 0)
16321 return NULL;
5ff904cd 16322
c7e4ee3a 16323 dsp[0].fname = NULL;
5ff904cd 16324
c7e4ee3a
CB
16325 /* If -I- was specified, don't search current dir, only spec'd ones. */
16326 if (!ignore_srcdir)
16327 {
16328 for (fp = &instack[indepth]; fp >= instack; fp--)
16329 {
16330 int n;
16331 char *ep;
16332 char *nam;
5ff904cd 16333
c7e4ee3a
CB
16334 if ((nam = fp->nominal_fname) != NULL)
16335 {
16336 /* Found a named file. Figure out dir of the file,
16337 and put it in front of the search list. */
16338 dsp[0].next = search_start;
16339 search_start = dsp;
16340#ifndef VMS
16341 ep = rindex (nam, '/');
16342#ifdef DIR_SEPARATOR
16343 if (ep == NULL) ep = rindex (nam, DIR_SEPARATOR);
16344 else {
16345 char *tmp = rindex (nam, DIR_SEPARATOR);
16346 if (tmp != NULL && tmp > ep) ep = tmp;
16347 }
16348#endif
16349#else /* VMS */
16350 ep = rindex (nam, ']');
16351 if (ep == NULL) ep = rindex (nam, '>');
16352 if (ep == NULL) ep = rindex (nam, ':');
16353 if (ep != NULL) ep++;
16354#endif /* VMS */
16355 if (ep != NULL)
16356 {
16357 n = ep - nam;
16358 dsp[0].fname = (char *) xmalloc (n + 1);
16359 strncpy (dsp[0].fname, nam, n);
16360 dsp[0].fname[n] = '\0';
16361 if (n + INCLUDE_LEN_FUDGE > max_include_len)
16362 max_include_len = n + INCLUDE_LEN_FUDGE;
16363 }
16364 else
16365 dsp[0].fname = NULL; /* Current directory */
16366 dsp[0].got_name_map = 0;
16367 break;
16368 }
16369 }
16370 }
5ff904cd 16371
c7e4ee3a
CB
16372 /* Allocate this permanently, because it gets stored in the definitions
16373 of macros. */
16374 fname = xmalloc (max_include_len + flen + 4);
16375 /* + 2 above for slash and terminating null. */
16376 /* + 2 added for '.h' on VMS (to support '#include filename') (NOT USED
16377 for g77 yet). */
5ff904cd 16378
c7e4ee3a 16379 /* If specified file name is absolute, just open it. */
5ff904cd 16380
c7e4ee3a
CB
16381 if (*fbeg == '/'
16382#ifdef DIR_SEPARATOR
16383 || *fbeg == DIR_SEPARATOR
16384#endif
16385 )
16386 {
16387 strncpy (fname, (char *) fbeg, flen);
16388 fname[flen] = 0;
16389 f = open_include_file (fname, NULL_PTR);
5ff904cd 16390 }
c7e4ee3a
CB
16391 else
16392 {
16393 f = NULL;
5ff904cd 16394
c7e4ee3a
CB
16395 /* Search directory path, trying to open the file.
16396 Copy each filename tried into FNAME. */
5ff904cd 16397
c7e4ee3a
CB
16398 for (searchptr = search_start; searchptr; searchptr = searchptr->next)
16399 {
16400 if (searchptr->fname)
16401 {
16402 /* The empty string in a search path is ignored.
16403 This makes it possible to turn off entirely
16404 a standard piece of the list. */
16405 if (searchptr->fname[0] == 0)
16406 continue;
16407 strcpy (fname, skip_redundant_dir_prefix (searchptr->fname));
16408 if (fname[0] && fname[strlen (fname) - 1] != '/')
16409 strcat (fname, "/");
16410 fname[strlen (fname) + flen] = 0;
16411 }
16412 else
16413 fname[0] = 0;
5ff904cd 16414
c7e4ee3a
CB
16415 strncat (fname, fbeg, flen);
16416#ifdef VMS
16417 /* Change this 1/2 Unix 1/2 VMS file specification into a
16418 full VMS file specification */
16419 if (searchptr->fname && (searchptr->fname[0] != 0))
16420 {
16421 /* Fix up the filename */
16422 hack_vms_include_specification (fname);
16423 }
16424 else
16425 {
16426 /* This is a normal VMS filespec, so use it unchanged. */
16427 strncpy (fname, (char *) fbeg, flen);
16428 fname[flen] = 0;
16429#if 0 /* Not for g77. */
16430 /* if it's '#include filename', add the missing .h */
16431 if (index (fname, '.') == NULL)
16432 strcat (fname, ".h");
5ff904cd 16433#endif
c7e4ee3a
CB
16434 }
16435#endif /* VMS */
16436 f = open_include_file (fname, searchptr);
16437#ifdef EACCES
16438 if (f == NULL && errno == EACCES)
16439 {
16440 print_containing_files (FFEBAD_severityWARNING);
16441 ffebad_start_msg ("At %0, INCLUDE file %A exists, but is not readable",
16442 FFEBAD_severityWARNING);
16443 ffebad_string (fname);
16444 ffebad_here (0, l, c);
16445 ffebad_finish ();
16446 }
16447#endif
16448 if (f != NULL)
16449 break;
16450 }
16451 }
5ff904cd 16452
c7e4ee3a 16453 if (f == NULL)
5ff904cd 16454 {
c7e4ee3a 16455 /* A file that was not found. */
5ff904cd 16456
c7e4ee3a
CB
16457 strncpy (fname, (char *) fbeg, flen);
16458 fname[flen] = 0;
16459 print_containing_files (ffebad_severity (FFEBAD_OPEN_INCLUDE));
16460 ffebad_start (FFEBAD_OPEN_INCLUDE);
16461 ffebad_here (0, l, c);
16462 ffebad_string (fname);
16463 ffebad_finish ();
5ff904cd
JL
16464 }
16465
c7e4ee3a
CB
16466 if (dsp[0].fname != NULL)
16467 free (dsp[0].fname);
5ff904cd 16468
c7e4ee3a
CB
16469 if (f == NULL)
16470 return NULL;
5ff904cd 16471
c7e4ee3a
CB
16472 if (indepth >= (INPUT_STACK_MAX - 1))
16473 {
16474 print_containing_files (FFEBAD_severityFATAL);
16475 ffebad_start_msg ("At %0, INCLUDE nesting too deep",
16476 FFEBAD_severityFATAL);
16477 ffebad_string (fname);
16478 ffebad_here (0, l, c);
16479 ffebad_finish ();
16480 return NULL;
16481 }
5ff904cd 16482
c7e4ee3a
CB
16483 instack[indepth].line = ffewhere_line_use (l);
16484 instack[indepth].column = ffewhere_column_use (c);
5ff904cd 16485
c7e4ee3a
CB
16486 fp = &instack[indepth + 1];
16487 memset ((char *) fp, 0, sizeof (FILE_BUF));
16488 fp->nominal_fname = fp->fname = fname;
16489 fp->dir = searchptr;
5ff904cd 16490
c7e4ee3a
CB
16491 indepth++;
16492 input_file_stack_tick++;
5ff904cd 16493
c7e4ee3a
CB
16494 return f;
16495}
16496#endif /* FFECOM_GCC_INCLUDE */
5ff904cd 16497
c7e4ee3a
CB
16498/**INDENT* (Do not reformat this comment even with -fca option.)
16499 Data-gathering files: Given the source file listed below, compiled with
16500 f2c I obtained the output file listed after that, and from the output
16501 file I derived the above code.
5ff904cd 16502
c7e4ee3a
CB
16503-------- (begin input file to f2c)
16504 implicit none
16505 character*10 A1,A2
16506 complex C1,C2
16507 integer I1,I2
16508 real R1,R2
16509 double precision D1,D2
16510C
16511 call getem(A1,A2,C1,C2,I1,I2,R1,R2,D1,D2)
16512c /
16513 call fooI(I1/I2)
16514 call fooR(R1/I1)
16515 call fooD(D1/I1)
16516 call fooC(C1/I1)
16517 call fooR(R1/R2)
16518 call fooD(R1/D1)
16519 call fooD(D1/D2)
16520 call fooD(D1/R1)
16521 call fooC(C1/C2)
16522 call fooC(C1/R1)
16523 call fooZ(C1/D1)
16524c **
16525 call fooI(I1**I2)
16526 call fooR(R1**I1)
16527 call fooD(D1**I1)
16528 call fooC(C1**I1)
16529 call fooR(R1**R2)
16530 call fooD(R1**D1)
16531 call fooD(D1**D2)
16532 call fooD(D1**R1)
16533 call fooC(C1**C2)
16534 call fooC(C1**R1)
16535 call fooZ(C1**D1)
16536c FFEINTRIN_impABS
16537 call fooR(ABS(R1))
16538c FFEINTRIN_impACOS
16539 call fooR(ACOS(R1))
16540c FFEINTRIN_impAIMAG
16541 call fooR(AIMAG(C1))
16542c FFEINTRIN_impAINT
16543 call fooR(AINT(R1))
16544c FFEINTRIN_impALOG
16545 call fooR(ALOG(R1))
16546c FFEINTRIN_impALOG10
16547 call fooR(ALOG10(R1))
16548c FFEINTRIN_impAMAX0
16549 call fooR(AMAX0(I1,I2))
16550c FFEINTRIN_impAMAX1
16551 call fooR(AMAX1(R1,R2))
16552c FFEINTRIN_impAMIN0
16553 call fooR(AMIN0(I1,I2))
16554c FFEINTRIN_impAMIN1
16555 call fooR(AMIN1(R1,R2))
16556c FFEINTRIN_impAMOD
16557 call fooR(AMOD(R1,R2))
16558c FFEINTRIN_impANINT
16559 call fooR(ANINT(R1))
16560c FFEINTRIN_impASIN
16561 call fooR(ASIN(R1))
16562c FFEINTRIN_impATAN
16563 call fooR(ATAN(R1))
16564c FFEINTRIN_impATAN2
16565 call fooR(ATAN2(R1,R2))
16566c FFEINTRIN_impCABS
16567 call fooR(CABS(C1))
16568c FFEINTRIN_impCCOS
16569 call fooC(CCOS(C1))
16570c FFEINTRIN_impCEXP
16571 call fooC(CEXP(C1))
16572c FFEINTRIN_impCHAR
16573 call fooA(CHAR(I1))
16574c FFEINTRIN_impCLOG
16575 call fooC(CLOG(C1))
16576c FFEINTRIN_impCONJG
16577 call fooC(CONJG(C1))
16578c FFEINTRIN_impCOS
16579 call fooR(COS(R1))
16580c FFEINTRIN_impCOSH
16581 call fooR(COSH(R1))
16582c FFEINTRIN_impCSIN
16583 call fooC(CSIN(C1))
16584c FFEINTRIN_impCSQRT
16585 call fooC(CSQRT(C1))
16586c FFEINTRIN_impDABS
16587 call fooD(DABS(D1))
16588c FFEINTRIN_impDACOS
16589 call fooD(DACOS(D1))
16590c FFEINTRIN_impDASIN
16591 call fooD(DASIN(D1))
16592c FFEINTRIN_impDATAN
16593 call fooD(DATAN(D1))
16594c FFEINTRIN_impDATAN2
16595 call fooD(DATAN2(D1,D2))
16596c FFEINTRIN_impDCOS
16597 call fooD(DCOS(D1))
16598c FFEINTRIN_impDCOSH
16599 call fooD(DCOSH(D1))
16600c FFEINTRIN_impDDIM
16601 call fooD(DDIM(D1,D2))
16602c FFEINTRIN_impDEXP
16603 call fooD(DEXP(D1))
16604c FFEINTRIN_impDIM
16605 call fooR(DIM(R1,R2))
16606c FFEINTRIN_impDINT
16607 call fooD(DINT(D1))
16608c FFEINTRIN_impDLOG
16609 call fooD(DLOG(D1))
16610c FFEINTRIN_impDLOG10
16611 call fooD(DLOG10(D1))
16612c FFEINTRIN_impDMAX1
16613 call fooD(DMAX1(D1,D2))
16614c FFEINTRIN_impDMIN1
16615 call fooD(DMIN1(D1,D2))
16616c FFEINTRIN_impDMOD
16617 call fooD(DMOD(D1,D2))
16618c FFEINTRIN_impDNINT
16619 call fooD(DNINT(D1))
16620c FFEINTRIN_impDPROD
16621 call fooD(DPROD(R1,R2))
16622c FFEINTRIN_impDSIGN
16623 call fooD(DSIGN(D1,D2))
16624c FFEINTRIN_impDSIN
16625 call fooD(DSIN(D1))
16626c FFEINTRIN_impDSINH
16627 call fooD(DSINH(D1))
16628c FFEINTRIN_impDSQRT
16629 call fooD(DSQRT(D1))
16630c FFEINTRIN_impDTAN
16631 call fooD(DTAN(D1))
16632c FFEINTRIN_impDTANH
16633 call fooD(DTANH(D1))
16634c FFEINTRIN_impEXP
16635 call fooR(EXP(R1))
16636c FFEINTRIN_impIABS
16637 call fooI(IABS(I1))
16638c FFEINTRIN_impICHAR
16639 call fooI(ICHAR(A1))
16640c FFEINTRIN_impIDIM
16641 call fooI(IDIM(I1,I2))
16642c FFEINTRIN_impIDNINT
16643 call fooI(IDNINT(D1))
16644c FFEINTRIN_impINDEX
16645 call fooI(INDEX(A1,A2))
16646c FFEINTRIN_impISIGN
16647 call fooI(ISIGN(I1,I2))
16648c FFEINTRIN_impLEN
16649 call fooI(LEN(A1))
16650c FFEINTRIN_impLGE
16651 call fooL(LGE(A1,A2))
16652c FFEINTRIN_impLGT
16653 call fooL(LGT(A1,A2))
16654c FFEINTRIN_impLLE
16655 call fooL(LLE(A1,A2))
16656c FFEINTRIN_impLLT
16657 call fooL(LLT(A1,A2))
16658c FFEINTRIN_impMAX0
16659 call fooI(MAX0(I1,I2))
16660c FFEINTRIN_impMAX1
16661 call fooI(MAX1(R1,R2))
16662c FFEINTRIN_impMIN0
16663 call fooI(MIN0(I1,I2))
16664c FFEINTRIN_impMIN1
16665 call fooI(MIN1(R1,R2))
16666c FFEINTRIN_impMOD
16667 call fooI(MOD(I1,I2))
16668c FFEINTRIN_impNINT
16669 call fooI(NINT(R1))
16670c FFEINTRIN_impSIGN
16671 call fooR(SIGN(R1,R2))
16672c FFEINTRIN_impSIN
16673 call fooR(SIN(R1))
16674c FFEINTRIN_impSINH
16675 call fooR(SINH(R1))
16676c FFEINTRIN_impSQRT
16677 call fooR(SQRT(R1))
16678c FFEINTRIN_impTAN
16679 call fooR(TAN(R1))
16680c FFEINTRIN_impTANH
16681 call fooR(TANH(R1))
16682c FFEINTRIN_imp_CMPLX_C
16683 call fooC(cmplx(C1,C2))
16684c FFEINTRIN_imp_CMPLX_D
16685 call fooZ(cmplx(D1,D2))
16686c FFEINTRIN_imp_CMPLX_I
16687 call fooC(cmplx(I1,I2))
16688c FFEINTRIN_imp_CMPLX_R
16689 call fooC(cmplx(R1,R2))
16690c FFEINTRIN_imp_DBLE_C
16691 call fooD(dble(C1))
16692c FFEINTRIN_imp_DBLE_D
16693 call fooD(dble(D1))
16694c FFEINTRIN_imp_DBLE_I
16695 call fooD(dble(I1))
16696c FFEINTRIN_imp_DBLE_R
16697 call fooD(dble(R1))
16698c FFEINTRIN_imp_INT_C
16699 call fooI(int(C1))
16700c FFEINTRIN_imp_INT_D
16701 call fooI(int(D1))
16702c FFEINTRIN_imp_INT_I
16703 call fooI(int(I1))
16704c FFEINTRIN_imp_INT_R
16705 call fooI(int(R1))
16706c FFEINTRIN_imp_REAL_C
16707 call fooR(real(C1))
16708c FFEINTRIN_imp_REAL_D
16709 call fooR(real(D1))
16710c FFEINTRIN_imp_REAL_I
16711 call fooR(real(I1))
16712c FFEINTRIN_imp_REAL_R
16713 call fooR(real(R1))
16714c
16715c FFEINTRIN_imp_INT_D:
16716c
16717c FFEINTRIN_specIDINT
16718 call fooI(IDINT(D1))
16719c
16720c FFEINTRIN_imp_INT_R:
16721c
16722c FFEINTRIN_specIFIX
16723 call fooI(IFIX(R1))
16724c FFEINTRIN_specINT
16725 call fooI(INT(R1))
16726c
16727c FFEINTRIN_imp_REAL_D:
16728c
16729c FFEINTRIN_specSNGL
16730 call fooR(SNGL(D1))
16731c
16732c FFEINTRIN_imp_REAL_I:
16733c
16734c FFEINTRIN_specFLOAT
16735 call fooR(FLOAT(I1))
16736c FFEINTRIN_specREAL
16737 call fooR(REAL(I1))
16738c
16739 end
16740-------- (end input file to f2c)
5ff904cd 16741
c7e4ee3a
CB
16742-------- (begin output from providing above input file as input to:
16743-------- `f2c | gcc -E -C - | sed -e "s:/[*]*://:g" -e "s:[*]*[/]://:g" \
16744-------- -e "s:^#.*$::g"')
5ff904cd 16745
c7e4ee3a
CB
16746// -- translated by f2c (version 19950223).
16747 You must link the resulting object file with the libraries:
16748 -lf2c -lm (in that order)
16749//
5ff904cd 16750
5ff904cd 16751
c7e4ee3a 16752// f2c.h -- Standard Fortran to C header file //
5ff904cd 16753
c7e4ee3a 16754/// barf [ba:rf] 2. "He suggested using FORTRAN, and everybody barfed."
5ff904cd 16755
c7e4ee3a 16756 - From The Shogakukan DICTIONARY OF NEW ENGLISH (Second edition) //
5ff904cd 16757
5ff904cd 16758
5ff904cd 16759
5ff904cd 16760
c7e4ee3a
CB
16761// F2C_INTEGER will normally be `int' but would be `long' on 16-bit systems //
16762// we assume short, float are OK //
16763typedef long int // long int // integer;
16764typedef char *address;
16765typedef short int shortint;
16766typedef float real;
16767typedef double doublereal;
16768typedef struct { real r, i; } complex;
16769typedef struct { doublereal r, i; } doublecomplex;
16770typedef long int // long int // logical;
16771typedef short int shortlogical;
16772typedef char logical1;
16773typedef char integer1;
16774// typedef long long longint; // // system-dependent //
5ff904cd 16775
5ff904cd 16776
5ff904cd 16777
5ff904cd 16778
c7e4ee3a 16779// Extern is for use with -E //
5ff904cd 16780
5ff904cd 16781
5ff904cd 16782
5ff904cd 16783
c7e4ee3a 16784// I/O stuff //
5ff904cd 16785
5ff904cd 16786
5ff904cd 16787
5ff904cd 16788
5ff904cd 16789
5ff904cd 16790
5ff904cd 16791
5ff904cd 16792
c7e4ee3a
CB
16793typedef long int // int or long int // flag;
16794typedef long int // int or long int // ftnlen;
16795typedef long int // int or long int // ftnint;
5ff904cd 16796
5ff904cd 16797
c7e4ee3a
CB
16798//external read, write//
16799typedef struct
16800{ flag cierr;
16801 ftnint ciunit;
16802 flag ciend;
16803 char *cifmt;
16804 ftnint cirec;
16805} cilist;
5ff904cd 16806
c7e4ee3a
CB
16807//internal read, write//
16808typedef struct
16809{ flag icierr;
16810 char *iciunit;
16811 flag iciend;
16812 char *icifmt;
16813 ftnint icirlen;
16814 ftnint icirnum;
16815} icilist;
5ff904cd 16816
c7e4ee3a
CB
16817//open//
16818typedef struct
16819{ flag oerr;
16820 ftnint ounit;
16821 char *ofnm;
16822 ftnlen ofnmlen;
16823 char *osta;
16824 char *oacc;
16825 char *ofm;
16826 ftnint orl;
16827 char *oblnk;
16828} olist;
5ff904cd 16829
c7e4ee3a
CB
16830//close//
16831typedef struct
16832{ flag cerr;
16833 ftnint cunit;
16834 char *csta;
16835} cllist;
5ff904cd 16836
c7e4ee3a
CB
16837//rewind, backspace, endfile//
16838typedef struct
16839{ flag aerr;
16840 ftnint aunit;
16841} alist;
5ff904cd 16842
c7e4ee3a
CB
16843// inquire //
16844typedef struct
16845{ flag inerr;
16846 ftnint inunit;
16847 char *infile;
16848 ftnlen infilen;
16849 ftnint *inex; //parameters in standard's order//
16850 ftnint *inopen;
16851 ftnint *innum;
16852 ftnint *innamed;
16853 char *inname;
16854 ftnlen innamlen;
16855 char *inacc;
16856 ftnlen inacclen;
16857 char *inseq;
16858 ftnlen inseqlen;
16859 char *indir;
16860 ftnlen indirlen;
16861 char *infmt;
16862 ftnlen infmtlen;
16863 char *inform;
16864 ftnint informlen;
16865 char *inunf;
16866 ftnlen inunflen;
16867 ftnint *inrecl;
16868 ftnint *innrec;
16869 char *inblank;
16870 ftnlen inblanklen;
16871} inlist;
5ff904cd 16872
5ff904cd 16873
5ff904cd 16874
c7e4ee3a
CB
16875union Multitype { // for multiple entry points //
16876 integer1 g;
16877 shortint h;
16878 integer i;
16879 // longint j; //
16880 real r;
16881 doublereal d;
16882 complex c;
16883 doublecomplex z;
16884 };
16885
16886typedef union Multitype Multitype;
5ff904cd 16887
c7e4ee3a 16888typedef long Long; // No longer used; formerly in Namelist //
5ff904cd 16889
c7e4ee3a
CB
16890struct Vardesc { // for Namelist //
16891 char *name;
16892 char *addr;
16893 ftnlen *dims;
16894 int type;
16895 };
16896typedef struct Vardesc Vardesc;
5ff904cd 16897
c7e4ee3a
CB
16898struct Namelist {
16899 char *name;
16900 Vardesc **vars;
16901 int nvars;
16902 };
16903typedef struct Namelist Namelist;
5ff904cd 16904
5ff904cd 16905
5ff904cd 16906
5ff904cd 16907
5ff904cd 16908
5ff904cd 16909
5ff904cd 16910
5ff904cd 16911
c7e4ee3a 16912// procedure parameter types for -A and -C++ //
5ff904cd 16913
5ff904cd 16914
5ff904cd 16915
5ff904cd 16916
c7e4ee3a
CB
16917typedef int // Unknown procedure type // (*U_fp)();
16918typedef shortint (*J_fp)();
16919typedef integer (*I_fp)();
16920typedef real (*R_fp)();
16921typedef doublereal (*D_fp)(), (*E_fp)();
16922typedef // Complex // void (*C_fp)();
16923typedef // Double Complex // void (*Z_fp)();
16924typedef logical (*L_fp)();
16925typedef shortlogical (*K_fp)();
16926typedef // Character // void (*H_fp)();
16927typedef // Subroutine // int (*S_fp)();
5ff904cd 16928
c7e4ee3a
CB
16929// E_fp is for real functions when -R is not specified //
16930typedef void C_f; // complex function //
16931typedef void H_f; // character function //
16932typedef void Z_f; // double complex function //
16933typedef doublereal E_f; // real function with -R not specified //
5ff904cd 16934
c7e4ee3a 16935// undef any lower-case symbols that your C compiler predefines, e.g.: //
5ff904cd 16936
5ff904cd 16937
c7e4ee3a
CB
16938// (No such symbols should be defined in a strict ANSI C compiler.
16939 We can avoid trouble with f2c-translated code by using
16940 gcc -ansi [-traditional].) //
16941
5ff904cd 16942
5ff904cd 16943
5ff904cd 16944
5ff904cd 16945
5ff904cd 16946
5ff904cd 16947
5ff904cd 16948
5ff904cd 16949
5ff904cd 16950
5ff904cd 16951
5ff904cd 16952
5ff904cd 16953
5ff904cd 16954
5ff904cd 16955
5ff904cd 16956
5ff904cd 16957
5ff904cd 16958
5ff904cd 16959
5ff904cd 16960
5ff904cd 16961
5ff904cd 16962
5ff904cd 16963
c7e4ee3a
CB
16964// Main program // MAIN__()
16965{
16966 // System generated locals //
16967 integer i__1;
16968 real r__1, r__2;
16969 doublereal d__1, d__2;
16970 complex q__1;
16971 doublecomplex z__1, z__2, z__3;
16972 logical L__1;
16973 char ch__1[1];
16974
16975 // Builtin functions //
16976 void c_div();
16977 integer pow_ii();
16978 double pow_ri(), pow_di();
16979 void pow_ci();
16980 double pow_dd();
16981 void pow_zz();
16982 double acos(), r_imag(), r_int(), log(), r_lg10(), r_mod(), r_nint(),
16983 asin(), atan(), atan2(), c_abs();
16984 void c_cos(), c_exp(), c_log(), r_cnjg();
16985 double cos(), cosh();
16986 void c_sin(), c_sqrt();
16987 double d_dim(), exp(), r_dim(), d_int(), d_lg10(), d_mod(), d_nint(),
16988 d_sign(), sin(), sinh(), sqrt(), tan(), tanh();
16989 integer i_dim(), i_dnnt(), i_indx(), i_sign(), i_len();
16990 logical l_ge(), l_gt(), l_le(), l_lt();
16991 integer i_nint();
16992 double r_sign();
16993
16994 // Local variables //
16995 extern // Subroutine // int fooa_(), fooc_(), food_(), fooi_(), foor_(),
16996 fool_(), fooz_(), getem_();
16997 static char a1[10], a2[10];
16998 static complex c1, c2;
16999 static doublereal d1, d2;
17000 static integer i1, i2;
17001 static real r1, r2;
17002
17003
17004 getem_(a1, a2, &c1, &c2, &i1, &i2, &r1, &r2, &d1, &d2, 10L, 10L);
17005// / //
17006 i__1 = i1 / i2;
17007 fooi_(&i__1);
17008 r__1 = r1 / i1;
17009 foor_(&r__1);
17010 d__1 = d1 / i1;
17011 food_(&d__1);
17012 d__1 = (doublereal) i1;
17013 q__1.r = c1.r / d__1, q__1.i = c1.i / d__1;
17014 fooc_(&q__1);
17015 r__1 = r1 / r2;
17016 foor_(&r__1);
17017 d__1 = r1 / d1;
17018 food_(&d__1);
17019 d__1 = d1 / d2;
17020 food_(&d__1);
17021 d__1 = d1 / r1;
17022 food_(&d__1);
17023 c_div(&q__1, &c1, &c2);
17024 fooc_(&q__1);
17025 q__1.r = c1.r / r1, q__1.i = c1.i / r1;
17026 fooc_(&q__1);
17027 z__1.r = c1.r / d1, z__1.i = c1.i / d1;
17028 fooz_(&z__1);
17029// ** //
17030 i__1 = pow_ii(&i1, &i2);
17031 fooi_(&i__1);
17032 r__1 = pow_ri(&r1, &i1);
17033 foor_(&r__1);
17034 d__1 = pow_di(&d1, &i1);
17035 food_(&d__1);
17036 pow_ci(&q__1, &c1, &i1);
17037 fooc_(&q__1);
17038 d__1 = (doublereal) r1;
17039 d__2 = (doublereal) r2;
17040 r__1 = pow_dd(&d__1, &d__2);
17041 foor_(&r__1);
17042 d__2 = (doublereal) r1;
17043 d__1 = pow_dd(&d__2, &d1);
17044 food_(&d__1);
17045 d__1 = pow_dd(&d1, &d2);
17046 food_(&d__1);
17047 d__2 = (doublereal) r1;
17048 d__1 = pow_dd(&d1, &d__2);
17049 food_(&d__1);
17050 z__2.r = c1.r, z__2.i = c1.i;
17051 z__3.r = c2.r, z__3.i = c2.i;
17052 pow_zz(&z__1, &z__2, &z__3);
17053 q__1.r = z__1.r, q__1.i = z__1.i;
17054 fooc_(&q__1);
17055 z__2.r = c1.r, z__2.i = c1.i;
17056 z__3.r = r1, z__3.i = 0.;
17057 pow_zz(&z__1, &z__2, &z__3);
17058 q__1.r = z__1.r, q__1.i = z__1.i;
17059 fooc_(&q__1);
17060 z__2.r = c1.r, z__2.i = c1.i;
17061 z__3.r = d1, z__3.i = 0.;
17062 pow_zz(&z__1, &z__2, &z__3);
17063 fooz_(&z__1);
17064// FFEINTRIN_impABS //
17065 r__1 = (doublereal)(( r1 ) >= 0 ? ( r1 ) : -( r1 )) ;
17066 foor_(&r__1);
17067// FFEINTRIN_impACOS //
17068 r__1 = acos(r1);
17069 foor_(&r__1);
17070// FFEINTRIN_impAIMAG //
17071 r__1 = r_imag(&c1);
17072 foor_(&r__1);
17073// FFEINTRIN_impAINT //
17074 r__1 = r_int(&r1);
17075 foor_(&r__1);
17076// FFEINTRIN_impALOG //
17077 r__1 = log(r1);
17078 foor_(&r__1);
17079// FFEINTRIN_impALOG10 //
17080 r__1 = r_lg10(&r1);
17081 foor_(&r__1);
17082// FFEINTRIN_impAMAX0 //
17083 r__1 = (real) (( i1 ) >= ( i2 ) ? ( i1 ) : ( i2 )) ;
17084 foor_(&r__1);
17085// FFEINTRIN_impAMAX1 //
17086 r__1 = (doublereal)(( r1 ) >= ( r2 ) ? ( r1 ) : ( r2 )) ;
17087 foor_(&r__1);
17088// FFEINTRIN_impAMIN0 //
17089 r__1 = (real) (( i1 ) <= ( i2 ) ? ( i1 ) : ( i2 )) ;
17090 foor_(&r__1);
17091// FFEINTRIN_impAMIN1 //
17092 r__1 = (doublereal)(( r1 ) <= ( r2 ) ? ( r1 ) : ( r2 )) ;
17093 foor_(&r__1);
17094// FFEINTRIN_impAMOD //
17095 r__1 = r_mod(&r1, &r2);
17096 foor_(&r__1);
17097// FFEINTRIN_impANINT //
17098 r__1 = r_nint(&r1);
17099 foor_(&r__1);
17100// FFEINTRIN_impASIN //
17101 r__1 = asin(r1);
17102 foor_(&r__1);
17103// FFEINTRIN_impATAN //
17104 r__1 = atan(r1);
17105 foor_(&r__1);
17106// FFEINTRIN_impATAN2 //
17107 r__1 = atan2(r1, r2);
17108 foor_(&r__1);
17109// FFEINTRIN_impCABS //
17110 r__1 = c_abs(&c1);
17111 foor_(&r__1);
17112// FFEINTRIN_impCCOS //
17113 c_cos(&q__1, &c1);
17114 fooc_(&q__1);
17115// FFEINTRIN_impCEXP //
17116 c_exp(&q__1, &c1);
17117 fooc_(&q__1);
17118// FFEINTRIN_impCHAR //
17119 *(unsigned char *)&ch__1[0] = i1;
17120 fooa_(ch__1, 1L);
17121// FFEINTRIN_impCLOG //
17122 c_log(&q__1, &c1);
17123 fooc_(&q__1);
17124// FFEINTRIN_impCONJG //
17125 r_cnjg(&q__1, &c1);
17126 fooc_(&q__1);
17127// FFEINTRIN_impCOS //
17128 r__1 = cos(r1);
17129 foor_(&r__1);
17130// FFEINTRIN_impCOSH //
17131 r__1 = cosh(r1);
17132 foor_(&r__1);
17133// FFEINTRIN_impCSIN //
17134 c_sin(&q__1, &c1);
17135 fooc_(&q__1);
17136// FFEINTRIN_impCSQRT //
17137 c_sqrt(&q__1, &c1);
17138 fooc_(&q__1);
17139// FFEINTRIN_impDABS //
17140 d__1 = (( d1 ) >= 0 ? ( d1 ) : -( d1 )) ;
17141 food_(&d__1);
17142// FFEINTRIN_impDACOS //
17143 d__1 = acos(d1);
17144 food_(&d__1);
17145// FFEINTRIN_impDASIN //
17146 d__1 = asin(d1);
17147 food_(&d__1);
17148// FFEINTRIN_impDATAN //
17149 d__1 = atan(d1);
17150 food_(&d__1);
17151// FFEINTRIN_impDATAN2 //
17152 d__1 = atan2(d1, d2);
17153 food_(&d__1);
17154// FFEINTRIN_impDCOS //
17155 d__1 = cos(d1);
17156 food_(&d__1);
17157// FFEINTRIN_impDCOSH //
17158 d__1 = cosh(d1);
17159 food_(&d__1);
17160// FFEINTRIN_impDDIM //
17161 d__1 = d_dim(&d1, &d2);
17162 food_(&d__1);
17163// FFEINTRIN_impDEXP //
17164 d__1 = exp(d1);
17165 food_(&d__1);
17166// FFEINTRIN_impDIM //
17167 r__1 = r_dim(&r1, &r2);
17168 foor_(&r__1);
17169// FFEINTRIN_impDINT //
17170 d__1 = d_int(&d1);
17171 food_(&d__1);
17172// FFEINTRIN_impDLOG //
17173 d__1 = log(d1);
17174 food_(&d__1);
17175// FFEINTRIN_impDLOG10 //
17176 d__1 = d_lg10(&d1);
17177 food_(&d__1);
17178// FFEINTRIN_impDMAX1 //
17179 d__1 = (( d1 ) >= ( d2 ) ? ( d1 ) : ( d2 )) ;
17180 food_(&d__1);
17181// FFEINTRIN_impDMIN1 //
17182 d__1 = (( d1 ) <= ( d2 ) ? ( d1 ) : ( d2 )) ;
17183 food_(&d__1);
17184// FFEINTRIN_impDMOD //
17185 d__1 = d_mod(&d1, &d2);
17186 food_(&d__1);
17187// FFEINTRIN_impDNINT //
17188 d__1 = d_nint(&d1);
17189 food_(&d__1);
17190// FFEINTRIN_impDPROD //
17191 d__1 = (doublereal) r1 * r2;
17192 food_(&d__1);
17193// FFEINTRIN_impDSIGN //
17194 d__1 = d_sign(&d1, &d2);
17195 food_(&d__1);
17196// FFEINTRIN_impDSIN //
17197 d__1 = sin(d1);
17198 food_(&d__1);
17199// FFEINTRIN_impDSINH //
17200 d__1 = sinh(d1);
17201 food_(&d__1);
17202// FFEINTRIN_impDSQRT //
17203 d__1 = sqrt(d1);
17204 food_(&d__1);
17205// FFEINTRIN_impDTAN //
17206 d__1 = tan(d1);
17207 food_(&d__1);
17208// FFEINTRIN_impDTANH //
17209 d__1 = tanh(d1);
17210 food_(&d__1);
17211// FFEINTRIN_impEXP //
17212 r__1 = exp(r1);
17213 foor_(&r__1);
17214// FFEINTRIN_impIABS //
17215 i__1 = (( i1 ) >= 0 ? ( i1 ) : -( i1 )) ;
17216 fooi_(&i__1);
17217// FFEINTRIN_impICHAR //
17218 i__1 = *(unsigned char *)a1;
17219 fooi_(&i__1);
17220// FFEINTRIN_impIDIM //
17221 i__1 = i_dim(&i1, &i2);
17222 fooi_(&i__1);
17223// FFEINTRIN_impIDNINT //
17224 i__1 = i_dnnt(&d1);
17225 fooi_(&i__1);
17226// FFEINTRIN_impINDEX //
17227 i__1 = i_indx(a1, a2, 10L, 10L);
17228 fooi_(&i__1);
17229// FFEINTRIN_impISIGN //
17230 i__1 = i_sign(&i1, &i2);
17231 fooi_(&i__1);
17232// FFEINTRIN_impLEN //
17233 i__1 = i_len(a1, 10L);
17234 fooi_(&i__1);
17235// FFEINTRIN_impLGE //
17236 L__1 = l_ge(a1, a2, 10L, 10L);
17237 fool_(&L__1);
17238// FFEINTRIN_impLGT //
17239 L__1 = l_gt(a1, a2, 10L, 10L);
17240 fool_(&L__1);
17241// FFEINTRIN_impLLE //
17242 L__1 = l_le(a1, a2, 10L, 10L);
17243 fool_(&L__1);
17244// FFEINTRIN_impLLT //
17245 L__1 = l_lt(a1, a2, 10L, 10L);
17246 fool_(&L__1);
17247// FFEINTRIN_impMAX0 //
17248 i__1 = (( i1 ) >= ( i2 ) ? ( i1 ) : ( i2 )) ;
17249 fooi_(&i__1);
17250// FFEINTRIN_impMAX1 //
17251 i__1 = (integer) (doublereal)(( r1 ) >= ( r2 ) ? ( r1 ) : ( r2 )) ;
17252 fooi_(&i__1);
17253// FFEINTRIN_impMIN0 //
17254 i__1 = (( i1 ) <= ( i2 ) ? ( i1 ) : ( i2 )) ;
17255 fooi_(&i__1);
17256// FFEINTRIN_impMIN1 //
17257 i__1 = (integer) (doublereal)(( r1 ) <= ( r2 ) ? ( r1 ) : ( r2 )) ;
17258 fooi_(&i__1);
17259// FFEINTRIN_impMOD //
17260 i__1 = i1 % i2;
17261 fooi_(&i__1);
17262// FFEINTRIN_impNINT //
17263 i__1 = i_nint(&r1);
17264 fooi_(&i__1);
17265// FFEINTRIN_impSIGN //
17266 r__1 = r_sign(&r1, &r2);
17267 foor_(&r__1);
17268// FFEINTRIN_impSIN //
17269 r__1 = sin(r1);
17270 foor_(&r__1);
17271// FFEINTRIN_impSINH //
17272 r__1 = sinh(r1);
17273 foor_(&r__1);
17274// FFEINTRIN_impSQRT //
17275 r__1 = sqrt(r1);
17276 foor_(&r__1);
17277// FFEINTRIN_impTAN //
17278 r__1 = tan(r1);
17279 foor_(&r__1);
17280// FFEINTRIN_impTANH //
17281 r__1 = tanh(r1);
17282 foor_(&r__1);
17283// FFEINTRIN_imp_CMPLX_C //
17284 r__1 = c1.r;
17285 r__2 = c2.r;
17286 q__1.r = r__1, q__1.i = r__2;
17287 fooc_(&q__1);
17288// FFEINTRIN_imp_CMPLX_D //
17289 z__1.r = d1, z__1.i = d2;
17290 fooz_(&z__1);
17291// FFEINTRIN_imp_CMPLX_I //
17292 r__1 = (real) i1;
17293 r__2 = (real) i2;
17294 q__1.r = r__1, q__1.i = r__2;
17295 fooc_(&q__1);
17296// FFEINTRIN_imp_CMPLX_R //
17297 q__1.r = r1, q__1.i = r2;
17298 fooc_(&q__1);
17299// FFEINTRIN_imp_DBLE_C //
17300 d__1 = (doublereal) c1.r;
17301 food_(&d__1);
17302// FFEINTRIN_imp_DBLE_D //
17303 d__1 = d1;
17304 food_(&d__1);
17305// FFEINTRIN_imp_DBLE_I //
17306 d__1 = (doublereal) i1;
17307 food_(&d__1);
17308// FFEINTRIN_imp_DBLE_R //
17309 d__1 = (doublereal) r1;
17310 food_(&d__1);
17311// FFEINTRIN_imp_INT_C //
17312 i__1 = (integer) c1.r;
17313 fooi_(&i__1);
17314// FFEINTRIN_imp_INT_D //
17315 i__1 = (integer) d1;
17316 fooi_(&i__1);
17317// FFEINTRIN_imp_INT_I //
17318 i__1 = i1;
17319 fooi_(&i__1);
17320// FFEINTRIN_imp_INT_R //
17321 i__1 = (integer) r1;
17322 fooi_(&i__1);
17323// FFEINTRIN_imp_REAL_C //
17324 r__1 = c1.r;
17325 foor_(&r__1);
17326// FFEINTRIN_imp_REAL_D //
17327 r__1 = (real) d1;
17328 foor_(&r__1);
17329// FFEINTRIN_imp_REAL_I //
17330 r__1 = (real) i1;
17331 foor_(&r__1);
17332// FFEINTRIN_imp_REAL_R //
17333 r__1 = r1;
17334 foor_(&r__1);
17335
17336// FFEINTRIN_imp_INT_D: //
17337
17338// FFEINTRIN_specIDINT //
17339 i__1 = (integer) d1;
17340 fooi_(&i__1);
17341
17342// FFEINTRIN_imp_INT_R: //
17343
17344// FFEINTRIN_specIFIX //
17345 i__1 = (integer) r1;
17346 fooi_(&i__1);
17347// FFEINTRIN_specINT //
17348 i__1 = (integer) r1;
17349 fooi_(&i__1);
17350
17351// FFEINTRIN_imp_REAL_D: //
5ff904cd 17352
c7e4ee3a
CB
17353// FFEINTRIN_specSNGL //
17354 r__1 = (real) d1;
17355 foor_(&r__1);
5ff904cd 17356
c7e4ee3a 17357// FFEINTRIN_imp_REAL_I: //
5ff904cd 17358
c7e4ee3a
CB
17359// FFEINTRIN_specFLOAT //
17360 r__1 = (real) i1;
17361 foor_(&r__1);
17362// FFEINTRIN_specREAL //
17363 r__1 = (real) i1;
17364 foor_(&r__1);
5ff904cd 17365
c7e4ee3a 17366} // MAIN__ //
5ff904cd 17367
c7e4ee3a 17368-------- (end output file from f2c)
5ff904cd 17369
c7e4ee3a 17370*/
This page took 2.541361 seconds and 5 git commands to generate.