1 /* com.c -- Implementation File (module.c template V1.0)
2 Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
3 Free Software Foundation, Inc.
4 Contributed by James Craig Burley.
6 This file is part of GNU Fortran.
8 GNU Fortran is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU Fortran is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Fortran; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
27 Contains compiler-specific functions.
32 /* Understanding this module means understanding the interface between
33 the g77 front end and the gcc back end (or, perhaps, some other
34 back end). In here are the functions called by the front end proper
35 to notify whatever back end is in place about certain things, and
36 also the back-end-specific functions. It's a bear to deal with, so
37 lately I've been trying to simplify things, especially with regard
38 to the gcc-back-end-specific stuff.
40 Building expressions generally seems quite easy, but building decls
41 has been challenging and is undergoing revision. gcc has several
44 TYPE_DECL -- a type (int, float, struct, function, etc.)
45 CONST_DECL -- a constant of some type other than function
46 LABEL_DECL -- a variable or a constant?
47 PARM_DECL -- an argument to a function (a variable that is a dummy)
48 RESULT_DECL -- the return value of a function (a variable)
49 VAR_DECL -- other variable (can hold a ptr-to-function, struct, int, etc.)
50 FUNCTION_DECL -- a function (either the actual function or an extern ref)
51 FIELD_DECL -- a field in a struct or union (goes into types)
53 g77 has a set of functions that somewhat parallels the gcc front end
54 when it comes to building decls:
56 Internal Function (one we define, not just declare as extern):
57 if (is_nested) push_f_function_context ();
58 start_function (get_identifier ("function_name"), function_type,
59 is_nested, is_public);
60 // for each arg, build PARM_DECL and call push_parm_decl (decl) with it;
61 store_parm_decls (is_main_program);
62 ffecom_start_compstmt ();
63 // for stmts and decls inside function, do appropriate things;
64 ffecom_end_compstmt ();
65 finish_function (is_nested);
66 if (is_nested) pop_f_function_context ();
71 // fill in external, public, static, &c for decl, and
72 // set DECL_INITIAL to error_mark_node if going to initialize
73 // set is_top_level TRUE only if not at top level and decl
74 // must go in top level (i.e. not within current function decl context)
75 d = start_decl (decl, is_top_level);
76 init = ...; // if have initializer
77 finish_decl (d, init, is_top_level);
89 #include "output.h" /* Must follow tree.h so TREE_CODE is defined! */
92 #include "diagnostic.h"
94 #include "langhooks.h"
95 #include "langhooks-def.h"
98 /* VMS-specific definitions */
101 #define O_RDONLY 0 /* Open arg for Read/Only */
102 #define O_WRONLY 1 /* Open arg for Write/Only */
103 #define read(fd,buf,size) VMS_read (fd,buf,size)
104 #define write(fd,buf,size) VMS_write (fd,buf,size)
105 #define open(fname,mode,prot) VMS_open (fname,mode,prot)
106 #define fopen(fname,mode) VMS_fopen (fname,mode)
107 #define freopen(fname,mode,ofile) VMS_freopen (fname,mode,ofile)
108 #define strncat(dst,src,cnt) VMS_strncat (dst,src,cnt)
109 #define fstat(fd,stbuf) VMS_fstat (fd,stbuf)
110 static int VMS_fstat (), VMS_stat ();
111 static char * VMS_strncat ();
112 static int VMS_read ();
113 static int VMS_write ();
114 static int VMS_open ();
115 static FILE * VMS_fopen ();
116 static FILE * VMS_freopen ();
117 static void hack_vms_include_specification ();
118 typedef struct { unsigned :16, :16, :16; } vms_ino_t;
119 #define ino_t vms_ino_t
120 #define INCLUDE_LEN_FUDGE 10 /* leave room for VMS syntax conversion */
123 #define FFECOM_DETERMINE_TYPES 1 /* for com.h */
140 /* Externals defined here. */
142 /* Stream for reading from the input file. */
145 /* These definitions parallel those in c-decl.c so that code from that
146 module can be used pretty much as is. Much of these defs aren't
147 otherwise used, i.e. by g77 code per se, except some of them are used
148 to build some of them that are. The ones that are global (i.e. not
149 "static") are those that ste.c and such might use (directly
150 or by using com macros that reference them in their definitions). */
152 tree string_type_node;
154 /* The rest of these are inventions for g77, though there might be
155 similar things in the C front end. As they are found, these
156 inventions should be renamed to be canonical. Note that only
157 the ones currently required to be global are so. */
159 static GTY(()) tree ffecom_tree_fun_type_void;
161 tree ffecom_integer_type_node; /* Abbrev for _tree_type[blah][blah]. */
162 tree ffecom_integer_zero_node; /* Like *_*_* with g77's integer type. */
163 tree ffecom_integer_one_node; /* " */
164 tree ffecom_tree_type[FFEINFO_basictype][FFEINFO_kindtype];
166 /* _fun_type things are the f2c-specific versions. For -fno-f2c,
167 just use build_function_type and build_pointer_type on the
168 appropriate _tree_type array element. */
170 static GTY(()) tree ffecom_tree_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
172 ffecom_tree_ptr_to_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
173 static GTY(()) tree ffecom_tree_subr_type;
174 static GTY(()) tree ffecom_tree_ptr_to_subr_type;
175 static GTY(()) tree ffecom_tree_blockdata_type;
177 static GTY(()) tree ffecom_tree_xargc_;
179 ffecomSymbol ffecom_symbol_null_
188 ffeinfoKindtype ffecom_pointer_kind_ = FFEINFO_basictypeNONE;
189 ffeinfoKindtype ffecom_label_kind_ = FFEINFO_basictypeNONE;
191 int ffecom_f2c_typecode_[FFEINFO_basictype][FFEINFO_kindtype];
192 tree ffecom_f2c_integer_type_node;
193 static GTY(()) tree ffecom_f2c_ptr_to_integer_type_node;
194 tree ffecom_f2c_address_type_node;
195 tree ffecom_f2c_real_type_node;
196 static GTY(()) tree ffecom_f2c_ptr_to_real_type_node;
197 tree ffecom_f2c_doublereal_type_node;
198 tree ffecom_f2c_complex_type_node;
199 tree ffecom_f2c_doublecomplex_type_node;
200 tree ffecom_f2c_longint_type_node;
201 tree ffecom_f2c_logical_type_node;
202 tree ffecom_f2c_flag_type_node;
203 tree ffecom_f2c_ftnlen_type_node;
204 tree ffecom_f2c_ftnlen_zero_node;
205 tree ffecom_f2c_ftnlen_one_node;
206 tree ffecom_f2c_ftnlen_two_node;
207 tree ffecom_f2c_ptr_to_ftnlen_type_node;
208 tree ffecom_f2c_ftnint_type_node;
209 tree ffecom_f2c_ptr_to_ftnint_type_node;
211 /* Simple definitions and enumerations. */
213 #ifndef FFECOM_sizeMAXSTACKITEM
214 #define FFECOM_sizeMAXSTACKITEM 32*1024 /* Keep user-declared things
215 larger than this # bytes
216 off stack if possible. */
219 /* For systems that have large enough stacks, they should define
220 this to 0, and here, for ease of use later on, we just undefine
223 #if FFECOM_sizeMAXSTACKITEM == 0
224 #undef FFECOM_sizeMAXSTACKITEM
230 FFECOM_rttypeVOIDSTAR_, /* C's `void *' type. */
231 FFECOM_rttypeFTNINT_, /* f2c's `ftnint' type. */
232 FFECOM_rttypeINTEGER_, /* f2c's `integer' type. */
233 FFECOM_rttypeLONGINT_, /* f2c's `longint' type. */
234 FFECOM_rttypeLOGICAL_, /* f2c's `logical' type. */
235 FFECOM_rttypeREAL_F2C_, /* f2c's `real' returned as `double'. */
236 FFECOM_rttypeREAL_GNU_, /* `real' returned as such. */
237 FFECOM_rttypeCOMPLEX_F2C_, /* f2c's `complex' returned via 1st arg. */
238 FFECOM_rttypeCOMPLEX_GNU_, /* f2c's `complex' returned directly. */
239 FFECOM_rttypeDOUBLE_, /* C's `double' type. */
240 FFECOM_rttypeDOUBLEREAL_, /* f2c's `doublereal' type. */
241 FFECOM_rttypeDBLCMPLX_F2C_, /* f2c's `doublecomplex' returned via 1st arg. */
242 FFECOM_rttypeDBLCMPLX_GNU_, /* f2c's `doublecomplex' returned directly. */
243 FFECOM_rttypeCHARACTER_, /* f2c `char *'/`ftnlen' pair. */
247 /* Internal typedefs. */
249 typedef struct _ffecom_concat_list_ ffecomConcatList_;
251 /* Private include files. */
254 /* Internal structure definitions. */
256 struct _ffecom_concat_list_
261 ffetargetCharacterSize minlen;
262 ffetargetCharacterSize maxlen;
265 /* Static functions (internal). */
267 static tree ffe_type_for_mode PARAMS ((enum machine_mode, int));
268 static tree ffe_type_for_size PARAMS ((unsigned int, int));
269 static tree ffe_unsigned_type PARAMS ((tree));
270 static tree ffe_signed_type PARAMS ((tree));
271 static tree ffe_signed_or_unsigned_type PARAMS ((int, tree));
272 static bool ffe_mark_addressable PARAMS ((tree));
273 static tree ffe_truthvalue_conversion PARAMS ((tree));
274 static void ffecom_init_decl_processing PARAMS ((void));
275 static tree ffecom_arglist_expr_ (const char *argstring, ffebld args);
276 static tree ffecom_widest_expr_type_ (ffebld list);
277 static bool ffecom_overlap_ (tree dest_decl, tree dest_offset,
278 tree dest_size, tree source_tree,
279 ffebld source, bool scalar_arg);
280 static bool ffecom_args_overlapping_ (tree dest_tree, ffebld dest,
281 tree args, tree callee_commons,
283 static tree ffecom_build_f2c_string_ (int i, const char *s);
284 static tree ffecom_call_ (tree fn, ffeinfoKindtype kt,
285 bool is_f2c_complex, tree type,
286 tree args, tree dest_tree,
287 ffebld dest, bool *dest_used,
288 tree callee_commons, bool scalar_args, tree hook);
289 static tree ffecom_call_binop_ (tree fn, ffeinfoKindtype kt,
290 bool is_f2c_complex, tree type,
291 ffebld left, ffebld right,
292 tree dest_tree, ffebld dest,
293 bool *dest_used, tree callee_commons,
294 bool scalar_args, bool ref, tree hook);
295 static void ffecom_char_args_x_ (tree *xitem, tree *length,
296 ffebld expr, bool with_null);
297 static tree ffecom_check_size_overflow_ (ffesymbol s, tree type, bool dummy);
298 static tree ffecom_char_enhance_arg_ (tree *xtype, ffesymbol s);
299 static ffecomConcatList_
300 ffecom_concat_list_gather_ (ffecomConcatList_ catlist,
302 ffetargetCharacterSize max);
303 static void ffecom_concat_list_kill_ (ffecomConcatList_ catlist);
304 static ffecomConcatList_ ffecom_concat_list_new_ (ffebld expr,
305 ffetargetCharacterSize max);
306 static void ffecom_debug_kludge_ (tree aggr, const char *aggr_type,
307 ffesymbol member, tree member_type,
308 ffetargetOffset offset);
309 static void ffecom_do_entry_ (ffesymbol fn, int entrynum);
310 static tree ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest,
311 bool *dest_used, bool assignp, bool widenp);
312 static tree ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree,
313 ffebld dest, bool *dest_used);
314 static tree ffecom_expr_power_integer_ (ffebld expr);
315 static void ffecom_expr_transform_ (ffebld expr);
316 static void ffecom_f2c_make_type_ (tree *type, int tcode, const char *name);
317 static void ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size,
319 static ffeglobal ffecom_finish_global_ (ffeglobal global);
320 static ffesymbol ffecom_finish_symbol_transform_ (ffesymbol s);
321 static tree ffecom_get_appended_identifier_ (char us, const char *text);
322 static tree ffecom_get_external_identifier_ (ffesymbol s);
323 static tree ffecom_get_identifier_ (const char *text);
324 static tree ffecom_gen_sfuncdef_ (ffesymbol s,
327 static const char *ffecom_gfrt_args_ (ffecomGfrt ix);
328 static tree ffecom_gfrt_tree_ (ffecomGfrt ix);
329 static tree ffecom_init_zero_ (tree decl);
330 static tree ffecom_intrinsic_ichar_ (tree tree_type, ffebld arg,
332 static tree ffecom_intrinsic_len_ (ffebld expr);
333 static void ffecom_let_char_ (tree dest_tree,
335 ffetargetCharacterSize dest_size,
337 static void ffecom_make_gfrt_ (ffecomGfrt ix);
338 static void ffecom_member_phase1_ (ffestorag mst, ffestorag st);
339 static void ffecom_member_phase2_ (ffestorag mst, ffestorag st);
340 static void ffecom_prepare_let_char_ (ffetargetCharacterSize dest_size,
342 static void ffecom_push_dummy_decls_ (ffebld dumlist,
344 static void ffecom_start_progunit_ (void);
345 static ffesymbol ffecom_sym_transform_ (ffesymbol s);
346 static ffesymbol ffecom_sym_transform_assign_ (ffesymbol s);
347 static void ffecom_transform_common_ (ffesymbol s);
348 static void ffecom_transform_equiv_ (ffestorag st);
349 static tree ffecom_transform_namelist_ (ffesymbol s);
350 static void ffecom_tree_canonize_ptr_ (tree *decl, tree *offset,
352 static void ffecom_tree_canonize_ref_ (tree *decl, tree *offset,
353 tree *size, tree tree);
354 static tree ffecom_tree_divide_ (tree tree_type, tree left, tree right,
355 tree dest_tree, ffebld dest,
356 bool *dest_used, tree hook);
357 static tree ffecom_type_localvar_ (ffesymbol s,
360 static tree ffecom_type_namelist_ (void);
361 static tree ffecom_type_vardesc_ (void);
362 static tree ffecom_vardesc_ (ffebld expr);
363 static tree ffecom_vardesc_array_ (ffesymbol s);
364 static tree ffecom_vardesc_dims_ (ffesymbol s);
365 static tree ffecom_convert_narrow_ (tree type, tree expr);
366 static tree ffecom_convert_widen_ (tree type, tree expr);
368 /* These are static functions that parallel those found in the C front
369 end and thus have the same names. */
371 static tree bison_rule_compstmt_ (void);
372 static void bison_rule_pushlevel_ (void);
373 static void delete_block (tree block);
374 static int duplicate_decls (tree newdecl, tree olddecl);
375 static void finish_decl (tree decl, tree init, bool is_top_level);
376 static void finish_function (int nested);
377 static const char *ffe_printable_name (tree decl, int v);
378 static void ffe_print_error_function (diagnostic_context *, const char *);
379 static tree lookup_name_current_level (tree name);
380 static struct f_binding_level *make_binding_level (void);
381 static void pop_f_function_context (void);
382 static void push_f_function_context (void);
383 static void push_parm_decl (tree parm);
384 static tree pushdecl_top_level (tree decl);
385 static int kept_level_p (void);
386 static tree storedecls (tree decls);
387 static void store_parm_decls (int is_main_program);
388 static tree start_decl (tree decl, bool is_top_level);
389 static void start_function (tree name, tree type, int nested, int public);
390 static void ffecom_file_ (const char *name);
391 static void ffecom_close_include_ (FILE *f);
392 static int ffecom_decode_include_option_ (char *spec);
393 static FILE *ffecom_open_include_ (char *name, ffewhereLine l,
396 /* Static objects accessed by functions in this module. */
398 static ffesymbol ffecom_primary_entry_ = NULL;
399 static ffesymbol ffecom_nested_entry_ = NULL;
400 static ffeinfoKind ffecom_primary_entry_kind_;
401 static bool ffecom_primary_entry_is_proc_;
402 static GTY(()) tree ffecom_outer_function_decl_;
403 static GTY(()) tree ffecom_previous_function_decl_;
404 static GTY(()) tree ffecom_which_entrypoint_decl_;
405 static GTY(()) tree ffecom_float_zero_;
406 static GTY(()) tree ffecom_float_half_;
407 static GTY(()) tree ffecom_double_zero_;
408 static GTY(()) tree ffecom_double_half_;
409 static GTY(()) tree ffecom_func_result_;/* For functions. */
410 static GTY(()) tree ffecom_func_length_;/* For CHARACTER fns. */
411 static ffebld ffecom_list_blockdata_;
412 static ffebld ffecom_list_common_;
413 static ffebld ffecom_master_arglist_;
414 static ffeinfoBasictype ffecom_master_bt_;
415 static ffeinfoKindtype ffecom_master_kt_;
416 static ffetargetCharacterSize ffecom_master_size_;
417 static int ffecom_num_fns_ = 0;
418 static int ffecom_num_entrypoints_ = 0;
419 static bool ffecom_is_altreturning_ = FALSE;
420 static GTY(()) tree ffecom_multi_type_node_;
421 static GTY(()) tree ffecom_multi_retval_;
423 ffecom_multi_fields_[FFEINFO_basictype][FFEINFO_kindtype];
424 static bool ffecom_member_namelisted_; /* _member_phase1_ namelisted? */
425 static bool ffecom_doing_entry_ = FALSE;
426 static bool ffecom_transform_only_dummies_ = FALSE;
427 static int ffecom_typesize_pointer_;
428 static int ffecom_typesize_integer1_;
430 /* Holds pointer-to-function expressions. */
432 static GTY(()) tree ffecom_gfrt_[FFECOM_gfrt];
434 /* Holds the external names of the functions. */
436 static const char *const ffecom_gfrt_name_[FFECOM_gfrt]
439 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) NAME,
440 #include "com-rt.def"
444 /* Whether the function returns. */
446 static const bool ffecom_gfrt_volatile_[FFECOM_gfrt]
449 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) VOLATILE,
450 #include "com-rt.def"
454 /* Whether the function returns type complex. */
456 static const bool ffecom_gfrt_complex_[FFECOM_gfrt]
459 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) COMPLEX,
460 #include "com-rt.def"
464 /* Whether the function is const
465 (i.e., has no side effects and only depends on its arguments). */
467 static const bool ffecom_gfrt_const_[FFECOM_gfrt]
470 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) CONST,
471 #include "com-rt.def"
475 /* Type code for the function return value. */
477 static const ffecomRttype_ ffecom_gfrt_type_[FFECOM_gfrt]
480 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) TYPE,
481 #include "com-rt.def"
485 /* String of codes for the function's arguments. */
487 static const char *const ffecom_gfrt_argstring_[FFECOM_gfrt]
490 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) ARGS,
491 #include "com-rt.def"
495 /* Internal macros. */
497 /* We let tm.h override the types used here, to handle trivial differences
498 such as the choice of unsigned int or long unsigned int for size_t.
499 When machines start needing nontrivial differences in the size type,
500 it would be best to do something here to figure out automatically
501 from other information what type to use. */
504 #define SIZE_TYPE "long unsigned int"
507 #define ffecom_concat_list_count_(catlist) ((catlist).count)
508 #define ffecom_concat_list_expr_(catlist,i) ((catlist).exprs[(i)])
509 #define ffecom_concat_list_maxlen_(catlist) ((catlist).maxlen)
510 #define ffecom_concat_list_minlen_(catlist) ((catlist).minlen)
512 #define ffecom_char_args_(i,l,e) ffecom_char_args_x_((i),(l),(e),FALSE)
513 #define ffecom_char_args_with_null_(i,l,e) ffecom_char_args_x_((i),(l),(e),TRUE)
515 /* For each binding contour we allocate a binding_level structure
516 * which records the names defined in that contour.
519 * 1) one for each function definition,
520 * where internal declarations of the parameters appear.
522 * The current meaning of a name can be found by searching the levels from
523 * the current one out to the global one.
526 /* Note that the information in the `names' component of the global contour
527 is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */
529 struct f_binding_level GTY(())
531 /* A chain of _DECL nodes for all variables, constants, functions,
532 and typedef types. These are in the reverse of the order supplied.
536 /* For each level (except not the global one),
537 a chain of BLOCK nodes for all the levels
538 that were entered and exited one level down. */
541 /* The BLOCK node for this level, if one has been preallocated.
542 If 0, the BLOCK is allocated (if needed) when the level is popped. */
545 /* The binding level which this one is contained in (inherits from). */
546 struct f_binding_level *level_chain;
548 /* 0: no ffecom_prepare_* functions called at this level yet;
549 1: ffecom_prepare* functions called, except not ffecom_prepare_end;
550 2: ffecom_prepare_end called. */
554 #define NULL_BINDING_LEVEL (struct f_binding_level *) NULL
556 /* The binding level currently in effect. */
558 static GTY(()) struct f_binding_level *current_binding_level;
560 /* A chain of binding_level structures awaiting reuse. */
562 static GTY((deletable (""))) struct f_binding_level *free_binding_level;
564 /* The outermost binding level, for names of file scope.
565 This is created when the compiler is started and exists
566 through the entire run. */
568 static struct f_binding_level *global_binding_level;
570 /* Binding level structures are initialized by copying this one. */
572 static const struct f_binding_level clear_binding_level
574 {NULL, NULL, NULL, NULL_BINDING_LEVEL, 0};
576 /* Language-dependent contents of an identifier. */
578 struct lang_identifier GTY(())
580 struct tree_identifier common;
587 /* Macros for access to language-specific slots in an identifier. */
588 /* Each of these slots contains a DECL node or null. */
590 /* This represents the value which the identifier has in the
591 file-scope namespace. */
592 #define IDENTIFIER_GLOBAL_VALUE(NODE) \
593 (((struct lang_identifier *)(NODE))->global_value)
594 /* This represents the value which the identifier has in the current
596 #define IDENTIFIER_LOCAL_VALUE(NODE) \
597 (((struct lang_identifier *)(NODE))->local_value)
598 /* This represents the value which the identifier has as a label in
599 the current label scope. */
600 #define IDENTIFIER_LABEL_VALUE(NODE) \
601 (((struct lang_identifier *)(NODE))->label_value)
602 /* This is nonzero if the identifier was "made up" by g77 code. */
603 #define IDENTIFIER_INVENTED(NODE) \
604 (((struct lang_identifier *)(NODE))->invented)
606 /* The resulting tree type. */
608 GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE")))
610 union tree_node GTY ((tag ("0"),
611 desc ("tree_node_structure (&%h)")))
613 struct lang_identifier GTY ((tag ("1"))) identifier;
616 /* Fortran doesn't use either of these. */
617 struct lang_decl GTY(())
620 struct lang_type GTY(())
624 /* In identifiers, C uses the following fields in a special way:
625 TREE_PUBLIC to record that there was a previous local extern decl.
626 TREE_USED to record that such a decl was used.
627 TREE_ADDRESSABLE to record that the address of such a decl was used. */
629 /* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function
630 that have names. Here so we can clear out their names' definitions
631 at the end of the function. */
633 static GTY(()) tree named_labels;
635 /* A list of LABEL_DECLs from outer contexts that are currently shadowed. */
637 static GTY(()) tree shadowed_labels;
639 /* Return the subscript expression, modified to do range-checking.
641 `array' is the array to be checked against.
642 `element' is the subscript expression to check.
643 `dim' is the dimension number (starting at 0).
644 `total_dims' is the total number of dimensions (0 for CHARACTER substring).
648 ffecom_subscript_check_ (tree array, tree element, int dim, int total_dims,
649 const char *array_name)
651 tree low = TYPE_MIN_VALUE (TYPE_DOMAIN (array));
652 tree high = TYPE_MAX_VALUE (TYPE_DOMAIN (array));
657 if (element == error_mark_node)
660 if (TREE_TYPE (low) != TREE_TYPE (element))
662 if (TYPE_PRECISION (TREE_TYPE (low))
663 > TYPE_PRECISION (TREE_TYPE (element)))
664 element = convert (TREE_TYPE (low), element);
667 low = convert (TREE_TYPE (element), low);
669 high = convert (TREE_TYPE (element), high);
673 element = ffecom_save_tree (element);
676 /* Special handling for substring range checks. Fortran allows the
677 end subscript < begin subscript, which means that expressions like
678 string(1:0) are valid (and yield a null string). In view of this,
679 enforce two simpler conditions:
680 1) element<=high for end-substring;
681 2) element>=low for start-substring.
682 Run-time character movement will enforce remaining conditions.
684 More complicated checks would be better, but present structure only
685 provides one index element at a time, so it is not possible to
686 enforce a check of both i and j in string(i:j). If it were, the
687 complete set of rules would read,
688 if ( ((j<i) && ((low<=i<=high) || (low<=j<=high))) ||
689 ((low<=i<=high) && (low<=j<=high)) )
695 cond = ffecom_2 (LE_EXPR, integer_type_node, element, high);
697 cond = ffecom_2 (LE_EXPR, integer_type_node, low, element);
701 /* Array reference substring range checking. */
703 cond = ffecom_2 (LE_EXPR, integer_type_node,
708 cond = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
710 ffecom_2 (LE_EXPR, integer_type_node,
728 var = concat (array_name, "[", (dim ? "end" : "start"),
729 "-substring]", NULL);
730 len = strlen (var) + 1;
731 arg1 = build_string (len, var);
736 len = strlen (array_name) + 1;
737 arg1 = build_string (len, array_name);
741 var = xmalloc (strlen (array_name) + 40);
742 sprintf (var, "%s[subscript-%d-of-%d]",
744 dim + 1, total_dims);
745 len = strlen (var) + 1;
746 arg1 = build_string (len, var);
752 = build_type_variant (build_array_type (char_type_node,
756 build_int_2 (len, 0))),
758 TREE_CONSTANT (arg1) = 1;
759 TREE_STATIC (arg1) = 1;
760 arg1 = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg1)),
763 /* s_rnge adds one to the element to print it, so bias against
764 that -- want to print a faithful *subscript* value. */
765 arg2 = convert (ffecom_f2c_ftnint_type_node,
766 ffecom_2 (MINUS_EXPR,
769 convert (TREE_TYPE (element),
772 proc = concat (input_filename, "/",
773 IDENTIFIER_POINTER (DECL_NAME (current_function_decl)),
775 len = strlen (proc) + 1;
776 arg3 = build_string (len, proc);
781 = build_type_variant (build_array_type (char_type_node,
785 build_int_2 (len, 0))),
787 TREE_CONSTANT (arg3) = 1;
788 TREE_STATIC (arg3) = 1;
789 arg3 = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg3)),
792 arg4 = convert (ffecom_f2c_ftnint_type_node,
793 build_int_2 (lineno, 0));
795 arg1 = build_tree_list (NULL_TREE, arg1);
796 arg2 = build_tree_list (NULL_TREE, arg2);
797 arg3 = build_tree_list (NULL_TREE, arg3);
798 arg4 = build_tree_list (NULL_TREE, arg4);
799 TREE_CHAIN (arg3) = arg4;
800 TREE_CHAIN (arg2) = arg3;
801 TREE_CHAIN (arg1) = arg2;
805 die = ffecom_call_gfrt (FFECOM_gfrtRANGE,
807 TREE_SIDE_EFFECTS (die) = 1;
809 element = ffecom_3 (COND_EXPR,
818 /* Return the computed element of an array reference.
820 `item' is NULL_TREE, or the transformed pointer to the array.
821 `expr' is the original opARRAYREF expression, which is transformed
822 if `item' is NULL_TREE.
823 `want_ptr' is non-zero if a pointer to the element, instead of
824 the element itself, is to be returned. */
827 ffecom_arrayref_ (tree item, ffebld expr, int want_ptr)
829 ffebld dims[FFECOM_dimensionsMAX];
832 int flatten = ffe_is_flatten_arrays ();
838 const char *array_name;
842 if (ffebld_op (ffebld_left (expr)) == FFEBLD_opSYMTER)
843 array_name = ffesymbol_text (ffebld_symter (ffebld_left (expr)));
845 array_name = "[expr?]";
847 /* Build up ARRAY_REFs in reverse order (since we're column major
848 here in Fortran land). */
850 for (i = 0, list = ffebld_right (expr);
852 ++i, list = ffebld_trail (list))
854 dims[i] = ffebld_head (list);
855 type = ffeinfo_type (ffebld_basictype (dims[i]),
856 ffebld_kindtype (dims[i]));
858 && ffecom_typesize_pointer_ > ffecom_typesize_integer1_
859 && ffetype_size (type) > ffecom_typesize_integer1_)
860 /* E.g. ARRAY(INDEX), given INTEGER*8 INDEX, on a system with 64-bit
861 pointers and 32-bit integers. Do the full 64-bit pointer
862 arithmetic, for codes using arrays for nonstandard heap-like
869 need_ptr = want_ptr || flatten;
874 item = ffecom_ptr_to_expr (ffebld_left (expr));
876 item = ffecom_expr (ffebld_left (expr));
878 if (item == error_mark_node)
881 if (ffeinfo_where (ffebld_info (expr)) == FFEINFO_whereFLEETING
882 && ! ffe_mark_addressable (item))
883 return error_mark_node;
886 if (item == error_mark_node)
893 for (--i, array = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item)));
895 --i, array = TYPE_MAIN_VARIANT (TREE_TYPE (array)))
897 min = TYPE_MIN_VALUE (TYPE_DOMAIN (array));
898 element = ffecom_expr_ (dims[i], NULL, NULL, NULL, FALSE, TRUE);
899 if (flag_bounds_check)
900 element = ffecom_subscript_check_ (array, element, i, total_dims,
902 if (element == error_mark_node)
905 /* Widen integral arithmetic as desired while preserving
907 tree_type = TREE_TYPE (element);
908 tree_type_x = tree_type;
910 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
911 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
912 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
914 if (TREE_TYPE (min) != tree_type_x)
915 min = convert (tree_type_x, min);
916 if (TREE_TYPE (element) != tree_type_x)
917 element = convert (tree_type_x, element);
919 item = ffecom_2 (PLUS_EXPR,
920 build_pointer_type (TREE_TYPE (array)),
922 size_binop (MULT_EXPR,
923 size_in_bytes (TREE_TYPE (array)),
925 fold (build (MINUS_EXPR,
931 item = ffecom_1 (INDIRECT_REF,
932 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item))),
942 array = TYPE_MAIN_VARIANT (TREE_TYPE (item));
944 element = ffecom_expr_ (dims[i], NULL, NULL, NULL, FALSE, TRUE);
945 if (flag_bounds_check)
946 element = ffecom_subscript_check_ (array, element, i, total_dims,
948 if (element == error_mark_node)
951 /* Widen integral arithmetic as desired while preserving
953 tree_type = TREE_TYPE (element);
954 tree_type_x = tree_type;
956 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
957 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
958 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
960 element = convert (tree_type_x, element);
962 item = ffecom_2 (ARRAY_REF,
963 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item))),
972 /* This is like gcc's stabilize_reference -- in fact, most of the code
973 comes from that -- but it handles the situation where the reference
974 is going to have its subparts picked at, and it shouldn't change
975 (or trigger extra invocations of functions in the subtrees) due to
976 this. save_expr is a bit overzealous, because we don't need the
977 entire thing calculated and saved like a temp. So, for DECLs, no
978 change is needed, because these are stable aggregates, and ARRAY_REF
979 and such might well be stable too, but for things like calculations,
980 we do need to calculate a snapshot of a value before picking at it. */
983 ffecom_stabilize_aggregate_ (tree ref)
986 enum tree_code code = TREE_CODE (ref);
993 /* No action is needed in this case. */
1000 case FIX_FLOOR_EXPR:
1001 case FIX_ROUND_EXPR:
1003 result = build_nt (code, stabilize_reference (TREE_OPERAND (ref, 0)));
1007 result = build_nt (INDIRECT_REF,
1008 stabilize_reference_1 (TREE_OPERAND (ref, 0)));
1012 result = build_nt (COMPONENT_REF,
1013 stabilize_reference (TREE_OPERAND (ref, 0)),
1014 TREE_OPERAND (ref, 1));
1018 result = build_nt (BIT_FIELD_REF,
1019 stabilize_reference (TREE_OPERAND (ref, 0)),
1020 stabilize_reference_1 (TREE_OPERAND (ref, 1)),
1021 stabilize_reference_1 (TREE_OPERAND (ref, 2)));
1025 result = build_nt (ARRAY_REF,
1026 stabilize_reference (TREE_OPERAND (ref, 0)),
1027 stabilize_reference_1 (TREE_OPERAND (ref, 1)));
1031 result = build_nt (COMPOUND_EXPR,
1032 stabilize_reference_1 (TREE_OPERAND (ref, 0)),
1033 stabilize_reference (TREE_OPERAND (ref, 1)));
1041 return save_expr (ref);
1044 return error_mark_node;
1047 TREE_TYPE (result) = TREE_TYPE (ref);
1048 TREE_READONLY (result) = TREE_READONLY (ref);
1049 TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (ref);
1050 TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (ref);
1055 /* A rip-off of gcc's convert.c convert_to_complex function,
1056 reworked to handle complex implemented as C structures
1057 (RECORD_TYPE with two fields, real and imaginary `r' and `i'). */
1060 ffecom_convert_to_complex_ (tree type, tree expr)
1062 register enum tree_code form = TREE_CODE (TREE_TYPE (expr));
1065 assert (TREE_CODE (type) == RECORD_TYPE);
1067 subtype = TREE_TYPE (TYPE_FIELDS (type));
1069 if (form == REAL_TYPE || form == INTEGER_TYPE || form == ENUMERAL_TYPE)
1071 expr = convert (subtype, expr);
1072 return ffecom_2 (COMPLEX_EXPR, type, expr,
1073 convert (subtype, integer_zero_node));
1076 if (form == RECORD_TYPE)
1078 tree elt_type = TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr)));
1079 if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype))
1083 expr = save_expr (expr);
1084 return ffecom_2 (COMPLEX_EXPR,
1087 ffecom_1 (REALPART_EXPR,
1088 TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))),
1091 ffecom_1 (IMAGPART_EXPR,
1092 TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))),
1097 if (form == POINTER_TYPE || form == REFERENCE_TYPE)
1098 error ("pointer value used where a complex was expected");
1100 error ("aggregate value used where a complex was expected");
1102 return ffecom_2 (COMPLEX_EXPR, type,
1103 convert (subtype, integer_zero_node),
1104 convert (subtype, integer_zero_node));
1107 /* Like gcc's convert(), but crashes if widening might happen. */
1110 ffecom_convert_narrow_ (type, expr)
1113 register tree e = expr;
1114 register enum tree_code code = TREE_CODE (type);
1116 if (type == TREE_TYPE (e)
1117 || TREE_CODE (e) == ERROR_MARK)
1119 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
1120 return fold (build1 (NOP_EXPR, type, e));
1121 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
1122 || code == ERROR_MARK)
1123 return error_mark_node;
1124 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
1126 assert ("void value not ignored as it ought to be" == NULL);
1127 return error_mark_node;
1129 assert (code != VOID_TYPE);
1130 if ((code != RECORD_TYPE)
1131 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
1132 assert ("converting COMPLEX to REAL" == NULL);
1133 assert (code != ENUMERAL_TYPE);
1134 if (code == INTEGER_TYPE)
1136 assert ((TREE_CODE (TREE_TYPE (e)) == INTEGER_TYPE
1137 && TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (e)))
1138 || (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE
1139 && (TYPE_PRECISION (type)
1140 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e))))));
1141 return fold (convert_to_integer (type, e));
1143 if (code == POINTER_TYPE)
1145 assert (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE);
1146 return fold (convert_to_pointer (type, e));
1148 if (code == REAL_TYPE)
1150 assert (TREE_CODE (TREE_TYPE (e)) == REAL_TYPE);
1151 assert (TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (e)));
1152 return fold (convert_to_real (type, e));
1154 if (code == COMPLEX_TYPE)
1156 assert (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE);
1157 assert (TYPE_PRECISION (TREE_TYPE (type)) <= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e))));
1158 return fold (convert_to_complex (type, e));
1160 if (code == RECORD_TYPE)
1162 assert (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE);
1163 /* Check that at least the first field name agrees. */
1164 assert (DECL_NAME (TYPE_FIELDS (type))
1165 == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e))));
1166 assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1167 <= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))));
1168 if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1169 == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))))
1171 return fold (ffecom_convert_to_complex_ (type, e));
1174 assert ("conversion to non-scalar type requested" == NULL);
1175 return error_mark_node;
1178 /* Like gcc's convert(), but crashes if narrowing might happen. */
1181 ffecom_convert_widen_ (type, expr)
1184 register tree e = expr;
1185 register enum tree_code code = TREE_CODE (type);
1187 if (type == TREE_TYPE (e)
1188 || TREE_CODE (e) == ERROR_MARK)
1190 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
1191 return fold (build1 (NOP_EXPR, type, e));
1192 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
1193 || code == ERROR_MARK)
1194 return error_mark_node;
1195 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
1197 assert ("void value not ignored as it ought to be" == NULL);
1198 return error_mark_node;
1200 assert (code != VOID_TYPE);
1201 if ((code != RECORD_TYPE)
1202 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
1203 assert ("narrowing COMPLEX to REAL" == NULL);
1204 assert (code != ENUMERAL_TYPE);
1205 if (code == INTEGER_TYPE)
1207 assert ((TREE_CODE (TREE_TYPE (e)) == INTEGER_TYPE
1208 && TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (e)))
1209 || (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE
1210 && (TYPE_PRECISION (type)
1211 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e))))));
1212 return fold (convert_to_integer (type, e));
1214 if (code == POINTER_TYPE)
1216 assert (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE);
1217 return fold (convert_to_pointer (type, e));
1219 if (code == REAL_TYPE)
1221 assert (TREE_CODE (TREE_TYPE (e)) == REAL_TYPE);
1222 assert (TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (e)));
1223 return fold (convert_to_real (type, e));
1225 if (code == COMPLEX_TYPE)
1227 assert (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE);
1228 assert (TYPE_PRECISION (TREE_TYPE (type)) >= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e))));
1229 return fold (convert_to_complex (type, e));
1231 if (code == RECORD_TYPE)
1233 assert (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE);
1234 /* Check that at least the first field name agrees. */
1235 assert (DECL_NAME (TYPE_FIELDS (type))
1236 == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e))));
1237 assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1238 >= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))));
1239 if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1240 == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))))
1242 return fold (ffecom_convert_to_complex_ (type, e));
1245 assert ("conversion to non-scalar type requested" == NULL);
1246 return error_mark_node;
1249 /* Handles making a COMPLEX type, either the standard
1250 (but buggy?) gbe way, or the safer (but less elegant?)
1254 ffecom_make_complex_type_ (tree subtype)
1260 if (ffe_is_emulate_complex ())
1262 type = make_node (RECORD_TYPE);
1263 realfield = ffecom_decl_field (type, NULL_TREE, "r", subtype);
1264 imagfield = ffecom_decl_field (type, realfield, "i", subtype);
1265 TYPE_FIELDS (type) = realfield;
1270 type = make_node (COMPLEX_TYPE);
1271 TREE_TYPE (type) = subtype;
1278 /* Chooses either the gbe or the f2c way to build a
1279 complex constant. */
1282 ffecom_build_complex_constant_ (tree type, tree realpart, tree imagpart)
1286 if (ffe_is_emulate_complex ())
1288 bothparts = build_tree_list (TYPE_FIELDS (type), realpart);
1289 TREE_CHAIN (bothparts) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), imagpart);
1290 bothparts = build (CONSTRUCTOR, type, NULL_TREE, bothparts);
1294 bothparts = build_complex (type, realpart, imagpart);
1301 ffecom_arglist_expr_ (const char *c, ffebld expr)
1304 tree *plist = &list;
1305 tree trail = NULL_TREE; /* Append char length args here. */
1306 tree *ptrail = &trail;
1311 tree wanted = NULL_TREE;
1312 static const char zed[] = "0";
1317 while (expr != NULL)
1340 wanted = ffecom_f2c_complex_type_node;
1344 wanted = ffecom_f2c_doublereal_type_node;
1348 wanted = ffecom_f2c_doublecomplex_type_node;
1352 wanted = ffecom_f2c_real_type_node;
1356 wanted = ffecom_f2c_integer_type_node;
1360 wanted = ffecom_f2c_longint_type_node;
1364 assert ("bad argstring code" == NULL);
1370 exprh = ffebld_head (expr);
1374 if ((wanted == NULL_TREE)
1377 (ffecom_tree_type[ffeinfo_basictype (ffebld_info (exprh))]
1378 [ffeinfo_kindtype (ffebld_info (exprh))])
1379 == TYPE_MODE (wanted))))
1381 = build_tree_list (NULL_TREE,
1382 ffecom_arg_ptr_to_expr (exprh,
1386 item = ffecom_arg_expr (exprh, &length);
1387 item = ffecom_convert_widen_ (wanted, item);
1390 item = ffecom_1 (ADDR_EXPR,
1391 build_pointer_type (TREE_TYPE (item)),
1395 = build_tree_list (NULL_TREE,
1399 plist = &TREE_CHAIN (*plist);
1400 expr = ffebld_trail (expr);
1401 if (length != NULL_TREE)
1403 *ptrail = build_tree_list (NULL_TREE, length);
1404 ptrail = &TREE_CHAIN (*ptrail);
1408 /* We've run out of args in the call; if the implementation expects
1409 more, supply null pointers for them, which the implementation can
1410 check to see if an arg was omitted. */
1412 while (*c != '\0' && *c != '0')
1417 assert ("missing arg to run-time routine!" == NULL);
1432 assert ("bad arg string code" == NULL);
1436 = build_tree_list (NULL_TREE,
1438 plist = &TREE_CHAIN (*plist);
1447 ffecom_widest_expr_type_ (ffebld list)
1450 ffebld widest = NULL;
1452 ffetype widest_type = NULL;
1455 for (; list != NULL; list = ffebld_trail (list))
1457 item = ffebld_head (list);
1460 if ((widest != NULL)
1461 && (ffeinfo_basictype (ffebld_info (item))
1462 != ffeinfo_basictype (ffebld_info (widest))))
1464 type = ffeinfo_type (ffeinfo_basictype (ffebld_info (item)),
1465 ffeinfo_kindtype (ffebld_info (item)));
1466 if ((widest == FFEINFO_kindtypeNONE)
1467 || (ffetype_size (type)
1468 > ffetype_size (widest_type)))
1475 assert (widest != NULL);
1476 t = ffecom_tree_type[ffeinfo_basictype (ffebld_info (widest))]
1477 [ffeinfo_kindtype (ffebld_info (widest))];
1478 assert (t != NULL_TREE);
1482 /* Check whether a partial overlap between two expressions is possible.
1484 Can *starting* to write a portion of expr1 change the value
1485 computed (perhaps already, *partially*) by expr2?
1487 Currently, this is a concern only for a COMPLEX expr1. But if it
1488 isn't in COMMON or local EQUIVALENCE, since we don't support
1489 aliasing of arguments, it isn't a concern. */
1492 ffecom_possible_partial_overlap_ (ffebld expr1, ffebld expr2 ATTRIBUTE_UNUSED)
1497 switch (ffebld_op (expr1))
1499 case FFEBLD_opSYMTER:
1500 sym = ffebld_symter (expr1);
1503 case FFEBLD_opARRAYREF:
1504 if (ffebld_op (ffebld_left (expr1)) != FFEBLD_opSYMTER)
1506 sym = ffebld_symter (ffebld_left (expr1));
1513 if (ffesymbol_where (sym) != FFEINFO_whereCOMMON
1514 && (ffesymbol_where (sym) != FFEINFO_whereLOCAL
1515 || ! (st = ffesymbol_storage (sym))
1516 || ! ffestorag_parent (st)))
1519 /* It's in COMMON or local EQUIVALENCE. */
1524 /* Check whether dest and source might overlap. ffebld versions of these
1525 might or might not be passed, will be NULL if not.
1527 The test is really whether source_tree is modifiable and, if modified,
1528 might overlap destination such that the value(s) in the destination might
1529 change before it is finally modified. dest_* are the canonized
1530 destination itself. */
1533 ffecom_overlap_ (tree dest_decl, tree dest_offset, tree dest_size,
1534 tree source_tree, ffebld source UNUSED,
1542 if (source_tree == NULL_TREE)
1545 switch (TREE_CODE (source_tree))
1548 case IDENTIFIER_NODE:
1559 case TRUNC_DIV_EXPR:
1561 case FLOOR_DIV_EXPR:
1562 case ROUND_DIV_EXPR:
1563 case TRUNC_MOD_EXPR:
1565 case FLOOR_MOD_EXPR:
1566 case ROUND_MOD_EXPR:
1568 case EXACT_DIV_EXPR:
1569 case FIX_TRUNC_EXPR:
1571 case FIX_FLOOR_EXPR:
1572 case FIX_ROUND_EXPR:
1586 case BIT_ANDTC_EXPR:
1588 case TRUTH_ANDIF_EXPR:
1589 case TRUTH_ORIF_EXPR:
1590 case TRUTH_AND_EXPR:
1592 case TRUTH_XOR_EXPR:
1593 case TRUTH_NOT_EXPR:
1609 return ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1610 TREE_OPERAND (source_tree, 1), NULL,
1614 return ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1615 TREE_OPERAND (source_tree, 0), NULL,
1620 case NON_LVALUE_EXPR:
1622 if (TREE_CODE (TREE_TYPE (source_tree)) != POINTER_TYPE)
1625 ffecom_tree_canonize_ptr_ (&source_decl, &source_offset,
1627 source_size = TYPE_SIZE (TREE_TYPE (TREE_TYPE (source_tree)));
1632 ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1633 TREE_OPERAND (source_tree, 1), NULL,
1635 || ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1636 TREE_OPERAND (source_tree, 2), NULL,
1641 ffecom_tree_canonize_ref_ (&source_decl, &source_offset,
1643 TREE_OPERAND (source_tree, 0));
1647 if (TREE_CODE (TREE_TYPE (source_tree)) != POINTER_TYPE)
1650 source_decl = source_tree;
1651 source_offset = bitsize_zero_node;
1652 source_size = TYPE_SIZE (TREE_TYPE (TREE_TYPE (source_tree)));
1656 case REFERENCE_EXPR:
1657 case PREDECREMENT_EXPR:
1658 case PREINCREMENT_EXPR:
1659 case POSTDECREMENT_EXPR:
1660 case POSTINCREMENT_EXPR:
1668 /* Come here when source_decl, source_offset, and source_size filled
1669 in appropriately. */
1671 if (source_decl == NULL_TREE)
1672 return FALSE; /* No decl involved, so no overlap. */
1674 if (source_decl != dest_decl)
1675 return FALSE; /* Different decl, no overlap. */
1677 if (TREE_CODE (dest_size) == ERROR_MARK)
1678 return TRUE; /* Assignment into entire assumed-size
1679 array? Shouldn't happen.... */
1681 t = ffecom_2 (LE_EXPR, integer_type_node,
1682 ffecom_2 (PLUS_EXPR, TREE_TYPE (dest_offset),
1684 convert (TREE_TYPE (dest_offset),
1686 convert (TREE_TYPE (dest_offset),
1689 if (integer_onep (t))
1690 return FALSE; /* Destination precedes source. */
1693 || (source_size == NULL_TREE)
1694 || (TREE_CODE (source_size) == ERROR_MARK)
1695 || integer_zerop (source_size))
1696 return TRUE; /* No way to tell if dest follows source. */
1698 t = ffecom_2 (LE_EXPR, integer_type_node,
1699 ffecom_2 (PLUS_EXPR, TREE_TYPE (source_offset),
1701 convert (TREE_TYPE (source_offset),
1703 convert (TREE_TYPE (source_offset),
1706 if (integer_onep (t))
1707 return FALSE; /* Destination follows source. */
1709 return TRUE; /* Destination and source overlap. */
1712 /* Check whether dest might overlap any of a list of arguments or is
1713 in a COMMON area the callee might know about (and thus modify). */
1716 ffecom_args_overlapping_ (tree dest_tree, ffebld dest UNUSED,
1717 tree args, tree callee_commons,
1725 ffecom_tree_canonize_ref_ (&dest_decl, &dest_offset, &dest_size,
1728 if (dest_decl == NULL_TREE)
1729 return FALSE; /* Seems unlikely! */
1731 /* If the decl cannot be determined reliably, or if its in COMMON
1732 and the callee isn't known to not futz with COMMON via other
1733 means, overlap might happen. */
1735 if ((TREE_CODE (dest_decl) == ERROR_MARK)
1736 || ((callee_commons != NULL_TREE)
1737 && TREE_PUBLIC (dest_decl)))
1740 for (; args != NULL_TREE; args = TREE_CHAIN (args))
1742 if (((arg = TREE_VALUE (args)) != NULL_TREE)
1743 && ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1744 arg, NULL, scalar_args))
1751 /* Build a string for a variable name as used by NAMELIST. This means that
1752 if we're using the f2c library, we build an uppercase string, since
1756 ffecom_build_f2c_string_ (int i, const char *s)
1758 if (!ffe_is_f2c_library ())
1759 return build_string (i, s);
1768 if (((size_t) i) > ARRAY_SIZE (space))
1769 tmp = malloc_new_ks (malloc_pool_image (), "f2c_string", i);
1773 for (p = s, q = tmp; *p != '\0'; ++p, ++q)
1777 t = build_string (i, tmp);
1779 if (((size_t) i) > ARRAY_SIZE (space))
1780 malloc_kill_ks (malloc_pool_image (), tmp, i);
1786 /* Returns CALL_EXPR or equivalent with given type (pass NULL_TREE for
1787 type to just get whatever the function returns), handling the
1788 f2c value-returning convention, if required, by prepending
1789 to the arglist a pointer to a temporary to receive the return value. */
1792 ffecom_call_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex,
1793 tree type, tree args, tree dest_tree,
1794 ffebld dest, bool *dest_used, tree callee_commons,
1795 bool scalar_args, tree hook)
1800 if (dest_used != NULL)
1805 if ((dest_used == NULL)
1807 || (ffeinfo_basictype (ffebld_info (dest))
1808 != FFEINFO_basictypeCOMPLEX)
1809 || (ffeinfo_kindtype (ffebld_info (dest)) != kt)
1810 || ((type != NULL_TREE) && (TREE_TYPE (dest_tree) != type))
1811 || ffecom_args_overlapping_ (dest_tree, dest, args,
1816 tempvar = ffecom_make_tempvar (ffecom_tree_type
1817 [FFEINFO_basictypeCOMPLEX][kt],
1818 FFETARGET_charactersizeNONE,
1828 tempvar = dest_tree;
1833 = build_tree_list (NULL_TREE,
1834 ffecom_1 (ADDR_EXPR,
1835 build_pointer_type (TREE_TYPE (tempvar)),
1837 TREE_CHAIN (item) = args;
1839 item = ffecom_3s (CALL_EXPR, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), fn,
1842 if (tempvar != dest_tree)
1843 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), item, tempvar);
1846 item = ffecom_3s (CALL_EXPR, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), fn,
1849 if ((type != NULL_TREE) && (TREE_TYPE (item) != type))
1850 item = ffecom_convert_narrow_ (type, item);
1855 /* Given two arguments, transform them and make a call to the given
1856 function via ffecom_call_. */
1859 ffecom_call_binop_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex,
1860 tree type, ffebld left, ffebld right,
1861 tree dest_tree, ffebld dest, bool *dest_used,
1862 tree callee_commons, bool scalar_args, bool ref, tree hook)
1871 /* Pass arguments by reference. */
1872 left_tree = ffecom_arg_ptr_to_expr (left, &left_length);
1873 right_tree = ffecom_arg_ptr_to_expr (right, &right_length);
1877 /* Pass arguments by value. */
1878 left_tree = ffecom_arg_expr (left, &left_length);
1879 right_tree = ffecom_arg_expr (right, &right_length);
1883 left_tree = build_tree_list (NULL_TREE, left_tree);
1884 right_tree = build_tree_list (NULL_TREE, right_tree);
1885 TREE_CHAIN (left_tree) = right_tree;
1887 if (left_length != NULL_TREE)
1889 left_length = build_tree_list (NULL_TREE, left_length);
1890 TREE_CHAIN (right_tree) = left_length;
1893 if (right_length != NULL_TREE)
1895 right_length = build_tree_list (NULL_TREE, right_length);
1896 if (left_length != NULL_TREE)
1897 TREE_CHAIN (left_length) = right_length;
1899 TREE_CHAIN (right_tree) = right_length;
1902 return ffecom_call_ (fn, kt, is_f2c_complex, type, left_tree,
1903 dest_tree, dest, dest_used, callee_commons,
1907 /* Return ptr/length args for char subexpression
1909 Handles CHARACTER-type CONTER, SYMTER, SUBSTR, ARRAYREF, and FUNCREF
1910 subexpressions by constructing the appropriate trees for the ptr-to-
1911 character-text and length-of-character-text arguments in a calling
1914 Note that if with_null is TRUE, and the expression is an opCONTER,
1915 a null byte is appended to the string. */
1918 ffecom_char_args_x_ (tree *xitem, tree *length, ffebld expr, bool with_null)
1922 ffetargetCharacter1 val;
1923 ffetargetCharacterSize newlen;
1925 switch (ffebld_op (expr))
1927 case FFEBLD_opCONTER:
1928 val = ffebld_constant_character1 (ffebld_conter (expr));
1929 newlen = ffetarget_length_character1 (val);
1932 /* Begin FFETARGET-NULL-KLUDGE. */
1936 *length = build_int_2 (newlen, 0);
1937 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
1938 high = build_int_2 (newlen, 0);
1939 TREE_TYPE (high) = ffecom_f2c_ftnlen_type_node;
1940 item = build_string (newlen,
1941 ffetarget_text_character1 (val));
1942 /* End FFETARGET-NULL-KLUDGE. */
1944 = build_type_variant
1948 (ffecom_f2c_ftnlen_type_node,
1949 ffecom_f2c_ftnlen_one_node,
1952 TREE_CONSTANT (item) = 1;
1953 TREE_STATIC (item) = 1;
1954 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
1958 case FFEBLD_opSYMTER:
1960 ffesymbol s = ffebld_symter (expr);
1962 item = ffesymbol_hook (s).decl_tree;
1963 if (item == NULL_TREE)
1965 s = ffecom_sym_transform_ (s);
1966 item = ffesymbol_hook (s).decl_tree;
1968 if (ffesymbol_kind (s) == FFEINFO_kindENTITY)
1970 if (ffesymbol_size (s) == FFETARGET_charactersizeNONE)
1971 *length = ffesymbol_hook (s).length_tree;
1974 *length = build_int_2 (ffesymbol_size (s), 0);
1975 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
1978 else if (item == error_mark_node)
1979 *length = error_mark_node;
1981 /* FFEINFO_kindFUNCTION. */
1982 *length = NULL_TREE;
1983 if (!ffesymbol_hook (s).addr
1984 && (item != error_mark_node))
1985 item = ffecom_1 (ADDR_EXPR,
1986 build_pointer_type (TREE_TYPE (item)),
1991 case FFEBLD_opARRAYREF:
1993 ffecom_char_args_ (&item, length, ffebld_left (expr));
1995 if (item == error_mark_node || *length == error_mark_node)
1997 item = *length = error_mark_node;
2001 item = ffecom_arrayref_ (item, expr, 1);
2005 case FFEBLD_opSUBSTR:
2009 ffebld thing = ffebld_right (expr);
2012 const char *char_name;
2016 assert (ffebld_op (thing) == FFEBLD_opITEM);
2017 start = ffebld_head (thing);
2018 thing = ffebld_trail (thing);
2019 assert (ffebld_trail (thing) == NULL);
2020 end = ffebld_head (thing);
2022 /* Determine name for pretty-printing range-check errors. */
2023 for (left_symter = ffebld_left (expr);
2024 left_symter && ffebld_op (left_symter) == FFEBLD_opARRAYREF;
2025 left_symter = ffebld_left (left_symter))
2027 if (ffebld_op (left_symter) == FFEBLD_opSYMTER)
2028 char_name = ffesymbol_text (ffebld_symter (left_symter));
2030 char_name = "[expr?]";
2032 ffecom_char_args_ (&item, length, ffebld_left (expr));
2034 if (item == error_mark_node || *length == error_mark_node)
2036 item = *length = error_mark_node;
2040 array = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item)));
2042 /* ~~~~Handle INTEGER*8 start/end, a la FFEBLD_opARRAYREF. */
2050 end_tree = ffecom_expr (end);
2051 if (flag_bounds_check)
2052 end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0,
2054 end_tree = convert (ffecom_f2c_ftnlen_type_node,
2057 if (end_tree == error_mark_node)
2059 item = *length = error_mark_node;
2068 start_tree = ffecom_expr (start);
2069 if (flag_bounds_check)
2070 start_tree = ffecom_subscript_check_ (array, start_tree, 0, 0,
2072 start_tree = convert (ffecom_f2c_ftnlen_type_node,
2075 if (start_tree == error_mark_node)
2077 item = *length = error_mark_node;
2081 start_tree = ffecom_save_tree (start_tree);
2083 item = ffecom_2 (PLUS_EXPR, TREE_TYPE (item),
2085 ffecom_2 (MINUS_EXPR,
2086 TREE_TYPE (start_tree),
2088 ffecom_f2c_ftnlen_one_node));
2092 *length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
2093 ffecom_f2c_ftnlen_one_node,
2094 ffecom_2 (MINUS_EXPR,
2095 ffecom_f2c_ftnlen_type_node,
2101 end_tree = ffecom_expr (end);
2102 if (flag_bounds_check)
2103 end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0,
2105 end_tree = convert (ffecom_f2c_ftnlen_type_node,
2108 if (end_tree == error_mark_node)
2110 item = *length = error_mark_node;
2114 *length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
2115 ffecom_f2c_ftnlen_one_node,
2116 ffecom_2 (MINUS_EXPR,
2117 ffecom_f2c_ftnlen_type_node,
2118 end_tree, start_tree));
2124 case FFEBLD_opFUNCREF:
2126 ffesymbol s = ffebld_symter (ffebld_left (expr));
2129 ffetargetCharacterSize size = ffeinfo_size (ffebld_info (expr));
2132 if (size == FFETARGET_charactersizeNONE)
2133 /* ~~Kludge alert! This should someday be fixed. */
2136 *length = build_int_2 (size, 0);
2137 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
2139 if (ffeinfo_where (ffebld_info (ffebld_left (expr)))
2140 == FFEINFO_whereINTRINSIC)
2144 /* Invocation of an intrinsic returning CHARACTER*1. */
2145 item = ffecom_expr_intrinsic_ (expr, NULL_TREE,
2149 ix = ffeintrin_gfrt_direct (ffebld_symter_implementation (ffebld_left (expr)));
2150 assert (ix != FFECOM_gfrt);
2151 item = ffecom_gfrt_tree_ (ix);
2156 item = ffesymbol_hook (s).decl_tree;
2157 if (item == NULL_TREE)
2159 s = ffecom_sym_transform_ (s);
2160 item = ffesymbol_hook (s).decl_tree;
2162 if (item == error_mark_node)
2164 item = *length = error_mark_node;
2168 if (!ffesymbol_hook (s).addr)
2169 item = ffecom_1_fn (item);
2173 tempvar = ffecom_push_tempvar (char_type_node, size, -1, TRUE);
2175 tempvar = ffebld_nonter_hook (expr);
2178 tempvar = ffecom_1 (ADDR_EXPR,
2179 build_pointer_type (TREE_TYPE (tempvar)),
2182 args = build_tree_list (NULL_TREE, tempvar);
2184 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT) /* Sfunc args by value. */
2185 TREE_CHAIN (args) = ffecom_list_expr (ffebld_right (expr));
2188 TREE_CHAIN (args) = build_tree_list (NULL_TREE, *length);
2189 if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC)
2191 TREE_CHAIN (TREE_CHAIN (args))
2192 = ffecom_arglist_expr_ (ffecom_gfrt_args_ (ix),
2193 ffebld_right (expr));
2197 TREE_CHAIN (TREE_CHAIN (args))
2198 = ffecom_list_ptr_to_expr (ffebld_right (expr));
2202 item = ffecom_3s (CALL_EXPR,
2203 TREE_TYPE (TREE_TYPE (TREE_TYPE (item))),
2204 item, args, NULL_TREE);
2205 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), item,
2210 case FFEBLD_opCONVERT:
2212 ffecom_char_args_ (&item, length, ffebld_left (expr));
2214 if (item == error_mark_node || *length == error_mark_node)
2216 item = *length = error_mark_node;
2220 if ((ffebld_size_known (ffebld_left (expr))
2221 == FFETARGET_charactersizeNONE)
2222 || (ffebld_size_known (ffebld_left (expr)) < (ffebld_size (expr))))
2223 { /* Possible blank-padding needed, copy into
2230 tempvar = ffecom_make_tempvar (char_type_node,
2231 ffebld_size (expr), -1);
2233 tempvar = ffebld_nonter_hook (expr);
2236 tempvar = ffecom_1 (ADDR_EXPR,
2237 build_pointer_type (TREE_TYPE (tempvar)),
2240 newlen = build_int_2 (ffebld_size (expr), 0);
2241 TREE_TYPE (newlen) = ffecom_f2c_ftnlen_type_node;
2243 args = build_tree_list (NULL_TREE, tempvar);
2244 TREE_CHAIN (args) = build_tree_list (NULL_TREE, item);
2245 TREE_CHAIN (TREE_CHAIN (args)) = build_tree_list (NULL_TREE, newlen);
2246 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (args)))
2247 = build_tree_list (NULL_TREE, *length);
2249 item = ffecom_call_gfrt (FFECOM_gfrtCOPY, args, NULL_TREE);
2250 TREE_SIDE_EFFECTS (item) = 1;
2251 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), fold (item),
2256 { /* Just truncate the length. */
2257 *length = build_int_2 (ffebld_size (expr), 0);
2258 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
2263 assert ("bad op for single char arg expr" == NULL);
2271 /* Check the size of the type to be sure it doesn't overflow the
2272 "portable" capacities of the compiler back end. `dummy' types
2273 can generally overflow the normal sizes as long as the computations
2274 themselves don't overflow. A particular target of the back end
2275 must still enforce its size requirements, though, and the back
2276 end takes care of this in stor-layout.c. */
2279 ffecom_check_size_overflow_ (ffesymbol s, tree type, bool dummy)
2281 if (TREE_CODE (type) == ERROR_MARK)
2284 if (TYPE_SIZE (type) == NULL_TREE)
2287 if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
2290 /* An array is too large if size is negative or the type_size overflows
2291 or its "upper half" is larger than 3 (which would make the signed
2292 byte size and offset computations overflow). */
2294 if ((tree_int_cst_sgn (TYPE_SIZE (type)) < 0)
2295 || (!dummy && (TREE_INT_CST_HIGH (TYPE_SIZE (type)) > 3
2296 || TREE_OVERFLOW (TYPE_SIZE (type)))))
2298 ffebad_start (FFEBAD_ARRAY_LARGE);
2299 ffebad_string (ffesymbol_text (s));
2300 ffebad_here (0, ffesymbol_where_line (s), ffesymbol_where_column (s));
2303 return error_mark_node;
2309 /* Builds a length argument (PARM_DECL). Also wraps type in an array type
2310 where the dimension info is (1:size) where <size> is ffesymbol_size(s) if
2311 known, length_arg if not known (FFETARGET_charactersizeNONE). */
2314 ffecom_char_enhance_arg_ (tree *xtype, ffesymbol s)
2316 ffetargetCharacterSize sz = ffesymbol_size (s);
2321 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT)
2322 tlen = NULL_TREE; /* A statement function, no length passed. */
2325 if (ffesymbol_where (s) == FFEINFO_whereDUMMY)
2326 tlen = ffecom_get_invented_identifier ("__g77_length_%s",
2327 ffesymbol_text (s));
2329 tlen = ffecom_get_invented_identifier ("__g77_%s", "length");
2330 tlen = build_decl (PARM_DECL, tlen, ffecom_f2c_ftnlen_type_node);
2331 DECL_ARTIFICIAL (tlen) = 1;
2334 if (sz == FFETARGET_charactersizeNONE)
2336 assert (tlen != NULL_TREE);
2337 highval = variable_size (tlen);
2341 highval = build_int_2 (sz, 0);
2342 TREE_TYPE (highval) = ffecom_f2c_ftnlen_type_node;
2345 type = build_array_type (type,
2346 build_range_type (ffecom_f2c_ftnlen_type_node,
2347 ffecom_f2c_ftnlen_one_node,
2354 /* ffecom_concat_list_gather_ -- Gather list of concatenated string exprs
2356 ffecomConcatList_ catlist;
2357 ffebld expr; // expr of CHARACTER basictype.
2358 ffetargetCharacterSize max; // max chars to gather or _...NONE if no max
2359 catlist = ffecom_concat_list_gather_(catlist,expr,max);
2361 Scans expr for character subexpressions, updates and returns catlist
2364 static ffecomConcatList_
2365 ffecom_concat_list_gather_ (ffecomConcatList_ catlist, ffebld expr,
2366 ffetargetCharacterSize max)
2368 ffetargetCharacterSize sz;
2375 if ((max != FFETARGET_charactersizeNONE) && (catlist.minlen >= max))
2376 return catlist; /* Don't append any more items. */
2378 switch (ffebld_op (expr))
2380 case FFEBLD_opCONTER:
2381 case FFEBLD_opSYMTER:
2382 case FFEBLD_opARRAYREF:
2383 case FFEBLD_opFUNCREF:
2384 case FFEBLD_opSUBSTR:
2385 case FFEBLD_opCONVERT: /* Callers should strip this off beforehand
2386 if they don't need to preserve it. */
2387 if (catlist.count == catlist.max)
2388 { /* Make a (larger) list. */
2392 newmax = (catlist.max == 0) ? 8 : catlist.max * 2;
2393 newx = malloc_new_ks (malloc_pool_image (), "catlist",
2394 newmax * sizeof (newx[0]));
2395 if (catlist.max != 0)
2397 memcpy (newx, catlist.exprs, catlist.max * sizeof (newx[0]));
2398 malloc_kill_ks (malloc_pool_image (), catlist.exprs,
2399 catlist.max * sizeof (newx[0]));
2401 catlist.max = newmax;
2402 catlist.exprs = newx;
2404 if ((sz = ffebld_size_known (expr)) != FFETARGET_charactersizeNONE)
2405 catlist.minlen += sz;
2407 ++catlist.minlen; /* Not true for F90; can be 0 length. */
2408 if ((sz = ffebld_size_max (expr)) == FFETARGET_charactersizeNONE)
2409 catlist.maxlen = sz;
2411 catlist.maxlen += sz;
2412 if ((max != FFETARGET_charactersizeNONE) && (catlist.minlen > max))
2413 { /* This item overlaps (or is beyond) the end
2414 of the destination. */
2415 switch (ffebld_op (expr))
2417 case FFEBLD_opCONTER:
2418 case FFEBLD_opSYMTER:
2419 case FFEBLD_opARRAYREF:
2420 case FFEBLD_opFUNCREF:
2421 case FFEBLD_opSUBSTR:
2422 /* ~~Do useful truncations here. */
2426 assert ("op changed or inconsistent switches!" == NULL);
2430 catlist.exprs[catlist.count++] = expr;
2433 case FFEBLD_opPAREN:
2434 expr = ffebld_left (expr);
2435 goto recurse; /* :::::::::::::::::::: */
2437 case FFEBLD_opCONCATENATE:
2438 catlist = ffecom_concat_list_gather_ (catlist, ffebld_left (expr), max);
2439 expr = ffebld_right (expr);
2440 goto recurse; /* :::::::::::::::::::: */
2442 #if 0 /* Breaks passing small actual arg to larger
2443 dummy arg of sfunc */
2444 case FFEBLD_opCONVERT:
2445 expr = ffebld_left (expr);
2447 ffetargetCharacterSize cmax;
2449 cmax = catlist.len + ffebld_size_known (expr);
2451 if ((max == FFETARGET_charactersizeNONE) || (max > cmax))
2454 goto recurse; /* :::::::::::::::::::: */
2461 assert ("bad op in _gather_" == NULL);
2466 /* ffecom_concat_list_kill_ -- Kill list of concatenated string exprs
2468 ffecomConcatList_ catlist;
2469 ffecom_concat_list_kill_(catlist);
2471 Anything allocated within the list info is deallocated. */
2474 ffecom_concat_list_kill_ (ffecomConcatList_ catlist)
2476 if (catlist.max != 0)
2477 malloc_kill_ks (malloc_pool_image (), catlist.exprs,
2478 catlist.max * sizeof (catlist.exprs[0]));
2481 /* Make list of concatenated string exprs.
2483 Returns a flattened list of concatenated subexpressions given a
2484 tree of such expressions. */
2486 static ffecomConcatList_
2487 ffecom_concat_list_new_ (ffebld expr, ffetargetCharacterSize max)
2489 ffecomConcatList_ catlist;
2491 catlist.maxlen = catlist.minlen = catlist.max = catlist.count = 0;
2492 return ffecom_concat_list_gather_ (catlist, expr, max);
2495 /* Provide some kind of useful info on member of aggregate area,
2496 since current g77/gcc technology does not provide debug info
2497 on these members. */
2500 ffecom_debug_kludge_ (tree aggr, const char *aggr_type, ffesymbol member,
2501 tree member_type UNUSED, ffetargetOffset offset)
2511 for (type_id = member_type;
2512 TREE_CODE (type_id) != IDENTIFIER_NODE;
2515 switch (TREE_CODE (type_id))
2519 type_id = TYPE_NAME (type_id);
2524 type_id = TREE_TYPE (type_id);
2528 assert ("no IDENTIFIER_NODE for type!" == NULL);
2529 type_id = error_mark_node;
2535 if (ffecom_transform_only_dummies_
2536 || !ffe_is_debug_kludge ())
2537 return; /* Can't do this yet, maybe later. */
2540 + strlen (aggr_type)
2541 + IDENTIFIER_LENGTH (DECL_NAME (aggr));
2543 + IDENTIFIER_LENGTH (type_id);
2546 if (((size_t) len) >= ARRAY_SIZE (space))
2547 buff = malloc_new_ks (malloc_pool_image (), "debug_kludge", len + 1);
2551 sprintf (&buff[0], "At (%s) `%s' plus %ld bytes",
2553 IDENTIFIER_POINTER (DECL_NAME (aggr)),
2556 value = build_string (len, buff);
2558 = build_type_variant (build_array_type (char_type_node,
2562 build_int_2 (strlen (buff), 0))),
2564 decl = build_decl (VAR_DECL,
2565 ffecom_get_identifier_ (ffesymbol_text (member)),
2567 TREE_CONSTANT (decl) = 1;
2568 TREE_STATIC (decl) = 1;
2569 DECL_INITIAL (decl) = error_mark_node;
2570 DECL_IN_SYSTEM_HEADER (decl) = 1; /* Don't let -Wunused complain. */
2571 decl = start_decl (decl, FALSE);
2572 finish_decl (decl, value, FALSE);
2574 if (buff != &space[0])
2575 malloc_kill_ks (malloc_pool_image (), buff, len + 1);
2578 /* ffecom_do_entry_ -- Do compilation of a particular entrypoint
2580 ffesymbol fn; // the SUBROUTINE, FUNCTION, or ENTRY symbol itself
2581 int i; // entry# for this entrypoint (used by master fn)
2582 ffecom_do_entrypoint_(s,i);
2584 Makes a public entry point that calls our private master fn (already
2588 ffecom_do_entry_ (ffesymbol fn, int entrynum)
2591 tree type; /* Type of function. */
2592 tree multi_retval; /* Var holding return value (union). */
2593 tree result; /* Var holding result. */
2594 ffeinfoBasictype bt;
2598 bool charfunc; /* All entry points return same type
2600 bool cmplxfunc; /* Use f2c way of returning COMPLEX. */
2601 bool multi; /* Master fn has multiple return types. */
2602 bool altreturning = FALSE; /* This entry point has alternate returns. */
2603 int old_lineno = lineno;
2604 const char *old_input_filename = input_filename;
2606 input_filename = ffesymbol_where_filename (fn);
2607 lineno = ffesymbol_where_filelinenum (fn);
2609 ffecom_doing_entry_ = TRUE; /* Don't bother with array dimensions. */
2611 switch (ffecom_primary_entry_kind_)
2613 case FFEINFO_kindFUNCTION:
2615 /* Determine actual return type for function. */
2617 gt = FFEGLOBAL_typeFUNC;
2618 bt = ffesymbol_basictype (fn);
2619 kt = ffesymbol_kindtype (fn);
2620 if (bt == FFEINFO_basictypeNONE)
2622 ffeimplic_establish_symbol (fn);
2623 if (ffesymbol_funcresult (fn) != NULL)
2624 ffeimplic_establish_symbol (ffesymbol_funcresult (fn));
2625 bt = ffesymbol_basictype (fn);
2626 kt = ffesymbol_kindtype (fn);
2629 if (bt == FFEINFO_basictypeCHARACTER)
2630 charfunc = TRUE, cmplxfunc = FALSE;
2631 else if ((bt == FFEINFO_basictypeCOMPLEX)
2632 && ffesymbol_is_f2c (fn))
2633 charfunc = FALSE, cmplxfunc = TRUE;
2635 charfunc = cmplxfunc = FALSE;
2638 type = ffecom_tree_fun_type_void;
2639 else if (ffesymbol_is_f2c (fn))
2640 type = ffecom_tree_fun_type[bt][kt];
2642 type = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
2644 if ((type == NULL_TREE)
2645 || (TREE_TYPE (type) == NULL_TREE))
2646 type = ffecom_tree_fun_type_void; /* _sym_exec_transition. */
2648 multi = (ffecom_master_bt_ == FFEINFO_basictypeNONE);
2651 case FFEINFO_kindSUBROUTINE:
2652 gt = FFEGLOBAL_typeSUBR;
2653 bt = FFEINFO_basictypeNONE;
2654 kt = FFEINFO_kindtypeNONE;
2655 if (ffecom_is_altreturning_)
2656 { /* Am _I_ altreturning? */
2657 for (item = ffesymbol_dummyargs (fn);
2659 item = ffebld_trail (item))
2661 if (ffebld_op (ffebld_head (item)) == FFEBLD_opSTAR)
2663 altreturning = TRUE;
2668 type = ffecom_tree_subr_type;
2670 type = ffecom_tree_fun_type_void;
2673 type = ffecom_tree_fun_type_void;
2680 assert ("say what??" == NULL);
2682 case FFEINFO_kindANY:
2683 gt = FFEGLOBAL_typeANY;
2684 bt = FFEINFO_basictypeNONE;
2685 kt = FFEINFO_kindtypeNONE;
2686 type = error_mark_node;
2693 /* build_decl uses the current lineno and input_filename to set the decl
2694 source info. So, I've putzed with ffestd and ffeste code to update that
2695 source info to point to the appropriate statement just before calling
2696 ffecom_do_entrypoint (which calls this fn). */
2698 start_function (ffecom_get_external_identifier_ (fn),
2700 0, /* nested/inline */
2701 1); /* TREE_PUBLIC */
2703 if (((g = ffesymbol_global (fn)) != NULL)
2704 && ((ffeglobal_type (g) == gt)
2705 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
2707 ffeglobal_set_hook (g, current_function_decl);
2710 /* Reset args in master arg list so they get retransitioned. */
2712 for (item = ffecom_master_arglist_;
2714 item = ffebld_trail (item))
2719 arg = ffebld_head (item);
2720 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2721 continue; /* Alternate return or some such thing. */
2722 s = ffebld_symter (arg);
2723 ffesymbol_hook (s).decl_tree = NULL_TREE;
2724 ffesymbol_hook (s).length_tree = NULL_TREE;
2727 /* Build dummy arg list for this entry point. */
2729 if (charfunc || cmplxfunc)
2730 { /* Prepend arg for where result goes. */
2735 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
2737 type = ffecom_tree_type[FFEINFO_basictypeCOMPLEX][kt];
2739 result = ffecom_get_invented_identifier ("__g77_%s", "result");
2741 /* Make length arg _and_ enhance type info for CHAR arg itself. */
2744 length = ffecom_char_enhance_arg_ (&type, fn);
2746 length = NULL_TREE; /* Not ref'd if !charfunc. */
2748 type = build_pointer_type (type);
2749 result = build_decl (PARM_DECL, result, type);
2751 push_parm_decl (result);
2752 ffecom_func_result_ = result;
2756 push_parm_decl (length);
2757 ffecom_func_length_ = length;
2761 result = DECL_RESULT (current_function_decl);
2763 ffecom_push_dummy_decls_ (ffesymbol_dummyargs (fn), FALSE);
2765 store_parm_decls (0);
2767 ffecom_start_compstmt ();
2768 /* Disallow temp vars at this level. */
2769 current_binding_level->prep_state = 2;
2771 /* Make local var to hold return type for multi-type master fn. */
2775 multi_retval = ffecom_get_invented_identifier ("__g77_%s",
2777 multi_retval = build_decl (VAR_DECL, multi_retval,
2778 ffecom_multi_type_node_);
2779 multi_retval = start_decl (multi_retval, FALSE);
2780 finish_decl (multi_retval, NULL_TREE, FALSE);
2783 multi_retval = NULL_TREE; /* Not actually ref'd if !multi. */
2785 /* Here we emit the actual code for the entry point. */
2791 tree arglist = NULL_TREE;
2792 tree *plist = &arglist;
2798 /* Prepare actual arg list based on master arg list. */
2800 for (list = ffecom_master_arglist_;
2802 list = ffebld_trail (list))
2804 arg = ffebld_head (list);
2805 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2807 s = ffebld_symter (arg);
2808 if (ffesymbol_hook (s).decl_tree == NULL_TREE
2809 || ffesymbol_hook (s).decl_tree == error_mark_node)
2810 actarg = null_pointer_node; /* We don't have this arg. */
2812 actarg = ffesymbol_hook (s).decl_tree;
2813 *plist = build_tree_list (NULL_TREE, actarg);
2814 plist = &TREE_CHAIN (*plist);
2817 /* This code appends the length arguments for character
2818 variables/arrays. */
2820 for (list = ffecom_master_arglist_;
2822 list = ffebld_trail (list))
2824 arg = ffebld_head (list);
2825 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2827 s = ffebld_symter (arg);
2828 if (ffesymbol_basictype (s) != FFEINFO_basictypeCHARACTER)
2829 continue; /* Only looking for CHARACTER arguments. */
2830 if (ffesymbol_kind (s) != FFEINFO_kindENTITY)
2831 continue; /* Only looking for variables and arrays. */
2832 if (ffesymbol_hook (s).length_tree == NULL_TREE
2833 || ffesymbol_hook (s).length_tree == error_mark_node)
2834 actarg = ffecom_f2c_ftnlen_zero_node; /* We don't have this arg. */
2836 actarg = ffesymbol_hook (s).length_tree;
2837 *plist = build_tree_list (NULL_TREE, actarg);
2838 plist = &TREE_CHAIN (*plist);
2841 /* Prepend character-value return info to actual arg list. */
2845 prepend = build_tree_list (NULL_TREE, ffecom_func_result_);
2846 TREE_CHAIN (prepend)
2847 = build_tree_list (NULL_TREE, ffecom_func_length_);
2848 TREE_CHAIN (TREE_CHAIN (prepend)) = arglist;
2852 /* Prepend multi-type return value to actual arg list. */
2857 = build_tree_list (NULL_TREE,
2858 ffecom_1 (ADDR_EXPR,
2859 build_pointer_type (TREE_TYPE (multi_retval)),
2861 TREE_CHAIN (prepend) = arglist;
2865 /* Prepend my entry-point number to the actual arg list. */
2867 prepend = build_tree_list (NULL_TREE, build_int_2 (entrynum, 0));
2868 TREE_CHAIN (prepend) = arglist;
2871 /* Build the call to the master function. */
2873 master_fn = ffecom_1_fn (ffecom_previous_function_decl_);
2874 call = ffecom_3s (CALL_EXPR,
2875 TREE_TYPE (TREE_TYPE (TREE_TYPE (master_fn))),
2876 master_fn, arglist, NULL_TREE);
2878 /* Decide whether the master function is a function or subroutine, and
2879 handle the return value for my entry point. */
2881 if (charfunc || ((ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE)
2884 expand_expr_stmt (call);
2885 expand_null_return ();
2887 else if (multi && cmplxfunc)
2889 expand_expr_stmt (call);
2891 = ffecom_1 (INDIRECT_REF,
2892 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result))),
2894 result = ffecom_modify (NULL_TREE, result,
2895 ffecom_2 (COMPONENT_REF, TREE_TYPE (result),
2897 ffecom_multi_fields_[bt][kt]));
2898 expand_expr_stmt (result);
2899 expand_null_return ();
2903 expand_expr_stmt (call);
2905 = ffecom_modify (NULL_TREE, result,
2906 convert (TREE_TYPE (result),
2907 ffecom_2 (COMPONENT_REF,
2908 ffecom_tree_type[bt][kt],
2910 ffecom_multi_fields_[bt][kt])));
2911 expand_return (result);
2916 = ffecom_1 (INDIRECT_REF,
2917 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result))),
2919 result = ffecom_modify (NULL_TREE, result, call);
2920 expand_expr_stmt (result);
2921 expand_null_return ();
2925 result = ffecom_modify (NULL_TREE,
2927 convert (TREE_TYPE (result),
2929 expand_return (result);
2933 ffecom_end_compstmt ();
2935 finish_function (0);
2937 lineno = old_lineno;
2938 input_filename = old_input_filename;
2940 ffecom_doing_entry_ = FALSE;
2943 /* Transform expr into gcc tree with possible destination
2945 Recursive descent on expr while making corresponding tree nodes and
2946 attaching type info and such. If destination supplied and compatible
2947 with temporary that would be made in certain cases, temporary isn't
2948 made, destination used instead, and dest_used flag set TRUE. */
2951 ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest,
2952 bool *dest_used, bool assignp, bool widenp)
2957 ffeinfoBasictype bt;
2960 tree dt; /* decl_tree for an ffesymbol. */
2961 tree tree_type, tree_type_x;
2964 enum tree_code code;
2966 assert (expr != NULL);
2968 if (dest_used != NULL)
2971 bt = ffeinfo_basictype (ffebld_info (expr));
2972 kt = ffeinfo_kindtype (ffebld_info (expr));
2973 tree_type = ffecom_tree_type[bt][kt];
2975 /* Widen integral arithmetic as desired while preserving signedness. */
2976 tree_type_x = NULL_TREE;
2977 if (widenp && tree_type
2978 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
2979 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
2980 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
2982 switch (ffebld_op (expr))
2984 case FFEBLD_opACCTER:
2987 ffebit bits = ffebld_accter_bits (expr);
2988 ffetargetOffset source_offset = 0;
2989 ffetargetOffset dest_offset = ffebld_accter_pad (expr);
2992 assert (dest_offset == 0
2993 || (bt == FFEINFO_basictypeCHARACTER
2994 && kt == FFEINFO_kindtypeCHARACTER1));
2999 ffebldConstantUnion cu;
3002 ffebldConstantArray ca = ffebld_accter (expr);
3004 ffebit_test (bits, source_offset, &value, &length);
3010 for (i = 0; i < length; ++i)
3012 cu = ffebld_constantarray_get (ca, bt, kt,
3015 t = ffecom_constantunion (&cu, bt, kt, tree_type);
3018 && dest_offset != 0)
3019 purpose = build_int_2 (dest_offset, 0);
3021 purpose = NULL_TREE;
3023 if (list == NULL_TREE)
3024 list = item = build_tree_list (purpose, t);
3027 TREE_CHAIN (item) = build_tree_list (purpose, t);
3028 item = TREE_CHAIN (item);
3032 source_offset += length;
3033 dest_offset += length;
3037 item = build_int_2 ((ffebld_accter_size (expr)
3038 + ffebld_accter_pad (expr)) - 1, 0);
3039 ffebit_kill (ffebld_accter_bits (expr));
3040 TREE_TYPE (item) = ffecom_integer_type_node;
3044 build_range_type (ffecom_integer_type_node,
3045 ffecom_integer_zero_node,
3047 list = build (CONSTRUCTOR, item, NULL_TREE, list);
3048 TREE_CONSTANT (list) = 1;
3049 TREE_STATIC (list) = 1;
3052 case FFEBLD_opARRTER:
3057 if (ffebld_arrter_pad (expr) == 0)
3061 assert (bt == FFEINFO_basictypeCHARACTER
3062 && kt == FFEINFO_kindtypeCHARACTER1);
3064 /* Becomes PURPOSE first time through loop. */
3065 item = build_int_2 (ffebld_arrter_pad (expr), 0);
3068 for (i = 0; i < ffebld_arrter_size (expr); ++i)
3070 ffebldConstantUnion cu
3071 = ffebld_constantarray_get (ffebld_arrter (expr), bt, kt, i);
3073 t = ffecom_constantunion (&cu, bt, kt, tree_type);
3075 if (list == NULL_TREE)
3076 /* Assume item is PURPOSE first time through loop. */
3077 list = item = build_tree_list (item, t);
3080 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
3081 item = TREE_CHAIN (item);
3086 item = build_int_2 ((ffebld_arrter_size (expr)
3087 + ffebld_arrter_pad (expr)) - 1, 0);
3088 TREE_TYPE (item) = ffecom_integer_type_node;
3092 build_range_type (ffecom_integer_type_node,
3093 ffecom_integer_zero_node,
3095 list = build (CONSTRUCTOR, item, NULL_TREE, list);
3096 TREE_CONSTANT (list) = 1;
3097 TREE_STATIC (list) = 1;
3100 case FFEBLD_opCONTER:
3101 assert (ffebld_conter_pad (expr) == 0);
3103 = ffecom_constantunion (&ffebld_constant_union (ffebld_conter (expr)),
3107 case FFEBLD_opSYMTER:
3108 if ((ffebld_symter_generic (expr) != FFEINTRIN_genNONE)
3109 || (ffebld_symter_specific (expr) != FFEINTRIN_specNONE))
3110 return ffecom_ptr_to_expr (expr); /* Same as %REF(intrinsic). */
3111 s = ffebld_symter (expr);
3112 t = ffesymbol_hook (s).decl_tree;
3115 { /* ASSIGN'ed-label expr. */
3116 if (ffe_is_ugly_assign ())
3118 /* User explicitly wants ASSIGN'ed variables to be at the same
3119 memory address as the variables when used in non-ASSIGN
3120 contexts. That can make old, arcane, non-standard code
3121 work, but don't try to do it when a pointer wouldn't fit
3122 in the normal variable (take other approach, and warn,
3127 s = ffecom_sym_transform_ (s);
3128 t = ffesymbol_hook (s).decl_tree;
3129 assert (t != NULL_TREE);
3132 if (t == error_mark_node)
3135 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (t)))
3136 >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
3138 if (ffesymbol_hook (s).addr)
3139 t = ffecom_1 (INDIRECT_REF,
3140 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), t);
3144 if (ffesymbol_hook (s).assign_tree == NULL_TREE)
3146 /* xgettext:no-c-format */
3147 ffebad_start_msg ("ASSIGN'ed label cannot fit into `%A' at %0 -- using wider sibling",
3148 FFEBAD_severityWARNING);
3149 ffebad_string (ffesymbol_text (s));
3150 ffebad_here (0, ffesymbol_where_line (s),
3151 ffesymbol_where_column (s));
3156 /* Don't use the normal variable's tree for ASSIGN, though mark
3157 it as in the system header (housekeeping). Use an explicit,
3158 specially created sibling that is known to be wide enough
3159 to hold pointers to labels. */
3162 && TREE_CODE (t) == VAR_DECL)
3163 DECL_IN_SYSTEM_HEADER (t) = 1; /* Don't let -Wunused complain. */
3165 t = ffesymbol_hook (s).assign_tree;
3168 s = ffecom_sym_transform_assign_ (s);
3169 t = ffesymbol_hook (s).assign_tree;
3170 assert (t != NULL_TREE);
3177 s = ffecom_sym_transform_ (s);
3178 t = ffesymbol_hook (s).decl_tree;
3179 assert (t != NULL_TREE);
3181 if (ffesymbol_hook (s).addr)
3182 t = ffecom_1 (INDIRECT_REF,
3183 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), t);
3187 case FFEBLD_opARRAYREF:
3188 return ffecom_arrayref_ (NULL_TREE, expr, 0);
3190 case FFEBLD_opUPLUS:
3191 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3192 return ffecom_1 (NOP_EXPR, tree_type, left);
3194 case FFEBLD_opPAREN:
3195 /* ~~~Make sure Fortran rules respected here */
3196 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3197 return ffecom_1 (NOP_EXPR, tree_type, left);
3199 case FFEBLD_opUMINUS:
3200 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3203 tree_type = tree_type_x;
3204 left = convert (tree_type, left);
3206 return ffecom_1 (NEGATE_EXPR, tree_type, left);
3209 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3210 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
3213 tree_type = tree_type_x;
3214 left = convert (tree_type, left);
3215 right = convert (tree_type, right);
3217 return ffecom_2 (PLUS_EXPR, tree_type, left, right);
3219 case FFEBLD_opSUBTRACT:
3220 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3221 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
3224 tree_type = tree_type_x;
3225 left = convert (tree_type, left);
3226 right = convert (tree_type, right);
3228 return ffecom_2 (MINUS_EXPR, tree_type, left, right);
3230 case FFEBLD_opMULTIPLY:
3231 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3232 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
3235 tree_type = tree_type_x;
3236 left = convert (tree_type, left);
3237 right = convert (tree_type, right);
3239 return ffecom_2 (MULT_EXPR, tree_type, left, right);
3241 case FFEBLD_opDIVIDE:
3242 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3243 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
3246 tree_type = tree_type_x;
3247 left = convert (tree_type, left);
3248 right = convert (tree_type, right);
3250 return ffecom_tree_divide_ (tree_type, left, right,
3251 dest_tree, dest, dest_used,
3252 ffebld_nonter_hook (expr));
3254 case FFEBLD_opPOWER:
3256 ffebld left = ffebld_left (expr);
3257 ffebld right = ffebld_right (expr);
3259 ffeinfoKindtype rtkt;
3260 ffeinfoKindtype ltkt;
3263 switch (ffeinfo_basictype (ffebld_info (right)))
3266 case FFEINFO_basictypeINTEGER:
3269 item = ffecom_expr_power_integer_ (expr);
3270 if (item != NULL_TREE)
3274 rtkt = FFEINFO_kindtypeINTEGER1;
3275 switch (ffeinfo_basictype (ffebld_info (left)))
3277 case FFEINFO_basictypeINTEGER:
3278 if ((ffeinfo_kindtype (ffebld_info (left))
3279 == FFEINFO_kindtypeINTEGER4)
3280 || (ffeinfo_kindtype (ffebld_info (right))
3281 == FFEINFO_kindtypeINTEGER4))
3283 code = FFECOM_gfrtPOW_QQ;
3284 ltkt = FFEINFO_kindtypeINTEGER4;
3285 rtkt = FFEINFO_kindtypeINTEGER4;
3289 code = FFECOM_gfrtPOW_II;
3290 ltkt = FFEINFO_kindtypeINTEGER1;
3294 case FFEINFO_basictypeREAL:
3295 if (ffeinfo_kindtype (ffebld_info (left))
3296 == FFEINFO_kindtypeREAL1)
3298 code = FFECOM_gfrtPOW_RI;
3299 ltkt = FFEINFO_kindtypeREAL1;
3303 code = FFECOM_gfrtPOW_DI;
3304 ltkt = FFEINFO_kindtypeREAL2;
3308 case FFEINFO_basictypeCOMPLEX:
3309 if (ffeinfo_kindtype (ffebld_info (left))
3310 == FFEINFO_kindtypeREAL1)
3312 code = FFECOM_gfrtPOW_CI; /* Overlapping result okay. */
3313 ltkt = FFEINFO_kindtypeREAL1;
3317 code = FFECOM_gfrtPOW_ZI; /* Overlapping result okay. */
3318 ltkt = FFEINFO_kindtypeREAL2;
3323 assert ("bad pow_*i" == NULL);
3324 code = FFECOM_gfrtPOW_CI; /* Overlapping result okay. */
3325 ltkt = FFEINFO_kindtypeREAL1;
3328 if (ffeinfo_kindtype (ffebld_info (left)) != ltkt)
3329 left = ffeexpr_convert (left, NULL, NULL,
3330 ffeinfo_basictype (ffebld_info (left)),
3332 FFETARGET_charactersizeNONE,
3333 FFEEXPR_contextLET);
3334 if (ffeinfo_kindtype (ffebld_info (right)) != rtkt)
3335 right = ffeexpr_convert (right, NULL, NULL,
3336 FFEINFO_basictypeINTEGER,
3338 FFETARGET_charactersizeNONE,
3339 FFEEXPR_contextLET);
3342 case FFEINFO_basictypeREAL:
3343 if (ffeinfo_kindtype (ffebld_info (left)) == FFEINFO_kindtypeREAL1)
3344 left = ffeexpr_convert (left, NULL, NULL, FFEINFO_basictypeREAL,
3345 FFEINFO_kindtypeREALDOUBLE, 0,
3346 FFETARGET_charactersizeNONE,
3347 FFEEXPR_contextLET);
3348 if (ffeinfo_kindtype (ffebld_info (right))
3349 == FFEINFO_kindtypeREAL1)
3350 right = ffeexpr_convert (right, NULL, NULL,
3351 FFEINFO_basictypeREAL,
3352 FFEINFO_kindtypeREALDOUBLE, 0,
3353 FFETARGET_charactersizeNONE,
3354 FFEEXPR_contextLET);
3355 /* We used to call FFECOM_gfrtPOW_DD here,
3356 which passes arguments by reference. */
3357 code = FFECOM_gfrtL_POW;
3358 /* Pass arguments by value. */
3362 case FFEINFO_basictypeCOMPLEX:
3363 if (ffeinfo_kindtype (ffebld_info (left)) == FFEINFO_kindtypeREAL1)
3364 left = ffeexpr_convert (left, NULL, NULL,
3365 FFEINFO_basictypeCOMPLEX,
3366 FFEINFO_kindtypeREALDOUBLE, 0,
3367 FFETARGET_charactersizeNONE,
3368 FFEEXPR_contextLET);
3369 if (ffeinfo_kindtype (ffebld_info (right))
3370 == FFEINFO_kindtypeREAL1)
3371 right = ffeexpr_convert (right, NULL, NULL,
3372 FFEINFO_basictypeCOMPLEX,
3373 FFEINFO_kindtypeREALDOUBLE, 0,
3374 FFETARGET_charactersizeNONE,
3375 FFEEXPR_contextLET);
3376 code = FFECOM_gfrtPOW_ZZ; /* Overlapping result okay. */
3377 ref = TRUE; /* Pass arguments by reference. */
3381 assert ("bad pow_x*" == NULL);
3382 code = FFECOM_gfrtPOW_II;
3385 return ffecom_call_binop_ (ffecom_gfrt_tree_ (code),
3386 ffecom_gfrt_kindtype (code),
3387 (ffe_is_f2c_library ()
3388 && ffecom_gfrt_complex_[code]),
3389 tree_type, left, right,
3390 dest_tree, dest, dest_used,
3391 NULL_TREE, FALSE, ref,
3392 ffebld_nonter_hook (expr));
3398 case FFEINFO_basictypeLOGICAL:
3399 item = ffecom_truth_value_invert (ffecom_expr (ffebld_left (expr)));
3400 return convert (tree_type, item);
3402 case FFEINFO_basictypeINTEGER:
3403 return ffecom_1 (BIT_NOT_EXPR, tree_type,
3404 ffecom_expr (ffebld_left (expr)));
3407 assert ("NOT bad basictype" == NULL);
3409 case FFEINFO_basictypeANY:
3410 return error_mark_node;
3414 case FFEBLD_opFUNCREF:
3415 assert (ffeinfo_basictype (ffebld_info (expr))
3416 != FFEINFO_basictypeCHARACTER);
3418 case FFEBLD_opSUBRREF:
3419 if (ffeinfo_where (ffebld_info (ffebld_left (expr)))
3420 == FFEINFO_whereINTRINSIC)
3421 { /* Invocation of an intrinsic. */
3422 item = ffecom_expr_intrinsic_ (expr, dest_tree, dest,
3426 s = ffebld_symter (ffebld_left (expr));
3427 dt = ffesymbol_hook (s).decl_tree;
3428 if (dt == NULL_TREE)
3430 s = ffecom_sym_transform_ (s);
3431 dt = ffesymbol_hook (s).decl_tree;
3433 if (dt == error_mark_node)
3436 if (ffesymbol_hook (s).addr)
3439 item = ffecom_1_fn (dt);
3441 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT)
3442 args = ffecom_list_expr (ffebld_right (expr));
3444 args = ffecom_list_ptr_to_expr (ffebld_right (expr));
3446 if (args == error_mark_node)
3447 return error_mark_node;
3449 item = ffecom_call_ (item, kt,
3450 ffesymbol_is_f2c (s)
3451 && (bt == FFEINFO_basictypeCOMPLEX)
3452 && (ffesymbol_where (s)
3453 != FFEINFO_whereCONSTANT),
3456 dest_tree, dest, dest_used,
3457 error_mark_node, FALSE,
3458 ffebld_nonter_hook (expr));
3459 TREE_SIDE_EFFECTS (item) = 1;
3465 case FFEINFO_basictypeLOGICAL:
3467 = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
3468 ffecom_truth_value (ffecom_expr (ffebld_left (expr))),
3469 ffecom_truth_value (ffecom_expr (ffebld_right (expr))));
3470 return convert (tree_type, item);
3472 case FFEINFO_basictypeINTEGER:
3473 return ffecom_2 (BIT_AND_EXPR, tree_type,
3474 ffecom_expr (ffebld_left (expr)),
3475 ffecom_expr (ffebld_right (expr)));
3478 assert ("AND bad basictype" == NULL);
3480 case FFEINFO_basictypeANY:
3481 return error_mark_node;
3488 case FFEINFO_basictypeLOGICAL:
3490 = ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
3491 ffecom_truth_value (ffecom_expr (ffebld_left (expr))),
3492 ffecom_truth_value (ffecom_expr (ffebld_right (expr))));
3493 return convert (tree_type, item);
3495 case FFEINFO_basictypeINTEGER:
3496 return ffecom_2 (BIT_IOR_EXPR, tree_type,
3497 ffecom_expr (ffebld_left (expr)),
3498 ffecom_expr (ffebld_right (expr)));
3501 assert ("OR bad basictype" == NULL);
3503 case FFEINFO_basictypeANY:
3504 return error_mark_node;
3512 case FFEINFO_basictypeLOGICAL:
3514 = ffecom_2 (NE_EXPR, integer_type_node,
3515 ffecom_expr (ffebld_left (expr)),
3516 ffecom_expr (ffebld_right (expr)));
3517 return convert (tree_type, ffecom_truth_value (item));
3519 case FFEINFO_basictypeINTEGER:
3520 return ffecom_2 (BIT_XOR_EXPR, tree_type,
3521 ffecom_expr (ffebld_left (expr)),
3522 ffecom_expr (ffebld_right (expr)));
3525 assert ("XOR/NEQV bad basictype" == NULL);
3527 case FFEINFO_basictypeANY:
3528 return error_mark_node;
3535 case FFEINFO_basictypeLOGICAL:
3537 = ffecom_2 (EQ_EXPR, integer_type_node,
3538 ffecom_expr (ffebld_left (expr)),
3539 ffecom_expr (ffebld_right (expr)));
3540 return convert (tree_type, ffecom_truth_value (item));
3542 case FFEINFO_basictypeINTEGER:
3544 ffecom_1 (BIT_NOT_EXPR, tree_type,
3545 ffecom_2 (BIT_XOR_EXPR, tree_type,
3546 ffecom_expr (ffebld_left (expr)),
3547 ffecom_expr (ffebld_right (expr))));
3550 assert ("EQV bad basictype" == NULL);
3552 case FFEINFO_basictypeANY:
3553 return error_mark_node;
3557 case FFEBLD_opCONVERT:
3558 if (ffebld_op (ffebld_left (expr)) == FFEBLD_opANY)
3559 return error_mark_node;
3563 case FFEINFO_basictypeLOGICAL:
3564 case FFEINFO_basictypeINTEGER:
3565 case FFEINFO_basictypeREAL:
3566 return convert (tree_type, ffecom_expr (ffebld_left (expr)));
3568 case FFEINFO_basictypeCOMPLEX:
3569 switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr))))
3571 case FFEINFO_basictypeINTEGER:
3572 case FFEINFO_basictypeLOGICAL:
3573 case FFEINFO_basictypeREAL:
3574 item = ffecom_expr (ffebld_left (expr));
3575 if (item == error_mark_node)
3576 return error_mark_node;
3577 /* convert() takes care of converting to the subtype first,
3578 at least in gcc-2.7.2. */
3579 item = convert (tree_type, item);
3582 case FFEINFO_basictypeCOMPLEX:
3583 return convert (tree_type, ffecom_expr (ffebld_left (expr)));
3586 assert ("CONVERT COMPLEX bad basictype" == NULL);
3588 case FFEINFO_basictypeANY:
3589 return error_mark_node;
3594 assert ("CONVERT bad basictype" == NULL);
3596 case FFEINFO_basictypeANY:
3597 return error_mark_node;
3603 goto relational; /* :::::::::::::::::::: */
3607 goto relational; /* :::::::::::::::::::: */
3611 goto relational; /* :::::::::::::::::::: */
3615 goto relational; /* :::::::::::::::::::: */
3619 goto relational; /* :::::::::::::::::::: */
3624 relational: /* :::::::::::::::::::: */
3625 switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr))))
3627 case FFEINFO_basictypeLOGICAL:
3628 case FFEINFO_basictypeINTEGER:
3629 case FFEINFO_basictypeREAL:
3630 item = ffecom_2 (code, integer_type_node,
3631 ffecom_expr (ffebld_left (expr)),
3632 ffecom_expr (ffebld_right (expr)));
3633 return convert (tree_type, item);
3635 case FFEINFO_basictypeCOMPLEX:
3636 assert (code == EQ_EXPR || code == NE_EXPR);
3639 tree arg1 = ffecom_expr (ffebld_left (expr));
3640 tree arg2 = ffecom_expr (ffebld_right (expr));
3642 if (arg1 == error_mark_node || arg2 == error_mark_node)
3643 return error_mark_node;
3645 arg1 = ffecom_save_tree (arg1);
3646 arg2 = ffecom_save_tree (arg2);
3648 if (TREE_CODE (TREE_TYPE (arg1)) == COMPLEX_TYPE)
3650 real_type = TREE_TYPE (TREE_TYPE (arg1));
3651 assert (real_type == TREE_TYPE (TREE_TYPE (arg2)));
3655 real_type = TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg1)));
3656 assert (real_type == TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg2))));
3660 = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
3661 ffecom_2 (EQ_EXPR, integer_type_node,
3662 ffecom_1 (REALPART_EXPR, real_type, arg1),
3663 ffecom_1 (REALPART_EXPR, real_type, arg2)),
3664 ffecom_2 (EQ_EXPR, integer_type_node,
3665 ffecom_1 (IMAGPART_EXPR, real_type, arg1),
3666 ffecom_1 (IMAGPART_EXPR, real_type,
3668 if (code == EQ_EXPR)
3669 item = ffecom_truth_value (item);
3671 item = ffecom_truth_value_invert (item);
3672 return convert (tree_type, item);
3675 case FFEINFO_basictypeCHARACTER:
3677 ffebld left = ffebld_left (expr);
3678 ffebld right = ffebld_right (expr);
3684 /* f2c run-time functions do the implicit blank-padding for us,
3685 so we don't usually have to implement blank-padding ourselves.
3686 (The exception is when we pass an argument to a separately
3687 compiled statement function -- if we know the arg is not the
3688 same length as the dummy, we must truncate or extend it. If
3689 we "inline" statement functions, that necessity goes away as
3692 Strip off the CONVERT operators that blank-pad. (Truncation by
3693 CONVERT shouldn't happen here, but it can happen in
3696 while (ffebld_op (left) == FFEBLD_opCONVERT)
3697 left = ffebld_left (left);
3698 while (ffebld_op (right) == FFEBLD_opCONVERT)
3699 right = ffebld_left (right);
3701 left_tree = ffecom_arg_ptr_to_expr (left, &left_length);
3702 right_tree = ffecom_arg_ptr_to_expr (right, &right_length);
3704 if (left_tree == error_mark_node || left_length == error_mark_node
3705 || right_tree == error_mark_node
3706 || right_length == error_mark_node)
3707 return error_mark_node;
3709 if ((ffebld_size_known (left) == 1)
3710 && (ffebld_size_known (right) == 1))
3713 = ffecom_1 (INDIRECT_REF,
3714 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree))),
3717 = ffecom_1 (INDIRECT_REF,
3718 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree))),
3722 = ffecom_2 (code, integer_type_node,
3723 ffecom_2 (ARRAY_REF,
3724 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree))),
3727 ffecom_2 (ARRAY_REF,
3728 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree))),
3734 item = build_tree_list (NULL_TREE, left_tree);
3735 TREE_CHAIN (item) = build_tree_list (NULL_TREE, right_tree);
3736 TREE_CHAIN (TREE_CHAIN (item)) = build_tree_list (NULL_TREE,
3738 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item)))
3739 = build_tree_list (NULL_TREE, right_length);
3740 item = ffecom_call_gfrt (FFECOM_gfrtCMP, item, NULL_TREE);
3741 item = ffecom_2 (code, integer_type_node,
3743 convert (TREE_TYPE (item),
3744 integer_zero_node));
3746 item = convert (tree_type, item);
3752 assert ("relational bad basictype" == NULL);
3754 case FFEINFO_basictypeANY:
3755 return error_mark_node;
3759 case FFEBLD_opPERCENT_LOC:
3760 item = ffecom_arg_ptr_to_expr (ffebld_left (expr), &list);
3761 return convert (tree_type, item);
3763 case FFEBLD_opPERCENT_VAL:
3764 item = ffecom_arg_expr (ffebld_left (expr), &list);
3765 return convert (tree_type, item);
3769 case FFEBLD_opBOUNDS:
3770 case FFEBLD_opREPEAT:
3771 case FFEBLD_opLABTER:
3772 case FFEBLD_opLABTOK:
3773 case FFEBLD_opIMPDO:
3774 case FFEBLD_opCONCATENATE:
3775 case FFEBLD_opSUBSTR:
3777 assert ("bad op" == NULL);
3780 return error_mark_node;
3784 assert ("didn't think anything got here anymore!!" == NULL);
3786 switch (ffebld_arity (expr))
3789 TREE_OPERAND (item, 0) = ffecom_expr (ffebld_left (expr));
3790 TREE_OPERAND (item, 1) = ffecom_expr (ffebld_right (expr));
3791 if (TREE_OPERAND (item, 0) == error_mark_node
3792 || TREE_OPERAND (item, 1) == error_mark_node)
3793 return error_mark_node;
3797 TREE_OPERAND (item, 0) = ffecom_expr (ffebld_left (expr));
3798 if (TREE_OPERAND (item, 0) == error_mark_node)
3799 return error_mark_node;
3810 /* Returns the tree that does the intrinsic invocation.
3812 Note: this function applies only to intrinsics returning
3813 CHARACTER*1 or non-CHARACTER results, and to intrinsic
3817 ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree,
3818 ffebld dest, bool *dest_used)
3821 tree saved_expr1; /* For those who need it. */
3822 tree saved_expr2; /* For those who need it. */
3823 ffeinfoBasictype bt;
3827 tree real_type; /* REAL type corresponding to COMPLEX. */
3829 ffebld list = ffebld_right (expr); /* List of (some) args. */
3830 ffebld arg1; /* For handy reference. */
3833 ffeintrinImp codegen_imp;
3836 assert (ffebld_op (ffebld_left (expr)) == FFEBLD_opSYMTER);
3838 if (dest_used != NULL)
3841 bt = ffeinfo_basictype (ffebld_info (expr));
3842 kt = ffeinfo_kindtype (ffebld_info (expr));
3843 tree_type = ffecom_tree_type[bt][kt];
3847 arg1 = ffebld_head (list);
3848 if (arg1 != NULL && ffebld_op (arg1) == FFEBLD_opANY)
3849 return error_mark_node;
3850 if ((list = ffebld_trail (list)) != NULL)
3852 arg2 = ffebld_head (list);
3853 if (arg2 != NULL && ffebld_op (arg2) == FFEBLD_opANY)
3854 return error_mark_node;
3855 if ((list = ffebld_trail (list)) != NULL)
3857 arg3 = ffebld_head (list);
3858 if (arg3 != NULL && ffebld_op (arg3) == FFEBLD_opANY)
3859 return error_mark_node;
3868 arg1 = arg2 = arg3 = NULL;
3870 /* <list> ends up at the opITEM of the 3rd arg, or NULL if there are < 3
3871 args. This is used by the MAX/MIN expansions. */
3874 arg1_type = ffecom_tree_type
3875 [ffeinfo_basictype (ffebld_info (arg1))]
3876 [ffeinfo_kindtype (ffebld_info (arg1))];
3878 arg1_type = NULL_TREE; /* Really not needed, but might catch bugs
3881 /* There are several ways for each of the cases in the following switch
3882 statements to exit (from simplest to use to most complicated):
3884 break; (when expr_tree == NULL)
3886 A standard call is made to the specific intrinsic just as if it had been
3887 passed in as a dummy procedure and called as any old procedure. This
3888 method can produce slower code but in some cases it's the easiest way for
3889 now. However, if a (presumably faster) direct call is available,
3890 that is used, so this is the easiest way in many more cases now.
3892 gfrt = FFECOM_gfrtWHATEVER;
3895 gfrt contains the gfrt index of a library function to call, passing the
3896 argument(s) by value rather than by reference. Used when a more
3897 careful choice of library function is needed than that provided
3898 by the vanilla `break;'.
3902 The expr_tree has been completely set up and is ready to be returned
3903 as is. No further actions are taken. Use this when the tree is not
3904 in the simple form for one of the arity_n labels. */
3906 /* For info on how the switch statement cases were written, see the files
3907 enclosed in comments below the switch statement. */
3909 codegen_imp = ffebld_symter_implementation (ffebld_left (expr));
3910 gfrt = ffeintrin_gfrt_direct (codegen_imp);
3911 if (gfrt == FFECOM_gfrt)
3912 gfrt = ffeintrin_gfrt_indirect (codegen_imp);
3914 switch (codegen_imp)
3916 case FFEINTRIN_impABS:
3917 case FFEINTRIN_impCABS:
3918 case FFEINTRIN_impCDABS:
3919 case FFEINTRIN_impDABS:
3920 case FFEINTRIN_impIABS:
3921 if (ffeinfo_basictype (ffebld_info (arg1))
3922 == FFEINFO_basictypeCOMPLEX)
3924 if (kt == FFEINFO_kindtypeREAL1)
3925 gfrt = FFECOM_gfrtCABS;
3926 else if (kt == FFEINFO_kindtypeREAL2)
3927 gfrt = FFECOM_gfrtCDABS;
3930 return ffecom_1 (ABS_EXPR, tree_type,
3931 convert (tree_type, ffecom_expr (arg1)));
3933 case FFEINTRIN_impACOS:
3934 case FFEINTRIN_impDACOS:
3937 case FFEINTRIN_impAIMAG:
3938 case FFEINTRIN_impDIMAG:
3939 case FFEINTRIN_impIMAGPART:
3940 if (TREE_CODE (arg1_type) == COMPLEX_TYPE)
3941 arg1_type = TREE_TYPE (arg1_type);
3943 arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type));
3947 ffecom_1 (IMAGPART_EXPR, arg1_type,
3948 ffecom_expr (arg1)));
3950 case FFEINTRIN_impAINT:
3951 case FFEINTRIN_impDINT:
3953 /* ~~Someday implement FIX_TRUNC_EXPR yielding same type as arg. */
3954 return ffecom_1 (FIX_TRUNC_EXPR, tree_type, ffecom_expr (arg1));
3955 #else /* in the meantime, must use floor to avoid range problems with ints */
3956 /* r__1 = r1 >= 0 ? floor(r1) : -floor(-r1); */
3957 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
3960 ffecom_3 (COND_EXPR, double_type_node,
3962 (ffecom_2 (GE_EXPR, integer_type_node,
3965 ffecom_float_zero_))),
3966 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
3967 build_tree_list (NULL_TREE,
3968 convert (double_type_node,
3971 ffecom_1 (NEGATE_EXPR, double_type_node,
3972 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
3973 build_tree_list (NULL_TREE,
3974 convert (double_type_node,
3975 ffecom_1 (NEGATE_EXPR,
3983 case FFEINTRIN_impANINT:
3984 case FFEINTRIN_impDNINT:
3985 #if 0 /* This way of doing it won't handle real
3986 numbers of large magnitudes. */
3987 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
3988 expr_tree = convert (tree_type,
3989 convert (integer_type_node,
3990 ffecom_3 (COND_EXPR, tree_type,
3995 ffecom_float_zero_)),
3996 ffecom_2 (PLUS_EXPR,
3999 ffecom_float_half_),
4000 ffecom_2 (MINUS_EXPR,
4003 ffecom_float_half_))));
4005 #else /* So we instead call floor. */
4006 /* r__1 = r1 >= 0 ? floor(r1 + .5) : -floor(.5 - r1) */
4007 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
4010 ffecom_3 (COND_EXPR, double_type_node,
4012 (ffecom_2 (GE_EXPR, integer_type_node,
4015 ffecom_float_zero_))),
4016 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
4017 build_tree_list (NULL_TREE,
4018 convert (double_type_node,
4019 ffecom_2 (PLUS_EXPR,
4023 ffecom_float_half_)))),
4025 ffecom_1 (NEGATE_EXPR, double_type_node,
4026 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
4027 build_tree_list (NULL_TREE,
4028 convert (double_type_node,
4029 ffecom_2 (MINUS_EXPR,
4032 ffecom_float_half_),
4039 case FFEINTRIN_impASIN:
4040 case FFEINTRIN_impDASIN:
4041 case FFEINTRIN_impATAN:
4042 case FFEINTRIN_impDATAN:
4043 case FFEINTRIN_impATAN2:
4044 case FFEINTRIN_impDATAN2:
4047 case FFEINTRIN_impCHAR:
4048 case FFEINTRIN_impACHAR:
4050 tempvar = ffecom_make_tempvar (char_type_node, 1, -1);
4052 tempvar = ffebld_nonter_hook (expr);
4056 tree tmv = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (tempvar)));
4058 expr_tree = ffecom_modify (tmv,
4059 ffecom_2 (ARRAY_REF, tmv, tempvar,
4061 convert (tmv, ffecom_expr (arg1)));
4063 expr_tree = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar),
4066 expr_tree = ffecom_1 (ADDR_EXPR,
4067 build_pointer_type (TREE_TYPE (expr_tree)),
4071 case FFEINTRIN_impCMPLX:
4072 case FFEINTRIN_impDCMPLX:
4075 convert (tree_type, ffecom_expr (arg1));
4077 real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
4079 ffecom_2 (COMPLEX_EXPR, tree_type,
4080 convert (real_type, ffecom_expr (arg1)),
4082 ffecom_expr (arg2)));
4084 case FFEINTRIN_impCOMPLEX:
4086 ffecom_2 (COMPLEX_EXPR, tree_type,
4088 ffecom_expr (arg2));
4090 case FFEINTRIN_impCONJG:
4091 case FFEINTRIN_impDCONJG:
4095 real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
4096 arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4098 ffecom_2 (COMPLEX_EXPR, tree_type,
4099 ffecom_1 (REALPART_EXPR, real_type, arg1_tree),
4100 ffecom_1 (NEGATE_EXPR, real_type,
4101 ffecom_1 (IMAGPART_EXPR, real_type, arg1_tree)));
4104 case FFEINTRIN_impCOS:
4105 case FFEINTRIN_impCCOS:
4106 case FFEINTRIN_impCDCOS:
4107 case FFEINTRIN_impDCOS:
4108 if (bt == FFEINFO_basictypeCOMPLEX)
4110 if (kt == FFEINFO_kindtypeREAL1)
4111 gfrt = FFECOM_gfrtCCOS; /* Overlapping result okay. */
4112 else if (kt == FFEINFO_kindtypeREAL2)
4113 gfrt = FFECOM_gfrtCDCOS; /* Overlapping result okay. */
4117 case FFEINTRIN_impCOSH:
4118 case FFEINTRIN_impDCOSH:
4121 case FFEINTRIN_impDBLE:
4122 case FFEINTRIN_impDFLOAT:
4123 case FFEINTRIN_impDREAL:
4124 case FFEINTRIN_impFLOAT:
4125 case FFEINTRIN_impIDINT:
4126 case FFEINTRIN_impIFIX:
4127 case FFEINTRIN_impINT2:
4128 case FFEINTRIN_impINT8:
4129 case FFEINTRIN_impINT:
4130 case FFEINTRIN_impLONG:
4131 case FFEINTRIN_impREAL:
4132 case FFEINTRIN_impSHORT:
4133 case FFEINTRIN_impSNGL:
4134 return convert (tree_type, ffecom_expr (arg1));
4136 case FFEINTRIN_impDIM:
4137 case FFEINTRIN_impDDIM:
4138 case FFEINTRIN_impIDIM:
4139 saved_expr1 = ffecom_save_tree (convert (tree_type,
4140 ffecom_expr (arg1)));
4141 saved_expr2 = ffecom_save_tree (convert (tree_type,
4142 ffecom_expr (arg2)));
4144 ffecom_3 (COND_EXPR, tree_type,
4146 (ffecom_2 (GT_EXPR, integer_type_node,
4149 ffecom_2 (MINUS_EXPR, tree_type,
4152 convert (tree_type, ffecom_float_zero_));
4154 case FFEINTRIN_impDPROD:
4156 ffecom_2 (MULT_EXPR, tree_type,
4157 convert (tree_type, ffecom_expr (arg1)),
4158 convert (tree_type, ffecom_expr (arg2)));
4160 case FFEINTRIN_impEXP:
4161 case FFEINTRIN_impCDEXP:
4162 case FFEINTRIN_impCEXP:
4163 case FFEINTRIN_impDEXP:
4164 if (bt == FFEINFO_basictypeCOMPLEX)
4166 if (kt == FFEINFO_kindtypeREAL1)
4167 gfrt = FFECOM_gfrtCEXP; /* Overlapping result okay. */
4168 else if (kt == FFEINFO_kindtypeREAL2)
4169 gfrt = FFECOM_gfrtCDEXP; /* Overlapping result okay. */
4173 case FFEINTRIN_impICHAR:
4174 case FFEINTRIN_impIACHAR:
4175 #if 0 /* The simple approach. */
4176 ffecom_char_args_ (&expr_tree, &saved_expr1 /* Ignored */ , arg1);
4178 = ffecom_1 (INDIRECT_REF,
4179 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
4182 = ffecom_2 (ARRAY_REF,
4183 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
4186 return convert (tree_type, expr_tree);
4187 #else /* The more interesting (and more optimal) approach. */
4188 expr_tree = ffecom_intrinsic_ichar_ (tree_type, arg1, &saved_expr1);
4189 expr_tree = ffecom_3 (COND_EXPR, tree_type,
4192 convert (tree_type, integer_zero_node));
4196 case FFEINTRIN_impINDEX:
4199 case FFEINTRIN_impLEN:
4201 break; /* The simple approach. */
4203 return ffecom_intrinsic_len_ (arg1); /* The more optimal approach. */
4206 case FFEINTRIN_impLGE:
4207 case FFEINTRIN_impLGT:
4208 case FFEINTRIN_impLLE:
4209 case FFEINTRIN_impLLT:
4212 case FFEINTRIN_impLOG:
4213 case FFEINTRIN_impALOG:
4214 case FFEINTRIN_impCDLOG:
4215 case FFEINTRIN_impCLOG:
4216 case FFEINTRIN_impDLOG:
4217 if (bt == FFEINFO_basictypeCOMPLEX)
4219 if (kt == FFEINFO_kindtypeREAL1)
4220 gfrt = FFECOM_gfrtCLOG; /* Overlapping result okay. */
4221 else if (kt == FFEINFO_kindtypeREAL2)
4222 gfrt = FFECOM_gfrtCDLOG; /* Overlapping result okay. */
4226 case FFEINTRIN_impLOG10:
4227 case FFEINTRIN_impALOG10:
4228 case FFEINTRIN_impDLOG10:
4229 if (gfrt != FFECOM_gfrt)
4230 break; /* Already picked one, stick with it. */
4232 if (kt == FFEINFO_kindtypeREAL1)
4233 /* We used to call FFECOM_gfrtALOG10 here. */
4234 gfrt = FFECOM_gfrtL_LOG10;
4235 else if (kt == FFEINFO_kindtypeREAL2)
4236 /* We used to call FFECOM_gfrtDLOG10 here. */
4237 gfrt = FFECOM_gfrtL_LOG10;
4240 case FFEINTRIN_impMAX:
4241 case FFEINTRIN_impAMAX0:
4242 case FFEINTRIN_impAMAX1:
4243 case FFEINTRIN_impDMAX1:
4244 case FFEINTRIN_impMAX0:
4245 case FFEINTRIN_impMAX1:
4246 if (bt != ffeinfo_basictype (ffebld_info (arg1)))
4247 arg1_type = ffecom_widest_expr_type_ (ffebld_right (expr));
4249 arg1_type = tree_type;
4250 expr_tree = ffecom_2 (MAX_EXPR, arg1_type,
4251 convert (arg1_type, ffecom_expr (arg1)),
4252 convert (arg1_type, ffecom_expr (arg2)));
4253 for (; list != NULL; list = ffebld_trail (list))
4255 if ((ffebld_head (list) == NULL)
4256 || (ffebld_op (ffebld_head (list)) == FFEBLD_opANY))
4258 expr_tree = ffecom_2 (MAX_EXPR, arg1_type,
4261 ffecom_expr (ffebld_head (list))));
4263 return convert (tree_type, expr_tree);
4265 case FFEINTRIN_impMIN:
4266 case FFEINTRIN_impAMIN0:
4267 case FFEINTRIN_impAMIN1:
4268 case FFEINTRIN_impDMIN1:
4269 case FFEINTRIN_impMIN0:
4270 case FFEINTRIN_impMIN1:
4271 if (bt != ffeinfo_basictype (ffebld_info (arg1)))
4272 arg1_type = ffecom_widest_expr_type_ (ffebld_right (expr));
4274 arg1_type = tree_type;
4275 expr_tree = ffecom_2 (MIN_EXPR, arg1_type,
4276 convert (arg1_type, ffecom_expr (arg1)),
4277 convert (arg1_type, ffecom_expr (arg2)));
4278 for (; list != NULL; list = ffebld_trail (list))
4280 if ((ffebld_head (list) == NULL)
4281 || (ffebld_op (ffebld_head (list)) == FFEBLD_opANY))
4283 expr_tree = ffecom_2 (MIN_EXPR, arg1_type,
4286 ffecom_expr (ffebld_head (list))));
4288 return convert (tree_type, expr_tree);
4290 case FFEINTRIN_impMOD:
4291 case FFEINTRIN_impAMOD:
4292 case FFEINTRIN_impDMOD:
4293 if (bt != FFEINFO_basictypeREAL)
4294 return ffecom_2 (TRUNC_MOD_EXPR, tree_type,
4295 convert (tree_type, ffecom_expr (arg1)),
4296 convert (tree_type, ffecom_expr (arg2)));
4298 if (kt == FFEINFO_kindtypeREAL1)
4299 /* We used to call FFECOM_gfrtAMOD here. */
4300 gfrt = FFECOM_gfrtL_FMOD;
4301 else if (kt == FFEINFO_kindtypeREAL2)
4302 /* We used to call FFECOM_gfrtDMOD here. */
4303 gfrt = FFECOM_gfrtL_FMOD;
4306 case FFEINTRIN_impNINT:
4307 case FFEINTRIN_impIDNINT:
4309 /* ~~Ideally FIX_ROUND_EXPR would be implemented, but it ain't yet. */
4310 return ffecom_1 (FIX_ROUND_EXPR, tree_type, ffecom_expr (arg1));
4312 /* i__1 = r1 >= 0 ? floor(r1 + .5) : -floor(.5 - r1); */
4313 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
4315 convert (ffecom_integer_type_node,
4316 ffecom_3 (COND_EXPR, arg1_type,
4318 (ffecom_2 (GE_EXPR, integer_type_node,
4321 ffecom_float_zero_))),
4322 ffecom_2 (PLUS_EXPR, arg1_type,
4325 ffecom_float_half_)),
4326 ffecom_2 (MINUS_EXPR, arg1_type,
4329 ffecom_float_half_))));
4332 case FFEINTRIN_impSIGN:
4333 case FFEINTRIN_impDSIGN:
4334 case FFEINTRIN_impISIGN:
4336 tree arg2_tree = ffecom_expr (arg2);
4340 (ffecom_1 (ABS_EXPR, tree_type,
4342 ffecom_expr (arg1))));
4344 = ffecom_3 (COND_EXPR, tree_type,
4346 (ffecom_2 (GE_EXPR, integer_type_node,
4348 convert (TREE_TYPE (arg2_tree),
4349 integer_zero_node))),
4351 ffecom_1 (NEGATE_EXPR, tree_type, saved_expr1));
4352 /* Make sure SAVE_EXPRs get referenced early enough. */
4354 = ffecom_2 (COMPOUND_EXPR, tree_type,
4355 convert (void_type_node, saved_expr1),
4360 case FFEINTRIN_impSIN:
4361 case FFEINTRIN_impCDSIN:
4362 case FFEINTRIN_impCSIN:
4363 case FFEINTRIN_impDSIN:
4364 if (bt == FFEINFO_basictypeCOMPLEX)
4366 if (kt == FFEINFO_kindtypeREAL1)
4367 gfrt = FFECOM_gfrtCSIN; /* Overlapping result okay. */
4368 else if (kt == FFEINFO_kindtypeREAL2)
4369 gfrt = FFECOM_gfrtCDSIN; /* Overlapping result okay. */
4373 case FFEINTRIN_impSINH:
4374 case FFEINTRIN_impDSINH:
4377 case FFEINTRIN_impSQRT:
4378 case FFEINTRIN_impCDSQRT:
4379 case FFEINTRIN_impCSQRT:
4380 case FFEINTRIN_impDSQRT:
4381 if (bt == FFEINFO_basictypeCOMPLEX)
4383 if (kt == FFEINFO_kindtypeREAL1)
4384 gfrt = FFECOM_gfrtCSQRT; /* Overlapping result okay. */
4385 else if (kt == FFEINFO_kindtypeREAL2)
4386 gfrt = FFECOM_gfrtCDSQRT; /* Overlapping result okay. */
4390 case FFEINTRIN_impTAN:
4391 case FFEINTRIN_impDTAN:
4392 case FFEINTRIN_impTANH:
4393 case FFEINTRIN_impDTANH:
4396 case FFEINTRIN_impREALPART:
4397 if (TREE_CODE (arg1_type) == COMPLEX_TYPE)
4398 arg1_type = TREE_TYPE (arg1_type);
4400 arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type));
4404 ffecom_1 (REALPART_EXPR, arg1_type,
4405 ffecom_expr (arg1)));
4407 case FFEINTRIN_impIAND:
4408 case FFEINTRIN_impAND:
4409 return ffecom_2 (BIT_AND_EXPR, tree_type,
4411 ffecom_expr (arg1)),
4413 ffecom_expr (arg2)));
4415 case FFEINTRIN_impIOR:
4416 case FFEINTRIN_impOR:
4417 return ffecom_2 (BIT_IOR_EXPR, tree_type,
4419 ffecom_expr (arg1)),
4421 ffecom_expr (arg2)));
4423 case FFEINTRIN_impIEOR:
4424 case FFEINTRIN_impXOR:
4425 return ffecom_2 (BIT_XOR_EXPR, tree_type,
4427 ffecom_expr (arg1)),
4429 ffecom_expr (arg2)));
4431 case FFEINTRIN_impLSHIFT:
4432 return ffecom_2 (LSHIFT_EXPR, tree_type,
4434 convert (integer_type_node,
4435 ffecom_expr (arg2)));
4437 case FFEINTRIN_impRSHIFT:
4438 return ffecom_2 (RSHIFT_EXPR, tree_type,
4440 convert (integer_type_node,
4441 ffecom_expr (arg2)));
4443 case FFEINTRIN_impNOT:
4444 return ffecom_1 (BIT_NOT_EXPR, tree_type, ffecom_expr (arg1));
4446 case FFEINTRIN_impBIT_SIZE:
4447 return convert (tree_type, TYPE_SIZE (arg1_type));
4449 case FFEINTRIN_impBTEST:
4451 ffetargetLogical1 target_true;
4452 ffetargetLogical1 target_false;
4456 ffetarget_logical1 (&target_true, TRUE);
4457 ffetarget_logical1 (&target_false, FALSE);
4458 if (target_true == 1)
4459 true_tree = convert (tree_type, integer_one_node);
4461 true_tree = convert (tree_type, build_int_2 (target_true, 0));
4462 if (target_false == 0)
4463 false_tree = convert (tree_type, integer_zero_node);
4465 false_tree = convert (tree_type, build_int_2 (target_false, 0));
4468 ffecom_3 (COND_EXPR, tree_type,
4470 (ffecom_2 (EQ_EXPR, integer_type_node,
4471 ffecom_2 (BIT_AND_EXPR, arg1_type,
4473 ffecom_2 (LSHIFT_EXPR, arg1_type,
4476 convert (integer_type_node,
4477 ffecom_expr (arg2)))),
4479 integer_zero_node))),
4484 case FFEINTRIN_impIBCLR:
4486 ffecom_2 (BIT_AND_EXPR, tree_type,
4488 ffecom_1 (BIT_NOT_EXPR, tree_type,
4489 ffecom_2 (LSHIFT_EXPR, tree_type,
4492 convert (integer_type_node,
4493 ffecom_expr (arg2)))));
4495 case FFEINTRIN_impIBITS:
4497 tree arg3_tree = ffecom_save_tree (convert (integer_type_node,
4498 ffecom_expr (arg3)));
4500 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4503 = ffecom_2 (BIT_AND_EXPR, tree_type,
4504 ffecom_2 (RSHIFT_EXPR, tree_type,
4506 convert (integer_type_node,
4507 ffecom_expr (arg2))),
4509 ffecom_2 (RSHIFT_EXPR, uns_type,
4510 ffecom_1 (BIT_NOT_EXPR,
4513 integer_zero_node)),
4514 ffecom_2 (MINUS_EXPR,
4516 TYPE_SIZE (uns_type),
4518 /* Fix up, because the RSHIFT_EXPR above can't shift over TYPE_SIZE. */
4520 = ffecom_3 (COND_EXPR, tree_type,
4522 (ffecom_2 (NE_EXPR, integer_type_node,
4524 integer_zero_node)),
4526 convert (tree_type, integer_zero_node));
4530 case FFEINTRIN_impIBSET:
4532 ffecom_2 (BIT_IOR_EXPR, tree_type,
4534 ffecom_2 (LSHIFT_EXPR, tree_type,
4535 convert (tree_type, integer_one_node),
4536 convert (integer_type_node,
4537 ffecom_expr (arg2))));
4539 case FFEINTRIN_impISHFT:
4541 tree arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4542 tree arg2_tree = ffecom_save_tree (convert (integer_type_node,
4543 ffecom_expr (arg2)));
4545 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4548 = ffecom_3 (COND_EXPR, tree_type,
4550 (ffecom_2 (GE_EXPR, integer_type_node,
4552 integer_zero_node)),
4553 ffecom_2 (LSHIFT_EXPR, tree_type,
4557 ffecom_2 (RSHIFT_EXPR, uns_type,
4558 convert (uns_type, arg1_tree),
4559 ffecom_1 (NEGATE_EXPR,
4562 /* Fix up, because {L|R}SHIFT_EXPR don't go over TYPE_SIZE bounds. */
4564 = ffecom_3 (COND_EXPR, tree_type,
4566 (ffecom_2 (NE_EXPR, integer_type_node,
4570 TYPE_SIZE (uns_type))),
4572 convert (tree_type, integer_zero_node));
4573 /* Make sure SAVE_EXPRs get referenced early enough. */
4575 = ffecom_2 (COMPOUND_EXPR, tree_type,
4576 convert (void_type_node, arg1_tree),
4577 ffecom_2 (COMPOUND_EXPR, tree_type,
4578 convert (void_type_node, arg2_tree),
4583 case FFEINTRIN_impISHFTC:
4585 tree arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4586 tree arg2_tree = ffecom_save_tree (convert (integer_type_node,
4587 ffecom_expr (arg2)));
4588 tree arg3_tree = (arg3 == NULL) ? TYPE_SIZE (tree_type)
4589 : ffecom_save_tree (convert (integer_type_node, ffecom_expr (arg3)));
4595 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4598 = ffecom_2 (LSHIFT_EXPR, tree_type,
4599 ffecom_1 (BIT_NOT_EXPR, tree_type,
4600 convert (tree_type, integer_zero_node)),
4602 /* Fix up, because LSHIFT_EXPR above can't shift over TYPE_SIZE. */
4604 = ffecom_3 (COND_EXPR, tree_type,
4606 (ffecom_2 (NE_EXPR, integer_type_node,
4608 TYPE_SIZE (uns_type))),
4610 convert (tree_type, integer_zero_node));
4611 mask_arg1 = ffecom_save_tree (mask_arg1);
4613 = ffecom_2 (BIT_AND_EXPR, tree_type,
4615 ffecom_1 (BIT_NOT_EXPR, tree_type,
4617 masked_arg1 = ffecom_save_tree (masked_arg1);
4619 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4621 ffecom_2 (RSHIFT_EXPR, uns_type,
4622 convert (uns_type, masked_arg1),
4623 ffecom_1 (NEGATE_EXPR,
4626 ffecom_2 (LSHIFT_EXPR, tree_type,
4628 ffecom_2 (PLUS_EXPR, integer_type_node,
4632 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4633 ffecom_2 (LSHIFT_EXPR, tree_type,
4637 ffecom_2 (RSHIFT_EXPR, uns_type,
4638 convert (uns_type, masked_arg1),
4639 ffecom_2 (MINUS_EXPR,
4644 = ffecom_3 (COND_EXPR, tree_type,
4646 (ffecom_2 (LT_EXPR, integer_type_node,
4648 integer_zero_node)),
4652 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4653 ffecom_2 (BIT_AND_EXPR, tree_type,
4656 ffecom_2 (BIT_AND_EXPR, tree_type,
4657 ffecom_1 (BIT_NOT_EXPR, tree_type,
4661 = ffecom_3 (COND_EXPR, tree_type,
4663 (ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
4664 ffecom_2 (EQ_EXPR, integer_type_node,
4669 ffecom_2 (EQ_EXPR, integer_type_node,
4671 integer_zero_node))),
4674 /* Make sure SAVE_EXPRs get referenced early enough. */
4676 = ffecom_2 (COMPOUND_EXPR, tree_type,
4677 convert (void_type_node, arg1_tree),
4678 ffecom_2 (COMPOUND_EXPR, tree_type,
4679 convert (void_type_node, arg2_tree),
4680 ffecom_2 (COMPOUND_EXPR, tree_type,
4681 convert (void_type_node,
4683 ffecom_2 (COMPOUND_EXPR, tree_type,
4684 convert (void_type_node,
4688 = ffecom_2 (COMPOUND_EXPR, tree_type,
4689 convert (void_type_node,
4695 case FFEINTRIN_impLOC:
4697 tree arg1_tree = ffecom_expr (arg1);
4700 = convert (tree_type,
4701 ffecom_1 (ADDR_EXPR,
4702 build_pointer_type (TREE_TYPE (arg1_tree)),
4707 case FFEINTRIN_impMVBITS:
4712 ffebld arg4 = ffebld_head (ffebld_trail (list));
4715 ffebld arg5 = ffebld_head (ffebld_trail (ffebld_trail (list)));
4719 tree arg5_plus_arg3;
4721 arg2_tree = convert (integer_type_node,
4722 ffecom_expr (arg2));
4723 arg3_tree = ffecom_save_tree (convert (integer_type_node,
4724 ffecom_expr (arg3)));
4725 arg4_tree = ffecom_expr_rw (NULL_TREE, arg4);
4726 arg4_type = TREE_TYPE (arg4_tree);
4728 arg1_tree = ffecom_save_tree (convert (arg4_type,
4729 ffecom_expr (arg1)));
4731 arg5_tree = ffecom_save_tree (convert (integer_type_node,
4732 ffecom_expr (arg5)));
4735 = ffecom_2 (LSHIFT_EXPR, arg4_type,
4736 ffecom_2 (BIT_AND_EXPR, arg4_type,
4737 ffecom_2 (RSHIFT_EXPR, arg4_type,
4740 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4741 ffecom_2 (LSHIFT_EXPR, arg4_type,
4742 ffecom_1 (BIT_NOT_EXPR,
4746 integer_zero_node)),
4750 = ffecom_save_tree (ffecom_2 (PLUS_EXPR, arg4_type,
4754 = ffecom_2 (LSHIFT_EXPR, arg4_type,
4755 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4757 integer_zero_node)),
4759 /* Fix up, because LSHIFT_EXPR above can't shift over TYPE_SIZE. */
4761 = ffecom_3 (COND_EXPR, arg4_type,
4763 (ffecom_2 (NE_EXPR, integer_type_node,
4765 convert (TREE_TYPE (arg5_plus_arg3),
4766 TYPE_SIZE (arg4_type)))),
4768 convert (arg4_type, integer_zero_node));
4770 = ffecom_2 (BIT_AND_EXPR, arg4_type,
4772 ffecom_2 (BIT_IOR_EXPR, arg4_type,
4774 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4775 ffecom_2 (LSHIFT_EXPR, arg4_type,
4776 ffecom_1 (BIT_NOT_EXPR,
4780 integer_zero_node)),
4783 = ffecom_2 (BIT_IOR_EXPR, arg4_type,
4786 /* Fix up (twice), because LSHIFT_EXPR above
4787 can't shift over TYPE_SIZE. */
4789 = ffecom_3 (COND_EXPR, arg4_type,
4791 (ffecom_2 (NE_EXPR, integer_type_node,
4793 convert (TREE_TYPE (arg3_tree),
4794 integer_zero_node))),
4798 = ffecom_3 (COND_EXPR, arg4_type,
4800 (ffecom_2 (NE_EXPR, integer_type_node,
4802 convert (TREE_TYPE (arg3_tree),
4803 TYPE_SIZE (arg4_type)))),
4807 = ffecom_2s (MODIFY_EXPR, void_type_node,
4810 /* Make sure SAVE_EXPRs get referenced early enough. */
4812 = ffecom_2 (COMPOUND_EXPR, void_type_node,
4814 ffecom_2 (COMPOUND_EXPR, void_type_node,
4816 ffecom_2 (COMPOUND_EXPR, void_type_node,
4818 ffecom_2 (COMPOUND_EXPR, void_type_node,
4822 = ffecom_2 (COMPOUND_EXPR, void_type_node,
4829 case FFEINTRIN_impDERF:
4830 case FFEINTRIN_impERF:
4831 case FFEINTRIN_impDERFC:
4832 case FFEINTRIN_impERFC:
4835 case FFEINTRIN_impIARGC:
4836 /* extern int xargc; i__1 = xargc - 1; */
4837 expr_tree = ffecom_2 (MINUS_EXPR, TREE_TYPE (ffecom_tree_xargc_),
4839 convert (TREE_TYPE (ffecom_tree_xargc_),
4843 case FFEINTRIN_impSIGNAL_func:
4844 case FFEINTRIN_impSIGNAL_subr:
4850 arg1_tree = convert (ffecom_f2c_integer_type_node,
4851 ffecom_expr (arg1));
4852 arg1_tree = ffecom_1 (ADDR_EXPR,
4853 build_pointer_type (TREE_TYPE (arg1_tree)),
4856 /* Pass procedure as a pointer to it, anything else by value. */
4857 if (ffeinfo_kind (ffebld_info (arg2)) == FFEINFO_kindENTITY)
4858 arg2_tree = convert (integer_type_node, ffecom_expr (arg2));
4860 arg2_tree = ffecom_ptr_to_expr (arg2);
4861 arg2_tree = convert (TREE_TYPE (null_pointer_node),
4865 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
4867 arg3_tree = NULL_TREE;
4869 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4870 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
4871 TREE_CHAIN (arg1_tree) = arg2_tree;
4874 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4875 ffecom_gfrt_kindtype (gfrt),
4877 ((codegen_imp == FFEINTRIN_impSIGNAL_subr) ?
4881 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4882 ffebld_nonter_hook (expr));
4884 if (arg3_tree != NULL_TREE)
4886 = ffecom_modify (NULL_TREE, arg3_tree,
4887 convert (TREE_TYPE (arg3_tree),
4892 case FFEINTRIN_impALARM:
4898 arg1_tree = convert (ffecom_f2c_integer_type_node,
4899 ffecom_expr (arg1));
4900 arg1_tree = ffecom_1 (ADDR_EXPR,
4901 build_pointer_type (TREE_TYPE (arg1_tree)),
4904 /* Pass procedure as a pointer to it, anything else by value. */
4905 if (ffeinfo_kind (ffebld_info (arg2)) == FFEINFO_kindENTITY)
4906 arg2_tree = convert (integer_type_node, ffecom_expr (arg2));
4908 arg2_tree = ffecom_ptr_to_expr (arg2);
4909 arg2_tree = convert (TREE_TYPE (null_pointer_node),
4913 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
4915 arg3_tree = NULL_TREE;
4917 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4918 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
4919 TREE_CHAIN (arg1_tree) = arg2_tree;
4922 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4923 ffecom_gfrt_kindtype (gfrt),
4927 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4928 ffebld_nonter_hook (expr));
4930 if (arg3_tree != NULL_TREE)
4932 = ffecom_modify (NULL_TREE, arg3_tree,
4933 convert (TREE_TYPE (arg3_tree),
4938 case FFEINTRIN_impCHDIR_subr:
4939 case FFEINTRIN_impFDATE_subr:
4940 case FFEINTRIN_impFGET_subr:
4941 case FFEINTRIN_impFPUT_subr:
4942 case FFEINTRIN_impGETCWD_subr:
4943 case FFEINTRIN_impHOSTNM_subr:
4944 case FFEINTRIN_impSYSTEM_subr:
4945 case FFEINTRIN_impUNLINK_subr:
4947 tree arg1_len = integer_zero_node;
4951 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
4954 arg2_tree = ffecom_expr_w (NULL_TREE, arg2);
4956 arg2_tree = NULL_TREE;
4958 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4959 arg1_len = build_tree_list (NULL_TREE, arg1_len);
4960 TREE_CHAIN (arg1_tree) = arg1_len;
4963 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4964 ffecom_gfrt_kindtype (gfrt),
4968 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4969 ffebld_nonter_hook (expr));
4971 if (arg2_tree != NULL_TREE)
4973 = ffecom_modify (NULL_TREE, arg2_tree,
4974 convert (TREE_TYPE (arg2_tree),
4979 case FFEINTRIN_impEXIT:
4983 expr_tree = build_tree_list (NULL_TREE,
4984 ffecom_1 (ADDR_EXPR,
4986 (ffecom_integer_type_node),
4987 integer_zero_node));
4990 ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4991 ffecom_gfrt_kindtype (gfrt),
4995 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4996 ffebld_nonter_hook (expr));
4998 case FFEINTRIN_impFLUSH:
5000 gfrt = FFECOM_gfrtFLUSH;
5002 gfrt = FFECOM_gfrtFLUSH1;
5005 case FFEINTRIN_impCHMOD_subr:
5006 case FFEINTRIN_impLINK_subr:
5007 case FFEINTRIN_impRENAME_subr:
5008 case FFEINTRIN_impSYMLNK_subr:
5010 tree arg1_len = integer_zero_node;
5012 tree arg2_len = integer_zero_node;
5016 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
5017 arg2_tree = ffecom_arg_ptr_to_expr (arg2, &arg2_len);
5019 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5021 arg3_tree = NULL_TREE;
5023 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5024 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5025 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5026 arg2_len = build_tree_list (NULL_TREE, arg2_len);
5027 TREE_CHAIN (arg1_tree) = arg2_tree;
5028 TREE_CHAIN (arg2_tree) = arg1_len;
5029 TREE_CHAIN (arg1_len) = arg2_len;
5030 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5031 ffecom_gfrt_kindtype (gfrt),
5035 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5036 ffebld_nonter_hook (expr));
5037 if (arg3_tree != NULL_TREE)
5038 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5039 convert (TREE_TYPE (arg3_tree),
5044 case FFEINTRIN_impLSTAT_subr:
5045 case FFEINTRIN_impSTAT_subr:
5047 tree arg1_len = integer_zero_node;
5052 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
5054 arg2_tree = ffecom_ptr_to_expr (arg2);
5057 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5059 arg3_tree = NULL_TREE;
5061 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5062 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5063 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5064 TREE_CHAIN (arg1_tree) = arg2_tree;
5065 TREE_CHAIN (arg2_tree) = arg1_len;
5066 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5067 ffecom_gfrt_kindtype (gfrt),
5071 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5072 ffebld_nonter_hook (expr));
5073 if (arg3_tree != NULL_TREE)
5074 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5075 convert (TREE_TYPE (arg3_tree),
5080 case FFEINTRIN_impFGETC_subr:
5081 case FFEINTRIN_impFPUTC_subr:
5085 tree arg2_len = integer_zero_node;
5088 arg1_tree = convert (ffecom_f2c_integer_type_node,
5089 ffecom_expr (arg1));
5090 arg1_tree = ffecom_1 (ADDR_EXPR,
5091 build_pointer_type (TREE_TYPE (arg1_tree)),
5094 arg2_tree = ffecom_arg_ptr_to_expr (arg2, &arg2_len);
5096 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5098 arg3_tree = NULL_TREE;
5100 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5101 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5102 arg2_len = build_tree_list (NULL_TREE, arg2_len);
5103 TREE_CHAIN (arg1_tree) = arg2_tree;
5104 TREE_CHAIN (arg2_tree) = arg2_len;
5106 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5107 ffecom_gfrt_kindtype (gfrt),
5111 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5112 ffebld_nonter_hook (expr));
5113 if (arg3_tree != NULL_TREE)
5114 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5115 convert (TREE_TYPE (arg3_tree),
5120 case FFEINTRIN_impFSTAT_subr:
5126 arg1_tree = convert (ffecom_f2c_integer_type_node,
5127 ffecom_expr (arg1));
5128 arg1_tree = ffecom_1 (ADDR_EXPR,
5129 build_pointer_type (TREE_TYPE (arg1_tree)),
5132 arg2_tree = convert (ffecom_f2c_ptr_to_integer_type_node,
5133 ffecom_ptr_to_expr (arg2));
5136 arg3_tree = NULL_TREE;
5138 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5140 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5141 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5142 TREE_CHAIN (arg1_tree) = arg2_tree;
5143 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5144 ffecom_gfrt_kindtype (gfrt),
5148 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5149 ffebld_nonter_hook (expr));
5150 if (arg3_tree != NULL_TREE) {
5151 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5152 convert (TREE_TYPE (arg3_tree),
5158 case FFEINTRIN_impKILL_subr:
5164 arg1_tree = convert (ffecom_f2c_integer_type_node,
5165 ffecom_expr (arg1));
5166 arg1_tree = ffecom_1 (ADDR_EXPR,
5167 build_pointer_type (TREE_TYPE (arg1_tree)),
5170 arg2_tree = convert (ffecom_f2c_integer_type_node,
5171 ffecom_expr (arg2));
5172 arg2_tree = ffecom_1 (ADDR_EXPR,
5173 build_pointer_type (TREE_TYPE (arg2_tree)),
5177 arg3_tree = NULL_TREE;
5179 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5181 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5182 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5183 TREE_CHAIN (arg1_tree) = arg2_tree;
5184 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5185 ffecom_gfrt_kindtype (gfrt),
5189 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5190 ffebld_nonter_hook (expr));
5191 if (arg3_tree != NULL_TREE) {
5192 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5193 convert (TREE_TYPE (arg3_tree),
5199 case FFEINTRIN_impCTIME_subr:
5200 case FFEINTRIN_impTTYNAM_subr:
5202 tree arg1_len = integer_zero_node;
5206 arg1_tree = ffecom_arg_ptr_to_expr (arg2, &arg1_len);
5208 arg2_tree = convert (((codegen_imp == FFEINTRIN_impCTIME_subr) ?
5209 ffecom_f2c_longint_type_node :
5210 ffecom_f2c_integer_type_node),
5211 ffecom_expr (arg1));
5212 arg2_tree = ffecom_1 (ADDR_EXPR,
5213 build_pointer_type (TREE_TYPE (arg2_tree)),
5216 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5217 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5218 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5219 TREE_CHAIN (arg1_len) = arg2_tree;
5220 TREE_CHAIN (arg1_tree) = arg1_len;
5223 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5224 ffecom_gfrt_kindtype (gfrt),
5228 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5229 ffebld_nonter_hook (expr));
5230 TREE_SIDE_EFFECTS (expr_tree) = 1;
5234 case FFEINTRIN_impIRAND:
5235 case FFEINTRIN_impRAND:
5236 /* Arg defaults to 0 (normal random case) */
5241 arg1_tree = ffecom_integer_zero_node;
5243 arg1_tree = ffecom_expr (arg1);
5244 arg1_tree = convert (ffecom_f2c_integer_type_node,
5246 arg1_tree = ffecom_1 (ADDR_EXPR,
5247 build_pointer_type (TREE_TYPE (arg1_tree)),
5249 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5251 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5252 ffecom_gfrt_kindtype (gfrt),
5254 ((codegen_imp == FFEINTRIN_impIRAND) ?
5255 ffecom_f2c_integer_type_node :
5256 ffecom_f2c_real_type_node),
5258 dest_tree, dest, dest_used,
5260 ffebld_nonter_hook (expr));
5264 case FFEINTRIN_impFTELL_subr:
5265 case FFEINTRIN_impUMASK_subr:
5270 arg1_tree = convert (ffecom_f2c_integer_type_node,
5271 ffecom_expr (arg1));
5272 arg1_tree = ffecom_1 (ADDR_EXPR,
5273 build_pointer_type (TREE_TYPE (arg1_tree)),
5277 arg2_tree = NULL_TREE;
5279 arg2_tree = ffecom_expr_w (NULL_TREE, arg2);
5281 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5282 ffecom_gfrt_kindtype (gfrt),
5285 build_tree_list (NULL_TREE, arg1_tree),
5286 NULL_TREE, NULL, NULL, NULL_TREE,
5288 ffebld_nonter_hook (expr));
5289 if (arg2_tree != NULL_TREE) {
5290 expr_tree = ffecom_modify (NULL_TREE, arg2_tree,
5291 convert (TREE_TYPE (arg2_tree),
5297 case FFEINTRIN_impCPU_TIME:
5298 case FFEINTRIN_impSECOND_subr:
5302 arg1_tree = ffecom_expr_w (NULL_TREE, arg1);
5305 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5306 ffecom_gfrt_kindtype (gfrt),
5310 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5311 ffebld_nonter_hook (expr));
5314 = ffecom_modify (NULL_TREE, arg1_tree,
5315 convert (TREE_TYPE (arg1_tree),
5320 case FFEINTRIN_impDTIME_subr:
5321 case FFEINTRIN_impETIME_subr:
5326 result_tree = ffecom_expr_w (NULL_TREE, arg2);
5328 arg1_tree = ffecom_ptr_to_expr (arg1);
5330 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5331 ffecom_gfrt_kindtype (gfrt),
5334 build_tree_list (NULL_TREE, arg1_tree),
5335 NULL_TREE, NULL, NULL, NULL_TREE,
5337 ffebld_nonter_hook (expr));
5338 expr_tree = ffecom_modify (NULL_TREE, result_tree,
5339 convert (TREE_TYPE (result_tree),
5344 /* Straightforward calls of libf2c routines: */
5345 case FFEINTRIN_impABORT:
5346 case FFEINTRIN_impACCESS:
5347 case FFEINTRIN_impBESJ0:
5348 case FFEINTRIN_impBESJ1:
5349 case FFEINTRIN_impBESJN:
5350 case FFEINTRIN_impBESY0:
5351 case FFEINTRIN_impBESY1:
5352 case FFEINTRIN_impBESYN:
5353 case FFEINTRIN_impCHDIR_func:
5354 case FFEINTRIN_impCHMOD_func:
5355 case FFEINTRIN_impDATE:
5356 case FFEINTRIN_impDATE_AND_TIME:
5357 case FFEINTRIN_impDBESJ0:
5358 case FFEINTRIN_impDBESJ1:
5359 case FFEINTRIN_impDBESJN:
5360 case FFEINTRIN_impDBESY0:
5361 case FFEINTRIN_impDBESY1:
5362 case FFEINTRIN_impDBESYN:
5363 case FFEINTRIN_impDTIME_func:
5364 case FFEINTRIN_impETIME_func:
5365 case FFEINTRIN_impFGETC_func:
5366 case FFEINTRIN_impFGET_func:
5367 case FFEINTRIN_impFNUM:
5368 case FFEINTRIN_impFPUTC_func:
5369 case FFEINTRIN_impFPUT_func:
5370 case FFEINTRIN_impFSEEK:
5371 case FFEINTRIN_impFSTAT_func:
5372 case FFEINTRIN_impFTELL_func:
5373 case FFEINTRIN_impGERROR:
5374 case FFEINTRIN_impGETARG:
5375 case FFEINTRIN_impGETCWD_func:
5376 case FFEINTRIN_impGETENV:
5377 case FFEINTRIN_impGETGID:
5378 case FFEINTRIN_impGETLOG:
5379 case FFEINTRIN_impGETPID:
5380 case FFEINTRIN_impGETUID:
5381 case FFEINTRIN_impGMTIME:
5382 case FFEINTRIN_impHOSTNM_func:
5383 case FFEINTRIN_impIDATE_unix:
5384 case FFEINTRIN_impIDATE_vxt:
5385 case FFEINTRIN_impIERRNO:
5386 case FFEINTRIN_impISATTY:
5387 case FFEINTRIN_impITIME:
5388 case FFEINTRIN_impKILL_func:
5389 case FFEINTRIN_impLINK_func:
5390 case FFEINTRIN_impLNBLNK:
5391 case FFEINTRIN_impLSTAT_func:
5392 case FFEINTRIN_impLTIME:
5393 case FFEINTRIN_impMCLOCK8:
5394 case FFEINTRIN_impMCLOCK:
5395 case FFEINTRIN_impPERROR:
5396 case FFEINTRIN_impRENAME_func:
5397 case FFEINTRIN_impSECNDS:
5398 case FFEINTRIN_impSECOND_func:
5399 case FFEINTRIN_impSLEEP:
5400 case FFEINTRIN_impSRAND:
5401 case FFEINTRIN_impSTAT_func:
5402 case FFEINTRIN_impSYMLNK_func:
5403 case FFEINTRIN_impSYSTEM_CLOCK:
5404 case FFEINTRIN_impSYSTEM_func:
5405 case FFEINTRIN_impTIME8:
5406 case FFEINTRIN_impTIME_unix:
5407 case FFEINTRIN_impTIME_vxt:
5408 case FFEINTRIN_impUMASK_func:
5409 case FFEINTRIN_impUNLINK_func:
5412 case FFEINTRIN_impCTIME_func: /* CHARACTER functions not handled here. */
5413 case FFEINTRIN_impFDATE_func: /* CHARACTER functions not handled here. */
5414 case FFEINTRIN_impTTYNAM_func: /* CHARACTER functions not handled here. */
5415 case FFEINTRIN_impNONE:
5416 case FFEINTRIN_imp: /* Hush up gcc warning. */
5417 fprintf (stderr, "No %s implementation.\n",
5418 ffeintrin_name_implementation (ffebld_symter_implementation (ffebld_left (expr))));
5419 assert ("unimplemented intrinsic" == NULL);
5420 return error_mark_node;
5423 assert (gfrt != FFECOM_gfrt); /* Must have an implementation! */
5425 expr_tree = ffecom_arglist_expr_ (ffecom_gfrt_args_ (gfrt),
5426 ffebld_right (expr));
5428 return ffecom_call_ (ffecom_gfrt_tree_ (gfrt), ffecom_gfrt_kindtype (gfrt),
5429 (ffe_is_f2c_library () && ffecom_gfrt_complex_[gfrt]),
5431 expr_tree, dest_tree, dest, dest_used,
5433 ffebld_nonter_hook (expr));
5435 /* See bottom of this file for f2c transforms used to determine
5436 many of the above implementations. The info seems to confuse
5437 Emacs's C mode indentation, which is why it's been moved to
5438 the bottom of this source file. */
5441 /* For power (exponentiation) where right-hand operand is type INTEGER,
5442 generate in-line code to do it the fast way (which, if the operand
5443 is a constant, might just mean a series of multiplies). */
5446 ffecom_expr_power_integer_ (ffebld expr)
5448 tree l = ffecom_expr (ffebld_left (expr));
5449 tree r = ffecom_expr (ffebld_right (expr));
5450 tree ltype = TREE_TYPE (l);
5451 tree rtype = TREE_TYPE (r);
5452 tree result = NULL_TREE;
5454 if (l == error_mark_node
5455 || r == error_mark_node)
5456 return error_mark_node;
5458 if (TREE_CODE (r) == INTEGER_CST)
5460 int sgn = tree_int_cst_sgn (r);
5463 return convert (ltype, integer_one_node);
5465 if ((TREE_CODE (ltype) == INTEGER_TYPE)
5468 /* Reciprocal of integer is either 0, -1, or 1, so after
5469 calculating that (which we leave to the back end to do
5470 or not do optimally), don't bother with any multiplying. */
5472 result = ffecom_tree_divide_ (ltype,
5473 convert (ltype, integer_one_node),
5475 NULL_TREE, NULL, NULL, NULL_TREE);
5476 r = ffecom_1 (NEGATE_EXPR,
5479 if ((TREE_INT_CST_LOW (r) & 1) == 0)
5480 result = ffecom_1 (ABS_EXPR, rtype,
5484 /* Generate appropriate series of multiplies, preceded
5485 by divide if the exponent is negative. */
5491 l = ffecom_tree_divide_ (ltype,
5492 convert (ltype, integer_one_node),
5494 NULL_TREE, NULL, NULL,
5495 ffebld_nonter_hook (expr));
5496 r = ffecom_1 (NEGATE_EXPR, rtype, r);
5497 assert (TREE_CODE (r) == INTEGER_CST);
5499 if (tree_int_cst_sgn (r) < 0)
5500 { /* The "most negative" number. */
5501 r = ffecom_1 (NEGATE_EXPR, rtype,
5502 ffecom_2 (RSHIFT_EXPR, rtype,
5506 l = ffecom_2 (MULT_EXPR, ltype,
5514 if (TREE_INT_CST_LOW (r) & 1)
5516 if (result == NULL_TREE)
5519 result = ffecom_2 (MULT_EXPR, ltype,
5524 r = ffecom_2 (RSHIFT_EXPR, rtype,
5527 if (integer_zerop (r))
5529 assert (TREE_CODE (r) == INTEGER_CST);
5532 l = ffecom_2 (MULT_EXPR, ltype,
5539 /* Though rhs isn't a constant, in-line code cannot be expanded
5540 while transforming dummies
5541 because the back end cannot be easily convinced to generate
5542 stores (MODIFY_EXPR), handle temporaries, and so on before
5543 all the appropriate rtx's have been generated for things like
5544 dummy args referenced in rhs -- which doesn't happen until
5545 store_parm_decls() is called (expand_function_start, I believe,
5546 does the actual rtx-stuffing of PARM_DECLs).
5548 So, in this case, let the caller generate the call to the
5549 run-time-library function to evaluate the power for us. */
5551 if (ffecom_transform_only_dummies_)
5554 /* Right-hand operand not a constant, expand in-line code to figure
5555 out how to do the multiplies, &c.
5557 The returned expression is expressed this way in GNU C, where l and
5560 ({ typeof (r) rtmp = r;
5561 typeof (l) ltmp = l;
5568 if ((basetypeof (l) == basetypeof (int))
5571 result = ((typeof (l)) 1) / ltmp;
5572 if ((ltmp < 0) && (((-rtmp) & 1) == 0))
5578 if ((basetypeof (l) != basetypeof (int))
5581 ltmp = ((typeof (l)) 1) / ltmp;
5585 rtmp = -(rtmp >> 1);
5593 if ((rtmp >>= 1) == 0)
5602 Note that some of the above is compile-time collapsable, such as
5603 the first part of the if statements that checks the base type of
5604 l against int. The if statements are phrased that way to suggest
5605 an easy way to generate the if/else constructs here, knowing that
5606 the back end should (and probably does) eliminate the resulting
5607 dead code (either the int case or the non-int case), something
5608 it couldn't do without the redundant phrasing, requiring explicit
5609 dead-code elimination here, which would be kind of difficult to
5616 tree basetypeof_l_is_int;
5621 = build_int_2 ((TREE_CODE (ltype) == INTEGER_TYPE), 0);
5623 se = expand_start_stmt_expr (/*has_scope=*/1);
5625 ffecom_start_compstmt ();
5628 rtmp = ffecom_make_tempvar ("power_r", rtype,
5629 FFETARGET_charactersizeNONE, -1);
5630 ltmp = ffecom_make_tempvar ("power_l", ltype,
5631 FFETARGET_charactersizeNONE, -1);
5632 result = ffecom_make_tempvar ("power_res", ltype,
5633 FFETARGET_charactersizeNONE, -1);
5634 if (TREE_CODE (ltype) == COMPLEX_TYPE
5635 || TREE_CODE (ltype) == RECORD_TYPE)
5636 divide = ffecom_make_tempvar ("power_div", ltype,
5637 FFETARGET_charactersizeNONE, -1);
5644 hook = ffebld_nonter_hook (expr);
5646 assert (TREE_CODE (hook) == TREE_VEC);
5647 assert (TREE_VEC_LENGTH (hook) == 4);
5648 rtmp = TREE_VEC_ELT (hook, 0);
5649 ltmp = TREE_VEC_ELT (hook, 1);
5650 result = TREE_VEC_ELT (hook, 2);
5651 divide = TREE_VEC_ELT (hook, 3);
5652 if (TREE_CODE (ltype) == COMPLEX_TYPE
5653 || TREE_CODE (ltype) == RECORD_TYPE)
5660 expand_expr_stmt (ffecom_modify (void_type_node,
5663 expand_expr_stmt (ffecom_modify (void_type_node,
5666 expand_start_cond (ffecom_truth_value
5667 (ffecom_2 (EQ_EXPR, integer_type_node,
5669 convert (rtype, integer_zero_node))),
5671 expand_expr_stmt (ffecom_modify (void_type_node,
5673 convert (ltype, integer_one_node)));
5674 expand_start_else ();
5675 if (! integer_zerop (basetypeof_l_is_int))
5677 expand_start_cond (ffecom_2 (LT_EXPR, integer_type_node,
5680 integer_zero_node)),
5682 expand_expr_stmt (ffecom_modify (void_type_node,
5686 convert (ltype, integer_one_node),
5688 NULL_TREE, NULL, NULL,
5690 expand_start_cond (ffecom_truth_value
5691 (ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
5692 ffecom_2 (LT_EXPR, integer_type_node,
5695 integer_zero_node)),
5696 ffecom_2 (EQ_EXPR, integer_type_node,
5697 ffecom_2 (BIT_AND_EXPR,
5699 ffecom_1 (NEGATE_EXPR,
5705 integer_zero_node)))),
5707 expand_expr_stmt (ffecom_modify (void_type_node,
5709 ffecom_1 (NEGATE_EXPR,
5713 expand_start_else ();
5715 expand_expr_stmt (ffecom_modify (void_type_node,
5717 convert (ltype, integer_one_node)));
5718 expand_start_cond (ffecom_truth_value
5719 (ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
5720 ffecom_truth_value_invert
5721 (basetypeof_l_is_int),
5722 ffecom_2 (LT_EXPR, integer_type_node,
5725 integer_zero_node)))),
5727 expand_expr_stmt (ffecom_modify (void_type_node,
5731 convert (ltype, integer_one_node),
5733 NULL_TREE, NULL, NULL,
5735 expand_expr_stmt (ffecom_modify (void_type_node,
5737 ffecom_1 (NEGATE_EXPR, rtype,
5739 expand_start_cond (ffecom_truth_value
5740 (ffecom_2 (LT_EXPR, integer_type_node,
5742 convert (rtype, integer_zero_node))),
5744 expand_expr_stmt (ffecom_modify (void_type_node,
5746 ffecom_1 (NEGATE_EXPR, rtype,
5747 ffecom_2 (RSHIFT_EXPR,
5750 integer_one_node))));
5751 expand_expr_stmt (ffecom_modify (void_type_node,
5753 ffecom_2 (MULT_EXPR, ltype,
5758 expand_start_loop (1);
5759 expand_start_cond (ffecom_truth_value
5760 (ffecom_2 (BIT_AND_EXPR, rtype,
5762 convert (rtype, integer_one_node))),
5764 expand_expr_stmt (ffecom_modify (void_type_node,
5766 ffecom_2 (MULT_EXPR, ltype,
5770 expand_exit_loop_if_false (NULL,
5772 (ffecom_modify (rtype,
5774 ffecom_2 (RSHIFT_EXPR,
5777 integer_one_node))));
5778 expand_expr_stmt (ffecom_modify (void_type_node,
5780 ffecom_2 (MULT_EXPR, ltype,
5785 if (!integer_zerop (basetypeof_l_is_int))
5787 expand_expr_stmt (result);
5789 t = ffecom_end_compstmt ();
5791 result = expand_end_stmt_expr (se);
5793 /* This code comes from c-parse.in, after its expand_end_stmt_expr. */
5795 if (TREE_CODE (t) == BLOCK)
5797 /* Make a BIND_EXPR for the BLOCK already made. */
5798 result = build (BIND_EXPR, TREE_TYPE (result),
5799 NULL_TREE, result, t);
5800 /* Remove the block from the tree at this point.
5801 It gets put back at the proper place
5802 when the BIND_EXPR is expanded. */
5812 /* ffecom_expr_transform_ -- Transform symbols in expr
5814 ffebld expr; // FFE expression.
5815 ffecom_expr_transform_ (expr);
5817 Recursive descent on expr while transforming any untransformed SYMTERs. */
5820 ffecom_expr_transform_ (ffebld expr)
5830 switch (ffebld_op (expr))
5832 case FFEBLD_opSYMTER:
5833 s = ffebld_symter (expr);
5834 t = ffesymbol_hook (s).decl_tree;
5835 if ((t == NULL_TREE)
5836 && ((ffesymbol_kind (s) != FFEINFO_kindNONE)
5837 || ((ffesymbol_where (s) != FFEINFO_whereNONE)
5838 && (ffesymbol_where (s) != FFEINFO_whereINTRINSIC))))
5840 s = ffecom_sym_transform_ (s);
5841 t = ffesymbol_hook (s).decl_tree; /* Sfunc expr non-dummy,
5844 break; /* Ok if (t == NULL) here. */
5847 ffecom_expr_transform_ (ffebld_head (expr));
5848 expr = ffebld_trail (expr);
5849 goto tail_recurse; /* :::::::::::::::::::: */
5855 switch (ffebld_arity (expr))
5858 ffecom_expr_transform_ (ffebld_left (expr));
5859 expr = ffebld_right (expr);
5860 goto tail_recurse; /* :::::::::::::::::::: */
5863 expr = ffebld_left (expr);
5864 goto tail_recurse; /* :::::::::::::::::::: */
5873 /* Make a type based on info in live f2c.h file. */
5876 ffecom_f2c_make_type_ (tree *type, int tcode, const char *name)
5880 case FFECOM_f2ccodeCHAR:
5881 *type = make_signed_type (CHAR_TYPE_SIZE);
5884 case FFECOM_f2ccodeSHORT:
5885 *type = make_signed_type (SHORT_TYPE_SIZE);
5888 case FFECOM_f2ccodeINT:
5889 *type = make_signed_type (INT_TYPE_SIZE);
5892 case FFECOM_f2ccodeLONG:
5893 *type = make_signed_type (LONG_TYPE_SIZE);
5896 case FFECOM_f2ccodeLONGLONG:
5897 *type = make_signed_type (LONG_LONG_TYPE_SIZE);
5900 case FFECOM_f2ccodeCHARPTR:
5901 *type = build_pointer_type (DEFAULT_SIGNED_CHAR
5902 ? signed_char_type_node
5903 : unsigned_char_type_node);
5906 case FFECOM_f2ccodeFLOAT:
5907 *type = make_node (REAL_TYPE);
5908 TYPE_PRECISION (*type) = FLOAT_TYPE_SIZE;
5909 layout_type (*type);
5912 case FFECOM_f2ccodeDOUBLE:
5913 *type = make_node (REAL_TYPE);
5914 TYPE_PRECISION (*type) = DOUBLE_TYPE_SIZE;
5915 layout_type (*type);
5918 case FFECOM_f2ccodeLONGDOUBLE:
5919 *type = make_node (REAL_TYPE);
5920 TYPE_PRECISION (*type) = LONG_DOUBLE_TYPE_SIZE;
5921 layout_type (*type);
5924 case FFECOM_f2ccodeTWOREALS:
5925 *type = ffecom_make_complex_type_ (ffecom_f2c_real_type_node);
5928 case FFECOM_f2ccodeTWODOUBLEREALS:
5929 *type = ffecom_make_complex_type_ (ffecom_f2c_doublereal_type_node);
5933 assert ("unexpected FFECOM_f2ccodeXYZZY!" == NULL);
5934 *type = error_mark_node;
5938 pushdecl (build_decl (TYPE_DECL,
5939 ffecom_get_invented_identifier ("__g77_f2c_%s", name),
5943 /* Set the f2c list-directed-I/O code for whatever (integral) type has the
5947 ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size,
5953 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
5954 if ((t = ffecom_tree_type[bt][j]) != NULL_TREE
5955 && compare_tree_int (TYPE_SIZE (t), size) == 0)
5957 assert (code != -1);
5958 ffecom_f2c_typecode_[bt][j] = code;
5963 /* Finish up globals after doing all program units in file
5965 Need to handle only uninitialized COMMON areas. */
5968 ffecom_finish_global_ (ffeglobal global)
5974 if (ffeglobal_type (global) != FFEGLOBAL_typeCOMMON)
5977 if (ffeglobal_common_init (global))
5980 cbt = ffeglobal_hook (global);
5981 if ((cbt == NULL_TREE)
5982 || !ffeglobal_common_have_size (global))
5983 return global; /* No need to make common, never ref'd. */
5985 DECL_EXTERNAL (cbt) = 0;
5987 /* Give the array a size now. */
5989 size = build_int_2 ((ffeglobal_common_size (global)
5990 + ffeglobal_common_pad (global)) - 1,
5993 cbtype = TREE_TYPE (cbt);
5994 TYPE_DOMAIN (cbtype) = build_range_type (integer_type_node,
5997 if (!TREE_TYPE (size))
5998 TREE_TYPE (size) = TYPE_DOMAIN (cbtype);
5999 layout_type (cbtype);
6001 cbt = start_decl (cbt, FALSE);
6002 assert (cbt == ffeglobal_hook (global));
6004 finish_decl (cbt, NULL_TREE, FALSE);
6009 /* Finish up any untransformed symbols. */
6012 ffecom_finish_symbol_transform_ (ffesymbol s)
6014 if ((s == NULL) || (TREE_CODE (current_function_decl) == ERROR_MARK))
6017 /* It's easy to know to transform an untransformed symbol, to make sure
6018 we put out debugging info for it. But COMMON variables, unlike
6019 EQUIVALENCE ones, aren't given declarations in addition to the
6020 tree expressions that specify offsets, because COMMON variables
6021 can be referenced in the outer scope where only dummy arguments
6022 (PARM_DECLs) should really be seen. To be safe, just don't do any
6023 VAR_DECLs for COMMON variables when we transform them for real
6024 use, and therefore we do all the VAR_DECL creating here. */
6026 if (ffesymbol_hook (s).decl_tree == NULL_TREE)
6028 if (ffesymbol_kind (s) != FFEINFO_kindNONE
6029 || (ffesymbol_where (s) != FFEINFO_whereNONE
6030 && ffesymbol_where (s) != FFEINFO_whereINTRINSIC
6031 && ffesymbol_where (s) != FFEINFO_whereDUMMY))
6032 /* Not transformed, and not CHARACTER*(*), and not a dummy
6033 argument, which can happen only if the entry point names
6034 it "rides in on" are all invalidated for other reasons. */
6035 s = ffecom_sym_transform_ (s);
6038 if ((ffesymbol_where (s) == FFEINFO_whereCOMMON)
6039 && (ffesymbol_hook (s).decl_tree != error_mark_node))
6041 /* This isn't working, at least for dbxout. The .s file looks
6042 okay to me (burley), but in gdb 4.9 at least, the variables
6043 appear to reside somewhere outside of the common area, so
6044 it doesn't make sense to mislead anyone by generating the info
6045 on those variables until this is fixed. NOTE: Same problem
6046 with EQUIVALENCE, sadly...see similar #if later. */
6047 ffecom_member_phase2_ (ffesymbol_storage (ffesymbol_common (s)),
6048 ffesymbol_storage (s));
6054 /* Append underscore(s) to name before calling get_identifier. "us"
6055 is nonzero if the name already contains an underscore and thus
6056 needs two underscores appended. */
6059 ffecom_get_appended_identifier_ (char us, const char *name)
6065 newname = xmalloc ((i = strlen (name)) + 1
6066 + ffe_is_underscoring ()
6068 memcpy (newname, name, i);
6070 newname[i + us] = '_';
6071 newname[i + 1 + us] = '\0';
6072 id = get_identifier (newname);
6079 /* Decide whether to append underscore to name before calling
6083 ffecom_get_external_identifier_ (ffesymbol s)
6086 const char *name = ffesymbol_text (s);
6088 /* If name is a built-in name, just return it as is. */
6090 if (!ffe_is_underscoring ()
6091 || (strcmp (name, FFETARGET_nameBLANK_COMMON) == 0)
6092 #if FFETARGET_isENFORCED_MAIN_NAME
6093 || (strcmp (name, FFETARGET_nameENFORCED_NAME) == 0)
6095 || (strcmp (name, FFETARGET_nameUNNAMED_MAIN) == 0)
6097 || (strcmp (name, FFETARGET_nameUNNAMED_BLOCK_DATA) == 0))
6098 return get_identifier (name);
6100 us = ffe_is_second_underscore ()
6101 ? (strchr (name, '_') != NULL)
6104 return ffecom_get_appended_identifier_ (us, name);
6107 /* Decide whether to append underscore to internal name before calling
6110 This is for non-external, top-function-context names only. Transform
6111 identifier so it doesn't conflict with the transformed result
6112 of using a _different_ external name. E.g. if "CALL FOO" is
6113 transformed into "FOO_();", then the variable in "FOO_ = 3"
6114 must be transformed into something that does not conflict, since
6115 these two things should be independent.
6117 The transformation is as follows. If the name does not contain
6118 an underscore, there is no possible conflict, so just return.
6119 If the name does contain an underscore, then transform it just
6120 like we transform an external identifier. */
6123 ffecom_get_identifier_ (const char *name)
6125 /* If name does not contain an underscore, just return it as is. */
6127 if (!ffe_is_underscoring ()
6128 || (strchr (name, '_') == NULL))
6129 return get_identifier (name);
6131 return ffecom_get_appended_identifier_ (ffe_is_second_underscore (),
6135 /* ffecom_gen_sfuncdef_ -- Generate definition of statement function
6138 ffesymbol s; // kindFUNCTION, whereIMMEDIATE.
6139 t = ffecom_gen_sfuncdef_(s,ffesymbol_basictype(s),
6140 ffesymbol_kindtype(s));
6142 Call after setting up containing function and getting trees for all
6146 ffecom_gen_sfuncdef_ (ffesymbol s, ffeinfoBasictype bt, ffeinfoKindtype kt)
6148 ffebld expr = ffesymbol_sfexpr (s);
6152 bool charfunc = (bt == FFEINFO_basictypeCHARACTER);
6153 static bool recurse = FALSE;
6154 int old_lineno = lineno;
6155 const char *old_input_filename = input_filename;
6157 ffecom_nested_entry_ = s;
6159 /* For now, we don't have a handy pointer to where the sfunc is actually
6160 defined, though that should be easy to add to an ffesymbol. (The
6161 token/where info available might well point to the place where the type
6162 of the sfunc is declared, especially if that precedes the place where
6163 the sfunc itself is defined, which is typically the case.) We should
6164 put out a null pointer rather than point somewhere wrong, but I want to
6165 see how it works at this point. */
6167 input_filename = ffesymbol_where_filename (s);
6168 lineno = ffesymbol_where_filelinenum (s);
6170 /* Pretransform the expression so any newly discovered things belong to the
6171 outer program unit, not to the statement function. */
6173 ffecom_expr_transform_ (expr);
6175 /* Make sure no recursive invocation of this fn (a specific case of failing
6176 to pretransform an sfunc's expression, i.e. where its expression
6177 references another untransformed sfunc) happens. */
6182 push_f_function_context ();
6185 type = void_type_node;
6188 type = ffecom_tree_type[bt][kt];
6189 if (type == NULL_TREE)
6190 type = integer_type_node; /* _sym_exec_transition reports
6194 start_function (ffecom_get_identifier_ (ffesymbol_text (s)),
6195 build_function_type (type, NULL_TREE),
6196 1, /* nested/inline */
6197 0); /* TREE_PUBLIC */
6199 /* We don't worry about COMPLEX return values here, because this is
6200 entirely internal to our code, and gcc has the ability to return COMPLEX
6201 directly as a value. */
6204 { /* Prepend arg for where result goes. */
6207 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
6209 result = ffecom_get_invented_identifier ("__g77_%s", "result");
6211 ffecom_char_enhance_arg_ (&type, s); /* Ignore returned length. */
6213 type = build_pointer_type (type);
6214 result = build_decl (PARM_DECL, result, type);
6216 push_parm_decl (result);
6219 result = NULL_TREE; /* Not ref'd if !charfunc. */
6221 ffecom_push_dummy_decls_ (ffesymbol_dummyargs (s), TRUE);
6223 store_parm_decls (0);
6225 ffecom_start_compstmt ();
6231 ffetargetCharacterSize sz = ffesymbol_size (s);
6234 result_length = build_int_2 (sz, 0);
6235 TREE_TYPE (result_length) = ffecom_f2c_ftnlen_type_node;
6237 ffecom_prepare_let_char_ (sz, expr);
6239 ffecom_prepare_end ();
6241 ffecom_let_char_ (result, result_length, sz, expr);
6242 expand_null_return ();
6246 ffecom_prepare_expr (expr);
6248 ffecom_prepare_end ();
6250 expand_return (ffecom_modify (NULL_TREE,
6251 DECL_RESULT (current_function_decl),
6252 ffecom_expr (expr)));
6256 ffecom_end_compstmt ();
6258 func = current_function_decl;
6259 finish_function (1);
6261 pop_f_function_context ();
6265 lineno = old_lineno;
6266 input_filename = old_input_filename;
6268 ffecom_nested_entry_ = NULL;
6274 ffecom_gfrt_args_ (ffecomGfrt ix)
6276 return ffecom_gfrt_argstring_[ix];
6280 ffecom_gfrt_tree_ (ffecomGfrt ix)
6282 if (ffecom_gfrt_[ix] == NULL_TREE)
6283 ffecom_make_gfrt_ (ix);
6285 return ffecom_1 (ADDR_EXPR,
6286 build_pointer_type (TREE_TYPE (ffecom_gfrt_[ix])),
6290 /* Return initialize-to-zero expression for this VAR_DECL. */
6292 /* A somewhat evil way to prevent the garbage collector
6293 from collecting 'tree' structures. */
6294 #define NUM_TRACKED_CHUNK 63
6295 struct tree_ggc_tracker GTY(())
6297 struct tree_ggc_tracker *next;
6298 tree trees[NUM_TRACKED_CHUNK];
6300 static GTY(()) struct tree_ggc_tracker *tracker_head;
6303 ffecom_save_tree_forever (tree t)
6306 if (tracker_head != NULL)
6307 for (i = 0; i < NUM_TRACKED_CHUNK; i++)
6308 if (tracker_head->trees[i] == NULL)
6310 tracker_head->trees[i] = t;
6315 /* Need to allocate a new block. */
6316 struct tree_ggc_tracker *old_head = tracker_head;
6318 tracker_head = ggc_alloc (sizeof (*tracker_head));
6319 tracker_head->next = old_head;
6320 tracker_head->trees[0] = t;
6321 for (i = 1; i < NUM_TRACKED_CHUNK; i++)
6322 tracker_head->trees[i] = NULL;
6327 ffecom_init_zero_ (tree decl)
6330 int incremental = TREE_STATIC (decl);
6331 tree type = TREE_TYPE (decl);
6335 make_decl_rtl (decl, NULL);
6336 assemble_variable (decl, TREE_PUBLIC (decl) ? 1 : 0, 0, 1);
6339 if ((TREE_CODE (type) != ARRAY_TYPE)
6340 && (TREE_CODE (type) != RECORD_TYPE)
6341 && (TREE_CODE (type) != UNION_TYPE)
6343 init = convert (type, integer_zero_node);
6344 else if (!incremental)
6346 init = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
6347 TREE_CONSTANT (init) = 1;
6348 TREE_STATIC (init) = 1;
6352 assemble_zeros (int_size_in_bytes (type));
6353 init = error_mark_node;
6360 ffecom_intrinsic_ichar_ (tree tree_type, ffebld arg,
6366 switch (ffebld_op (arg))
6368 case FFEBLD_opCONTER: /* For F90, check 0-length. */
6369 if (ffetarget_length_character1
6370 (ffebld_constant_character1
6371 (ffebld_conter (arg))) == 0)
6373 *maybe_tree = integer_zero_node;
6374 return convert (tree_type, integer_zero_node);
6377 *maybe_tree = integer_one_node;
6378 expr_tree = build_int_2 (*ffetarget_text_character1
6379 (ffebld_constant_character1
6380 (ffebld_conter (arg))),
6382 TREE_TYPE (expr_tree) = tree_type;
6385 case FFEBLD_opSYMTER:
6386 case FFEBLD_opARRAYREF:
6387 case FFEBLD_opFUNCREF:
6388 case FFEBLD_opSUBSTR:
6389 ffecom_char_args_ (&expr_tree, &length_tree, arg);
6391 if ((expr_tree == error_mark_node)
6392 || (length_tree == error_mark_node))
6394 *maybe_tree = error_mark_node;
6395 return error_mark_node;
6398 if (integer_zerop (length_tree))
6400 *maybe_tree = integer_zero_node;
6401 return convert (tree_type, integer_zero_node);
6405 = ffecom_1 (INDIRECT_REF,
6406 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
6409 = ffecom_2 (ARRAY_REF,
6410 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
6413 expr_tree = convert (tree_type, expr_tree);
6415 if (TREE_CODE (length_tree) == INTEGER_CST)
6416 *maybe_tree = integer_one_node;
6417 else /* Must check length at run time. */
6419 = ffecom_truth_value
6420 (ffecom_2 (GT_EXPR, integer_type_node,
6422 ffecom_f2c_ftnlen_zero_node));
6425 case FFEBLD_opPAREN:
6426 case FFEBLD_opCONVERT:
6427 if (ffeinfo_size (ffebld_info (arg)) == 0)
6429 *maybe_tree = integer_zero_node;
6430 return convert (tree_type, integer_zero_node);
6432 return ffecom_intrinsic_ichar_ (tree_type, ffebld_left (arg),
6435 case FFEBLD_opCONCATENATE:
6442 expr_left = ffecom_intrinsic_ichar_ (tree_type, ffebld_left (arg),
6444 expr_right = ffecom_intrinsic_ichar_ (tree_type, ffebld_right (arg),
6446 *maybe_tree = ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
6449 expr_tree = ffecom_3 (COND_EXPR, tree_type,
6457 assert ("bad op in ICHAR" == NULL);
6458 return error_mark_node;
6462 /* ffecom_intrinsic_len_ -- Return length info for char arg (LEN())
6466 length_arg = ffecom_intrinsic_len_ (expr);
6468 Handles CHARACTER-type CONTER, SYMTER, SUBSTR, ARRAYREF, and FUNCREF
6469 subexpressions by constructing the appropriate tree for the
6470 length-of-character-text argument in a calling sequence. */
6473 ffecom_intrinsic_len_ (ffebld expr)
6475 ffetargetCharacter1 val;
6478 switch (ffebld_op (expr))
6480 case FFEBLD_opCONTER:
6481 val = ffebld_constant_character1 (ffebld_conter (expr));
6482 length = build_int_2 (ffetarget_length_character1 (val), 0);
6483 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6486 case FFEBLD_opSYMTER:
6488 ffesymbol s = ffebld_symter (expr);
6491 item = ffesymbol_hook (s).decl_tree;
6492 if (item == NULL_TREE)
6494 s = ffecom_sym_transform_ (s);
6495 item = ffesymbol_hook (s).decl_tree;
6497 if (ffesymbol_kind (s) == FFEINFO_kindENTITY)
6499 if (ffesymbol_size (s) == FFETARGET_charactersizeNONE)
6500 length = ffesymbol_hook (s).length_tree;
6503 length = build_int_2 (ffesymbol_size (s), 0);
6504 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6507 else if (item == error_mark_node)
6508 length = error_mark_node;
6509 else /* FFEINFO_kindFUNCTION: */
6514 case FFEBLD_opARRAYREF:
6515 length = ffecom_intrinsic_len_ (ffebld_left (expr));
6518 case FFEBLD_opSUBSTR:
6522 ffebld thing = ffebld_right (expr);
6526 assert (ffebld_op (thing) == FFEBLD_opITEM);
6527 start = ffebld_head (thing);
6528 thing = ffebld_trail (thing);
6529 assert (ffebld_trail (thing) == NULL);
6530 end = ffebld_head (thing);
6532 length = ffecom_intrinsic_len_ (ffebld_left (expr));
6534 if (length == error_mark_node)
6543 length = convert (ffecom_f2c_ftnlen_type_node,
6549 start_tree = convert (ffecom_f2c_ftnlen_type_node,
6550 ffecom_expr (start));
6552 if (start_tree == error_mark_node)
6554 length = error_mark_node;
6560 length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6561 ffecom_f2c_ftnlen_one_node,
6562 ffecom_2 (MINUS_EXPR,
6563 ffecom_f2c_ftnlen_type_node,
6569 end_tree = convert (ffecom_f2c_ftnlen_type_node,
6572 if (end_tree == error_mark_node)
6574 length = error_mark_node;
6578 length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6579 ffecom_f2c_ftnlen_one_node,
6580 ffecom_2 (MINUS_EXPR,
6581 ffecom_f2c_ftnlen_type_node,
6582 end_tree, start_tree));
6588 case FFEBLD_opCONCATENATE:
6590 = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6591 ffecom_intrinsic_len_ (ffebld_left (expr)),
6592 ffecom_intrinsic_len_ (ffebld_right (expr)));
6595 case FFEBLD_opFUNCREF:
6596 case FFEBLD_opCONVERT:
6597 length = build_int_2 (ffebld_size (expr), 0);
6598 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6602 assert ("bad op for single char arg expr" == NULL);
6603 length = ffecom_f2c_ftnlen_zero_node;
6607 assert (length != NULL_TREE);
6612 /* Handle CHARACTER assignments.
6614 Generates code to do the assignment. Used by ordinary assignment
6615 statement handler ffecom_let_stmt and by statement-function
6616 handler to generate code for a statement function. */
6619 ffecom_let_char_ (tree dest_tree, tree dest_length,
6620 ffetargetCharacterSize dest_size, ffebld source)
6622 ffecomConcatList_ catlist;
6627 if ((dest_tree == error_mark_node)
6628 || (dest_length == error_mark_node))
6631 assert (dest_tree != NULL_TREE);
6632 assert (dest_length != NULL_TREE);
6634 /* Source might be an opCONVERT, which just means it is a different size
6635 than the destination. Since the underlying implementation here handles
6636 that (directly or via the s_copy or s_cat run-time-library functions),
6637 we don't need the "convenience" of an opCONVERT that tells us to
6638 truncate or blank-pad, particularly since the resulting implementation
6639 would probably be slower than otherwise. */
6641 while (ffebld_op (source) == FFEBLD_opCONVERT)
6642 source = ffebld_left (source);
6644 catlist = ffecom_concat_list_new_ (source, dest_size);
6645 switch (ffecom_concat_list_count_ (catlist))
6647 case 0: /* Shouldn't happen, but in case it does... */
6648 ffecom_concat_list_kill_ (catlist);
6649 source_tree = null_pointer_node;
6650 source_length = ffecom_f2c_ftnlen_zero_node;
6651 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6652 TREE_CHAIN (expr_tree) = build_tree_list (NULL_TREE, source_tree);
6653 TREE_CHAIN (TREE_CHAIN (expr_tree))
6654 = build_tree_list (NULL_TREE, dest_length);
6655 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6656 = build_tree_list (NULL_TREE, source_length);
6658 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCOPY, expr_tree, NULL_TREE);
6659 TREE_SIDE_EFFECTS (expr_tree) = 1;
6661 expand_expr_stmt (expr_tree);
6665 case 1: /* The (fairly) easy case. */
6666 ffecom_char_args_ (&source_tree, &source_length,
6667 ffecom_concat_list_expr_ (catlist, 0));
6668 ffecom_concat_list_kill_ (catlist);
6669 assert (source_tree != NULL_TREE);
6670 assert (source_length != NULL_TREE);
6672 if ((source_tree == error_mark_node)
6673 || (source_length == error_mark_node))
6679 = ffecom_1 (INDIRECT_REF,
6680 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6684 = ffecom_2 (ARRAY_REF,
6685 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6690 = ffecom_1 (INDIRECT_REF,
6691 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6695 = ffecom_2 (ARRAY_REF,
6696 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6701 expr_tree = ffecom_modify (void_type_node, dest_tree, source_tree);
6703 expand_expr_stmt (expr_tree);
6708 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6709 TREE_CHAIN (expr_tree) = build_tree_list (NULL_TREE, source_tree);
6710 TREE_CHAIN (TREE_CHAIN (expr_tree))
6711 = build_tree_list (NULL_TREE, dest_length);
6712 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6713 = build_tree_list (NULL_TREE, source_length);
6715 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCOPY, expr_tree, NULL_TREE);
6716 TREE_SIDE_EFFECTS (expr_tree) = 1;
6718 expand_expr_stmt (expr_tree);
6722 default: /* Must actually concatenate things. */
6726 /* Heavy-duty concatenation. */
6729 int count = ffecom_concat_list_count_ (catlist);
6741 = ffecom_push_tempvar (ffecom_f2c_ftnlen_type_node,
6742 FFETARGET_charactersizeNONE, count, TRUE);
6743 item_array = items = ffecom_push_tempvar (ffecom_f2c_address_type_node,
6744 FFETARGET_charactersizeNONE,
6750 hook = ffebld_nonter_hook (source);
6752 assert (TREE_CODE (hook) == TREE_VEC);
6753 assert (TREE_VEC_LENGTH (hook) == 2);
6754 length_array = lengths = TREE_VEC_ELT (hook, 0);
6755 item_array = items = TREE_VEC_ELT (hook, 1);
6759 for (i = 0; i < count; ++i)
6761 ffecom_char_args_ (&citem, &clength,
6762 ffecom_concat_list_expr_ (catlist, i));
6763 if ((citem == error_mark_node)
6764 || (clength == error_mark_node))
6766 ffecom_concat_list_kill_ (catlist);
6771 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (items),
6772 ffecom_modify (void_type_node,
6773 ffecom_2 (ARRAY_REF,
6774 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array))),
6776 build_int_2 (i, 0)),
6780 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (lengths),
6781 ffecom_modify (void_type_node,
6782 ffecom_2 (ARRAY_REF,
6783 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array))),
6785 build_int_2 (i, 0)),
6790 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6791 TREE_CHAIN (expr_tree)
6792 = build_tree_list (NULL_TREE,
6793 ffecom_1 (ADDR_EXPR,
6794 build_pointer_type (TREE_TYPE (items)),
6796 TREE_CHAIN (TREE_CHAIN (expr_tree))
6797 = build_tree_list (NULL_TREE,
6798 ffecom_1 (ADDR_EXPR,
6799 build_pointer_type (TREE_TYPE (lengths)),
6801 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6804 ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
6805 convert (ffecom_f2c_ftnlen_type_node,
6806 build_int_2 (count, 0))));
6807 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree))))
6808 = build_tree_list (NULL_TREE, dest_length);
6810 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCAT, expr_tree, NULL_TREE);
6811 TREE_SIDE_EFFECTS (expr_tree) = 1;
6813 expand_expr_stmt (expr_tree);
6816 ffecom_concat_list_kill_ (catlist);
6819 /* ffecom_make_gfrt_ -- Make initial info for run-time routine
6822 ffecom_make_gfrt_(ix);
6824 Assumes gfrt_[ix] is NULL_TREE, and replaces it with the FUNCTION_DECL
6825 for the indicated run-time routine (ix). */
6828 ffecom_make_gfrt_ (ffecomGfrt ix)
6833 switch (ffecom_gfrt_type_[ix])
6835 case FFECOM_rttypeVOID_:
6836 ttype = void_type_node;
6839 case FFECOM_rttypeVOIDSTAR_:
6840 ttype = TREE_TYPE (null_pointer_node); /* `void *'. */
6843 case FFECOM_rttypeFTNINT_:
6844 ttype = ffecom_f2c_ftnint_type_node;
6847 case FFECOM_rttypeINTEGER_:
6848 ttype = ffecom_f2c_integer_type_node;
6851 case FFECOM_rttypeLONGINT_:
6852 ttype = ffecom_f2c_longint_type_node;
6855 case FFECOM_rttypeLOGICAL_:
6856 ttype = ffecom_f2c_logical_type_node;
6859 case FFECOM_rttypeREAL_F2C_:
6860 ttype = double_type_node;
6863 case FFECOM_rttypeREAL_GNU_:
6864 ttype = float_type_node;
6867 case FFECOM_rttypeCOMPLEX_F2C_:
6868 ttype = void_type_node;
6871 case FFECOM_rttypeCOMPLEX_GNU_:
6872 ttype = ffecom_f2c_complex_type_node;
6875 case FFECOM_rttypeDOUBLE_:
6876 ttype = double_type_node;
6879 case FFECOM_rttypeDOUBLEREAL_:
6880 ttype = ffecom_f2c_doublereal_type_node;
6883 case FFECOM_rttypeDBLCMPLX_F2C_:
6884 ttype = void_type_node;
6887 case FFECOM_rttypeDBLCMPLX_GNU_:
6888 ttype = ffecom_f2c_doublecomplex_type_node;
6891 case FFECOM_rttypeCHARACTER_:
6892 ttype = void_type_node;
6897 assert ("bad rttype" == NULL);
6901 ttype = build_function_type (ttype, NULL_TREE);
6902 t = build_decl (FUNCTION_DECL,
6903 get_identifier (ffecom_gfrt_name_[ix]),
6905 DECL_EXTERNAL (t) = 1;
6906 TREE_READONLY (t) = ffecom_gfrt_const_[ix] ? 1 : 0;
6907 TREE_PUBLIC (t) = 1;
6908 TREE_THIS_VOLATILE (t) = ffecom_gfrt_volatile_[ix] ? 1 : 0;
6910 /* Sanity check: A function that's const cannot be volatile. */
6912 assert (ffecom_gfrt_const_[ix] ? !ffecom_gfrt_volatile_[ix] : 1);
6914 /* Sanity check: A function that's const cannot return complex. */
6916 assert (ffecom_gfrt_const_[ix] ? !ffecom_gfrt_complex_[ix] : 1);
6918 t = start_decl (t, TRUE);
6920 finish_decl (t, NULL_TREE, TRUE);
6922 ffecom_gfrt_[ix] = t;
6925 /* Phase 1 pass over each member of a COMMON/EQUIVALENCE group. */
6928 ffecom_member_phase1_ (ffestorag mst UNUSED, ffestorag st)
6930 ffesymbol s = ffestorag_symbol (st);
6932 if (ffesymbol_namelisted (s))
6933 ffecom_member_namelisted_ = TRUE;
6936 /* Phase 2 pass over each member of a COMMON/EQUIVALENCE group. Declare
6937 the member so debugger will see it. Otherwise nobody should be
6938 referencing the member. */
6941 ffecom_member_phase2_ (ffestorag mst, ffestorag st)
6949 || ((mt = ffestorag_hook (mst)) == NULL)
6950 || (mt == error_mark_node))
6954 || ((s = ffestorag_symbol (st)) == NULL))
6957 type = ffecom_type_localvar_ (s,
6958 ffesymbol_basictype (s),
6959 ffesymbol_kindtype (s));
6960 if (type == error_mark_node)
6963 t = build_decl (VAR_DECL,
6964 ffecom_get_identifier_ (ffesymbol_text (s)),
6967 TREE_STATIC (t) = TREE_STATIC (mt);
6968 DECL_INITIAL (t) = NULL_TREE;
6969 TREE_ASM_WRITTEN (t) = 1;
6973 gen_rtx (MEM, TYPE_MODE (type),
6974 plus_constant (XEXP (DECL_RTL (mt), 0),
6975 ffestorag_modulo (mst)
6976 + ffestorag_offset (st)
6977 - ffestorag_offset (mst))));
6979 t = start_decl (t, FALSE);
6981 finish_decl (t, NULL_TREE, FALSE);
6984 /* Prepare source expression for assignment into a destination perhaps known
6985 to be of a specific size. */
6988 ffecom_prepare_let_char_ (ffetargetCharacterSize dest_size, ffebld source)
6990 ffecomConcatList_ catlist;
6995 tree tempvar = NULL_TREE;
6997 while (ffebld_op (source) == FFEBLD_opCONVERT)
6998 source = ffebld_left (source);
7000 catlist = ffecom_concat_list_new_ (source, dest_size);
7001 count = ffecom_concat_list_count_ (catlist);
7006 = ffecom_make_tempvar ("let_char_len", ffecom_f2c_ftnlen_type_node,
7007 FFETARGET_charactersizeNONE, count);
7009 = ffecom_make_tempvar ("let_char_item", ffecom_f2c_address_type_node,
7010 FFETARGET_charactersizeNONE, count);
7012 tempvar = make_tree_vec (2);
7013 TREE_VEC_ELT (tempvar, 0) = ltmp;
7014 TREE_VEC_ELT (tempvar, 1) = itmp;
7017 for (i = 0; i < count; ++i)
7018 ffecom_prepare_arg_ptr_to_expr (ffecom_concat_list_expr_ (catlist, i));
7020 ffecom_concat_list_kill_ (catlist);
7024 ffebld_nonter_set_hook (source, tempvar);
7025 current_binding_level->prep_state = 1;
7029 /* ffecom_push_dummy_decls_ -- Transform dummy args, push parm decls in order
7031 Ignores STAR (alternate-return) dummies. All other get exec-transitioned
7032 (which generates their trees) and then their trees get push_parm_decl'd.
7034 The second arg is TRUE if the dummies are for a statement function, in
7035 which case lengths are not pushed for character arguments (since they are
7036 always known by both the caller and the callee, though the code allows
7037 for someday permitting CHAR*(*) stmtfunc dummies). */
7040 ffecom_push_dummy_decls_ (ffebld dummy_list, bool stmtfunc)
7047 ffecom_transform_only_dummies_ = TRUE;
7049 /* First push the parms corresponding to actual dummy "contents". */
7051 for (dumlist = dummy_list; dumlist != NULL; dumlist = ffebld_trail (dumlist))
7053 dummy = ffebld_head (dumlist);
7054 switch (ffebld_op (dummy))
7058 continue; /* Forget alternate returns. */
7063 assert (ffebld_op (dummy) == FFEBLD_opSYMTER);
7064 s = ffebld_symter (dummy);
7065 parm = ffesymbol_hook (s).decl_tree;
7066 if (parm == NULL_TREE)
7068 s = ffecom_sym_transform_ (s);
7069 parm = ffesymbol_hook (s).decl_tree;
7070 assert (parm != NULL_TREE);
7072 if (parm != error_mark_node)
7073 push_parm_decl (parm);
7076 /* Then, for CHARACTER dummies, push the parms giving their lengths. */
7078 for (dumlist = dummy_list; dumlist != NULL; dumlist = ffebld_trail (dumlist))
7080 dummy = ffebld_head (dumlist);
7081 switch (ffebld_op (dummy))
7085 continue; /* Forget alternate returns, they mean
7091 s = ffebld_symter (dummy);
7092 if (ffesymbol_basictype (s) != FFEINFO_basictypeCHARACTER)
7093 continue; /* Only looking for CHARACTER arguments. */
7094 if (stmtfunc && (ffesymbol_size (s) != FFETARGET_charactersizeNONE))
7095 continue; /* Stmtfunc arg with known size needs no
7097 if (ffesymbol_kind (s) != FFEINFO_kindENTITY)
7098 continue; /* Only looking for variables and arrays. */
7099 parm = ffesymbol_hook (s).length_tree;
7100 assert (parm != NULL_TREE);
7101 if (parm != error_mark_node)
7102 push_parm_decl (parm);
7105 ffecom_transform_only_dummies_ = FALSE;
7108 /* ffecom_start_progunit_ -- Beginning of program unit
7110 Does GNU back end stuff necessary to teach it about the start of its
7111 equivalent of a Fortran program unit. */
7114 ffecom_start_progunit_ ()
7116 ffesymbol fn = ffecom_primary_entry_;
7118 tree id; /* Identifier (name) of function. */
7119 tree type; /* Type of function. */
7120 tree result; /* Result of function. */
7121 ffeinfoBasictype bt;
7125 ffeglobalType egt = FFEGLOBAL_type;
7128 bool altentries = (ffecom_num_entrypoints_ != 0);
7131 && (ffecom_primary_entry_kind_ == FFEINFO_kindFUNCTION)
7132 && (ffecom_master_bt_ == FFEINFO_basictypeNONE);
7133 bool main_program = FALSE;
7134 int old_lineno = lineno;
7135 const char *old_input_filename = input_filename;
7137 assert (fn != NULL);
7138 assert (ffesymbol_hook (fn).decl_tree == NULL_TREE);
7140 input_filename = ffesymbol_where_filename (fn);
7141 lineno = ffesymbol_where_filelinenum (fn);
7143 switch (ffecom_primary_entry_kind_)
7145 case FFEINFO_kindPROGRAM:
7146 main_program = TRUE;
7147 gt = FFEGLOBAL_typeMAIN;
7148 bt = FFEINFO_basictypeNONE;
7149 kt = FFEINFO_kindtypeNONE;
7150 type = ffecom_tree_fun_type_void;
7155 case FFEINFO_kindBLOCKDATA:
7156 gt = FFEGLOBAL_typeBDATA;
7157 bt = FFEINFO_basictypeNONE;
7158 kt = FFEINFO_kindtypeNONE;
7159 type = ffecom_tree_fun_type_void;
7164 case FFEINFO_kindFUNCTION:
7165 gt = FFEGLOBAL_typeFUNC;
7166 egt = FFEGLOBAL_typeEXT;
7167 bt = ffesymbol_basictype (fn);
7168 kt = ffesymbol_kindtype (fn);
7169 if (bt == FFEINFO_basictypeNONE)
7171 ffeimplic_establish_symbol (fn);
7172 if (ffesymbol_funcresult (fn) != NULL)
7173 ffeimplic_establish_symbol (ffesymbol_funcresult (fn));
7174 bt = ffesymbol_basictype (fn);
7175 kt = ffesymbol_kindtype (fn);
7179 charfunc = cmplxfunc = FALSE;
7180 else if (bt == FFEINFO_basictypeCHARACTER)
7181 charfunc = TRUE, cmplxfunc = FALSE;
7182 else if ((bt == FFEINFO_basictypeCOMPLEX)
7183 && ffesymbol_is_f2c (fn)
7185 charfunc = FALSE, cmplxfunc = TRUE;
7187 charfunc = cmplxfunc = FALSE;
7189 if (multi || charfunc)
7190 type = ffecom_tree_fun_type_void;
7191 else if (ffesymbol_is_f2c (fn) && !altentries)
7192 type = ffecom_tree_fun_type[bt][kt];
7194 type = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
7196 if ((type == NULL_TREE)
7197 || (TREE_TYPE (type) == NULL_TREE))
7198 type = ffecom_tree_fun_type_void; /* _sym_exec_transition. */
7201 case FFEINFO_kindSUBROUTINE:
7202 gt = FFEGLOBAL_typeSUBR;
7203 egt = FFEGLOBAL_typeEXT;
7204 bt = FFEINFO_basictypeNONE;
7205 kt = FFEINFO_kindtypeNONE;
7206 if (ffecom_is_altreturning_)
7207 type = ffecom_tree_subr_type;
7209 type = ffecom_tree_fun_type_void;
7215 assert ("say what??" == NULL);
7217 case FFEINFO_kindANY:
7218 gt = FFEGLOBAL_typeANY;
7219 bt = FFEINFO_basictypeNONE;
7220 kt = FFEINFO_kindtypeNONE;
7221 type = error_mark_node;
7229 id = ffecom_get_invented_identifier ("__g77_masterfun_%s",
7230 ffesymbol_text (fn));
7232 #if FFETARGET_isENFORCED_MAIN
7233 else if (main_program)
7234 id = get_identifier (FFETARGET_nameENFORCED_MAIN_NAME);
7237 id = ffecom_get_external_identifier_ (fn);
7241 0, /* nested/inline */
7242 !altentries); /* TREE_PUBLIC */
7244 TREE_USED (current_function_decl) = 1; /* Avoid spurious warning if altentries. */
7247 && ((g = ffesymbol_global (fn)) != NULL)
7248 && ((ffeglobal_type (g) == gt)
7249 || (ffeglobal_type (g) == egt)))
7251 ffeglobal_set_hook (g, current_function_decl);
7254 /* Arg handling needs exec-transitioned ffesymbols to work with. But
7255 exec-transitioning needs current_function_decl to be filled in. So we
7256 do these things in two phases. */
7259 { /* 1st arg identifies which entrypoint. */
7260 ffecom_which_entrypoint_decl_
7261 = build_decl (PARM_DECL,
7262 ffecom_get_invented_identifier ("__g77_%s",
7263 "which_entrypoint"),
7265 push_parm_decl (ffecom_which_entrypoint_decl_);
7271 { /* Arg for result (return value). */
7276 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
7278 type = ffecom_tree_type[FFEINFO_basictypeCOMPLEX][kt];
7280 type = ffecom_multi_type_node_;
7282 result = ffecom_get_invented_identifier ("__g77_%s", "result");
7284 /* Make length arg _and_ enhance type info for CHAR arg itself. */
7287 length = ffecom_char_enhance_arg_ (&type, fn);
7289 length = NULL_TREE; /* Not ref'd if !charfunc. */
7291 type = build_pointer_type (type);
7292 result = build_decl (PARM_DECL, result, type);
7294 push_parm_decl (result);
7296 ffecom_multi_retval_ = result;
7298 ffecom_func_result_ = result;
7302 push_parm_decl (length);
7303 ffecom_func_length_ = length;
7307 if (ffecom_primary_entry_is_proc_)
7310 arglist = ffecom_master_arglist_;
7312 arglist = ffesymbol_dummyargs (fn);
7313 ffecom_push_dummy_decls_ (arglist, FALSE);
7316 if (TREE_CODE (current_function_decl) != ERROR_MARK)
7317 store_parm_decls (main_program ? 1 : 0);
7319 ffecom_start_compstmt ();
7320 /* Disallow temp vars at this level. */
7321 current_binding_level->prep_state = 2;
7323 lineno = old_lineno;
7324 input_filename = old_input_filename;
7326 /* This handles any symbols still untransformed, in case -g specified.
7327 This used to be done in ffecom_finish_progunit, but it turns out to
7328 be necessary to do it here so that statement functions are
7329 expanded before code. But don't bother for BLOCK DATA. */
7331 if (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA)
7332 ffesymbol_drive (ffecom_finish_symbol_transform_);
7335 /* ffecom_sym_transform_ -- Transform FFE sym into backend sym
7338 ffecom_sym_transform_(s);
7340 The ffesymbol_hook info for s is updated with appropriate backend info
7344 ffecom_sym_transform_ (ffesymbol s)
7346 tree t; /* Transformed thingy. */
7347 tree tlen; /* Length if CHAR*(*). */
7348 bool addr; /* Is t the address of the thingy? */
7349 ffeinfoBasictype bt;
7352 int old_lineno = lineno;
7353 const char *old_input_filename = input_filename;
7355 /* Must ensure special ASSIGN variables are declared at top of outermost
7356 block, else they'll end up in the innermost block when their first
7357 ASSIGN is seen, which leaves them out of scope when they're the
7358 subject of a GOTO or I/O statement.
7360 We make this variable even if -fugly-assign. Just let it go unused,
7361 in case it turns out there are cases where we really want to use this
7362 variable anyway (e.g. ASSIGN to INTEGER*2 variable). */
7364 if (! ffecom_transform_only_dummies_
7365 && ffesymbol_assigned (s)
7366 && ! ffesymbol_hook (s).assign_tree)
7367 s = ffecom_sym_transform_assign_ (s);
7369 if (ffesymbol_sfdummyparent (s) == NULL)
7371 input_filename = ffesymbol_where_filename (s);
7372 lineno = ffesymbol_where_filelinenum (s);
7376 ffesymbol sf = ffesymbol_sfdummyparent (s);
7378 input_filename = ffesymbol_where_filename (sf);
7379 lineno = ffesymbol_where_filelinenum (sf);
7382 bt = ffeinfo_basictype (ffebld_info (s));
7383 kt = ffeinfo_kindtype (ffebld_info (s));
7389 switch (ffesymbol_kind (s))
7391 case FFEINFO_kindNONE:
7392 switch (ffesymbol_where (s))
7394 case FFEINFO_whereDUMMY: /* Subroutine or function. */
7395 assert (ffecom_transform_only_dummies_);
7397 /* Before 0.4, this could be ENTITY/DUMMY, but see
7398 ffestu_sym_end_transition -- no longer true (in particular, if
7399 it could be an ENTITY, it _will_ be made one, so that
7400 possibility won't come through here). So we never make length
7401 arg for CHARACTER type. */
7403 t = build_decl (PARM_DECL,
7404 ffecom_get_identifier_ (ffesymbol_text (s)),
7405 ffecom_tree_ptr_to_subr_type);
7406 DECL_ARTIFICIAL (t) = 1;
7410 case FFEINFO_whereGLOBAL: /* Subroutine or function. */
7411 assert (!ffecom_transform_only_dummies_);
7413 if (((g = ffesymbol_global (s)) != NULL)
7414 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
7415 || (ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
7416 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
7417 && (ffeglobal_hook (g) != NULL_TREE)
7418 && ffe_is_globals ())
7420 t = ffeglobal_hook (g);
7424 t = build_decl (FUNCTION_DECL,
7425 ffecom_get_external_identifier_ (s),
7426 ffecom_tree_subr_type); /* Assume subr. */
7427 DECL_EXTERNAL (t) = 1;
7428 TREE_PUBLIC (t) = 1;
7430 t = start_decl (t, FALSE);
7431 finish_decl (t, NULL_TREE, FALSE);
7434 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
7435 || (ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
7436 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
7437 ffeglobal_set_hook (g, t);
7439 ffecom_save_tree_forever (t);
7444 assert ("NONE where unexpected" == NULL);
7446 case FFEINFO_whereANY:
7451 case FFEINFO_kindENTITY:
7452 switch (ffeinfo_where (ffesymbol_info (s)))
7455 case FFEINFO_whereCONSTANT:
7456 /* ~~Debugging info needed? */
7457 assert (!ffecom_transform_only_dummies_);
7458 t = error_mark_node; /* Shouldn't ever see this in expr. */
7461 case FFEINFO_whereLOCAL:
7462 assert (!ffecom_transform_only_dummies_);
7465 ffestorag st = ffesymbol_storage (s);
7469 && (ffestorag_size (st) == 0))
7471 t = error_mark_node;
7475 type = ffecom_type_localvar_ (s, bt, kt);
7477 if (type == error_mark_node)
7479 t = error_mark_node;
7484 && (ffestorag_parent (st) != NULL))
7485 { /* Child of EQUIVALENCE parent. */
7488 ffetargetOffset offset;
7490 est = ffestorag_parent (st);
7491 ffecom_transform_equiv_ (est);
7493 et = ffestorag_hook (est);
7494 assert (et != NULL_TREE);
7496 if (! TREE_STATIC (et))
7497 put_var_into_stack (et);
7499 offset = ffestorag_modulo (est)
7500 + ffestorag_offset (ffesymbol_storage (s))
7501 - ffestorag_offset (est);
7503 ffecom_debug_kludge_ (et, "EQUIVALENCE", s, type, offset);
7505 /* (t_type *) (((char *) &et) + offset) */
7507 t = convert (string_type_node, /* (char *) */
7508 ffecom_1 (ADDR_EXPR,
7509 build_pointer_type (TREE_TYPE (et)),
7511 t = ffecom_2 (PLUS_EXPR, TREE_TYPE (t),
7513 build_int_2 (offset, 0));
7514 t = convert (build_pointer_type (type),
7516 TREE_CONSTANT (t) = staticp (et);
7523 bool init = ffesymbol_is_init (s);
7525 t = build_decl (VAR_DECL,
7526 ffecom_get_identifier_ (ffesymbol_text (s)),
7530 || ffesymbol_namelisted (s)
7531 #ifdef FFECOM_sizeMAXSTACKITEM
7533 && (ffestorag_size (st) > FFECOM_sizeMAXSTACKITEM))
7535 || ((ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
7536 && (ffecom_primary_entry_kind_
7537 != FFEINFO_kindBLOCKDATA)
7538 && (ffesymbol_is_save (s) || ffe_is_saveall ())))
7539 TREE_STATIC (t) = !ffesymbol_attr (s, FFESYMBOL_attrADJUSTABLE);
7541 TREE_STATIC (t) = 0; /* No need to make static. */
7543 if (init || ffe_is_init_local_zero ())
7544 DECL_INITIAL (t) = error_mark_node;
7546 /* Keep -Wunused from complaining about var if it
7547 is used as sfunc arg or DATA implied-DO. */
7548 if (ffesymbol_attrs (s) & FFESYMBOL_attrsSFARG)
7549 DECL_IN_SYSTEM_HEADER (t) = 1;
7551 t = start_decl (t, FALSE);
7555 if (ffesymbol_init (s) != NULL)
7556 initexpr = ffecom_expr (ffesymbol_init (s));
7558 initexpr = ffecom_init_zero_ (t);
7560 else if (ffe_is_init_local_zero ())
7561 initexpr = ffecom_init_zero_ (t);
7563 initexpr = NULL_TREE; /* Not ref'd if !init. */
7565 finish_decl (t, initexpr, FALSE);
7567 if (st != NULL && DECL_SIZE (t) != error_mark_node)
7569 assert (TREE_CODE (DECL_SIZE_UNIT (t)) == INTEGER_CST);
7570 assert (0 == compare_tree_int (DECL_SIZE_UNIT (t),
7571 ffestorag_size (st)));
7577 case FFEINFO_whereRESULT:
7578 assert (!ffecom_transform_only_dummies_);
7580 if (bt == FFEINFO_basictypeCHARACTER)
7581 { /* Result is already in list of dummies, use
7583 t = ffecom_func_result_;
7584 tlen = ffecom_func_length_;
7588 if ((ffecom_num_entrypoints_ == 0)
7589 && (bt == FFEINFO_basictypeCOMPLEX)
7590 && (ffesymbol_is_f2c (ffecom_primary_entry_)))
7591 { /* Result is already in list of dummies, use
7593 t = ffecom_func_result_;
7597 if (ffecom_func_result_ != NULL_TREE)
7599 t = ffecom_func_result_;
7602 if ((ffecom_num_entrypoints_ != 0)
7603 && (ffecom_master_bt_ == FFEINFO_basictypeNONE))
7605 assert (ffecom_multi_retval_ != NULL_TREE);
7606 t = ffecom_1 (INDIRECT_REF, ffecom_multi_type_node_,
7607 ffecom_multi_retval_);
7608 t = ffecom_2 (COMPONENT_REF, ffecom_tree_type[bt][kt],
7609 t, ffecom_multi_fields_[bt][kt]);
7614 t = build_decl (VAR_DECL,
7615 ffecom_get_identifier_ (ffesymbol_text (s)),
7616 ffecom_tree_type[bt][kt]);
7617 TREE_STATIC (t) = 0; /* Put result on stack. */
7618 t = start_decl (t, FALSE);
7619 finish_decl (t, NULL_TREE, FALSE);
7621 ffecom_func_result_ = t;
7625 case FFEINFO_whereDUMMY:
7633 bool adjustable = FALSE; /* Conditionally adjustable? */
7635 type = ffecom_tree_type[bt][kt];
7636 if (ffesymbol_sfdummyparent (s) != NULL)
7638 if (current_function_decl == ffecom_outer_function_decl_)
7639 { /* Exec transition before sfunc
7640 context; get it later. */
7643 t = ffecom_get_identifier_ (ffesymbol_text
7644 (ffesymbol_sfdummyparent (s)));
7647 t = ffecom_get_identifier_ (ffesymbol_text (s));
7649 assert (ffecom_transform_only_dummies_);
7651 old_sizes = get_pending_sizes ();
7652 put_pending_sizes (old_sizes);
7654 if (bt == FFEINFO_basictypeCHARACTER)
7655 tlen = ffecom_char_enhance_arg_ (&type, s);
7656 type = ffecom_check_size_overflow_ (s, type, TRUE);
7658 for (dl = ffesymbol_dims (s); dl != NULL; dl = ffebld_trail (dl))
7660 if (type == error_mark_node)
7663 dim = ffebld_head (dl);
7664 assert (ffebld_op (dim) == FFEBLD_opBOUNDS);
7665 if ((ffebld_left (dim) == NULL) || ffecom_doing_entry_)
7666 low = ffecom_integer_one_node;
7668 low = ffecom_expr (ffebld_left (dim));
7669 assert (ffebld_right (dim) != NULL);
7670 if ((ffebld_op (ffebld_right (dim)) == FFEBLD_opSTAR)
7671 || ffecom_doing_entry_)
7673 /* Used to just do high=low. But for ffecom_tree_
7674 canonize_ref_, it probably is important to correctly
7675 assess the size. E.g. given COMPLEX C(*),CFUNC and
7676 C(2)=CFUNC(C), overlap can happen, while it can't
7677 for, say, C(1)=CFUNC(C(2)). */
7678 /* Even more recently used to set to INT_MAX, but that
7679 broke when some overflow checking went into the back
7680 end. Now we just leave the upper bound unspecified. */
7684 high = ffecom_expr (ffebld_right (dim));
7686 /* Determine whether array is conditionally adjustable,
7687 to decide whether back-end magic is needed.
7689 Normally the front end uses the back-end function
7690 variable_size to wrap SAVE_EXPR's around expressions
7691 affecting the size/shape of an array so that the
7692 size/shape info doesn't change during execution
7693 of the compiled code even though variables and
7694 functions referenced in those expressions might.
7696 variable_size also makes sure those saved expressions
7697 get evaluated immediately upon entry to the
7698 compiled procedure -- the front end normally doesn't
7699 have to worry about that.
7701 However, there is a problem with this that affects
7702 g77's implementation of entry points, and that is
7703 that it is _not_ true that each invocation of the
7704 compiled procedure is permitted to evaluate
7705 array size/shape info -- because it is possible
7706 that, for some invocations, that info is invalid (in
7707 which case it is "promised" -- i.e. a violation of
7708 the Fortran standard -- that the compiled code
7709 won't reference the array or its size/shape
7710 during that particular invocation).
7712 To phrase this in C terms, consider this gcc function:
7714 void foo (int *n, float (*a)[*n])
7716 // a is "pointer to array ...", fyi.
7719 Suppose that, for some invocations, it is permitted
7720 for a caller of foo to do this:
7724 Now the _written_ code for foo can take such a call
7725 into account by either testing explicitly for whether
7726 (a == NULL) || (n == NULL) -- presumably it is
7727 not permitted to reference *a in various fashions
7728 if (n == NULL) I suppose -- or it can avoid it by
7729 looking at other info (other arguments, static/global
7732 However, this won't work in gcc 2.5.8 because it'll
7733 automatically emit the code to save the "*n"
7734 expression, which'll yield a NULL dereference for
7735 the "foo (NULL, NULL)" call, something the code
7736 for foo cannot prevent.
7738 g77 definitely needs to avoid executing such
7739 code anytime the pointer to the adjustable array
7740 is NULL, because even if its bounds expressions
7741 don't have any references to possible "absent"
7742 variables like "*n" -- say all variable references
7743 are to COMMON variables, i.e. global (though in C,
7744 local static could actually make sense) -- the
7745 expressions could yield other run-time problems
7746 for allowably "dead" values in those variables.
7748 For example, let's consider a more complicated
7754 void foo (float (*a)[i/j])
7759 The above is (essentially) quite valid for Fortran
7760 but, again, for a call like "foo (NULL);", it is
7761 permitted for i and j to be undefined when the
7762 call is made. If j happened to be zero, for
7763 example, emitting the code to evaluate "i/j"
7764 could result in a run-time error.
7766 Offhand, though I don't have my F77 or F90
7767 standards handy, it might even be valid for a
7768 bounds expression to contain a function reference,
7769 in which case I doubt it is permitted for an
7770 implementation to invoke that function in the
7771 Fortran case involved here (invocation of an
7772 alternate ENTRY point that doesn't have the adjustable
7773 array as one of its arguments).
7775 So, the code that the compiler would normally emit
7776 to preevaluate the size/shape info for an
7777 adjustable array _must not_ be executed at run time
7778 in certain cases. Specifically, for Fortran,
7779 the case is when the pointer to the adjustable
7780 array == NULL. (For gnu-ish C, it might be nice
7781 for the source code itself to specify an expression
7782 that, if TRUE, inhibits execution of the code. Or
7783 reverse the sense for elegance.)
7785 (Note that g77 could use a different test than NULL,
7786 actually, since it happens to always pass an
7787 integer to the called function that specifies which
7788 entry point is being invoked. Hmm, this might
7789 solve the next problem.)
7791 One way a user could, I suppose, write "foo" so
7792 it works is to insert COND_EXPR's for the
7793 size/shape info so the dangerous stuff isn't
7794 actually done, as in:
7796 void foo (int *n, float (*a)[(a == NULL) ? 0 : *n])
7801 The next problem is that the front end needs to
7802 be able to tell the back end about the array's
7803 decl _before_ it tells it about the conditional
7804 expression to inhibit evaluation of size/shape info,
7807 To solve this, the front end needs to be able
7808 to give the back end the expression to inhibit
7809 generation of the preevaluation code _after_
7810 it makes the decl for the adjustable array.
7812 Until then, the above example using the COND_EXPR
7813 doesn't pass muster with gcc because the "(a == NULL)"
7814 part has a reference to "a", which is still
7815 undefined at that point.
7817 g77 will therefore use a different mechanism in the
7821 && ((TREE_CODE (low) != INTEGER_CST)
7822 || (high && TREE_CODE (high) != INTEGER_CST)))
7825 #if 0 /* Old approach -- see below. */
7826 if (TREE_CODE (low) != INTEGER_CST)
7827 low = ffecom_3 (COND_EXPR, integer_type_node,
7828 ffecom_adjarray_passed_ (s),
7830 ffecom_integer_zero_node);
7832 if (high && TREE_CODE (high) != INTEGER_CST)
7833 high = ffecom_3 (COND_EXPR, integer_type_node,
7834 ffecom_adjarray_passed_ (s),
7836 ffecom_integer_zero_node);
7839 /* ~~~gcc/stor-layout.c (layout_type) should do this,
7840 probably. Fixes 950302-1.f. */
7842 if (TREE_CODE (low) != INTEGER_CST)
7843 low = variable_size (low);
7845 /* ~~~Similarly, this fixes dumb0.f. The C front end
7846 does this, which is why dumb0.c would work. */
7848 if (high && TREE_CODE (high) != INTEGER_CST)
7849 high = variable_size (high);
7854 build_range_type (ffecom_integer_type_node,
7856 type = ffecom_check_size_overflow_ (s, type, TRUE);
7859 if (type == error_mark_node)
7861 t = error_mark_node;
7865 if ((ffesymbol_sfdummyparent (s) == NULL)
7866 || (ffesymbol_basictype (s) == FFEINFO_basictypeCHARACTER))
7868 type = build_pointer_type (type);
7872 t = build_decl (PARM_DECL, t, type);
7873 DECL_ARTIFICIAL (t) = 1;
7875 /* If this arg is present in every entry point's list of
7876 dummy args, then we're done. */
7878 if (ffesymbol_numentries (s)
7879 == (ffecom_num_entrypoints_ + 1))
7884 /* If variable_size in stor-layout has been called during
7885 the above, then get_pending_sizes should have the
7886 yet-to-be-evaluated saved expressions pending.
7887 Make the whole lot of them get emitted, conditionally
7888 on whether the array decl ("t" above) is not NULL. */
7891 tree sizes = get_pending_sizes ();
7896 tem = TREE_CHAIN (tem))
7898 tree temv = TREE_VALUE (tem);
7904 = ffecom_2 (COMPOUND_EXPR,
7913 = ffecom_3 (COND_EXPR,
7920 convert (TREE_TYPE (sizes),
7921 integer_zero_node));
7922 sizes = ffecom_save_tree (sizes);
7925 = tree_cons (NULL_TREE, sizes, tem);
7929 put_pending_sizes (sizes);
7935 && (ffesymbol_numentries (s)
7936 != ffecom_num_entrypoints_ + 1))
7938 = ffecom_2 (NE_EXPR, integer_type_node,
7944 && (ffesymbol_numentries (s)
7945 != ffecom_num_entrypoints_ + 1))
7947 ffebad_start (FFEBAD_MISSING_ADJARRAY_UNSUPPORTED);
7948 ffebad_here (0, ffesymbol_where_line (s),
7949 ffesymbol_where_column (s));
7950 ffebad_string (ffesymbol_text (s));
7959 case FFEINFO_whereCOMMON:
7964 ffestorag st = ffesymbol_storage (s);
7967 cs = ffesymbol_common (s); /* The COMMON area itself. */
7968 if (st != NULL) /* Else not laid out. */
7970 ffecom_transform_common_ (cs);
7971 st = ffesymbol_storage (s);
7974 type = ffecom_type_localvar_ (s, bt, kt);
7976 cg = ffesymbol_global (cs); /* The global COMMON info. */
7978 || (ffeglobal_type (cg) != FFEGLOBAL_typeCOMMON))
7981 ct = ffeglobal_hook (cg); /* The common area's tree. */
7983 if ((ct == NULL_TREE)
7985 || (type == error_mark_node))
7986 t = error_mark_node;
7989 ffetargetOffset offset;
7992 cst = ffestorag_parent (st);
7993 assert (cst == ffesymbol_storage (cs));
7995 offset = ffestorag_modulo (cst)
7996 + ffestorag_offset (st)
7997 - ffestorag_offset (cst);
7999 ffecom_debug_kludge_ (ct, "COMMON", s, type, offset);
8001 /* (t_type *) (((char *) &ct) + offset) */
8003 t = convert (string_type_node, /* (char *) */
8004 ffecom_1 (ADDR_EXPR,
8005 build_pointer_type (TREE_TYPE (ct)),
8007 t = ffecom_2 (PLUS_EXPR, TREE_TYPE (t),
8009 build_int_2 (offset, 0));
8010 t = convert (build_pointer_type (type),
8012 TREE_CONSTANT (t) = 1;
8019 case FFEINFO_whereIMMEDIATE:
8020 case FFEINFO_whereGLOBAL:
8021 case FFEINFO_whereFLEETING:
8022 case FFEINFO_whereFLEETING_CADDR:
8023 case FFEINFO_whereFLEETING_IADDR:
8024 case FFEINFO_whereINTRINSIC:
8025 case FFEINFO_whereCONSTANT_SUBOBJECT:
8027 assert ("ENTITY where unheard of" == NULL);
8029 case FFEINFO_whereANY:
8030 t = error_mark_node;
8035 case FFEINFO_kindFUNCTION:
8036 switch (ffeinfo_where (ffesymbol_info (s)))
8038 case FFEINFO_whereLOCAL: /* Me. */
8039 assert (!ffecom_transform_only_dummies_);
8040 t = current_function_decl;
8043 case FFEINFO_whereGLOBAL:
8044 assert (!ffecom_transform_only_dummies_);
8046 if (((g = ffesymbol_global (s)) != NULL)
8047 && ((ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
8048 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
8049 && (ffeglobal_hook (g) != NULL_TREE)
8050 && ffe_is_globals ())
8052 t = ffeglobal_hook (g);
8056 if (ffesymbol_is_f2c (s)
8057 && (ffesymbol_where (s) != FFEINFO_whereCONSTANT))
8058 t = ffecom_tree_fun_type[bt][kt];
8060 t = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
8062 t = build_decl (FUNCTION_DECL,
8063 ffecom_get_external_identifier_ (s),
8065 DECL_EXTERNAL (t) = 1;
8066 TREE_PUBLIC (t) = 1;
8068 t = start_decl (t, FALSE);
8069 finish_decl (t, NULL_TREE, FALSE);
8072 && ((ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
8073 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
8074 ffeglobal_set_hook (g, t);
8076 ffecom_save_tree_forever (t);
8080 case FFEINFO_whereDUMMY:
8081 assert (ffecom_transform_only_dummies_);
8083 if (ffesymbol_is_f2c (s)
8084 && (ffesymbol_where (s) != FFEINFO_whereCONSTANT))
8085 t = ffecom_tree_ptr_to_fun_type[bt][kt];
8087 t = build_pointer_type
8088 (build_function_type (ffecom_tree_type[bt][kt], NULL_TREE));
8090 t = build_decl (PARM_DECL,
8091 ffecom_get_identifier_ (ffesymbol_text (s)),
8093 DECL_ARTIFICIAL (t) = 1;
8097 case FFEINFO_whereCONSTANT: /* Statement function. */
8098 assert (!ffecom_transform_only_dummies_);
8099 t = ffecom_gen_sfuncdef_ (s, bt, kt);
8102 case FFEINFO_whereINTRINSIC:
8103 assert (!ffecom_transform_only_dummies_);
8104 break; /* Let actual references generate their
8108 assert ("FUNCTION where unheard of" == NULL);
8110 case FFEINFO_whereANY:
8111 t = error_mark_node;
8116 case FFEINFO_kindSUBROUTINE:
8117 switch (ffeinfo_where (ffesymbol_info (s)))
8119 case FFEINFO_whereLOCAL: /* Me. */
8120 assert (!ffecom_transform_only_dummies_);
8121 t = current_function_decl;
8124 case FFEINFO_whereGLOBAL:
8125 assert (!ffecom_transform_only_dummies_);
8127 if (((g = ffesymbol_global (s)) != NULL)
8128 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
8129 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
8130 && (ffeglobal_hook (g) != NULL_TREE)
8131 && ffe_is_globals ())
8133 t = ffeglobal_hook (g);
8137 t = build_decl (FUNCTION_DECL,
8138 ffecom_get_external_identifier_ (s),
8139 ffecom_tree_subr_type);
8140 DECL_EXTERNAL (t) = 1;
8141 TREE_PUBLIC (t) = 1;
8143 t = start_decl (t, FALSE);
8144 finish_decl (t, NULL_TREE, FALSE);
8147 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
8148 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
8149 ffeglobal_set_hook (g, t);
8151 ffecom_save_tree_forever (t);
8155 case FFEINFO_whereDUMMY:
8156 assert (ffecom_transform_only_dummies_);
8158 t = build_decl (PARM_DECL,
8159 ffecom_get_identifier_ (ffesymbol_text (s)),
8160 ffecom_tree_ptr_to_subr_type);
8161 DECL_ARTIFICIAL (t) = 1;
8165 case FFEINFO_whereINTRINSIC:
8166 assert (!ffecom_transform_only_dummies_);
8167 break; /* Let actual references generate their
8171 assert ("SUBROUTINE where unheard of" == NULL);
8173 case FFEINFO_whereANY:
8174 t = error_mark_node;
8179 case FFEINFO_kindPROGRAM:
8180 switch (ffeinfo_where (ffesymbol_info (s)))
8182 case FFEINFO_whereLOCAL: /* Me. */
8183 assert (!ffecom_transform_only_dummies_);
8184 t = current_function_decl;
8187 case FFEINFO_whereCOMMON:
8188 case FFEINFO_whereDUMMY:
8189 case FFEINFO_whereGLOBAL:
8190 case FFEINFO_whereRESULT:
8191 case FFEINFO_whereFLEETING:
8192 case FFEINFO_whereFLEETING_CADDR:
8193 case FFEINFO_whereFLEETING_IADDR:
8194 case FFEINFO_whereIMMEDIATE:
8195 case FFEINFO_whereINTRINSIC:
8196 case FFEINFO_whereCONSTANT:
8197 case FFEINFO_whereCONSTANT_SUBOBJECT:
8199 assert ("PROGRAM where unheard of" == NULL);
8201 case FFEINFO_whereANY:
8202 t = error_mark_node;
8207 case FFEINFO_kindBLOCKDATA:
8208 switch (ffeinfo_where (ffesymbol_info (s)))
8210 case FFEINFO_whereLOCAL: /* Me. */
8211 assert (!ffecom_transform_only_dummies_);
8212 t = current_function_decl;
8215 case FFEINFO_whereGLOBAL:
8216 assert (!ffecom_transform_only_dummies_);
8218 t = build_decl (FUNCTION_DECL,
8219 ffecom_get_external_identifier_ (s),
8220 ffecom_tree_blockdata_type);
8221 DECL_EXTERNAL (t) = 1;
8222 TREE_PUBLIC (t) = 1;
8224 t = start_decl (t, FALSE);
8225 finish_decl (t, NULL_TREE, FALSE);
8227 ffecom_save_tree_forever (t);
8231 case FFEINFO_whereCOMMON:
8232 case FFEINFO_whereDUMMY:
8233 case FFEINFO_whereRESULT:
8234 case FFEINFO_whereFLEETING:
8235 case FFEINFO_whereFLEETING_CADDR:
8236 case FFEINFO_whereFLEETING_IADDR:
8237 case FFEINFO_whereIMMEDIATE:
8238 case FFEINFO_whereINTRINSIC:
8239 case FFEINFO_whereCONSTANT:
8240 case FFEINFO_whereCONSTANT_SUBOBJECT:
8242 assert ("BLOCKDATA where unheard of" == NULL);
8244 case FFEINFO_whereANY:
8245 t = error_mark_node;
8250 case FFEINFO_kindCOMMON:
8251 switch (ffeinfo_where (ffesymbol_info (s)))
8253 case FFEINFO_whereLOCAL:
8254 assert (!ffecom_transform_only_dummies_);
8255 ffecom_transform_common_ (s);
8258 case FFEINFO_whereNONE:
8259 case FFEINFO_whereCOMMON:
8260 case FFEINFO_whereDUMMY:
8261 case FFEINFO_whereGLOBAL:
8262 case FFEINFO_whereRESULT:
8263 case FFEINFO_whereFLEETING:
8264 case FFEINFO_whereFLEETING_CADDR:
8265 case FFEINFO_whereFLEETING_IADDR:
8266 case FFEINFO_whereIMMEDIATE:
8267 case FFEINFO_whereINTRINSIC:
8268 case FFEINFO_whereCONSTANT:
8269 case FFEINFO_whereCONSTANT_SUBOBJECT:
8271 assert ("COMMON where unheard of" == NULL);
8273 case FFEINFO_whereANY:
8274 t = error_mark_node;
8279 case FFEINFO_kindCONSTRUCT:
8280 switch (ffeinfo_where (ffesymbol_info (s)))
8282 case FFEINFO_whereLOCAL:
8283 assert (!ffecom_transform_only_dummies_);
8286 case FFEINFO_whereNONE:
8287 case FFEINFO_whereCOMMON:
8288 case FFEINFO_whereDUMMY:
8289 case FFEINFO_whereGLOBAL:
8290 case FFEINFO_whereRESULT:
8291 case FFEINFO_whereFLEETING:
8292 case FFEINFO_whereFLEETING_CADDR:
8293 case FFEINFO_whereFLEETING_IADDR:
8294 case FFEINFO_whereIMMEDIATE:
8295 case FFEINFO_whereINTRINSIC:
8296 case FFEINFO_whereCONSTANT:
8297 case FFEINFO_whereCONSTANT_SUBOBJECT:
8299 assert ("CONSTRUCT where unheard of" == NULL);
8301 case FFEINFO_whereANY:
8302 t = error_mark_node;
8307 case FFEINFO_kindNAMELIST:
8308 switch (ffeinfo_where (ffesymbol_info (s)))
8310 case FFEINFO_whereLOCAL:
8311 assert (!ffecom_transform_only_dummies_);
8312 t = ffecom_transform_namelist_ (s);
8315 case FFEINFO_whereNONE:
8316 case FFEINFO_whereCOMMON:
8317 case FFEINFO_whereDUMMY:
8318 case FFEINFO_whereGLOBAL:
8319 case FFEINFO_whereRESULT:
8320 case FFEINFO_whereFLEETING:
8321 case FFEINFO_whereFLEETING_CADDR:
8322 case FFEINFO_whereFLEETING_IADDR:
8323 case FFEINFO_whereIMMEDIATE:
8324 case FFEINFO_whereINTRINSIC:
8325 case FFEINFO_whereCONSTANT:
8326 case FFEINFO_whereCONSTANT_SUBOBJECT:
8328 assert ("NAMELIST where unheard of" == NULL);
8330 case FFEINFO_whereANY:
8331 t = error_mark_node;
8337 assert ("kind unheard of" == NULL);
8339 case FFEINFO_kindANY:
8340 t = error_mark_node;
8344 ffesymbol_hook (s).decl_tree = t;
8345 ffesymbol_hook (s).length_tree = tlen;
8346 ffesymbol_hook (s).addr = addr;
8348 lineno = old_lineno;
8349 input_filename = old_input_filename;
8354 /* Transform into ASSIGNable symbol.
8356 Symbol has already been transformed, but for whatever reason, the
8357 resulting decl_tree has been deemed not usable for an ASSIGN target.
8358 (E.g. it isn't wide enough to hold a pointer.) So, here we invent
8359 another local symbol of type void * and stuff that in the assign_tree
8360 argument. The F77/F90 standards allow this implementation. */
8363 ffecom_sym_transform_assign_ (ffesymbol s)
8365 tree t; /* Transformed thingy. */
8366 int old_lineno = lineno;
8367 const char *old_input_filename = input_filename;
8369 if (ffesymbol_sfdummyparent (s) == NULL)
8371 input_filename = ffesymbol_where_filename (s);
8372 lineno = ffesymbol_where_filelinenum (s);
8376 ffesymbol sf = ffesymbol_sfdummyparent (s);
8378 input_filename = ffesymbol_where_filename (sf);
8379 lineno = ffesymbol_where_filelinenum (sf);
8382 assert (!ffecom_transform_only_dummies_);
8384 t = build_decl (VAR_DECL,
8385 ffecom_get_invented_identifier ("__g77_ASSIGN_%s",
8386 ffesymbol_text (s)),
8387 TREE_TYPE (null_pointer_node));
8389 switch (ffesymbol_where (s))
8391 case FFEINFO_whereLOCAL:
8392 /* Unlike for regular vars, SAVE status is easy to determine for
8393 ASSIGNed vars, since there's no initialization, there's no
8394 effective storage association (so "SAVE J" does not apply to
8395 K even given "EQUIVALENCE (J,K)"), there's no size issue
8396 to worry about, etc. */
8397 if ((ffesymbol_is_save (s) || ffe_is_saveall ())
8398 && (ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
8399 && (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA))
8400 TREE_STATIC (t) = 1; /* SAVEd in proc, make static. */
8402 TREE_STATIC (t) = 0; /* No need to make static. */
8405 case FFEINFO_whereCOMMON:
8406 TREE_STATIC (t) = 1; /* Assume COMMONs always SAVEd. */
8409 case FFEINFO_whereDUMMY:
8410 /* Note that twinning a DUMMY means the caller won't see
8411 the ASSIGNed value. But both F77 and F90 allow implementations
8412 to do this, i.e. disallow Fortran code that would try and
8413 take advantage of actually putting a label into a variable
8414 via a dummy argument (or any other storage association, for
8416 TREE_STATIC (t) = 0;
8420 TREE_STATIC (t) = 0;
8424 t = start_decl (t, FALSE);
8425 finish_decl (t, NULL_TREE, FALSE);
8427 ffesymbol_hook (s).assign_tree = t;
8429 lineno = old_lineno;
8430 input_filename = old_input_filename;
8435 /* Implement COMMON area in back end.
8437 Because COMMON-based variables can be referenced in the dimension
8438 expressions of dummy (adjustable) arrays, and because dummies
8439 (in the gcc back end) need to be put in the outer binding level
8440 of a function (which has two binding levels, the outer holding
8441 the dummies and the inner holding the other vars), special care
8442 must be taken to handle COMMON areas.
8444 The current strategy is basically to always tell the back end about
8445 the COMMON area as a top-level external reference to just a block
8446 of storage of the master type of that area (e.g. integer, real,
8447 character, whatever -- not a structure). As a distinct action,
8448 if initial values are provided, tell the back end about the area
8449 as a top-level non-external (initialized) area and remember not to
8450 allow further initialization or expansion of the area. Meanwhile,
8451 if no initialization happens at all, tell the back end about
8452 the largest size we've seen declared so the space does get reserved.
8453 (This function doesn't handle all that stuff, but it does some
8454 of the important things.)
8456 Meanwhile, for COMMON variables themselves, just keep creating
8457 references like *((float *) (&common_area + offset)) each time
8458 we reference the variable. In other words, don't make a VAR_DECL
8459 or any kind of component reference (like we used to do before 0.4),
8460 though we might do that as well just for debugging purposes (and
8461 stuff the rtl with the appropriate offset expression). */
8464 ffecom_transform_common_ (ffesymbol s)
8466 ffestorag st = ffesymbol_storage (s);
8467 ffeglobal g = ffesymbol_global (s);
8472 bool is_init = ffestorag_is_init (st);
8474 assert (st != NULL);
8477 || (ffeglobal_type (g) != FFEGLOBAL_typeCOMMON))
8480 /* First update the size of the area in global terms. */
8482 ffeglobal_size_common (s, ffestorag_size (st));
8484 if (!ffeglobal_common_init (g))
8485 is_init = FALSE; /* No explicit init, don't let erroneous joins init. */
8487 cbt = ffeglobal_hook (g);
8489 /* If we already have declared this common block for a previous program
8490 unit, and either we already initialized it or we don't have new
8491 initialization for it, just return what we have without changing it. */
8493 if ((cbt != NULL_TREE)
8495 || !DECL_EXTERNAL (cbt)))
8497 if (st->hook == NULL) ffestorag_set_hook (st, cbt);
8501 /* Process inits. */
8505 if (ffestorag_init (st) != NULL)
8509 /* Set the padding for the expression, so ffecom_expr
8510 knows to insert that many zeros. */
8511 switch (ffebld_op (sexp = ffestorag_init (st)))
8513 case FFEBLD_opCONTER:
8514 ffebld_conter_set_pad (sexp, ffestorag_modulo (st));
8517 case FFEBLD_opARRTER:
8518 ffebld_arrter_set_pad (sexp, ffestorag_modulo (st));
8521 case FFEBLD_opACCTER:
8522 ffebld_accter_set_pad (sexp, ffestorag_modulo (st));
8526 assert ("bad op for cmn init (pad)" == NULL);
8530 init = ffecom_expr (sexp);
8531 if (init == error_mark_node)
8532 { /* Hopefully the back end complained! */
8534 if (cbt != NULL_TREE)
8539 init = error_mark_node;
8544 /* cbtype must be permanently allocated! */
8546 /* Allocate the MAX of the areas so far, seen filewide. */
8547 high = build_int_2 ((ffeglobal_common_size (g)
8548 + ffeglobal_common_pad (g)) - 1, 0);
8549 TREE_TYPE (high) = ffecom_integer_type_node;
8552 cbtype = build_array_type (char_type_node,
8553 build_range_type (integer_type_node,
8557 cbtype = build_array_type (char_type_node, NULL_TREE);
8559 if (cbt == NULL_TREE)
8562 = build_decl (VAR_DECL,
8563 ffecom_get_external_identifier_ (s),
8565 TREE_STATIC (cbt) = 1;
8566 TREE_PUBLIC (cbt) = 1;
8571 TREE_TYPE (cbt) = cbtype;
8573 DECL_EXTERNAL (cbt) = init ? 0 : 1;
8574 DECL_INITIAL (cbt) = init ? error_mark_node : NULL_TREE;
8576 cbt = start_decl (cbt, TRUE);
8577 if (ffeglobal_hook (g) != NULL)
8578 assert (cbt == ffeglobal_hook (g));
8580 assert (!init || !DECL_EXTERNAL (cbt));
8582 /* Make sure that any type can live in COMMON and be referenced
8583 without getting a bus error. We could pick the most restrictive
8584 alignment of all entities actually placed in the COMMON, but
8585 this seems easy enough. */
8587 DECL_ALIGN (cbt) = BIGGEST_ALIGNMENT;
8588 DECL_USER_ALIGN (cbt) = 0;
8590 if (is_init && (ffestorag_init (st) == NULL))
8591 init = ffecom_init_zero_ (cbt);
8593 finish_decl (cbt, init, TRUE);
8596 ffestorag_set_init (st, ffebld_new_any ());
8600 assert (DECL_SIZE_UNIT (cbt) != NULL_TREE);
8601 assert (TREE_CODE (DECL_SIZE_UNIT (cbt)) == INTEGER_CST);
8602 assert (0 == compare_tree_int (DECL_SIZE_UNIT (cbt),
8603 (ffeglobal_common_size (g)
8604 + ffeglobal_common_pad (g))));
8607 ffeglobal_set_hook (g, cbt);
8609 ffestorag_set_hook (st, cbt);
8611 ffecom_save_tree_forever (cbt);
8614 /* Make master area for local EQUIVALENCE. */
8617 ffecom_transform_equiv_ (ffestorag eqst)
8623 bool is_init = ffestorag_is_init (eqst);
8625 assert (eqst != NULL);
8627 eqt = ffestorag_hook (eqst);
8629 if (eqt != NULL_TREE)
8632 /* Process inits. */
8636 if (ffestorag_init (eqst) != NULL)
8640 /* Set the padding for the expression, so ffecom_expr
8641 knows to insert that many zeros. */
8642 switch (ffebld_op (sexp = ffestorag_init (eqst)))
8644 case FFEBLD_opCONTER:
8645 ffebld_conter_set_pad (sexp, ffestorag_modulo (eqst));
8648 case FFEBLD_opARRTER:
8649 ffebld_arrter_set_pad (sexp, ffestorag_modulo (eqst));
8652 case FFEBLD_opACCTER:
8653 ffebld_accter_set_pad (sexp, ffestorag_modulo (eqst));
8657 assert ("bad op for eqv init (pad)" == NULL);
8661 init = ffecom_expr (sexp);
8662 if (init == error_mark_node)
8663 init = NULL_TREE; /* Hopefully the back end complained! */
8666 init = error_mark_node;
8668 else if (ffe_is_init_local_zero ())
8669 init = error_mark_node;
8673 ffecom_member_namelisted_ = FALSE;
8674 ffestorag_drive (ffestorag_list_equivs (eqst),
8675 &ffecom_member_phase1_,
8678 high = build_int_2 ((ffestorag_size (eqst)
8679 + ffestorag_modulo (eqst)) - 1, 0);
8680 TREE_TYPE (high) = ffecom_integer_type_node;
8682 eqtype = build_array_type (char_type_node,
8683 build_range_type (ffecom_integer_type_node,
8684 ffecom_integer_zero_node,
8687 eqt = build_decl (VAR_DECL,
8688 ffecom_get_invented_identifier ("__g77_equiv_%s",
8690 (ffestorag_symbol (eqst))),
8692 DECL_EXTERNAL (eqt) = 0;
8694 || ffecom_member_namelisted_
8695 #ifdef FFECOM_sizeMAXSTACKITEM
8696 || (ffestorag_size (eqst) > FFECOM_sizeMAXSTACKITEM)
8698 || ((ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
8699 && (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA)
8700 && (ffestorag_is_save (eqst) || ffe_is_saveall ())))
8701 TREE_STATIC (eqt) = 1;
8703 TREE_STATIC (eqt) = 0;
8704 TREE_PUBLIC (eqt) = 0;
8705 TREE_ADDRESSABLE (eqt) = 1; /* Ensure non-register allocation */
8706 DECL_CONTEXT (eqt) = current_function_decl;
8708 DECL_INITIAL (eqt) = error_mark_node;
8710 DECL_INITIAL (eqt) = NULL_TREE;
8712 eqt = start_decl (eqt, FALSE);
8714 /* Make sure that any type can live in EQUIVALENCE and be referenced
8715 without getting a bus error. We could pick the most restrictive
8716 alignment of all entities actually placed in the EQUIVALENCE, but
8717 this seems easy enough. */
8719 DECL_ALIGN (eqt) = BIGGEST_ALIGNMENT;
8720 DECL_USER_ALIGN (eqt) = 0;
8722 if ((!is_init && ffe_is_init_local_zero ())
8723 || (is_init && (ffestorag_init (eqst) == NULL)))
8724 init = ffecom_init_zero_ (eqt);
8726 finish_decl (eqt, init, FALSE);
8729 ffestorag_set_init (eqst, ffebld_new_any ());
8732 assert (TREE_CODE (DECL_SIZE_UNIT (eqt)) == INTEGER_CST);
8733 assert (0 == compare_tree_int (DECL_SIZE_UNIT (eqt),
8734 (ffestorag_size (eqst)
8735 + ffestorag_modulo (eqst))));
8738 ffestorag_set_hook (eqst, eqt);
8740 ffestorag_drive (ffestorag_list_equivs (eqst),
8741 &ffecom_member_phase2_,
8745 /* Implement NAMELIST in back end. See f2c/format.c for more info. */
8748 ffecom_transform_namelist_ (ffesymbol s)
8751 tree nmltype = ffecom_type_namelist_ ();
8759 static int mynumber = 0;
8761 nmlt = build_decl (VAR_DECL,
8762 ffecom_get_invented_identifier ("__g77_namelist_%d",
8765 TREE_STATIC (nmlt) = 1;
8766 DECL_INITIAL (nmlt) = error_mark_node;
8768 nmlt = start_decl (nmlt, FALSE);
8770 /* Process inits. */
8772 i = strlen (ffesymbol_text (s));
8774 high = build_int_2 (i, 0);
8775 TREE_TYPE (high) = ffecom_f2c_ftnlen_type_node;
8777 nameinit = ffecom_build_f2c_string_ (i + 1,
8778 ffesymbol_text (s));
8779 TREE_TYPE (nameinit)
8780 = build_type_variant
8783 build_range_type (ffecom_f2c_ftnlen_type_node,
8784 ffecom_f2c_ftnlen_one_node,
8787 TREE_CONSTANT (nameinit) = 1;
8788 TREE_STATIC (nameinit) = 1;
8789 nameinit = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (nameinit)),
8792 varsinit = ffecom_vardesc_array_ (s);
8793 varsinit = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (varsinit)),
8795 TREE_CONSTANT (varsinit) = 1;
8796 TREE_STATIC (varsinit) = 1;
8801 for (i = 0, b = ffesymbol_namelist (s); b != NULL; b = ffebld_trail (b))
8804 nvarsinit = build_int_2 (i, 0);
8805 TREE_TYPE (nvarsinit) = integer_type_node;
8806 TREE_CONSTANT (nvarsinit) = 1;
8807 TREE_STATIC (nvarsinit) = 1;
8809 nmlinits = build_tree_list ((field = TYPE_FIELDS (nmltype)), nameinit);
8810 TREE_CHAIN (nmlinits) = build_tree_list ((field = TREE_CHAIN (field)),
8812 TREE_CHAIN (TREE_CHAIN (nmlinits))
8813 = build_tree_list ((field = TREE_CHAIN (field)), nvarsinit);
8815 nmlinits = build (CONSTRUCTOR, nmltype, NULL_TREE, nmlinits);
8816 TREE_CONSTANT (nmlinits) = 1;
8817 TREE_STATIC (nmlinits) = 1;
8819 finish_decl (nmlt, nmlinits, FALSE);
8821 nmlt = ffecom_1 (ADDR_EXPR, build_pointer_type (nmltype), nmlt);
8826 /* A subroutine of ffecom_tree_canonize_ref_. The incoming tree is
8827 analyzed on the assumption it is calculating a pointer to be
8828 indirected through. It must return the proper decl and offset,
8829 taking into account different units of measurements for offsets. */
8832 ffecom_tree_canonize_ptr_ (tree *decl, tree *offset,
8835 switch (TREE_CODE (t))
8839 case NON_LVALUE_EXPR:
8840 ffecom_tree_canonize_ptr_ (decl, offset, TREE_OPERAND (t, 0));
8844 ffecom_tree_canonize_ptr_ (decl, offset, TREE_OPERAND (t, 0));
8845 if ((*decl == NULL_TREE)
8846 || (*decl == error_mark_node))
8849 if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST)
8851 /* An offset into COMMON. */
8852 *offset = fold (build (PLUS_EXPR, TREE_TYPE (*offset),
8853 *offset, TREE_OPERAND (t, 1)));
8854 /* Convert offset (presumably in bytes) into canonical units
8855 (presumably bits). */
8856 *offset = size_binop (MULT_EXPR,
8857 convert (bitsizetype, *offset),
8858 TYPE_SIZE (TREE_TYPE (TREE_TYPE (t))));
8861 /* Not a COMMON reference, so an unrecognized pattern. */
8862 *decl = error_mark_node;
8867 *offset = bitsize_zero_node;
8871 if (TREE_CODE (TREE_OPERAND (t, 0)) == VAR_DECL)
8873 /* A reference to COMMON. */
8874 *decl = TREE_OPERAND (t, 0);
8875 *offset = bitsize_zero_node;
8880 /* Not a COMMON reference, so an unrecognized pattern. */
8881 *decl = error_mark_node;
8886 /* Given a tree that is possibly intended for use as an lvalue, return
8887 information representing a canonical view of that tree as a decl, an
8888 offset into that decl, and a size for the lvalue.
8890 If there's no applicable decl, NULL_TREE is returned for the decl,
8891 and the other fields are left undefined.
8893 If the tree doesn't fit the recognizable forms, an ERROR_MARK node
8894 is returned for the decl, and the other fields are left undefined.
8896 Otherwise, the decl returned currently is either a VAR_DECL or a
8899 The offset returned is always valid, but of course not necessarily
8900 a constant, and not necessarily converted into the appropriate
8901 type, leaving that up to the caller (so as to avoid that overhead
8902 if the decls being looked at are different anyway).
8904 If the size cannot be determined (e.g. an adjustable array),
8905 an ERROR_MARK node is returned for the size. Otherwise, the
8906 size returned is valid, not necessarily a constant, and not
8907 necessarily converted into the appropriate type as with the
8910 Note that the offset and size expressions are expressed in the
8911 base storage units (usually bits) rather than in the units of
8912 the type of the decl, because two decls with different types
8913 might overlap but with apparently non-overlapping array offsets,
8914 whereas converting the array offsets to consistant offsets will
8915 reveal the overlap. */
8918 ffecom_tree_canonize_ref_ (tree *decl, tree *offset,
8921 /* The default path is to report a nonexistant decl. */
8927 switch (TREE_CODE (t))
8930 case IDENTIFIER_NODE:
8939 case TRUNC_DIV_EXPR:
8941 case FLOOR_DIV_EXPR:
8942 case ROUND_DIV_EXPR:
8943 case TRUNC_MOD_EXPR:
8945 case FLOOR_MOD_EXPR:
8946 case ROUND_MOD_EXPR:
8948 case EXACT_DIV_EXPR:
8949 case FIX_TRUNC_EXPR:
8951 case FIX_FLOOR_EXPR:
8952 case FIX_ROUND_EXPR:
8966 case BIT_ANDTC_EXPR:
8968 case TRUTH_ANDIF_EXPR:
8969 case TRUTH_ORIF_EXPR:
8970 case TRUTH_AND_EXPR:
8972 case TRUTH_XOR_EXPR:
8973 case TRUTH_NOT_EXPR:
8993 *offset = bitsize_zero_node;
8994 *size = TYPE_SIZE (TREE_TYPE (t));
8999 tree array = TREE_OPERAND (t, 0);
9000 tree element = TREE_OPERAND (t, 1);
9003 if ((array == NULL_TREE)
9004 || (element == NULL_TREE))
9006 *decl = error_mark_node;
9010 ffecom_tree_canonize_ref_ (decl, &init_offset, size,
9012 if ((*decl == NULL_TREE)
9013 || (*decl == error_mark_node))
9016 /* Calculate ((element - base) * NBBY) + init_offset. */
9017 *offset = fold (build (MINUS_EXPR, TREE_TYPE (element),
9019 TYPE_MIN_VALUE (TYPE_DOMAIN
9020 (TREE_TYPE (array)))));
9022 *offset = size_binop (MULT_EXPR,
9023 convert (bitsizetype, *offset),
9024 TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))));
9026 *offset = size_binop (PLUS_EXPR, init_offset, *offset);
9028 *size = TYPE_SIZE (TREE_TYPE (t));
9034 /* Most of this code is to handle references to COMMON. And so
9035 far that is useful only for calling library functions, since
9036 external (user) functions might reference common areas. But
9037 even calling an external function, it's worthwhile to decode
9038 COMMON references because if not storing into COMMON, we don't
9039 want COMMON-based arguments to gratuitously force use of a
9042 *size = TYPE_SIZE (TREE_TYPE (t));
9044 ffecom_tree_canonize_ptr_ (decl, offset,
9045 TREE_OPERAND (t, 0));
9052 case NON_LVALUE_EXPR:
9055 case COND_EXPR: /* More cases than we can handle. */
9057 case REFERENCE_EXPR:
9058 case PREDECREMENT_EXPR:
9059 case PREINCREMENT_EXPR:
9060 case POSTDECREMENT_EXPR:
9061 case POSTINCREMENT_EXPR:
9064 *decl = error_mark_node;
9069 /* Do divide operation appropriate to type of operands. */
9072 ffecom_tree_divide_ (tree tree_type, tree left, tree right,
9073 tree dest_tree, ffebld dest, bool *dest_used,
9076 if ((left == error_mark_node)
9077 || (right == error_mark_node))
9078 return error_mark_node;
9080 switch (TREE_CODE (tree_type))
9083 return ffecom_2 (TRUNC_DIV_EXPR, tree_type,
9088 if (! optimize_size)
9089 return ffecom_2 (RDIV_EXPR, tree_type,
9095 if (TREE_TYPE (tree_type)
9096 == ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1])
9097 ix = FFECOM_gfrtDIV_CC; /* Overlapping result okay. */
9099 ix = FFECOM_gfrtDIV_ZZ; /* Overlapping result okay. */
9101 left = ffecom_1 (ADDR_EXPR,
9102 build_pointer_type (TREE_TYPE (left)),
9104 left = build_tree_list (NULL_TREE, left);
9105 right = ffecom_1 (ADDR_EXPR,
9106 build_pointer_type (TREE_TYPE (right)),
9108 right = build_tree_list (NULL_TREE, right);
9109 TREE_CHAIN (left) = right;
9111 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
9112 ffecom_gfrt_kindtype (ix),
9113 ffe_is_f2c_library (),
9116 dest_tree, dest, dest_used,
9117 NULL_TREE, TRUE, hook);
9125 if (TREE_TYPE (TYPE_FIELDS (tree_type))
9126 == ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1])
9127 ix = FFECOM_gfrtDIV_CC; /* Overlapping result okay. */
9129 ix = FFECOM_gfrtDIV_ZZ; /* Overlapping result okay. */
9131 left = ffecom_1 (ADDR_EXPR,
9132 build_pointer_type (TREE_TYPE (left)),
9134 left = build_tree_list (NULL_TREE, left);
9135 right = ffecom_1 (ADDR_EXPR,
9136 build_pointer_type (TREE_TYPE (right)),
9138 right = build_tree_list (NULL_TREE, right);
9139 TREE_CHAIN (left) = right;
9141 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
9142 ffecom_gfrt_kindtype (ix),
9143 ffe_is_f2c_library (),
9146 dest_tree, dest, dest_used,
9147 NULL_TREE, TRUE, hook);
9152 return ffecom_2 (RDIV_EXPR, tree_type,
9158 /* Build type info for non-dummy variable. */
9161 ffecom_type_localvar_ (ffesymbol s, ffeinfoBasictype bt,
9170 type = ffecom_tree_type[bt][kt];
9171 if (bt == FFEINFO_basictypeCHARACTER)
9173 hight = build_int_2 (ffesymbol_size (s), 0);
9174 TREE_TYPE (hight) = ffecom_f2c_ftnlen_type_node;
9179 build_range_type (ffecom_f2c_ftnlen_type_node,
9180 ffecom_f2c_ftnlen_one_node,
9182 type = ffecom_check_size_overflow_ (s, type, FALSE);
9185 for (dl = ffesymbol_dims (s); dl != NULL; dl = ffebld_trail (dl))
9187 if (type == error_mark_node)
9190 dim = ffebld_head (dl);
9191 assert (ffebld_op (dim) == FFEBLD_opBOUNDS);
9193 if (ffebld_left (dim) == NULL)
9194 lowt = integer_one_node;
9196 lowt = ffecom_expr (ffebld_left (dim));
9198 if (TREE_CODE (lowt) != INTEGER_CST)
9199 lowt = variable_size (lowt);
9201 assert (ffebld_right (dim) != NULL);
9202 hight = ffecom_expr (ffebld_right (dim));
9204 if (TREE_CODE (hight) != INTEGER_CST)
9205 hight = variable_size (hight);
9207 type = build_array_type (type,
9208 build_range_type (ffecom_integer_type_node,
9210 type = ffecom_check_size_overflow_ (s, type, FALSE);
9216 /* Build Namelist type. */
9218 static GTY(()) tree ffecom_type_namelist_var;
9220 ffecom_type_namelist_ ()
9222 if (ffecom_type_namelist_var == NULL_TREE)
9224 tree namefield, varsfield, nvarsfield, vardesctype, type;
9226 vardesctype = ffecom_type_vardesc_ ();
9228 type = make_node (RECORD_TYPE);
9230 vardesctype = build_pointer_type (build_pointer_type (vardesctype));
9232 namefield = ffecom_decl_field (type, NULL_TREE, "name",
9234 varsfield = ffecom_decl_field (type, namefield, "vars", vardesctype);
9235 nvarsfield = ffecom_decl_field (type, varsfield, "nvars",
9238 TYPE_FIELDS (type) = namefield;
9241 ffecom_type_namelist_var = type;
9244 return ffecom_type_namelist_var;
9247 /* Build Vardesc type. */
9249 static GTY(()) tree ffecom_type_vardesc_var;
9251 ffecom_type_vardesc_ ()
9253 if (ffecom_type_vardesc_var == NULL_TREE)
9255 tree namefield, addrfield, dimsfield, typefield, type;
9256 type = make_node (RECORD_TYPE);
9258 namefield = ffecom_decl_field (type, NULL_TREE, "name",
9260 addrfield = ffecom_decl_field (type, namefield, "addr",
9262 dimsfield = ffecom_decl_field (type, addrfield, "dims",
9263 ffecom_f2c_ptr_to_ftnlen_type_node);
9264 typefield = ffecom_decl_field (type, dimsfield, "type",
9267 TYPE_FIELDS (type) = namefield;
9270 ffecom_type_vardesc_var = type;
9273 return ffecom_type_vardesc_var;
9277 ffecom_vardesc_ (ffebld expr)
9281 assert (ffebld_op (expr) == FFEBLD_opSYMTER);
9282 s = ffebld_symter (expr);
9284 if (ffesymbol_hook (s).vardesc_tree == NULL_TREE)
9287 tree vardesctype = ffecom_type_vardesc_ ();
9295 static int mynumber = 0;
9297 var = build_decl (VAR_DECL,
9298 ffecom_get_invented_identifier ("__g77_vardesc_%d",
9301 TREE_STATIC (var) = 1;
9302 DECL_INITIAL (var) = error_mark_node;
9304 var = start_decl (var, FALSE);
9306 /* Process inits. */
9308 nameinit = ffecom_build_f2c_string_ ((i = strlen (ffesymbol_text (s)))
9310 ffesymbol_text (s));
9311 TREE_TYPE (nameinit)
9312 = build_type_variant
9315 build_range_type (integer_type_node,
9317 build_int_2 (i, 0))),
9319 TREE_CONSTANT (nameinit) = 1;
9320 TREE_STATIC (nameinit) = 1;
9321 nameinit = ffecom_1 (ADDR_EXPR,
9322 build_pointer_type (TREE_TYPE (nameinit)),
9325 addrinit = ffecom_arg_ptr_to_expr (expr, &typeinit);
9327 dimsinit = ffecom_vardesc_dims_ (s);
9329 if (typeinit == NULL_TREE)
9331 ffeinfoBasictype bt = ffesymbol_basictype (s);
9332 ffeinfoKindtype kt = ffesymbol_kindtype (s);
9333 int tc = ffecom_f2c_typecode (bt, kt);
9336 typeinit = build_int_2 (tc, (tc < 0) ? -1 : 0);
9339 typeinit = ffecom_1 (NEGATE_EXPR, TREE_TYPE (typeinit), typeinit);
9341 varinits = build_tree_list ((field = TYPE_FIELDS (vardesctype)),
9343 TREE_CHAIN (varinits) = build_tree_list ((field = TREE_CHAIN (field)),
9345 TREE_CHAIN (TREE_CHAIN (varinits))
9346 = build_tree_list ((field = TREE_CHAIN (field)), dimsinit);
9347 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (varinits)))
9348 = build_tree_list ((field = TREE_CHAIN (field)), typeinit);
9350 varinits = build (CONSTRUCTOR, vardesctype, NULL_TREE, varinits);
9351 TREE_CONSTANT (varinits) = 1;
9352 TREE_STATIC (varinits) = 1;
9354 finish_decl (var, varinits, FALSE);
9356 var = ffecom_1 (ADDR_EXPR, build_pointer_type (vardesctype), var);
9358 ffesymbol_hook (s).vardesc_tree = var;
9361 return ffesymbol_hook (s).vardesc_tree;
9365 ffecom_vardesc_array_ (ffesymbol s)
9369 tree item = NULL_TREE;
9372 static int mynumber = 0;
9374 for (i = 0, list = NULL_TREE, b = ffesymbol_namelist (s);
9376 b = ffebld_trail (b), ++i)
9380 t = ffecom_vardesc_ (ffebld_head (b));
9382 if (list == NULL_TREE)
9383 list = item = build_tree_list (NULL_TREE, t);
9386 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
9387 item = TREE_CHAIN (item);
9391 item = build_array_type (build_pointer_type (ffecom_type_vardesc_ ()),
9392 build_range_type (integer_type_node,
9394 build_int_2 (i, 0)));
9395 list = build (CONSTRUCTOR, item, NULL_TREE, list);
9396 TREE_CONSTANT (list) = 1;
9397 TREE_STATIC (list) = 1;
9399 var = ffecom_get_invented_identifier ("__g77_vardesc_array_%d", mynumber++);
9400 var = build_decl (VAR_DECL, var, item);
9401 TREE_STATIC (var) = 1;
9402 DECL_INITIAL (var) = error_mark_node;
9403 var = start_decl (var, FALSE);
9404 finish_decl (var, list, FALSE);
9410 ffecom_vardesc_dims_ (ffesymbol s)
9412 if (ffesymbol_dims (s) == NULL)
9413 return convert (ffecom_f2c_ptr_to_ftnlen_type_node,
9421 tree item = NULL_TREE;
9425 tree baseoff = NULL_TREE;
9426 static int mynumber = 0;
9428 numdim = build_int_2 ((int) ffesymbol_rank (s), 0);
9429 TREE_TYPE (numdim) = ffecom_f2c_ftnlen_type_node;
9431 numelem = ffecom_expr (ffesymbol_arraysize (s));
9432 TREE_TYPE (numelem) = ffecom_f2c_ftnlen_type_node;
9435 backlist = NULL_TREE;
9436 for (b = ffesymbol_dims (s), e = ffesymbol_extents (s);
9438 b = ffebld_trail (b), e = ffebld_trail (e))
9444 if (ffebld_trail (b) == NULL)
9448 t = convert (ffecom_f2c_ftnlen_type_node,
9449 ffecom_expr (ffebld_head (e)));
9451 if (list == NULL_TREE)
9452 list = item = build_tree_list (NULL_TREE, t);
9455 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
9456 item = TREE_CHAIN (item);
9460 if (ffebld_left (ffebld_head (b)) == NULL)
9461 low = ffecom_integer_one_node;
9463 low = ffecom_expr (ffebld_left (ffebld_head (b)));
9464 low = convert (ffecom_f2c_ftnlen_type_node, low);
9466 back = build_tree_list (low, t);
9467 TREE_CHAIN (back) = backlist;
9471 for (item = backlist; item != NULL_TREE; item = TREE_CHAIN (item))
9473 if (TREE_VALUE (item) == NULL_TREE)
9474 baseoff = TREE_PURPOSE (item);
9476 baseoff = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
9477 TREE_PURPOSE (item),
9478 ffecom_2 (MULT_EXPR,
9479 ffecom_f2c_ftnlen_type_node,
9484 /* backlist now dead, along with all TREE_PURPOSEs on it. */
9486 baseoff = build_tree_list (NULL_TREE, baseoff);
9487 TREE_CHAIN (baseoff) = list;
9489 numelem = build_tree_list (NULL_TREE, numelem);
9490 TREE_CHAIN (numelem) = baseoff;
9492 numdim = build_tree_list (NULL_TREE, numdim);
9493 TREE_CHAIN (numdim) = numelem;
9495 item = build_array_type (ffecom_f2c_ftnlen_type_node,
9496 build_range_type (integer_type_node,
9499 ((int) ffesymbol_rank (s)
9501 list = build (CONSTRUCTOR, item, NULL_TREE, numdim);
9502 TREE_CONSTANT (list) = 1;
9503 TREE_STATIC (list) = 1;
9505 var = ffecom_get_invented_identifier ("__g77_dims_%d", mynumber++);
9506 var = build_decl (VAR_DECL, var, item);
9507 TREE_STATIC (var) = 1;
9508 DECL_INITIAL (var) = error_mark_node;
9509 var = start_decl (var, FALSE);
9510 finish_decl (var, list, FALSE);
9512 var = ffecom_1 (ADDR_EXPR, build_pointer_type (item), var);
9518 /* Essentially does a "fold (build1 (code, type, node))" while checking
9519 for certain housekeeping things.
9521 NOTE: for building an ADDR_EXPR around a FUNCTION_DECL, use
9522 ffecom_1_fn instead. */
9525 ffecom_1 (enum tree_code code, tree type, tree node)
9529 if ((node == error_mark_node)
9530 || (type == error_mark_node))
9531 return error_mark_node;
9533 if (code == ADDR_EXPR)
9535 if (!ffe_mark_addressable (node))
9536 assert ("can't mark_addressable this node!" == NULL);
9539 switch (ffe_is_emulate_complex () ? code : NOP_EXPR)
9544 item = build (COMPONENT_REF, type, node, TYPE_FIELDS (TREE_TYPE (node)));
9548 item = build (COMPONENT_REF, type, node, TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (node))));
9553 if (TREE_CODE (type) != RECORD_TYPE)
9555 item = build1 (code, type, node);
9558 node = ffecom_stabilize_aggregate_ (node);
9559 realtype = TREE_TYPE (TYPE_FIELDS (type));
9561 ffecom_2 (COMPLEX_EXPR, type,
9562 ffecom_1 (NEGATE_EXPR, realtype,
9563 ffecom_1 (REALPART_EXPR, realtype,
9565 ffecom_1 (NEGATE_EXPR, realtype,
9566 ffecom_1 (IMAGPART_EXPR, realtype,
9571 item = build1 (code, type, node);
9575 if (TREE_SIDE_EFFECTS (node))
9576 TREE_SIDE_EFFECTS (item) = 1;
9577 if (code == ADDR_EXPR && staticp (node))
9578 TREE_CONSTANT (item) = 1;
9579 else if (code == INDIRECT_REF)
9580 TREE_READONLY (item) = TYPE_READONLY (type);
9584 /* Like ffecom_1 (ADDR_EXPR, TREE_TYPE (node), node), except
9585 handles TREE_CODE (node) == FUNCTION_DECL. In particular,
9586 does not set TREE_ADDRESSABLE (because calling an inline
9587 function does not mean the function needs to be separately
9591 ffecom_1_fn (tree node)
9596 if (node == error_mark_node)
9597 return error_mark_node;
9599 type = build_type_variant (TREE_TYPE (node),
9600 TREE_READONLY (node),
9601 TREE_THIS_VOLATILE (node));
9602 item = build1 (ADDR_EXPR,
9603 build_pointer_type (type), node);
9604 if (TREE_SIDE_EFFECTS (node))
9605 TREE_SIDE_EFFECTS (item) = 1;
9607 TREE_CONSTANT (item) = 1;
9611 /* Essentially does a "fold (build (code, type, node1, node2))" while
9612 checking for certain housekeeping things. */
9615 ffecom_2 (enum tree_code code, tree type, tree node1,
9620 if ((node1 == error_mark_node)
9621 || (node2 == error_mark_node)
9622 || (type == error_mark_node))
9623 return error_mark_node;
9625 switch (ffe_is_emulate_complex () ? code : NOP_EXPR)
9627 tree a, b, c, d, realtype;
9630 assert ("no CONJ_EXPR support yet" == NULL);
9631 return error_mark_node;
9634 item = build_tree_list (TYPE_FIELDS (type), node1);
9635 TREE_CHAIN (item) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), node2);
9636 item = build (CONSTRUCTOR, type, NULL_TREE, item);
9640 if (TREE_CODE (type) != RECORD_TYPE)
9642 item = build (code, type, node1, node2);
9645 node1 = ffecom_stabilize_aggregate_ (node1);
9646 node2 = ffecom_stabilize_aggregate_ (node2);
9647 realtype = TREE_TYPE (TYPE_FIELDS (type));
9649 ffecom_2 (COMPLEX_EXPR, type,
9650 ffecom_2 (PLUS_EXPR, realtype,
9651 ffecom_1 (REALPART_EXPR, realtype,
9653 ffecom_1 (REALPART_EXPR, realtype,
9655 ffecom_2 (PLUS_EXPR, realtype,
9656 ffecom_1 (IMAGPART_EXPR, realtype,
9658 ffecom_1 (IMAGPART_EXPR, realtype,
9663 if (TREE_CODE (type) != RECORD_TYPE)
9665 item = build (code, type, node1, node2);
9668 node1 = ffecom_stabilize_aggregate_ (node1);
9669 node2 = ffecom_stabilize_aggregate_ (node2);
9670 realtype = TREE_TYPE (TYPE_FIELDS (type));
9672 ffecom_2 (COMPLEX_EXPR, type,
9673 ffecom_2 (MINUS_EXPR, realtype,
9674 ffecom_1 (REALPART_EXPR, realtype,
9676 ffecom_1 (REALPART_EXPR, realtype,
9678 ffecom_2 (MINUS_EXPR, realtype,
9679 ffecom_1 (IMAGPART_EXPR, realtype,
9681 ffecom_1 (IMAGPART_EXPR, realtype,
9686 if (TREE_CODE (type) != RECORD_TYPE)
9688 item = build (code, type, node1, node2);
9691 node1 = ffecom_stabilize_aggregate_ (node1);
9692 node2 = ffecom_stabilize_aggregate_ (node2);
9693 realtype = TREE_TYPE (TYPE_FIELDS (type));
9694 a = save_expr (ffecom_1 (REALPART_EXPR, realtype,
9696 b = save_expr (ffecom_1 (IMAGPART_EXPR, realtype,
9698 c = save_expr (ffecom_1 (REALPART_EXPR, realtype,
9700 d = save_expr (ffecom_1 (IMAGPART_EXPR, realtype,
9703 ffecom_2 (COMPLEX_EXPR, type,
9704 ffecom_2 (MINUS_EXPR, realtype,
9705 ffecom_2 (MULT_EXPR, realtype,
9708 ffecom_2 (MULT_EXPR, realtype,
9711 ffecom_2 (PLUS_EXPR, realtype,
9712 ffecom_2 (MULT_EXPR, realtype,
9715 ffecom_2 (MULT_EXPR, realtype,
9721 if ((TREE_CODE (node1) != RECORD_TYPE)
9722 && (TREE_CODE (node2) != RECORD_TYPE))
9724 item = build (code, type, node1, node2);
9727 assert (TREE_CODE (node1) == RECORD_TYPE);
9728 assert (TREE_CODE (node2) == RECORD_TYPE);
9729 node1 = ffecom_stabilize_aggregate_ (node1);
9730 node2 = ffecom_stabilize_aggregate_ (node2);
9731 realtype = TREE_TYPE (TYPE_FIELDS (type));
9733 ffecom_2 (TRUTH_ANDIF_EXPR, type,
9734 ffecom_2 (code, type,
9735 ffecom_1 (REALPART_EXPR, realtype,
9737 ffecom_1 (REALPART_EXPR, realtype,
9739 ffecom_2 (code, type,
9740 ffecom_1 (IMAGPART_EXPR, realtype,
9742 ffecom_1 (IMAGPART_EXPR, realtype,
9747 if ((TREE_CODE (node1) != RECORD_TYPE)
9748 && (TREE_CODE (node2) != RECORD_TYPE))
9750 item = build (code, type, node1, node2);
9753 assert (TREE_CODE (node1) == RECORD_TYPE);
9754 assert (TREE_CODE (node2) == RECORD_TYPE);
9755 node1 = ffecom_stabilize_aggregate_ (node1);
9756 node2 = ffecom_stabilize_aggregate_ (node2);
9757 realtype = TREE_TYPE (TYPE_FIELDS (type));
9759 ffecom_2 (TRUTH_ORIF_EXPR, type,
9760 ffecom_2 (code, type,
9761 ffecom_1 (REALPART_EXPR, realtype,
9763 ffecom_1 (REALPART_EXPR, realtype,
9765 ffecom_2 (code, type,
9766 ffecom_1 (IMAGPART_EXPR, realtype,
9768 ffecom_1 (IMAGPART_EXPR, realtype,
9773 item = build (code, type, node1, node2);
9777 if (TREE_SIDE_EFFECTS (node1) || TREE_SIDE_EFFECTS (node2))
9778 TREE_SIDE_EFFECTS (item) = 1;
9782 /* ffecom_2pass_advise_entrypoint -- Advise that there's this entrypoint
9784 ffesymbol s; // the ENTRY point itself
9785 if (ffecom_2pass_advise_entrypoint(s))
9786 // the ENTRY point has been accepted
9788 Does whatever compiler needs to do when it learns about the entrypoint,
9789 like determine the return type of the master function, count the
9790 number of entrypoints, etc. Returns FALSE if the return type is
9791 not compatible with the return type(s) of other entrypoint(s).
9793 NOTE: for every call to this fn that returns TRUE, _do_entrypoint must
9794 later (after _finish_progunit) be called with the same entrypoint(s)
9795 as passed to this fn for which TRUE was returned.
9798 Return FALSE if the return type conflicts with previous entrypoints. */
9801 ffecom_2pass_advise_entrypoint (ffesymbol entry)
9803 ffebld list; /* opITEM. */
9804 ffebld mlist; /* opITEM. */
9805 ffebld plist; /* opITEM. */
9806 ffebld arg; /* ffebld_head(opITEM). */
9807 ffebld item; /* opITEM. */
9808 ffesymbol s; /* ffebld_symter(arg). */
9809 ffeinfoBasictype bt = ffesymbol_basictype (entry);
9810 ffeinfoKindtype kt = ffesymbol_kindtype (entry);
9811 ffetargetCharacterSize size = ffesymbol_size (entry);
9814 if (ffecom_num_entrypoints_ == 0)
9815 { /* First entrypoint, make list of main
9816 arglist's dummies. */
9817 assert (ffecom_primary_entry_ != NULL);
9819 ffecom_master_bt_ = ffesymbol_basictype (ffecom_primary_entry_);
9820 ffecom_master_kt_ = ffesymbol_kindtype (ffecom_primary_entry_);
9821 ffecom_master_size_ = ffesymbol_size (ffecom_primary_entry_);
9823 for (plist = NULL, list = ffesymbol_dummyargs (ffecom_primary_entry_);
9825 list = ffebld_trail (list))
9827 arg = ffebld_head (list);
9828 if (ffebld_op (arg) != FFEBLD_opSYMTER)
9829 continue; /* Alternate return or some such thing. */
9830 item = ffebld_new_item (arg, NULL);
9832 ffecom_master_arglist_ = item;
9834 ffebld_set_trail (plist, item);
9839 /* If necessary, scan entry arglist for alternate returns. Do this scan
9840 apparently redundantly (it's done below to UNIONize the arglists) so
9841 that we don't complain about RETURN 1 if an offending ENTRY is the only
9842 one with an alternate return. */
9844 if (!ffecom_is_altreturning_)
9846 for (list = ffesymbol_dummyargs (entry);
9848 list = ffebld_trail (list))
9850 arg = ffebld_head (list);
9851 if (ffebld_op (arg) == FFEBLD_opSTAR)
9853 ffecom_is_altreturning_ = TRUE;
9859 /* Now check type compatibility. */
9861 switch (ffecom_master_bt_)
9863 case FFEINFO_basictypeNONE:
9864 ok = (bt != FFEINFO_basictypeCHARACTER);
9867 case FFEINFO_basictypeCHARACTER:
9869 = (bt == FFEINFO_basictypeCHARACTER)
9870 && (kt == ffecom_master_kt_)
9871 && (size == ffecom_master_size_);
9874 case FFEINFO_basictypeANY:
9875 return FALSE; /* Just don't bother. */
9878 if (bt == FFEINFO_basictypeCHARACTER)
9884 if ((bt != ffecom_master_bt_) || (kt != ffecom_master_kt_))
9886 ffecom_master_bt_ = FFEINFO_basictypeNONE;
9887 ffecom_master_kt_ = FFEINFO_kindtypeNONE;
9894 ffebad_start (FFEBAD_ENTRY_CONFLICTS);
9895 ffest_ffebad_here_current_stmt (0);
9897 return FALSE; /* Can't handle entrypoint. */
9900 /* Entrypoint type compatible with previous types. */
9902 ++ffecom_num_entrypoints_;
9904 /* Master-arg-list = UNION(Master-arg-list,entry-arg-list). */
9906 for (list = ffesymbol_dummyargs (entry);
9908 list = ffebld_trail (list))
9910 arg = ffebld_head (list);
9911 if (ffebld_op (arg) != FFEBLD_opSYMTER)
9912 continue; /* Alternate return or some such thing. */
9913 s = ffebld_symter (arg);
9914 for (plist = NULL, mlist = ffecom_master_arglist_;
9916 plist = mlist, mlist = ffebld_trail (mlist))
9917 { /* plist points to previous item for easy
9918 appending of arg. */
9919 if (ffebld_symter (ffebld_head (mlist)) == s)
9920 break; /* Already have this arg in the master list. */
9923 continue; /* Already have this arg in the master list. */
9925 /* Append this arg to the master list. */
9927 item = ffebld_new_item (arg, NULL);
9929 ffecom_master_arglist_ = item;
9931 ffebld_set_trail (plist, item);
9937 /* ffecom_2pass_do_entrypoint -- Do compilation of entrypoint
9939 ffesymbol s; // the ENTRY point itself
9940 ffecom_2pass_do_entrypoint(s);
9942 Does whatever compiler needs to do to make the entrypoint actually
9943 happen. Must be called for each entrypoint after
9944 ffecom_finish_progunit is called. */
9947 ffecom_2pass_do_entrypoint (ffesymbol entry)
9949 static int mfn_num = 0;
9952 if (mfn_num != ffecom_num_fns_)
9953 { /* First entrypoint for this program unit. */
9955 mfn_num = ffecom_num_fns_;
9956 ffecom_do_entry_ (ffecom_primary_entry_, 0);
9961 --ffecom_num_entrypoints_;
9963 ffecom_do_entry_ (entry, ent_num);
9966 /* Essentially does a "fold (build (code, type, node1, node2))" while
9967 checking for certain housekeeping things. Always sets
9968 TREE_SIDE_EFFECTS. */
9971 ffecom_2s (enum tree_code code, tree type, tree node1,
9976 if ((node1 == error_mark_node)
9977 || (node2 == error_mark_node)
9978 || (type == error_mark_node))
9979 return error_mark_node;
9981 item = build (code, type, node1, node2);
9982 TREE_SIDE_EFFECTS (item) = 1;
9986 /* Essentially does a "fold (build (code, type, node1, node2, node3))" while
9987 checking for certain housekeeping things. */
9990 ffecom_3 (enum tree_code code, tree type, tree node1,
9991 tree node2, tree node3)
9995 if ((node1 == error_mark_node)
9996 || (node2 == error_mark_node)
9997 || (node3 == error_mark_node)
9998 || (type == error_mark_node))
9999 return error_mark_node;
10001 item = build (code, type, node1, node2, node3);
10002 if (TREE_SIDE_EFFECTS (node1) || TREE_SIDE_EFFECTS (node2)
10003 || (node3 != NULL_TREE && TREE_SIDE_EFFECTS (node3)))
10004 TREE_SIDE_EFFECTS (item) = 1;
10005 return fold (item);
10008 /* Essentially does a "fold (build (code, type, node1, node2, node3))" while
10009 checking for certain housekeeping things. Always sets
10010 TREE_SIDE_EFFECTS. */
10013 ffecom_3s (enum tree_code code, tree type, tree node1,
10014 tree node2, tree node3)
10018 if ((node1 == error_mark_node)
10019 || (node2 == error_mark_node)
10020 || (node3 == error_mark_node)
10021 || (type == error_mark_node))
10022 return error_mark_node;
10024 item = build (code, type, node1, node2, node3);
10025 TREE_SIDE_EFFECTS (item) = 1;
10026 return fold (item);
10029 /* ffecom_arg_expr -- Transform argument expr into gcc tree
10031 See use by ffecom_list_expr.
10033 If expression is NULL, returns an integer zero tree. If it is not
10034 a CHARACTER expression, returns whatever ffecom_expr
10035 returns and sets the length return value to NULL_TREE. Otherwise
10036 generates code to evaluate the character expression, returns the proper
10037 pointer to the result, but does NOT set the length return value to a tree
10038 that specifies the length of the result. (In other words, the length
10039 variable is always set to NULL_TREE, because a length is never passed.)
10042 Don't set returned length, since nobody needs it (yet; someday if
10043 we allow CHARACTER*(*) dummies to statement functions, we'll need
10047 ffecom_arg_expr (ffebld expr, tree *length)
10051 *length = NULL_TREE;
10054 return integer_zero_node;
10056 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10057 return ffecom_expr (expr);
10059 return ffecom_arg_ptr_to_expr (expr, &ign);
10062 /* Transform expression into constant argument-pointer-to-expression tree.
10064 If the expression can be transformed into a argument-pointer-to-expression
10065 tree that is constant, that is done, and the tree returned. Else
10066 NULL_TREE is returned.
10068 That way, a caller can attempt to provide compile-time initialization
10069 of a variable and, if that fails, *then* choose to start a new block
10070 and resort to using temporaries, as appropriate. */
10073 ffecom_arg_ptr_to_const_expr (ffebld expr, tree *length)
10076 return integer_zero_node;
10078 if (ffebld_op (expr) == FFEBLD_opANY)
10081 *length = error_mark_node;
10082 return error_mark_node;
10085 if (ffebld_arity (expr) == 0
10086 && (ffebld_op (expr) != FFEBLD_opSYMTER
10087 || ffebld_where (expr) == FFEINFO_whereCOMMON
10088 || ffebld_where (expr) == FFEINFO_whereGLOBAL
10089 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
10093 t = ffecom_arg_ptr_to_expr (expr, length);
10094 assert (TREE_CONSTANT (t));
10095 assert (! length || TREE_CONSTANT (*length));
10100 && ffebld_size (expr) != FFETARGET_charactersizeNONE)
10101 *length = build_int_2 (ffebld_size (expr), 0);
10103 *length = NULL_TREE;
10107 /* ffecom_arg_ptr_to_expr -- Transform argument expr into gcc tree
10109 See use by ffecom_list_ptr_to_expr.
10111 If expression is NULL, returns an integer zero tree. If it is not
10112 a CHARACTER expression, returns whatever ffecom_ptr_to_expr
10113 returns and sets the length return value to NULL_TREE. Otherwise
10114 generates code to evaluate the character expression, returns the proper
10115 pointer to the result, AND sets the length return value to a tree that
10116 specifies the length of the result.
10118 If the length argument is NULL, this is a slightly special
10119 case of building a FORMAT expression, that is, an expression that
10120 will be used at run time without regard to length. For the current
10121 implementation, which uses the libf2c library, this means it is nice
10122 to append a null byte to the end of the expression, where feasible,
10123 to make sure any diagnostic about the FORMAT string terminates at
10126 For now, treat %REF(char-expr) as the same as char-expr with a NULL
10127 length argument. This might even be seen as a feature, if a null
10128 byte can always be appended. */
10131 ffecom_arg_ptr_to_expr (ffebld expr, tree *length)
10135 ffecomConcatList_ catlist;
10137 if (length != NULL)
10138 *length = NULL_TREE;
10141 return integer_zero_node;
10143 switch (ffebld_op (expr))
10145 case FFEBLD_opPERCENT_VAL:
10146 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10147 return ffecom_expr (ffebld_left (expr));
10152 temp_exp = ffecom_arg_ptr_to_expr (ffebld_left (expr), &temp_length);
10153 if (temp_exp == error_mark_node)
10154 return error_mark_node;
10156 return ffecom_1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (temp_exp)),
10160 case FFEBLD_opPERCENT_REF:
10161 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10162 return ffecom_ptr_to_expr (ffebld_left (expr));
10163 if (length != NULL)
10165 ign_length = NULL_TREE;
10166 length = &ign_length;
10168 expr = ffebld_left (expr);
10171 case FFEBLD_opPERCENT_DESCR:
10172 switch (ffeinfo_basictype (ffebld_info (expr)))
10174 #ifdef PASS_HOLLERITH_BY_DESCRIPTOR
10175 case FFEINFO_basictypeHOLLERITH:
10177 case FFEINFO_basictypeCHARACTER:
10178 break; /* Passed by descriptor anyway. */
10181 item = ffecom_ptr_to_expr (expr);
10182 if (item != error_mark_node)
10183 *length = TYPE_SIZE (TREE_TYPE (TREE_TYPE (item)));
10192 #ifdef PASS_HOLLERITH_BY_DESCRIPTOR
10193 if ((ffeinfo_basictype (ffebld_info (expr)) == FFEINFO_basictypeHOLLERITH)
10194 && (length != NULL))
10195 { /* Pass Hollerith by descriptor. */
10196 ffetargetHollerith h;
10198 assert (ffebld_op (expr) == FFEBLD_opCONTER);
10199 h = ffebld_cu_val_hollerith (ffebld_constant_union
10200 (ffebld_conter (expr)));
10202 = build_int_2 (h.length, 0);
10203 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
10207 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10208 return ffecom_ptr_to_expr (expr);
10210 assert (ffeinfo_kindtype (ffebld_info (expr))
10211 == FFEINFO_kindtypeCHARACTER1);
10213 while (ffebld_op (expr) == FFEBLD_opPAREN)
10214 expr = ffebld_left (expr);
10216 catlist = ffecom_concat_list_new_ (expr, FFETARGET_charactersizeNONE);
10217 switch (ffecom_concat_list_count_ (catlist))
10219 case 0: /* Shouldn't happen, but in case it does... */
10220 if (length != NULL)
10222 *length = ffecom_f2c_ftnlen_zero_node;
10223 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
10225 ffecom_concat_list_kill_ (catlist);
10226 return null_pointer_node;
10228 case 1: /* The (fairly) easy case. */
10229 if (length == NULL)
10230 ffecom_char_args_with_null_ (&item, &ign_length,
10231 ffecom_concat_list_expr_ (catlist, 0));
10233 ffecom_char_args_ (&item, length,
10234 ffecom_concat_list_expr_ (catlist, 0));
10235 ffecom_concat_list_kill_ (catlist);
10236 assert (item != NULL_TREE);
10239 default: /* Must actually concatenate things. */
10244 int count = ffecom_concat_list_count_ (catlist);
10255 ffetargetCharacterSize sz;
10257 sz = ffecom_concat_list_maxlen_ (catlist);
10259 assert (sz != FFETARGET_charactersizeNONE);
10264 = ffecom_push_tempvar (ffecom_f2c_ftnlen_type_node,
10265 FFETARGET_charactersizeNONE, count, TRUE);
10268 = ffecom_push_tempvar (ffecom_f2c_address_type_node,
10269 FFETARGET_charactersizeNONE, count, TRUE);
10270 temporary = ffecom_push_tempvar (char_type_node,
10276 hook = ffebld_nonter_hook (expr);
10278 assert (TREE_CODE (hook) == TREE_VEC);
10279 assert (TREE_VEC_LENGTH (hook) == 3);
10280 length_array = lengths = TREE_VEC_ELT (hook, 0);
10281 item_array = items = TREE_VEC_ELT (hook, 1);
10282 temporary = TREE_VEC_ELT (hook, 2);
10286 known_length = ffecom_f2c_ftnlen_zero_node;
10288 for (i = 0; i < count; ++i)
10291 && (length == NULL))
10292 ffecom_char_args_with_null_ (&citem, &clength,
10293 ffecom_concat_list_expr_ (catlist, i));
10295 ffecom_char_args_ (&citem, &clength,
10296 ffecom_concat_list_expr_ (catlist, i));
10297 if ((citem == error_mark_node)
10298 || (clength == error_mark_node))
10300 ffecom_concat_list_kill_ (catlist);
10301 *length = error_mark_node;
10302 return error_mark_node;
10306 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (items),
10307 ffecom_modify (void_type_node,
10308 ffecom_2 (ARRAY_REF,
10309 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array))),
10311 build_int_2 (i, 0)),
10314 clength = ffecom_save_tree (clength);
10315 if (length != NULL)
10317 = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
10321 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (lengths),
10322 ffecom_modify (void_type_node,
10323 ffecom_2 (ARRAY_REF,
10324 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array))),
10326 build_int_2 (i, 0)),
10331 temporary = ffecom_1 (ADDR_EXPR,
10332 build_pointer_type (TREE_TYPE (temporary)),
10335 item = build_tree_list (NULL_TREE, temporary);
10337 = build_tree_list (NULL_TREE,
10338 ffecom_1 (ADDR_EXPR,
10339 build_pointer_type (TREE_TYPE (items)),
10341 TREE_CHAIN (TREE_CHAIN (item))
10342 = build_tree_list (NULL_TREE,
10343 ffecom_1 (ADDR_EXPR,
10344 build_pointer_type (TREE_TYPE (lengths)),
10346 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item)))
10349 ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
10350 convert (ffecom_f2c_ftnlen_type_node,
10351 build_int_2 (count, 0))));
10352 num = build_int_2 (sz, 0);
10353 TREE_TYPE (num) = ffecom_f2c_ftnlen_type_node;
10354 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item))))
10355 = build_tree_list (NULL_TREE, num);
10357 item = ffecom_call_gfrt (FFECOM_gfrtCAT, item, NULL_TREE);
10358 TREE_SIDE_EFFECTS (item) = 1;
10359 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (temporary),
10363 if (length != NULL)
10364 *length = known_length;
10367 ffecom_concat_list_kill_ (catlist);
10368 assert (item != NULL_TREE);
10372 /* Generate call to run-time function.
10374 The first arg is the GNU Fortran Run-Time function index, the second
10375 arg is the list of arguments to pass to it. Returned is the expression
10376 (WITHOUT TREE_SIDE_EFFECTS set!) that makes the call and returns the
10377 result (which may be void). */
10380 ffecom_call_gfrt (ffecomGfrt ix, tree args, tree hook)
10382 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
10383 ffecom_gfrt_kindtype (ix),
10384 ffe_is_f2c_library () && ffecom_gfrt_complex_[ix],
10385 NULL_TREE, args, NULL_TREE, NULL,
10386 NULL, NULL_TREE, TRUE, hook);
10389 /* Transform constant-union to tree. */
10392 ffecom_constantunion (ffebldConstantUnion *cu, ffeinfoBasictype bt,
10393 ffeinfoKindtype kt, tree tree_type)
10399 case FFEINFO_basictypeINTEGER:
10405 #if FFETARGET_okINTEGER1
10406 case FFEINFO_kindtypeINTEGER1:
10407 val = ffebld_cu_val_integer1 (*cu);
10411 #if FFETARGET_okINTEGER2
10412 case FFEINFO_kindtypeINTEGER2:
10413 val = ffebld_cu_val_integer2 (*cu);
10417 #if FFETARGET_okINTEGER3
10418 case FFEINFO_kindtypeINTEGER3:
10419 val = ffebld_cu_val_integer3 (*cu);
10423 #if FFETARGET_okINTEGER4
10424 case FFEINFO_kindtypeINTEGER4:
10425 val = ffebld_cu_val_integer4 (*cu);
10430 assert ("bad INTEGER constant kind type" == NULL);
10431 /* Fall through. */
10432 case FFEINFO_kindtypeANY:
10433 return error_mark_node;
10435 item = build_int_2 (val, (val < 0) ? -1 : 0);
10436 TREE_TYPE (item) = tree_type;
10440 case FFEINFO_basictypeLOGICAL:
10446 #if FFETARGET_okLOGICAL1
10447 case FFEINFO_kindtypeLOGICAL1:
10448 val = ffebld_cu_val_logical1 (*cu);
10452 #if FFETARGET_okLOGICAL2
10453 case FFEINFO_kindtypeLOGICAL2:
10454 val = ffebld_cu_val_logical2 (*cu);
10458 #if FFETARGET_okLOGICAL3
10459 case FFEINFO_kindtypeLOGICAL3:
10460 val = ffebld_cu_val_logical3 (*cu);
10464 #if FFETARGET_okLOGICAL4
10465 case FFEINFO_kindtypeLOGICAL4:
10466 val = ffebld_cu_val_logical4 (*cu);
10471 assert ("bad LOGICAL constant kind type" == NULL);
10472 /* Fall through. */
10473 case FFEINFO_kindtypeANY:
10474 return error_mark_node;
10476 item = build_int_2 (val, (val < 0) ? -1 : 0);
10477 TREE_TYPE (item) = tree_type;
10481 case FFEINFO_basictypeREAL:
10483 REAL_VALUE_TYPE val;
10487 #if FFETARGET_okREAL1
10488 case FFEINFO_kindtypeREAL1:
10489 val = ffetarget_value_real1 (ffebld_cu_val_real1 (*cu));
10493 #if FFETARGET_okREAL2
10494 case FFEINFO_kindtypeREAL2:
10495 val = ffetarget_value_real2 (ffebld_cu_val_real2 (*cu));
10499 #if FFETARGET_okREAL3
10500 case FFEINFO_kindtypeREAL3:
10501 val = ffetarget_value_real3 (ffebld_cu_val_real3 (*cu));
10505 #if FFETARGET_okREAL4
10506 case FFEINFO_kindtypeREAL4:
10507 val = ffetarget_value_real4 (ffebld_cu_val_real4 (*cu));
10512 assert ("bad REAL constant kind type" == NULL);
10513 /* Fall through. */
10514 case FFEINFO_kindtypeANY:
10515 return error_mark_node;
10517 item = build_real (tree_type, val);
10521 case FFEINFO_basictypeCOMPLEX:
10523 REAL_VALUE_TYPE real;
10524 REAL_VALUE_TYPE imag;
10525 tree el_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
10529 #if FFETARGET_okCOMPLEX1
10530 case FFEINFO_kindtypeREAL1:
10531 real = ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu).real);
10532 imag = ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu).imaginary);
10536 #if FFETARGET_okCOMPLEX2
10537 case FFEINFO_kindtypeREAL2:
10538 real = ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu).real);
10539 imag = ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu).imaginary);
10543 #if FFETARGET_okCOMPLEX3
10544 case FFEINFO_kindtypeREAL3:
10545 real = ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu).real);
10546 imag = ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu).imaginary);
10550 #if FFETARGET_okCOMPLEX4
10551 case FFEINFO_kindtypeREAL4:
10552 real = ffetarget_value_real4 (ffebld_cu_val_complex4 (*cu).real);
10553 imag = ffetarget_value_real4 (ffebld_cu_val_complex4 (*cu).imaginary);
10558 assert ("bad REAL constant kind type" == NULL);
10559 /* Fall through. */
10560 case FFEINFO_kindtypeANY:
10561 return error_mark_node;
10563 item = ffecom_build_complex_constant_ (tree_type,
10564 build_real (el_type, real),
10565 build_real (el_type, imag));
10569 case FFEINFO_basictypeCHARACTER:
10570 { /* Happens only in DATA and similar contexts. */
10571 ffetargetCharacter1 val;
10575 #if FFETARGET_okCHARACTER1
10576 case FFEINFO_kindtypeLOGICAL1:
10577 val = ffebld_cu_val_character1 (*cu);
10582 assert ("bad CHARACTER constant kind type" == NULL);
10583 /* Fall through. */
10584 case FFEINFO_kindtypeANY:
10585 return error_mark_node;
10587 item = build_string (ffetarget_length_character1 (val),
10588 ffetarget_text_character1 (val));
10590 = build_type_variant (build_array_type (char_type_node,
10592 (integer_type_node,
10595 (ffetarget_length_character1
10601 case FFEINFO_basictypeHOLLERITH:
10603 ffetargetHollerith h;
10605 h = ffebld_cu_val_hollerith (*cu);
10607 /* If not at least as wide as default INTEGER, widen it. */
10608 if (h.length >= FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE)
10609 item = build_string (h.length, h.text);
10612 char str[FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE];
10614 memcpy (str, h.text, h.length);
10615 memset (&str[h.length], ' ',
10616 FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE
10618 item = build_string (FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE,
10622 = build_type_variant (build_array_type (char_type_node,
10624 (integer_type_node,
10632 case FFEINFO_basictypeTYPELESS:
10634 ffetargetInteger1 ival;
10635 ffetargetTypeless tless;
10638 tless = ffebld_cu_val_typeless (*cu);
10639 error = ffetarget_convert_integer1_typeless (&ival, tless);
10640 assert (error == FFEBAD);
10642 item = build_int_2 ((int) ival, 0);
10647 assert ("not yet on constant type" == NULL);
10648 /* Fall through. */
10649 case FFEINFO_basictypeANY:
10650 return error_mark_node;
10653 TREE_CONSTANT (item) = 1;
10658 /* Transform expression into constant tree.
10660 If the expression can be transformed into a tree that is constant,
10661 that is done, and the tree returned. Else NULL_TREE is returned.
10663 That way, a caller can attempt to provide compile-time initialization
10664 of a variable and, if that fails, *then* choose to start a new block
10665 and resort to using temporaries, as appropriate. */
10668 ffecom_const_expr (ffebld expr)
10671 return integer_zero_node;
10673 if (ffebld_op (expr) == FFEBLD_opANY)
10674 return error_mark_node;
10676 if (ffebld_arity (expr) == 0
10677 && (ffebld_op (expr) != FFEBLD_opSYMTER
10679 /* ~~Enable once common/equivalence is handled properly? */
10680 || ffebld_where (expr) == FFEINFO_whereCOMMON
10682 || ffebld_where (expr) == FFEINFO_whereGLOBAL
10683 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
10687 t = ffecom_expr (expr);
10688 assert (TREE_CONSTANT (t));
10695 /* Handy way to make a field in a struct/union. */
10698 ffecom_decl_field (tree context, tree prevfield,
10699 const char *name, tree type)
10703 field = build_decl (FIELD_DECL, get_identifier (name), type);
10704 DECL_CONTEXT (field) = context;
10705 DECL_ALIGN (field) = 0;
10706 DECL_USER_ALIGN (field) = 0;
10707 if (prevfield != NULL_TREE)
10708 TREE_CHAIN (prevfield) = field;
10714 ffecom_close_include (FILE *f)
10716 ffecom_close_include_ (f);
10720 ffecom_decode_include_option (char *spec)
10722 return ffecom_decode_include_option_ (spec);
10725 /* End a compound statement (block). */
10728 ffecom_end_compstmt (void)
10730 return bison_rule_compstmt_ ();
10733 /* ffecom_end_transition -- Perform end transition on all symbols
10735 ffecom_end_transition();
10737 Calls ffecom_sym_end_transition for each global and local symbol. */
10740 ffecom_end_transition ()
10744 if (ffe_is_ffedebug ())
10745 fprintf (dmpout, "; end_stmt_transition\n");
10747 ffecom_list_blockdata_ = NULL;
10748 ffecom_list_common_ = NULL;
10750 ffesymbol_drive (ffecom_sym_end_transition);
10751 if (ffe_is_ffedebug ())
10753 ffestorag_report ();
10756 ffecom_start_progunit_ ();
10758 for (item = ffecom_list_blockdata_;
10760 item = ffebld_trail (item))
10767 static int number = 0;
10769 callee = ffebld_head (item);
10770 s = ffebld_symter (callee);
10771 t = ffesymbol_hook (s).decl_tree;
10772 if (t == NULL_TREE)
10774 s = ffecom_sym_transform_ (s);
10775 t = ffesymbol_hook (s).decl_tree;
10778 dt = build_pointer_type (TREE_TYPE (t));
10780 var = build_decl (VAR_DECL,
10781 ffecom_get_invented_identifier ("__g77_forceload_%d",
10784 DECL_EXTERNAL (var) = 0;
10785 TREE_STATIC (var) = 1;
10786 TREE_PUBLIC (var) = 0;
10787 DECL_INITIAL (var) = error_mark_node;
10788 TREE_USED (var) = 1;
10790 var = start_decl (var, FALSE);
10792 t = ffecom_1 (ADDR_EXPR, dt, t);
10794 finish_decl (var, t, FALSE);
10797 /* This handles any COMMON areas that weren't referenced but have, for
10798 example, important initial data. */
10800 for (item = ffecom_list_common_;
10802 item = ffebld_trail (item))
10803 ffecom_transform_common_ (ffebld_symter (ffebld_head (item)));
10805 ffecom_list_common_ = NULL;
10808 /* ffecom_exec_transition -- Perform exec transition on all symbols
10810 ffecom_exec_transition();
10812 Calls ffecom_sym_exec_transition for each global and local symbol.
10813 Make sure error updating not inhibited. */
10816 ffecom_exec_transition ()
10820 if (ffe_is_ffedebug ())
10821 fprintf (dmpout, "; exec_stmt_transition\n");
10823 inhibited = ffebad_inhibit ();
10824 ffebad_set_inhibit (FALSE);
10826 ffesymbol_drive (ffecom_sym_exec_transition); /* Don't retract! */
10827 ffeequiv_exec_transition (); /* Handle all pending EQUIVALENCEs. */
10828 if (ffe_is_ffedebug ())
10830 ffestorag_report ();
10834 ffebad_set_inhibit (TRUE);
10837 /* Handle assignment statement.
10839 Convert dest and source using ffecom_expr, then join them
10840 with an ASSIGN op and pass the whole thing to expand_expr_stmt. */
10843 ffecom_expand_let_stmt (ffebld dest, ffebld source)
10850 if (ffeinfo_basictype (ffebld_info (dest)) != FFEINFO_basictypeCHARACTER)
10855 /* This attempts to replicate the test below, but must not be
10856 true when the test below is false. (Always err on the side
10857 of creating unused temporaries, to avoid ICEs.) */
10858 if (ffebld_op (dest) != FFEBLD_opSYMTER
10859 || ((dest_tree = ffesymbol_hook (ffebld_symter (dest)).decl_tree)
10860 && (TREE_CODE (dest_tree) != VAR_DECL
10861 || TREE_ADDRESSABLE (dest_tree))))
10863 ffecom_prepare_expr_ (source, dest);
10868 ffecom_prepare_expr_ (source, NULL);
10872 ffecom_prepare_expr_w (NULL_TREE, dest);
10874 /* For COMPLEX assignment like C1=C2, if partial overlap is possible,
10875 create a temporary through which the assignment is to take place,
10876 since MODIFY_EXPR doesn't handle partial overlap properly. */
10877 if (ffebld_basictype (dest) == FFEINFO_basictypeCOMPLEX
10878 && ffecom_possible_partial_overlap_ (dest, source))
10880 assign_temp = ffecom_make_tempvar ("complex_let",
10882 [ffebld_basictype (dest)]
10883 [ffebld_kindtype (dest)],
10884 FFETARGET_charactersizeNONE,
10888 assign_temp = NULL_TREE;
10890 ffecom_prepare_end ();
10892 dest_tree = ffecom_expr_w (NULL_TREE, dest);
10893 if (dest_tree == error_mark_node)
10896 if ((TREE_CODE (dest_tree) != VAR_DECL)
10897 || TREE_ADDRESSABLE (dest_tree))
10898 source_tree = ffecom_expr_ (source, dest_tree, dest, &dest_used,
10902 assert (! dest_used);
10904 source_tree = ffecom_expr (source);
10906 if (source_tree == error_mark_node)
10910 expr_tree = source_tree;
10911 else if (assign_temp)
10914 /* The back end understands a conceptual move (evaluate source;
10915 store into dest), so use that, in case it can determine
10916 that it is going to use, say, two registers as temporaries
10917 anyway. So don't use the temp (and someday avoid generating
10918 it, once this code starts triggering regularly). */
10919 expr_tree = ffecom_2s (MOVE_EXPR, void_type_node,
10923 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
10926 expand_expr_stmt (expr_tree);
10927 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
10933 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
10937 expand_expr_stmt (expr_tree);
10941 ffecom_prepare_let_char_ (ffebld_size_known (dest), source);
10942 ffecom_prepare_expr_w (NULL_TREE, dest);
10944 ffecom_prepare_end ();
10946 ffecom_char_args_ (&dest_tree, &dest_length, dest);
10947 ffecom_let_char_ (dest_tree, dest_length, ffebld_size_known (dest),
10951 /* ffecom_expr -- Transform expr into gcc tree
10954 ffebld expr; // FFE expression.
10955 tree = ffecom_expr(expr);
10957 Recursive descent on expr while making corresponding tree nodes and
10958 attaching type info and such. */
10961 ffecom_expr (ffebld expr)
10963 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, FALSE, FALSE);
10966 /* Like ffecom_expr, but return tree usable for assigned GOTO or FORMAT. */
10969 ffecom_expr_assign (ffebld expr)
10971 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, TRUE, FALSE);
10974 /* Like ffecom_expr_rw, but return tree usable for ASSIGN. */
10977 ffecom_expr_assign_w (ffebld expr)
10979 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, TRUE, FALSE);
10982 /* Transform expr for use as into read/write tree and stabilize the
10983 reference. Not for use on CHARACTER expressions.
10985 Recursive descent on expr while making corresponding tree nodes and
10986 attaching type info and such. */
10989 ffecom_expr_rw (tree type, ffebld expr)
10991 assert (expr != NULL);
10992 /* Different target types not yet supported. */
10993 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
10995 return stabilize_reference (ffecom_expr (expr));
10998 /* Transform expr for use as into write tree and stabilize the
10999 reference. Not for use on CHARACTER expressions.
11001 Recursive descent on expr while making corresponding tree nodes and
11002 attaching type info and such. */
11005 ffecom_expr_w (tree type, ffebld expr)
11007 assert (expr != NULL);
11008 /* Different target types not yet supported. */
11009 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
11011 return stabilize_reference (ffecom_expr (expr));
11014 /* Do global stuff. */
11017 ffecom_finish_compile ()
11019 assert (ffecom_outer_function_decl_ == NULL_TREE);
11020 assert (current_function_decl == NULL_TREE);
11022 ffeglobal_drive (ffecom_finish_global_);
11025 /* Public entry point for front end to access finish_decl. */
11028 ffecom_finish_decl (tree decl, tree init, bool is_top_level)
11030 assert (!is_top_level);
11031 finish_decl (decl, init, FALSE);
11034 /* Finish a program unit. */
11037 ffecom_finish_progunit ()
11039 ffecom_end_compstmt ();
11041 ffecom_previous_function_decl_ = current_function_decl;
11042 ffecom_which_entrypoint_decl_ = NULL_TREE;
11044 finish_function (0);
11047 /* Wrapper for get_identifier. pattern is sprintf-like. */
11050 ffecom_get_invented_identifier (const char *pattern, ...)
11056 va_start (ap, pattern);
11057 if (vasprintf (&nam, pattern, ap) == 0)
11060 decl = get_identifier (nam);
11062 IDENTIFIER_INVENTED (decl) = 1;
11067 ffecom_gfrt_basictype (ffecomGfrt gfrt)
11069 assert (gfrt < FFECOM_gfrt);
11071 switch (ffecom_gfrt_type_[gfrt])
11073 case FFECOM_rttypeVOID_:
11074 case FFECOM_rttypeVOIDSTAR_:
11075 return FFEINFO_basictypeNONE;
11077 case FFECOM_rttypeFTNINT_:
11078 return FFEINFO_basictypeINTEGER;
11080 case FFECOM_rttypeINTEGER_:
11081 return FFEINFO_basictypeINTEGER;
11083 case FFECOM_rttypeLONGINT_:
11084 return FFEINFO_basictypeINTEGER;
11086 case FFECOM_rttypeLOGICAL_:
11087 return FFEINFO_basictypeLOGICAL;
11089 case FFECOM_rttypeREAL_F2C_:
11090 case FFECOM_rttypeREAL_GNU_:
11091 return FFEINFO_basictypeREAL;
11093 case FFECOM_rttypeCOMPLEX_F2C_:
11094 case FFECOM_rttypeCOMPLEX_GNU_:
11095 return FFEINFO_basictypeCOMPLEX;
11097 case FFECOM_rttypeDOUBLE_:
11098 case FFECOM_rttypeDOUBLEREAL_:
11099 return FFEINFO_basictypeREAL;
11101 case FFECOM_rttypeDBLCMPLX_F2C_:
11102 case FFECOM_rttypeDBLCMPLX_GNU_:
11103 return FFEINFO_basictypeCOMPLEX;
11105 case FFECOM_rttypeCHARACTER_:
11106 return FFEINFO_basictypeCHARACTER;
11109 return FFEINFO_basictypeANY;
11114 ffecom_gfrt_kindtype (ffecomGfrt gfrt)
11116 assert (gfrt < FFECOM_gfrt);
11118 switch (ffecom_gfrt_type_[gfrt])
11120 case FFECOM_rttypeVOID_:
11121 case FFECOM_rttypeVOIDSTAR_:
11122 return FFEINFO_kindtypeNONE;
11124 case FFECOM_rttypeFTNINT_:
11125 return FFEINFO_kindtypeINTEGER1;
11127 case FFECOM_rttypeINTEGER_:
11128 return FFEINFO_kindtypeINTEGER1;
11130 case FFECOM_rttypeLONGINT_:
11131 return FFEINFO_kindtypeINTEGER4;
11133 case FFECOM_rttypeLOGICAL_:
11134 return FFEINFO_kindtypeLOGICAL1;
11136 case FFECOM_rttypeREAL_F2C_:
11137 case FFECOM_rttypeREAL_GNU_:
11138 return FFEINFO_kindtypeREAL1;
11140 case FFECOM_rttypeCOMPLEX_F2C_:
11141 case FFECOM_rttypeCOMPLEX_GNU_:
11142 return FFEINFO_kindtypeREAL1;
11144 case FFECOM_rttypeDOUBLE_:
11145 case FFECOM_rttypeDOUBLEREAL_:
11146 return FFEINFO_kindtypeREAL2;
11148 case FFECOM_rttypeDBLCMPLX_F2C_:
11149 case FFECOM_rttypeDBLCMPLX_GNU_:
11150 return FFEINFO_kindtypeREAL2;
11152 case FFECOM_rttypeCHARACTER_:
11153 return FFEINFO_kindtypeCHARACTER1;
11156 return FFEINFO_kindtypeANY;
11170 tree double_ftype_double;
11171 tree float_ftype_float;
11172 tree ldouble_ftype_ldouble;
11173 tree ffecom_tree_ptr_to_fun_type_void;
11175 /* This block of code comes from the now-obsolete cktyps.c. It checks
11176 whether the compiler environment is buggy in known ways, some of which
11177 would, if not explicitly checked here, result in subtle bugs in g77. */
11179 if (ffe_is_do_internal_checks ())
11181 static const char names[][12]
11183 {"bar", "bletch", "foo", "foobar"};
11188 name = bsearch ("foo", &names[0], ARRAY_SIZE (names), sizeof (names[0]),
11189 (int (*)(const void *, const void *)) strcmp);
11190 if (name != &names[0][2])
11192 assert ("bsearch doesn't work, #define FFEPROJ_BSEARCH 0 in proj.h"
11197 ul = strtoul ("123456789", NULL, 10);
11198 if (ul != 123456789L)
11200 assert ("strtoul doesn't have enough range, #define FFEPROJ_STRTOUL 0\
11201 in proj.h" == NULL);
11205 fl = atof ("56.789");
11206 if ((fl < 56.788) || (fl > 56.79))
11208 assert ("atof not type double, fix your #include <stdio.h>"
11214 ffecom_outer_function_decl_ = NULL_TREE;
11215 current_function_decl = NULL_TREE;
11216 named_labels = NULL_TREE;
11217 current_binding_level = NULL_BINDING_LEVEL;
11218 free_binding_level = NULL_BINDING_LEVEL;
11219 /* Make the binding_level structure for global names. */
11221 global_binding_level = current_binding_level;
11222 current_binding_level->prep_state = 2;
11224 build_common_tree_nodes (1);
11226 /* Define `int' and `char' first so that dbx will output them first. */
11227 pushdecl (build_decl (TYPE_DECL, get_identifier ("int"),
11228 integer_type_node));
11229 /* CHARACTER*1 is unsigned in ICHAR contexts. */
11230 char_type_node = make_unsigned_type (CHAR_TYPE_SIZE);
11231 pushdecl (build_decl (TYPE_DECL, get_identifier ("char"),
11233 pushdecl (build_decl (TYPE_DECL, get_identifier ("long int"),
11234 long_integer_type_node));
11235 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned int"),
11236 unsigned_type_node));
11237 pushdecl (build_decl (TYPE_DECL, get_identifier ("long unsigned int"),
11238 long_unsigned_type_node));
11239 pushdecl (build_decl (TYPE_DECL, get_identifier ("long long int"),
11240 long_long_integer_type_node));
11241 pushdecl (build_decl (TYPE_DECL, get_identifier ("long long unsigned int"),
11242 long_long_unsigned_type_node));
11243 pushdecl (build_decl (TYPE_DECL, get_identifier ("short int"),
11244 short_integer_type_node));
11245 pushdecl (build_decl (TYPE_DECL, get_identifier ("short unsigned int"),
11246 short_unsigned_type_node));
11248 /* Set the sizetype before we make other types. This *should* be the
11249 first type we create. */
11252 (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE))));
11253 ffecom_typesize_pointer_
11254 = TREE_INT_CST_LOW (TYPE_SIZE (sizetype)) / BITS_PER_UNIT;
11256 build_common_tree_nodes_2 (0);
11258 /* Define both `signed char' and `unsigned char'. */
11259 pushdecl (build_decl (TYPE_DECL, get_identifier ("signed char"),
11260 signed_char_type_node));
11262 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned char"),
11263 unsigned_char_type_node));
11265 pushdecl (build_decl (TYPE_DECL, get_identifier ("float"),
11267 pushdecl (build_decl (TYPE_DECL, get_identifier ("double"),
11268 double_type_node));
11269 pushdecl (build_decl (TYPE_DECL, get_identifier ("long double"),
11270 long_double_type_node));
11272 /* For now, override what build_common_tree_nodes has done. */
11273 complex_integer_type_node = ffecom_make_complex_type_ (integer_type_node);
11274 complex_float_type_node = ffecom_make_complex_type_ (float_type_node);
11275 complex_double_type_node = ffecom_make_complex_type_ (double_type_node);
11276 complex_long_double_type_node
11277 = ffecom_make_complex_type_ (long_double_type_node);
11279 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex int"),
11280 complex_integer_type_node));
11281 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex float"),
11282 complex_float_type_node));
11283 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex double"),
11284 complex_double_type_node));
11285 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex long double"),
11286 complex_long_double_type_node));
11288 pushdecl (build_decl (TYPE_DECL, get_identifier ("void"),
11290 /* We are not going to have real types in C with less than byte alignment,
11291 so we might as well not have any types that claim to have it. */
11292 TYPE_ALIGN (void_type_node) = BITS_PER_UNIT;
11293 TYPE_USER_ALIGN (void_type_node) = 0;
11295 string_type_node = build_pointer_type (char_type_node);
11297 ffecom_tree_fun_type_void
11298 = build_function_type (void_type_node, NULL_TREE);
11300 ffecom_tree_ptr_to_fun_type_void
11301 = build_pointer_type (ffecom_tree_fun_type_void);
11303 endlink = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
11306 = build_function_type (float_type_node,
11307 tree_cons (NULL_TREE, float_type_node, endlink));
11309 double_ftype_double
11310 = build_function_type (double_type_node,
11311 tree_cons (NULL_TREE, double_type_node, endlink));
11313 ldouble_ftype_ldouble
11314 = build_function_type (long_double_type_node,
11315 tree_cons (NULL_TREE, long_double_type_node,
11318 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11319 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11321 ffecom_tree_type[i][j] = NULL_TREE;
11322 ffecom_tree_fun_type[i][j] = NULL_TREE;
11323 ffecom_tree_ptr_to_fun_type[i][j] = NULL_TREE;
11324 ffecom_f2c_typecode_[i][j] = -1;
11327 /* Set up standard g77 types. Note that INTEGER and LOGICAL are set
11328 to size FLOAT_TYPE_SIZE because they have to be the same size as
11329 REAL, which also is FLOAT_TYPE_SIZE, according to the standard.
11330 Compiler options and other such stuff that change the ways these
11331 types are set should not affect this particular setup. */
11333 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER1]
11334 = t = make_signed_type (FLOAT_TYPE_SIZE);
11335 pushdecl (build_decl (TYPE_DECL, get_identifier ("integer"),
11337 type = ffetype_new ();
11339 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER1,
11341 ffetype_set_ams (type,
11342 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11343 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11344 ffetype_set_star (base_type,
11345 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11347 ffetype_set_kind (base_type, 1, type);
11348 ffecom_typesize_integer1_ = ffetype_size (type);
11349 assert (ffetype_size (type) == sizeof (ffetargetInteger1));
11351 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER1]
11352 = t = make_unsigned_type (FLOAT_TYPE_SIZE); /* HOLLERITH means unsigned. */
11353 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned"),
11356 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER2]
11357 = t = make_signed_type (CHAR_TYPE_SIZE);
11358 pushdecl (build_decl (TYPE_DECL, get_identifier ("byte"),
11360 type = ffetype_new ();
11361 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER2,
11363 ffetype_set_ams (type,
11364 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11365 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11366 ffetype_set_star (base_type,
11367 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11369 ffetype_set_kind (base_type, 3, type);
11370 assert (ffetype_size (type) == sizeof (ffetargetInteger2));
11372 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER2]
11373 = t = make_unsigned_type (CHAR_TYPE_SIZE);
11374 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned byte"),
11377 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER3]
11378 = t = make_signed_type (CHAR_TYPE_SIZE * 2);
11379 pushdecl (build_decl (TYPE_DECL, get_identifier ("word"),
11381 type = ffetype_new ();
11382 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER3,
11384 ffetype_set_ams (type,
11385 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11386 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11387 ffetype_set_star (base_type,
11388 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11390 ffetype_set_kind (base_type, 6, type);
11391 assert (ffetype_size (type) == sizeof (ffetargetInteger3));
11393 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER3]
11394 = t = make_unsigned_type (CHAR_TYPE_SIZE * 2);
11395 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned word"),
11398 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER4]
11399 = t = make_signed_type (FLOAT_TYPE_SIZE * 2);
11400 pushdecl (build_decl (TYPE_DECL, get_identifier ("integer4"),
11402 type = ffetype_new ();
11403 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER4,
11405 ffetype_set_ams (type,
11406 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11407 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11408 ffetype_set_star (base_type,
11409 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11411 ffetype_set_kind (base_type, 2, type);
11412 assert (ffetype_size (type) == sizeof (ffetargetInteger4));
11414 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER4]
11415 = t = make_unsigned_type (FLOAT_TYPE_SIZE * 2);
11416 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned4"),
11420 if (ffe_is_do_internal_checks ()
11421 && LONG_TYPE_SIZE != FLOAT_TYPE_SIZE
11422 && LONG_TYPE_SIZE != CHAR_TYPE_SIZE
11423 && LONG_TYPE_SIZE != SHORT_TYPE_SIZE
11424 && LONG_TYPE_SIZE != LONG_LONG_TYPE_SIZE)
11426 fprintf (stderr, "Sorry, no g77 support for LONG_TYPE_SIZE (%d bits) yet.\n",
11431 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL1]
11432 = t = make_signed_type (FLOAT_TYPE_SIZE);
11433 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical"),
11435 type = ffetype_new ();
11437 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL1,
11439 ffetype_set_ams (type,
11440 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11441 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11442 ffetype_set_star (base_type,
11443 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11445 ffetype_set_kind (base_type, 1, type);
11446 assert (ffetype_size (type) == sizeof (ffetargetLogical1));
11448 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL2]
11449 = t = make_signed_type (CHAR_TYPE_SIZE);
11450 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical2"),
11452 type = ffetype_new ();
11453 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL2,
11455 ffetype_set_ams (type,
11456 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11457 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11458 ffetype_set_star (base_type,
11459 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11461 ffetype_set_kind (base_type, 3, type);
11462 assert (ffetype_size (type) == sizeof (ffetargetLogical2));
11464 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL3]
11465 = t = make_signed_type (CHAR_TYPE_SIZE * 2);
11466 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical3"),
11468 type = ffetype_new ();
11469 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL3,
11471 ffetype_set_ams (type,
11472 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11473 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11474 ffetype_set_star (base_type,
11475 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11477 ffetype_set_kind (base_type, 6, type);
11478 assert (ffetype_size (type) == sizeof (ffetargetLogical3));
11480 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL4]
11481 = t = make_signed_type (FLOAT_TYPE_SIZE * 2);
11482 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical4"),
11484 type = ffetype_new ();
11485 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL4,
11487 ffetype_set_ams (type,
11488 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11489 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11490 ffetype_set_star (base_type,
11491 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11493 ffetype_set_kind (base_type, 2, type);
11494 assert (ffetype_size (type) == sizeof (ffetargetLogical4));
11496 ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]
11497 = t = make_node (REAL_TYPE);
11498 TYPE_PRECISION (t) = FLOAT_TYPE_SIZE;
11499 pushdecl (build_decl (TYPE_DECL, get_identifier ("real"),
11502 type = ffetype_new ();
11504 ffeinfo_set_type (FFEINFO_basictypeREAL, FFEINFO_kindtypeREAL1,
11506 ffetype_set_ams (type,
11507 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11508 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11509 ffetype_set_star (base_type,
11510 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11512 ffetype_set_kind (base_type, 1, type);
11513 ffecom_f2c_typecode_[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]
11514 = FFETARGET_f2cTYREAL;
11515 assert (ffetype_size (type) == sizeof (ffetargetReal1));
11517 ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREALDOUBLE]
11518 = t = make_node (REAL_TYPE);
11519 TYPE_PRECISION (t) = FLOAT_TYPE_SIZE * 2; /* Always twice REAL. */
11520 pushdecl (build_decl (TYPE_DECL, get_identifier ("double precision"),
11523 type = ffetype_new ();
11524 ffeinfo_set_type (FFEINFO_basictypeREAL, FFEINFO_kindtypeREALDOUBLE,
11526 ffetype_set_ams (type,
11527 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11528 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11529 ffetype_set_star (base_type,
11530 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11532 ffetype_set_kind (base_type, 2, type);
11533 ffecom_f2c_typecode_[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2]
11534 = FFETARGET_f2cTYDREAL;
11535 assert (ffetype_size (type) == sizeof (ffetargetReal2));
11537 ffecom_tree_type[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL1]
11538 = t = ffecom_make_complex_type_ (ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]);
11539 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex"),
11541 type = ffetype_new ();
11543 ffeinfo_set_type (FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREAL1,
11545 ffetype_set_ams (type,
11546 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11547 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11548 ffetype_set_star (base_type,
11549 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11551 ffetype_set_kind (base_type, 1, type);
11552 ffecom_f2c_typecode_[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL1]
11553 = FFETARGET_f2cTYCOMPLEX;
11554 assert (ffetype_size (type) == sizeof (ffetargetComplex1));
11556 ffecom_tree_type[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREALDOUBLE]
11557 = t = ffecom_make_complex_type_ (ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2]);
11558 pushdecl (build_decl (TYPE_DECL, get_identifier ("double complex"),
11560 type = ffetype_new ();
11561 ffeinfo_set_type (FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREALDOUBLE,
11563 ffetype_set_ams (type,
11564 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11565 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11566 ffetype_set_star (base_type,
11567 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11569 ffetype_set_kind (base_type, 2,
11571 ffecom_f2c_typecode_[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL2]
11572 = FFETARGET_f2cTYDCOMPLEX;
11573 assert (ffetype_size (type) == sizeof (ffetargetComplex2));
11575 /* Make function and ptr-to-function types for non-CHARACTER types. */
11577 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11578 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11580 if ((t = ffecom_tree_type[i][j]) != NULL_TREE)
11582 if (i == FFEINFO_basictypeINTEGER)
11584 /* Figure out the smallest INTEGER type that can hold
11585 a pointer on this machine. */
11586 if (GET_MODE_SIZE (TYPE_MODE (t))
11587 >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
11589 if ((ffecom_pointer_kind_ == FFEINFO_kindtypeNONE)
11590 || (GET_MODE_SIZE (TYPE_MODE (ffecom_tree_type[i][ffecom_pointer_kind_]))
11591 > GET_MODE_SIZE (TYPE_MODE (t))))
11592 ffecom_pointer_kind_ = j;
11595 else if (i == FFEINFO_basictypeCOMPLEX)
11596 t = void_type_node;
11597 /* For f2c compatibility, REAL functions are really
11598 implemented as DOUBLE PRECISION. */
11599 else if ((i == FFEINFO_basictypeREAL)
11600 && (j == FFEINFO_kindtypeREAL1))
11601 t = ffecom_tree_type
11602 [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2];
11604 t = ffecom_tree_fun_type[i][j] = build_function_type (t,
11606 ffecom_tree_ptr_to_fun_type[i][j] = build_pointer_type (t);
11610 /* Set up pointer types. */
11612 if (ffecom_pointer_kind_ == FFEINFO_basictypeNONE)
11613 fatal_error ("no INTEGER type can hold a pointer on this configuration");
11614 else if (0 && ffe_is_do_internal_checks ())
11615 fprintf (stderr, "Pointer type kt=%d\n", ffecom_pointer_kind_);
11616 ffetype_set_kind (ffeinfo_type (FFEINFO_basictypeINTEGER,
11617 FFEINFO_kindtypeINTEGERDEFAULT),
11619 ffeinfo_type (FFEINFO_basictypeINTEGER,
11620 ffecom_pointer_kind_));
11622 if (ffe_is_ugly_assign ())
11623 ffecom_label_kind_ = ffecom_pointer_kind_; /* Require ASSIGN etc to this. */
11625 ffecom_label_kind_ = FFEINFO_kindtypeINTEGERDEFAULT;
11626 if (0 && ffe_is_do_internal_checks ())
11627 fprintf (stderr, "Label type kt=%d\n", ffecom_label_kind_);
11629 ffecom_integer_type_node
11630 = ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER1];
11631 ffecom_integer_zero_node = convert (ffecom_integer_type_node,
11632 integer_zero_node);
11633 ffecom_integer_one_node = convert (ffecom_integer_type_node,
11636 /* Yes, the "FLOAT_TYPE_SIZE" references below are intentional.
11637 Turns out that by TYLONG, runtime/libI77/lio.h really means
11638 "whatever size an ftnint is". For consistency and sanity,
11639 com.h and runtime/f2c.h.in agree that flag, ftnint, and ftlen
11640 all are INTEGER, which we also make out of whatever back-end
11641 integer type is FLOAT_TYPE_SIZE bits wide. This change, from
11642 LONG_TYPE_SIZE, for TYLONG and TYLOGICAL, was necessary to
11643 accommodate machines like the Alpha. Note that this suggests
11644 f2c and libf2c are missing a distinction perhaps needed on
11645 some machines between "int" and "long int". -- burley 0.5.5 950215 */
11647 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, FLOAT_TYPE_SIZE,
11648 FFETARGET_f2cTYLONG);
11649 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, SHORT_TYPE_SIZE,
11650 FFETARGET_f2cTYSHORT);
11651 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, CHAR_TYPE_SIZE,
11652 FFETARGET_f2cTYINT1);
11653 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, LONG_LONG_TYPE_SIZE,
11654 FFETARGET_f2cTYQUAD);
11655 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, FLOAT_TYPE_SIZE,
11656 FFETARGET_f2cTYLOGICAL);
11657 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, SHORT_TYPE_SIZE,
11658 FFETARGET_f2cTYLOGICAL2);
11659 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, CHAR_TYPE_SIZE,
11660 FFETARGET_f2cTYLOGICAL1);
11661 /* ~~~Not really such a type in libf2c, e.g. I/O support? */
11662 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, LONG_LONG_TYPE_SIZE,
11663 FFETARGET_f2cTYQUAD);
11665 /* CHARACTER stuff is all special-cased, so it is not handled in the above
11666 loop. CHARACTER items are built as arrays of unsigned char. */
11668 ffecom_tree_type[FFEINFO_basictypeCHARACTER]
11669 [FFEINFO_kindtypeCHARACTER1] = t = char_type_node;
11670 type = ffetype_new ();
11672 ffeinfo_set_type (FFEINFO_basictypeCHARACTER,
11673 FFEINFO_kindtypeCHARACTER1,
11675 ffetype_set_ams (type,
11676 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11677 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11678 ffetype_set_kind (base_type, 1, type);
11679 assert (ffetype_size (type)
11680 == sizeof (((ffetargetCharacter1) { 0, NULL }).text[0]));
11682 ffecom_tree_fun_type[FFEINFO_basictypeCHARACTER]
11683 [FFEINFO_kindtypeCHARACTER1] = ffecom_tree_fun_type_void;
11684 ffecom_tree_ptr_to_fun_type[FFEINFO_basictypeCHARACTER]
11685 [FFEINFO_kindtypeCHARACTER1]
11686 = ffecom_tree_ptr_to_fun_type_void;
11687 ffecom_f2c_typecode_[FFEINFO_basictypeCHARACTER][FFEINFO_kindtypeCHARACTER1]
11688 = FFETARGET_f2cTYCHAR;
11690 ffecom_f2c_typecode_[FFEINFO_basictypeANY][FFEINFO_kindtypeANY]
11693 /* Make multi-return-value type and fields. */
11695 ffecom_multi_type_node_ = make_node (UNION_TYPE);
11699 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11700 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11704 if (ffecom_tree_type[i][j] == NULL_TREE)
11705 continue; /* Not supported. */
11706 sprintf (&name[0], "bt_%s_kt_%s",
11707 ffeinfo_basictype_string ((ffeinfoBasictype) i),
11708 ffeinfo_kindtype_string ((ffeinfoKindtype) j));
11709 ffecom_multi_fields_[i][j] = build_decl (FIELD_DECL,
11710 get_identifier (name),
11711 ffecom_tree_type[i][j]);
11712 DECL_CONTEXT (ffecom_multi_fields_[i][j])
11713 = ffecom_multi_type_node_;
11714 DECL_ALIGN (ffecom_multi_fields_[i][j]) = 0;
11715 DECL_USER_ALIGN (ffecom_multi_fields_[i][j]) = 0;
11716 TREE_CHAIN (ffecom_multi_fields_[i][j]) = field;
11717 field = ffecom_multi_fields_[i][j];
11720 TYPE_FIELDS (ffecom_multi_type_node_) = field;
11721 layout_type (ffecom_multi_type_node_);
11723 /* Subroutines usually return integer because they might have alternate
11726 ffecom_tree_subr_type
11727 = build_function_type (integer_type_node, NULL_TREE);
11728 ffecom_tree_ptr_to_subr_type
11729 = build_pointer_type (ffecom_tree_subr_type);
11730 ffecom_tree_blockdata_type
11731 = build_function_type (void_type_node, NULL_TREE);
11733 builtin_function ("__builtin_sqrtf", float_ftype_float,
11734 BUILT_IN_SQRTF, BUILT_IN_NORMAL, "sqrtf");
11735 builtin_function ("__builtin_sqrt", double_ftype_double,
11736 BUILT_IN_SQRT, BUILT_IN_NORMAL, "sqrt");
11737 builtin_function ("__builtin_sqrtl", ldouble_ftype_ldouble,
11738 BUILT_IN_SQRTL, BUILT_IN_NORMAL, "sqrtl");
11739 builtin_function ("__builtin_sinf", float_ftype_float,
11740 BUILT_IN_SINF, BUILT_IN_NORMAL, "sinf");
11741 builtin_function ("__builtin_sin", double_ftype_double,
11742 BUILT_IN_SIN, BUILT_IN_NORMAL, "sin");
11743 builtin_function ("__builtin_sinl", ldouble_ftype_ldouble,
11744 BUILT_IN_SINL, BUILT_IN_NORMAL, "sinl");
11745 builtin_function ("__builtin_cosf", float_ftype_float,
11746 BUILT_IN_COSF, BUILT_IN_NORMAL, "cosf");
11747 builtin_function ("__builtin_cos", double_ftype_double,
11748 BUILT_IN_COS, BUILT_IN_NORMAL, "cos");
11749 builtin_function ("__builtin_cosl", ldouble_ftype_ldouble,
11750 BUILT_IN_COSL, BUILT_IN_NORMAL, "cosl");
11752 pedantic_lvalues = FALSE;
11754 ffecom_f2c_make_type_ (&ffecom_f2c_integer_type_node,
11757 ffecom_f2c_make_type_ (&ffecom_f2c_address_type_node,
11760 ffecom_f2c_make_type_ (&ffecom_f2c_real_type_node,
11763 ffecom_f2c_make_type_ (&ffecom_f2c_doublereal_type_node,
11764 FFECOM_f2cDOUBLEREAL,
11766 ffecom_f2c_make_type_ (&ffecom_f2c_complex_type_node,
11769 ffecom_f2c_make_type_ (&ffecom_f2c_doublecomplex_type_node,
11770 FFECOM_f2cDOUBLECOMPLEX,
11772 ffecom_f2c_make_type_ (&ffecom_f2c_longint_type_node,
11775 ffecom_f2c_make_type_ (&ffecom_f2c_logical_type_node,
11778 ffecom_f2c_make_type_ (&ffecom_f2c_flag_type_node,
11781 ffecom_f2c_make_type_ (&ffecom_f2c_ftnlen_type_node,
11784 ffecom_f2c_make_type_ (&ffecom_f2c_ftnint_type_node,
11788 ffecom_f2c_ftnlen_zero_node
11789 = convert (ffecom_f2c_ftnlen_type_node, integer_zero_node);
11791 ffecom_f2c_ftnlen_one_node
11792 = convert (ffecom_f2c_ftnlen_type_node, integer_one_node);
11794 ffecom_f2c_ftnlen_two_node = build_int_2 (2, 0);
11795 TREE_TYPE (ffecom_f2c_ftnlen_two_node) = ffecom_integer_type_node;
11797 ffecom_f2c_ptr_to_ftnlen_type_node
11798 = build_pointer_type (ffecom_f2c_ftnlen_type_node);
11800 ffecom_f2c_ptr_to_ftnint_type_node
11801 = build_pointer_type (ffecom_f2c_ftnint_type_node);
11803 ffecom_f2c_ptr_to_integer_type_node
11804 = build_pointer_type (ffecom_f2c_integer_type_node);
11806 ffecom_f2c_ptr_to_real_type_node
11807 = build_pointer_type (ffecom_f2c_real_type_node);
11809 ffecom_float_zero_ = build_real (float_type_node, dconst0);
11810 ffecom_double_zero_ = build_real (double_type_node, dconst0);
11812 REAL_VALUE_TYPE point_5;
11814 REAL_ARITHMETIC (point_5, RDIV_EXPR, dconst1, dconst2);
11815 ffecom_float_half_ = build_real (float_type_node, point_5);
11816 ffecom_double_half_ = build_real (double_type_node, point_5);
11819 /* Do "extern int xargc;". */
11821 ffecom_tree_xargc_ = build_decl (VAR_DECL,
11822 get_identifier ("f__xargc"),
11823 integer_type_node);
11824 DECL_EXTERNAL (ffecom_tree_xargc_) = 1;
11825 TREE_STATIC (ffecom_tree_xargc_) = 1;
11826 TREE_PUBLIC (ffecom_tree_xargc_) = 1;
11827 ffecom_tree_xargc_ = start_decl (ffecom_tree_xargc_, FALSE);
11828 finish_decl (ffecom_tree_xargc_, NULL_TREE, FALSE);
11830 #if 0 /* This is being fixed, and seems to be working now. */
11831 if ((FLOAT_TYPE_SIZE != 32)
11832 || (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node))) != 32))
11834 warning ("configuration: REAL, INTEGER, and LOGICAL are %d bits wide,",
11835 (int) FLOAT_TYPE_SIZE);
11836 warning ("and pointers are %d bits wide, but g77 doesn't yet work",
11837 (int) TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node))));
11838 warning ("properly unless they all are 32 bits wide");
11839 warning ("Please keep this in mind before you report bugs.");
11843 #if 0 /* Code in ste.c that would crash has been commented out. */
11844 if (TYPE_PRECISION (ffecom_f2c_ftnlen_type_node)
11845 < TYPE_PRECISION (string_type_node))
11846 /* I/O will probably crash. */
11847 warning ("configuration: char * holds %d bits, but ftnlen only %d",
11848 TYPE_PRECISION (string_type_node),
11849 TYPE_PRECISION (ffecom_f2c_ftnlen_type_node));
11852 #if 0 /* ASSIGN-related stuff has been changed to accommodate this. */
11853 if (TYPE_PRECISION (ffecom_integer_type_node)
11854 < TYPE_PRECISION (string_type_node))
11855 /* ASSIGN 10 TO I will crash. */
11856 warning ("configuration: char * holds %d bits, but INTEGER only %d --\n\
11857 ASSIGN statement might fail",
11858 TYPE_PRECISION (string_type_node),
11859 TYPE_PRECISION (ffecom_integer_type_node));
11863 /* ffecom_init_2 -- Initialize
11865 ffecom_init_2(); */
11870 assert (ffecom_outer_function_decl_ == NULL_TREE);
11871 assert (current_function_decl == NULL_TREE);
11872 assert (ffecom_which_entrypoint_decl_ == NULL_TREE);
11874 ffecom_master_arglist_ = NULL;
11876 ffecom_primary_entry_ = NULL;
11877 ffecom_is_altreturning_ = FALSE;
11878 ffecom_func_result_ = NULL_TREE;
11879 ffecom_multi_retval_ = NULL_TREE;
11882 /* ffecom_list_expr -- Transform list of exprs into gcc tree
11885 ffebld expr; // FFE opITEM list.
11886 tree = ffecom_list_expr(expr);
11888 List of actual args is transformed into corresponding gcc backend list. */
11891 ffecom_list_expr (ffebld expr)
11894 tree *plist = &list;
11895 tree trail = NULL_TREE; /* Append char length args here. */
11896 tree *ptrail = &trail;
11899 while (expr != NULL)
11901 tree texpr = ffecom_arg_expr (ffebld_head (expr), &length);
11903 if (texpr == error_mark_node)
11904 return error_mark_node;
11906 *plist = build_tree_list (NULL_TREE, texpr);
11907 plist = &TREE_CHAIN (*plist);
11908 expr = ffebld_trail (expr);
11909 if (length != NULL_TREE)
11911 *ptrail = build_tree_list (NULL_TREE, length);
11912 ptrail = &TREE_CHAIN (*ptrail);
11921 /* ffecom_list_ptr_to_expr -- Transform list of exprs into gcc tree
11924 ffebld expr; // FFE opITEM list.
11925 tree = ffecom_list_ptr_to_expr(expr);
11927 List of actual args is transformed into corresponding gcc backend list for
11928 use in calling an external procedure (vs. a statement function). */
11931 ffecom_list_ptr_to_expr (ffebld expr)
11934 tree *plist = &list;
11935 tree trail = NULL_TREE; /* Append char length args here. */
11936 tree *ptrail = &trail;
11939 while (expr != NULL)
11941 tree texpr = ffecom_arg_ptr_to_expr (ffebld_head (expr), &length);
11943 if (texpr == error_mark_node)
11944 return error_mark_node;
11946 *plist = build_tree_list (NULL_TREE, texpr);
11947 plist = &TREE_CHAIN (*plist);
11948 expr = ffebld_trail (expr);
11949 if (length != NULL_TREE)
11951 *ptrail = build_tree_list (NULL_TREE, length);
11952 ptrail = &TREE_CHAIN (*ptrail);
11961 /* Obtain gcc's LABEL_DECL tree for label. */
11964 ffecom_lookup_label (ffelab label)
11968 if (ffelab_hook (label) == NULL_TREE)
11970 char labelname[16];
11972 switch (ffelab_type (label))
11974 case FFELAB_typeLOOPEND:
11975 case FFELAB_typeNOTLOOP:
11976 case FFELAB_typeENDIF:
11977 sprintf (labelname, "%" ffelabValue_f "u", ffelab_value (label));
11978 glabel = build_decl (LABEL_DECL, get_identifier (labelname),
11980 DECL_CONTEXT (glabel) = current_function_decl;
11981 DECL_MODE (glabel) = VOIDmode;
11984 case FFELAB_typeFORMAT:
11985 glabel = build_decl (VAR_DECL,
11986 ffecom_get_invented_identifier
11987 ("__g77_format_%d", (int) ffelab_value (label)),
11988 build_type_variant (build_array_type
11992 TREE_CONSTANT (glabel) = 1;
11993 TREE_STATIC (glabel) = 1;
11994 DECL_CONTEXT (glabel) = current_function_decl;
11995 DECL_INITIAL (glabel) = NULL;
11996 make_decl_rtl (glabel, NULL);
11997 expand_decl (glabel);
11999 ffecom_save_tree_forever (glabel);
12003 case FFELAB_typeANY:
12004 glabel = error_mark_node;
12008 assert ("bad label type" == NULL);
12012 ffelab_set_hook (label, glabel);
12016 glabel = ffelab_hook (label);
12022 /* Stabilizes the arguments. Don't use this if the lhs and rhs come from
12023 a single source specification (as in the fourth argument of MVBITS).
12024 If the type is NULL_TREE, the type of lhs is used to make the type of
12025 the MODIFY_EXPR. */
12028 ffecom_modify (tree newtype, tree lhs,
12031 if (lhs == error_mark_node || rhs == error_mark_node)
12032 return error_mark_node;
12034 if (newtype == NULL_TREE)
12035 newtype = TREE_TYPE (lhs);
12037 if (TREE_SIDE_EFFECTS (lhs))
12038 lhs = stabilize_reference (lhs);
12040 return ffecom_2s (MODIFY_EXPR, newtype, lhs, rhs);
12043 /* Register source file name. */
12046 ffecom_file (const char *name)
12048 ffecom_file_ (name);
12051 /* ffecom_notify_init_storage -- An aggregate storage is now fully init'ed
12054 ffecom_notify_init_storage(st);
12056 Gets called when all possible units in an aggregate storage area (a LOCAL
12057 with equivalences or a COMMON) have been initialized. The initialization
12058 info either is in ffestorag_init or, if that is NULL,
12059 ffestorag_accretion:
12061 ffestorag_init may contain an opCONTER or opARRTER. opCONTER may occur
12062 even for an array if the array is one element in length!
12064 ffestorag_accretion will contain an opACCTER. It is much like an
12065 opARRTER except it has an ffebit object in it instead of just a size.
12066 The back end can use the info in the ffebit object, if it wants, to
12067 reduce the amount of actual initialization, but in any case it should
12068 kill the ffebit object when done. Also, set accretion to NULL but
12069 init to a non-NULL value.
12071 After performing initialization, DO NOT set init to NULL, because that'll
12072 tell the front end it is ok for more initialization to happen. Instead,
12073 set init to an opANY expression or some such thing that you can use to
12074 tell that you've already initialized the object.
12077 Support two-pass FFE. */
12080 ffecom_notify_init_storage (ffestorag st)
12082 ffebld init; /* The initialization expression. */
12084 if (ffestorag_init (st) == NULL)
12086 init = ffestorag_accretion (st);
12087 assert (init != NULL);
12088 ffestorag_set_accretion (st, NULL);
12089 ffestorag_set_accretes (st, 0);
12090 ffestorag_set_init (st, init);
12094 /* ffecom_notify_init_symbol -- A symbol is now fully init'ed
12097 ffecom_notify_init_symbol(s);
12099 Gets called when all possible units in a symbol (not placed in COMMON
12100 or involved in EQUIVALENCE, unless it as yet has no ffestorag object)
12101 have been initialized. The initialization info either is in
12102 ffesymbol_init or, if that is NULL, ffesymbol_accretion:
12104 ffesymbol_init may contain an opCONTER or opARRTER. opCONTER may occur
12105 even for an array if the array is one element in length!
12107 ffesymbol_accretion will contain an opACCTER. It is much like an
12108 opARRTER except it has an ffebit object in it instead of just a size.
12109 The back end can use the info in the ffebit object, if it wants, to
12110 reduce the amount of actual initialization, but in any case it should
12111 kill the ffebit object when done. Also, set accretion to NULL but
12112 init to a non-NULL value.
12114 After performing initialization, DO NOT set init to NULL, because that'll
12115 tell the front end it is ok for more initialization to happen. Instead,
12116 set init to an opANY expression or some such thing that you can use to
12117 tell that you've already initialized the object.
12120 Support two-pass FFE. */
12123 ffecom_notify_init_symbol (ffesymbol s)
12125 ffebld init; /* The initialization expression. */
12127 if (ffesymbol_storage (s) == NULL)
12128 return; /* Do nothing until COMMON/EQUIVALENCE
12129 possibilities checked. */
12131 if ((ffesymbol_init (s) == NULL)
12132 && ((init = ffesymbol_accretion (s)) != NULL))
12134 ffesymbol_set_accretion (s, NULL);
12135 ffesymbol_set_accretes (s, 0);
12136 ffesymbol_set_init (s, init);
12140 /* ffecom_notify_primary_entry -- Learn which is the primary entry point
12143 ffecom_notify_primary_entry(s);
12145 Gets called when implicit or explicit PROGRAM statement seen or when
12146 FUNCTION, SUBROUTINE, or BLOCK DATA statement seen, with the primary
12147 global symbol that serves as the entry point. */
12150 ffecom_notify_primary_entry (ffesymbol s)
12152 ffecom_primary_entry_ = s;
12153 ffecom_primary_entry_kind_ = ffesymbol_kind (s);
12155 if ((ffecom_primary_entry_kind_ == FFEINFO_kindFUNCTION)
12156 || (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE))
12157 ffecom_primary_entry_is_proc_ = TRUE;
12159 ffecom_primary_entry_is_proc_ = FALSE;
12161 if (!ffe_is_silent ())
12163 if (ffecom_primary_entry_kind_ == FFEINFO_kindPROGRAM)
12164 fprintf (stderr, "%s:\n", ffesymbol_text (s));
12166 fprintf (stderr, " %s:\n", ffesymbol_text (s));
12169 if (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE)
12174 for (list = ffesymbol_dummyargs (s);
12176 list = ffebld_trail (list))
12178 arg = ffebld_head (list);
12179 if (ffebld_op (arg) == FFEBLD_opSTAR)
12181 ffecom_is_altreturning_ = TRUE;
12189 ffecom_open_include (char *name, ffewhereLine l, ffewhereColumn c)
12191 return ffecom_open_include_ (name, l, c);
12194 /* ffecom_ptr_to_expr -- Transform expr into gcc tree with & in front
12197 ffebld expr; // FFE expression.
12198 tree = ffecom_ptr_to_expr(expr);
12200 Like ffecom_expr, but sticks address-of in front of most things. */
12203 ffecom_ptr_to_expr (ffebld expr)
12206 ffeinfoBasictype bt;
12207 ffeinfoKindtype kt;
12210 assert (expr != NULL);
12212 switch (ffebld_op (expr))
12214 case FFEBLD_opSYMTER:
12215 s = ffebld_symter (expr);
12216 if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC)
12220 ix = ffeintrin_gfrt_indirect (ffebld_symter_implementation (expr));
12221 assert (ix != FFECOM_gfrt);
12222 if ((item = ffecom_gfrt_[ix]) == NULL_TREE)
12224 ffecom_make_gfrt_ (ix);
12225 item = ffecom_gfrt_[ix];
12230 item = ffesymbol_hook (s).decl_tree;
12231 if (item == NULL_TREE)
12233 s = ffecom_sym_transform_ (s);
12234 item = ffesymbol_hook (s).decl_tree;
12237 assert (item != NULL);
12238 if (item == error_mark_node)
12240 if (!ffesymbol_hook (s).addr)
12241 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12245 case FFEBLD_opARRAYREF:
12246 return ffecom_arrayref_ (NULL_TREE, expr, 1);
12248 case FFEBLD_opCONTER:
12250 bt = ffeinfo_basictype (ffebld_info (expr));
12251 kt = ffeinfo_kindtype (ffebld_info (expr));
12253 item = ffecom_constantunion (&ffebld_constant_union
12254 (ffebld_conter (expr)), bt, kt,
12255 ffecom_tree_type[bt][kt]);
12256 if (item == error_mark_node)
12257 return error_mark_node;
12258 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12263 return error_mark_node;
12266 bt = ffeinfo_basictype (ffebld_info (expr));
12267 kt = ffeinfo_kindtype (ffebld_info (expr));
12269 item = ffecom_expr (expr);
12270 if (item == error_mark_node)
12271 return error_mark_node;
12273 /* The back end currently optimizes a bit too zealously for us, in that
12274 we fail JCB001 if the following block of code is omitted. It checks
12275 to see if the transformed expression is a symbol or array reference,
12276 and encloses it in a SAVE_EXPR if that is the case. */
12279 if ((TREE_CODE (item) == VAR_DECL)
12280 || (TREE_CODE (item) == PARM_DECL)
12281 || (TREE_CODE (item) == RESULT_DECL)
12282 || (TREE_CODE (item) == INDIRECT_REF)
12283 || (TREE_CODE (item) == ARRAY_REF)
12284 || (TREE_CODE (item) == COMPONENT_REF)
12286 || (TREE_CODE (item) == OFFSET_REF)
12288 || (TREE_CODE (item) == BUFFER_REF)
12289 || (TREE_CODE (item) == REALPART_EXPR)
12290 || (TREE_CODE (item) == IMAGPART_EXPR))
12292 item = ffecom_save_tree (item);
12295 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12300 assert ("fall-through error" == NULL);
12301 return error_mark_node;
12304 /* Obtain a temp var with given data type.
12306 size is FFETARGET_charactersizeNONE for a non-CHARACTER type
12307 or >= 0 for a CHARACTER type.
12309 elements is -1 for a scalar or > 0 for an array of type. */
12312 ffecom_make_tempvar (const char *commentary, tree type,
12313 ffetargetCharacterSize size, int elements)
12316 static int mynumber;
12318 assert (current_binding_level->prep_state < 2);
12320 if (type == error_mark_node)
12321 return error_mark_node;
12323 if (size != FFETARGET_charactersizeNONE)
12324 type = build_array_type (type,
12325 build_range_type (ffecom_f2c_ftnlen_type_node,
12326 ffecom_f2c_ftnlen_one_node,
12327 build_int_2 (size, 0)));
12328 if (elements != -1)
12329 type = build_array_type (type,
12330 build_range_type (integer_type_node,
12332 build_int_2 (elements - 1,
12334 t = build_decl (VAR_DECL,
12335 ffecom_get_invented_identifier ("__g77_%s_%d",
12340 t = start_decl (t, FALSE);
12341 finish_decl (t, NULL_TREE, FALSE);
12346 /* Prepare argument pointer to expression.
12348 Like ffecom_prepare_expr, except for expressions to be evaluated
12349 via ffecom_arg_ptr_to_expr. */
12352 ffecom_prepare_arg_ptr_to_expr (ffebld expr)
12354 /* ~~For now, it seems to be the same thing. */
12355 ffecom_prepare_expr (expr);
12359 /* End of preparations. */
12362 ffecom_prepare_end (void)
12364 int prep_state = current_binding_level->prep_state;
12366 assert (prep_state < 2);
12367 current_binding_level->prep_state = 2;
12369 return (prep_state == 1) ? TRUE : FALSE;
12372 /* Prepare expression.
12374 This is called before any code is generated for the current block.
12375 It scans the expression, declares any temporaries that might be needed
12376 during evaluation of the expression, and stores those temporaries in
12377 the appropriate "hook" fields of the expression. `dest', if not NULL,
12378 specifies the destination that ffecom_expr_ will see, in case that
12379 helps avoid generating unused temporaries.
12381 ~~Improve to avoid allocating unused temporaries by taking `dest'
12382 into account vis-a-vis aliasing requirements of complex/character
12386 ffecom_prepare_expr_ (ffebld expr, ffebld dest UNUSED)
12388 ffeinfoBasictype bt;
12389 ffeinfoKindtype kt;
12390 ffetargetCharacterSize sz;
12391 tree tempvar = NULL_TREE;
12393 assert (current_binding_level->prep_state < 2);
12398 bt = ffeinfo_basictype (ffebld_info (expr));
12399 kt = ffeinfo_kindtype (ffebld_info (expr));
12400 sz = ffeinfo_size (ffebld_info (expr));
12402 /* Generate whatever temporaries are needed to represent the result
12403 of the expression. */
12405 if (bt == FFEINFO_basictypeCHARACTER)
12407 while (ffebld_op (expr) == FFEBLD_opPAREN)
12408 expr = ffebld_left (expr);
12411 switch (ffebld_op (expr))
12414 /* Don't make temps for SYMTER, CONTER, etc. */
12415 if (ffebld_arity (expr) == 0)
12420 case FFEINFO_basictypeCOMPLEX:
12421 if (ffebld_op (expr) == FFEBLD_opFUNCREF)
12425 if (ffebld_op (ffebld_left (expr)) != FFEBLD_opSYMTER)
12428 s = ffebld_symter (ffebld_left (expr));
12429 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT
12430 || (ffesymbol_where (s) != FFEINFO_whereINTRINSIC
12431 && ! ffesymbol_is_f2c (s))
12432 || (ffesymbol_where (s) == FFEINFO_whereINTRINSIC
12433 && ! ffe_is_f2c_library ()))
12436 else if (ffebld_op (expr) == FFEBLD_opPOWER)
12438 /* Requires special treatment. There's no POW_CC function
12439 in libg2c, so POW_ZZ is used, which means we always
12440 need a double-complex temp, not a single-complex. */
12441 kt = FFEINFO_kindtypeREAL2;
12443 else if (ffebld_op (expr) != FFEBLD_opDIVIDE)
12444 /* The other ops don't need temps for complex operands. */
12447 /* ~~~Avoid making temps for some intrinsics, such as AIMAG(C),
12448 REAL(C). See 19990325-0.f, routine `check', for cases. */
12449 tempvar = ffecom_make_tempvar ("complex",
12451 [FFEINFO_basictypeCOMPLEX][kt],
12452 FFETARGET_charactersizeNONE,
12456 case FFEINFO_basictypeCHARACTER:
12457 if (ffebld_op (expr) != FFEBLD_opFUNCREF)
12460 if (sz == FFETARGET_charactersizeNONE)
12461 /* ~~Kludge alert! This should someday be fixed. */
12464 tempvar = ffecom_make_tempvar ("char", char_type_node, sz, -1);
12473 case FFEBLD_opPOWER:
12476 tree rtmp, ltmp, result;
12478 ltype = ffecom_type_expr (ffebld_left (expr));
12479 rtype = ffecom_type_expr (ffebld_right (expr));
12481 rtmp = ffecom_make_tempvar (rtype, FFETARGET_charactersizeNONE, -1);
12482 ltmp = ffecom_make_tempvar (ltype, FFETARGET_charactersizeNONE, -1);
12483 result = ffecom_make_tempvar (ltype, FFETARGET_charactersizeNONE, -1);
12485 tempvar = make_tree_vec (3);
12486 TREE_VEC_ELT (tempvar, 0) = rtmp;
12487 TREE_VEC_ELT (tempvar, 1) = ltmp;
12488 TREE_VEC_ELT (tempvar, 2) = result;
12493 case FFEBLD_opCONCATENATE:
12495 /* This gets special handling, because only one set of temps
12496 is needed for a tree of these -- the tree is treated as
12497 a flattened list of concatenations when generating code. */
12499 ffecomConcatList_ catlist;
12500 tree ltmp, itmp, result;
12504 catlist = ffecom_concat_list_new_ (expr, FFETARGET_charactersizeNONE);
12505 count = ffecom_concat_list_count_ (catlist);
12510 = ffecom_make_tempvar ("concat_len",
12511 ffecom_f2c_ftnlen_type_node,
12512 FFETARGET_charactersizeNONE, count);
12514 = ffecom_make_tempvar ("concat_item",
12515 ffecom_f2c_address_type_node,
12516 FFETARGET_charactersizeNONE, count);
12518 = ffecom_make_tempvar ("concat_res",
12520 ffecom_concat_list_maxlen_ (catlist),
12523 tempvar = make_tree_vec (3);
12524 TREE_VEC_ELT (tempvar, 0) = ltmp;
12525 TREE_VEC_ELT (tempvar, 1) = itmp;
12526 TREE_VEC_ELT (tempvar, 2) = result;
12529 for (i = 0; i < count; ++i)
12530 ffecom_prepare_arg_ptr_to_expr (ffecom_concat_list_expr_ (catlist,
12533 ffecom_concat_list_kill_ (catlist);
12537 ffebld_nonter_set_hook (expr, tempvar);
12538 current_binding_level->prep_state = 1;
12543 case FFEBLD_opCONVERT:
12544 if (bt == FFEINFO_basictypeCHARACTER
12545 && ((ffebld_size_known (ffebld_left (expr))
12546 == FFETARGET_charactersizeNONE)
12547 || (ffebld_size_known (ffebld_left (expr)) >= sz)))
12548 tempvar = ffecom_make_tempvar ("convert", char_type_node, sz, -1);
12554 ffebld_nonter_set_hook (expr, tempvar);
12555 current_binding_level->prep_state = 1;
12558 /* Prepare subexpressions for this expr. */
12560 switch (ffebld_op (expr))
12562 case FFEBLD_opPERCENT_LOC:
12563 ffecom_prepare_ptr_to_expr (ffebld_left (expr));
12566 case FFEBLD_opPERCENT_VAL:
12567 case FFEBLD_opPERCENT_REF:
12568 ffecom_prepare_expr (ffebld_left (expr));
12571 case FFEBLD_opPERCENT_DESCR:
12572 ffecom_prepare_arg_ptr_to_expr (ffebld_left (expr));
12575 case FFEBLD_opITEM:
12581 item = ffebld_trail (item))
12582 if (ffebld_head (item) != NULL)
12583 ffecom_prepare_expr (ffebld_head (item));
12588 /* Need to handle character conversion specially. */
12589 switch (ffebld_arity (expr))
12592 ffecom_prepare_expr (ffebld_left (expr));
12593 ffecom_prepare_expr (ffebld_right (expr));
12597 ffecom_prepare_expr (ffebld_left (expr));
12608 /* Prepare expression for reading and writing.
12610 Like ffecom_prepare_expr, except for expressions to be evaluated
12611 via ffecom_expr_rw. */
12614 ffecom_prepare_expr_rw (tree type, ffebld expr)
12616 /* This is all we support for now. */
12617 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
12619 /* ~~For now, it seems to be the same thing. */
12620 ffecom_prepare_expr (expr);
12624 /* Prepare expression for writing.
12626 Like ffecom_prepare_expr, except for expressions to be evaluated
12627 via ffecom_expr_w. */
12630 ffecom_prepare_expr_w (tree type, ffebld expr)
12632 /* This is all we support for now. */
12633 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
12635 /* ~~For now, it seems to be the same thing. */
12636 ffecom_prepare_expr (expr);
12640 /* Prepare expression for returning.
12642 Like ffecom_prepare_expr, except for expressions to be evaluated
12643 via ffecom_return_expr. */
12646 ffecom_prepare_return_expr (ffebld expr)
12648 assert (current_binding_level->prep_state < 2);
12650 if (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE
12651 && ffecom_is_altreturning_
12653 ffecom_prepare_expr (expr);
12656 /* Prepare pointer to expression.
12658 Like ffecom_prepare_expr, except for expressions to be evaluated
12659 via ffecom_ptr_to_expr. */
12662 ffecom_prepare_ptr_to_expr (ffebld expr)
12664 /* ~~For now, it seems to be the same thing. */
12665 ffecom_prepare_expr (expr);
12669 /* Transform expression into constant pointer-to-expression tree.
12671 If the expression can be transformed into a pointer-to-expression tree
12672 that is constant, that is done, and the tree returned. Else NULL_TREE
12675 That way, a caller can attempt to provide compile-time initialization
12676 of a variable and, if that fails, *then* choose to start a new block
12677 and resort to using temporaries, as appropriate. */
12680 ffecom_ptr_to_const_expr (ffebld expr)
12683 return integer_zero_node;
12685 if (ffebld_op (expr) == FFEBLD_opANY)
12686 return error_mark_node;
12688 if (ffebld_arity (expr) == 0
12689 && (ffebld_op (expr) != FFEBLD_opSYMTER
12690 || ffebld_where (expr) == FFEINFO_whereCOMMON
12691 || ffebld_where (expr) == FFEINFO_whereGLOBAL
12692 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
12696 t = ffecom_ptr_to_expr (expr);
12697 assert (TREE_CONSTANT (t));
12704 /* ffecom_return_expr -- Returns return-value expr given alt return expr
12706 tree rtn; // NULL_TREE means use expand_null_return()
12707 ffebld expr; // NULL if no alt return expr to RETURN stmt
12708 rtn = ffecom_return_expr(expr);
12710 Based on the program unit type and other info (like return function
12711 type, return master function type when alternate ENTRY points,
12712 whether subroutine has any alternate RETURN points, etc), returns the
12713 appropriate expression to be returned to the caller, or NULL_TREE
12714 meaning no return value or the caller expects it to be returned somewhere
12715 else (which is handled by other parts of this module). */
12718 ffecom_return_expr (ffebld expr)
12722 switch (ffecom_primary_entry_kind_)
12724 case FFEINFO_kindPROGRAM:
12725 case FFEINFO_kindBLOCKDATA:
12729 case FFEINFO_kindSUBROUTINE:
12730 if (!ffecom_is_altreturning_)
12731 rtn = NULL_TREE; /* No alt returns, never an expr. */
12732 else if (expr == NULL)
12733 rtn = integer_zero_node;
12735 rtn = ffecom_expr (expr);
12738 case FFEINFO_kindFUNCTION:
12739 if ((ffecom_multi_retval_ != NULL_TREE)
12740 || (ffesymbol_basictype (ffecom_primary_entry_)
12741 == FFEINFO_basictypeCHARACTER)
12742 || ((ffesymbol_basictype (ffecom_primary_entry_)
12743 == FFEINFO_basictypeCOMPLEX)
12744 && (ffecom_num_entrypoints_ == 0)
12745 && ffesymbol_is_f2c (ffecom_primary_entry_)))
12746 { /* Value is returned by direct assignment
12747 into (implicit) dummy. */
12751 rtn = ffecom_func_result_;
12753 /* Spurious error if RETURN happens before first reference! So elide
12754 this code. In particular, for debugging registry, rtn should always
12755 be non-null after all, but TREE_USED won't be set until we encounter
12756 a reference in the code. Perfectly okay (but weird) code that,
12757 e.g., has "GOTO 20;10 RETURN;20 RTN=0;GOTO 10", would result in
12758 this diagnostic for no reason. Have people use -O -Wuninitialized
12759 and leave it to the back end to find obviously weird cases. */
12761 /* Used to "assert(rtn != NULL_TREE);" here, but it's kind of a valid
12762 situation; if the return value has never been referenced, it won't
12763 have a tree under 2pass mode. */
12764 if ((rtn == NULL_TREE)
12765 || !TREE_USED (rtn))
12767 ffebad_start (FFEBAD_RETURN_VALUE_UNSET);
12768 ffebad_here (0, ffesymbol_where_line (ffecom_primary_entry_),
12769 ffesymbol_where_column (ffecom_primary_entry_));
12770 ffebad_string (ffesymbol_text (ffesymbol_funcresult
12771 (ffecom_primary_entry_)));
12778 assert ("bad unit kind" == NULL);
12779 case FFEINFO_kindANY:
12780 rtn = error_mark_node;
12787 /* Do save_expr only if tree is not error_mark_node. */
12790 ffecom_save_tree (tree t)
12792 return save_expr (t);
12795 /* Start a compound statement (block). */
12798 ffecom_start_compstmt (void)
12800 bison_rule_pushlevel_ ();
12803 /* Public entry point for front end to access start_decl. */
12806 ffecom_start_decl (tree decl, bool is_initialized)
12808 DECL_INITIAL (decl) = is_initialized ? error_mark_node : NULL_TREE;
12809 return start_decl (decl, FALSE);
12812 /* ffecom_sym_commit -- Symbol's state being committed to reality
12815 ffecom_sym_commit(s);
12817 Does whatever the backend needs when a symbol is committed after having
12818 been backtrackable for a period of time. */
12821 ffecom_sym_commit (ffesymbol s UNUSED)
12823 assert (!ffesymbol_retractable ());
12826 /* ffecom_sym_end_transition -- Perform end transition on all symbols
12828 ffecom_sym_end_transition();
12830 Does backend-specific stuff and also calls ffest_sym_end_transition
12831 to do the necessary FFE stuff.
12833 Backtracking is never enabled when this fn is called, so don't worry
12837 ffecom_sym_end_transition (ffesymbol s)
12841 assert (!ffesymbol_retractable ());
12843 s = ffest_sym_end_transition (s);
12845 if ((ffesymbol_kind (s) == FFEINFO_kindBLOCKDATA)
12846 && (ffesymbol_where (s) == FFEINFO_whereGLOBAL))
12848 ffecom_list_blockdata_
12849 = ffebld_new_item (ffebld_new_symter (s, FFEINTRIN_genNONE,
12850 FFEINTRIN_specNONE,
12851 FFEINTRIN_impNONE),
12852 ffecom_list_blockdata_);
12855 /* This is where we finally notice that a symbol has partial initialization
12856 and finalize it. */
12858 if (ffesymbol_accretion (s) != NULL)
12860 assert (ffesymbol_init (s) == NULL);
12861 ffecom_notify_init_symbol (s);
12863 else if (((st = ffesymbol_storage (s)) != NULL)
12864 && ((st = ffestorag_parent (st)) != NULL)
12865 && (ffestorag_accretion (st) != NULL))
12867 assert (ffestorag_init (st) == NULL);
12868 ffecom_notify_init_storage (st);
12871 if ((ffesymbol_kind (s) == FFEINFO_kindCOMMON)
12872 && (ffesymbol_where (s) == FFEINFO_whereLOCAL)
12873 && (ffesymbol_storage (s) != NULL))
12875 ffecom_list_common_
12876 = ffebld_new_item (ffebld_new_symter (s, FFEINTRIN_genNONE,
12877 FFEINTRIN_specNONE,
12878 FFEINTRIN_impNONE),
12879 ffecom_list_common_);
12885 /* ffecom_sym_exec_transition -- Perform exec transition on all symbols
12887 ffecom_sym_exec_transition();
12889 Does backend-specific stuff and also calls ffest_sym_exec_transition
12890 to do the necessary FFE stuff.
12892 See the long-winded description in ffecom_sym_learned for info
12893 on handling the situation where backtracking is inhibited. */
12896 ffecom_sym_exec_transition (ffesymbol s)
12898 s = ffest_sym_exec_transition (s);
12903 /* ffecom_sym_learned -- Initial or more info gained on symbol after exec
12906 s = ffecom_sym_learned(s);
12908 Called when a new symbol is seen after the exec transition or when more
12909 info (perhaps) is gained for an UNCERTAIN symbol. The symbol state when
12910 it arrives here is that all its latest info is updated already, so its
12911 state may be UNCERTAIN or UNDERSTOOD, it might already have the hook
12912 field filled in if its gone through here or exec_transition first, and
12915 The backend probably wants to check ffesymbol_retractable() to see if
12916 backtracking is in effect. If so, the FFE's changes to the symbol may
12917 be retracted (undone) or committed (ratified), at which time the
12918 appropriate ffecom_sym_retract or _commit function will be called
12921 If the backend has its own backtracking mechanism, great, use it so that
12922 committal is a simple operation. Though it doesn't make much difference,
12923 I suppose: the reason for tentative symbol evolution in the FFE is to
12924 enable error detection in weird incorrect statements early and to disable
12925 incorrect error detection on a correct statement. The backend is not
12926 likely to introduce any information that'll get involved in these
12927 considerations, so it is probably just fine that the implementation
12928 model for this fn and for _exec_transition is to not do anything
12929 (besides the required FFE stuff) if ffesymbol_retractable() returns TRUE
12930 and instead wait until ffecom_sym_commit is called (which it never
12931 will be as long as we're using ambiguity-detecting statement analysis in
12932 the FFE, which we are initially to shake out the code, but don't depend
12933 on this), otherwise go ahead and do whatever is needed.
12935 In essence, then, when this fn and _exec_transition get called while
12936 backtracking is enabled, a general mechanism would be to flag which (or
12937 both) of these were called (and in what order? neat question as to what
12938 might happen that I'm too lame to think through right now) and then when
12939 _commit is called reproduce the original calling sequence, if any, for
12940 the two fns (at which point backtracking will, of course, be disabled). */
12943 ffecom_sym_learned (ffesymbol s)
12945 ffestorag_exec_layout (s);
12950 /* ffecom_sym_retract -- Symbol's state being retracted from reality
12953 ffecom_sym_retract(s);
12955 Does whatever the backend needs when a symbol is retracted after having
12956 been backtrackable for a period of time. */
12959 ffecom_sym_retract (ffesymbol s UNUSED)
12961 assert (!ffesymbol_retractable ());
12963 #if 0 /* GCC doesn't commit any backtrackable sins,
12964 so nothing needed here. */
12965 switch (ffesymbol_hook (s).state)
12967 case 0: /* nothing happened yet. */
12970 case 1: /* exec transition happened. */
12973 case 2: /* learned happened. */
12976 case 3: /* learned then exec. */
12979 case 4: /* exec then learned. */
12983 assert ("bad hook state" == NULL);
12989 /* Create temporary gcc label. */
12992 ffecom_temp_label ()
12995 static int mynumber = 0;
12997 glabel = build_decl (LABEL_DECL,
12998 ffecom_get_invented_identifier ("__g77_label_%d",
13001 DECL_CONTEXT (glabel) = current_function_decl;
13002 DECL_MODE (glabel) = VOIDmode;
13007 /* Return an expression that is usable as an arg in a conditional context
13008 (IF, DO WHILE, .NOT., and so on).
13010 Use the one provided for the back end as of >2.6.0. */
13013 ffecom_truth_value (tree expr)
13015 return ffe_truthvalue_conversion (expr);
13018 /* Return the inversion of a truth value (the inversion of what
13019 ffecom_truth_value builds).
13021 Apparently invert_truthvalue, which is properly in the back end, is
13022 enough for now, so just use it. */
13025 ffecom_truth_value_invert (tree expr)
13027 return invert_truthvalue (ffecom_truth_value (expr));
13030 /* Return the tree that is the type of the expression, as would be
13031 returned in TREE_TYPE(ffecom_expr(expr)), without otherwise
13032 transforming the expression, generating temporaries, etc. */
13035 ffecom_type_expr (ffebld expr)
13037 ffeinfoBasictype bt;
13038 ffeinfoKindtype kt;
13041 assert (expr != NULL);
13043 bt = ffeinfo_basictype (ffebld_info (expr));
13044 kt = ffeinfo_kindtype (ffebld_info (expr));
13045 tree_type = ffecom_tree_type[bt][kt];
13047 switch (ffebld_op (expr))
13049 case FFEBLD_opCONTER:
13050 case FFEBLD_opSYMTER:
13051 case FFEBLD_opARRAYREF:
13052 case FFEBLD_opUPLUS:
13053 case FFEBLD_opPAREN:
13054 case FFEBLD_opUMINUS:
13056 case FFEBLD_opSUBTRACT:
13057 case FFEBLD_opMULTIPLY:
13058 case FFEBLD_opDIVIDE:
13059 case FFEBLD_opPOWER:
13061 case FFEBLD_opFUNCREF:
13062 case FFEBLD_opSUBRREF:
13066 case FFEBLD_opNEQV:
13068 case FFEBLD_opCONVERT:
13075 case FFEBLD_opPERCENT_LOC:
13078 case FFEBLD_opACCTER:
13079 case FFEBLD_opARRTER:
13080 case FFEBLD_opITEM:
13081 case FFEBLD_opSTAR:
13082 case FFEBLD_opBOUNDS:
13083 case FFEBLD_opREPEAT:
13084 case FFEBLD_opLABTER:
13085 case FFEBLD_opLABTOK:
13086 case FFEBLD_opIMPDO:
13087 case FFEBLD_opCONCATENATE:
13088 case FFEBLD_opSUBSTR:
13090 assert ("bad op for ffecom_type_expr" == NULL);
13091 /* Fall through. */
13093 return error_mark_node;
13097 /* Return PARM_DECL for arg#1 of master fn containing alternate ENTRY points
13099 If the PARM_DECL already exists, return it, else create it. It's an
13100 integer_type_node argument for the master function that implements a
13101 subroutine or function with more than one entrypoint and is bound at
13102 run time with the entrypoint number (0 for SUBROUTINE/FUNCTION, 1 for
13103 first ENTRY statement, and so on). */
13106 ffecom_which_entrypoint_decl ()
13108 assert (ffecom_which_entrypoint_decl_ != NULL_TREE);
13110 return ffecom_which_entrypoint_decl_;
13113 /* The following sections consists of private and public functions
13114 that have the same names and perform roughly the same functions
13115 as counterparts in the C front end. Changes in the C front end
13116 might affect how things should be done here. Only functions
13117 needed by the back end should be public here; the rest should
13118 be private (static in the C sense). Functions needed by other
13119 g77 front-end modules should be accessed by them via public
13120 ffecom_* names, which should themselves call private versions
13121 in this section so the private versions are easy to recognize
13122 when upgrading to a new gcc and finding interesting changes
13125 Functions named after rule "foo:" in c-parse.y are named
13126 "bison_rule_foo_" so they are easy to find. */
13129 bison_rule_pushlevel_ ()
13131 emit_line_note (input_filename, lineno);
13133 clear_last_expr ();
13134 expand_start_bindings (0);
13138 bison_rule_compstmt_ ()
13141 int keep = kept_level_p ();
13143 /* Make the temps go away. */
13145 current_binding_level->names = NULL_TREE;
13147 emit_line_note (input_filename, lineno);
13148 expand_end_bindings (getdecls (), keep, 0);
13149 t = poplevel (keep, 1, 0);
13154 /* Return a definition for a builtin function named NAME and whose data type
13155 is TYPE. TYPE should be a function type with argument types.
13156 FUNCTION_CODE tells later passes how to compile calls to this function.
13157 See tree.h for its possible values.
13159 If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME,
13160 the name to be called if we can't opencode the function. */
13163 builtin_function (const char *name, tree type, int function_code,
13164 enum built_in_class class,
13165 const char *library_name)
13167 tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
13168 DECL_EXTERNAL (decl) = 1;
13169 TREE_PUBLIC (decl) = 1;
13171 SET_DECL_ASSEMBLER_NAME (decl, get_identifier (library_name));
13172 make_decl_rtl (decl, NULL);
13174 DECL_BUILT_IN_CLASS (decl) = class;
13175 DECL_FUNCTION_CODE (decl) = function_code;
13180 /* Handle when a new declaration NEWDECL
13181 has the same name as an old one OLDDECL
13182 in the same binding contour.
13183 Prints an error message if appropriate.
13185 If safely possible, alter OLDDECL to look like NEWDECL, and return 1.
13186 Otherwise, return 0. */
13189 duplicate_decls (tree newdecl, tree olddecl)
13191 int types_match = 1;
13192 int new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL
13193 && DECL_INITIAL (newdecl) != 0);
13194 tree oldtype = TREE_TYPE (olddecl);
13195 tree newtype = TREE_TYPE (newdecl);
13197 if (olddecl == newdecl)
13200 if (TREE_CODE (newtype) == ERROR_MARK
13201 || TREE_CODE (oldtype) == ERROR_MARK)
13204 /* New decl is completely inconsistent with the old one =>
13205 tell caller to replace the old one.
13206 This is always an error except in the case of shadowing a builtin. */
13207 if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
13210 /* For real parm decl following a forward decl,
13211 return 1 so old decl will be reused. */
13212 if (types_match && TREE_CODE (newdecl) == PARM_DECL
13213 && TREE_ASM_WRITTEN (olddecl) && ! TREE_ASM_WRITTEN (newdecl))
13216 /* The new declaration is the same kind of object as the old one.
13217 The declarations may partially match. Print warnings if they don't
13218 match enough. Ultimately, copy most of the information from the new
13219 decl to the old one, and keep using the old one. */
13221 if (TREE_CODE (olddecl) == FUNCTION_DECL
13222 && DECL_BUILT_IN (olddecl))
13224 /* A function declaration for a built-in function. */
13225 if (!TREE_PUBLIC (newdecl))
13227 else if (!types_match)
13229 /* Accept the return type of the new declaration if same modes. */
13230 tree oldreturntype = TREE_TYPE (TREE_TYPE (olddecl));
13231 tree newreturntype = TREE_TYPE (TREE_TYPE (newdecl));
13233 if (TYPE_MODE (oldreturntype) == TYPE_MODE (newreturntype))
13235 /* Function types may be shared, so we can't just modify
13236 the return type of olddecl's function type. */
13238 = build_function_type (newreturntype,
13239 TYPE_ARG_TYPES (TREE_TYPE (olddecl)));
13243 TREE_TYPE (olddecl) = newtype;
13249 else if (TREE_CODE (olddecl) == FUNCTION_DECL
13250 && DECL_SOURCE_LINE (olddecl) == 0)
13252 /* A function declaration for a predeclared function
13253 that isn't actually built in. */
13254 if (!TREE_PUBLIC (newdecl))
13256 else if (!types_match)
13258 /* If the types don't match, preserve volatility indication.
13259 Later on, we will discard everything else about the
13260 default declaration. */
13261 TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
13265 /* Copy all the DECL_... slots specified in the new decl
13266 except for any that we copy here from the old type.
13268 Past this point, we don't change OLDTYPE and NEWTYPE
13269 even if we change the types of NEWDECL and OLDDECL. */
13273 /* Merge the data types specified in the two decls. */
13274 if (TREE_CODE (newdecl) != FUNCTION_DECL || !DECL_BUILT_IN (olddecl))
13275 TREE_TYPE (newdecl)
13276 = TREE_TYPE (olddecl)
13277 = TREE_TYPE (newdecl);
13279 /* Lay the type out, unless already done. */
13280 if (oldtype != TREE_TYPE (newdecl))
13282 if (TREE_TYPE (newdecl) != error_mark_node)
13283 layout_type (TREE_TYPE (newdecl));
13284 if (TREE_CODE (newdecl) != FUNCTION_DECL
13285 && TREE_CODE (newdecl) != TYPE_DECL
13286 && TREE_CODE (newdecl) != CONST_DECL)
13287 layout_decl (newdecl, 0);
13291 /* Since the type is OLDDECL's, make OLDDECL's size go with. */
13292 DECL_SIZE (newdecl) = DECL_SIZE (olddecl);
13293 DECL_SIZE_UNIT (newdecl) = DECL_SIZE_UNIT (olddecl);
13294 if (TREE_CODE (olddecl) != FUNCTION_DECL)
13295 if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl))
13297 DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl);
13298 DECL_USER_ALIGN (newdecl) |= DECL_USER_ALIGN (olddecl);
13302 /* Keep the old rtl since we can safely use it. */
13303 COPY_DECL_RTL (olddecl, newdecl);
13305 /* Merge the type qualifiers. */
13306 if (DECL_BUILT_IN_NONANSI (olddecl) && TREE_THIS_VOLATILE (olddecl)
13307 && !TREE_THIS_VOLATILE (newdecl))
13308 TREE_THIS_VOLATILE (olddecl) = 0;
13309 if (TREE_READONLY (newdecl))
13310 TREE_READONLY (olddecl) = 1;
13311 if (TREE_THIS_VOLATILE (newdecl))
13313 TREE_THIS_VOLATILE (olddecl) = 1;
13314 if (TREE_CODE (newdecl) == VAR_DECL)
13315 make_var_volatile (newdecl);
13318 /* Keep source location of definition rather than declaration.
13319 Likewise, keep decl at outer scope. */
13320 if ((DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0)
13321 || (DECL_CONTEXT (newdecl) != 0 && DECL_CONTEXT (olddecl) == 0))
13323 DECL_SOURCE_LINE (newdecl) = DECL_SOURCE_LINE (olddecl);
13324 DECL_SOURCE_FILE (newdecl) = DECL_SOURCE_FILE (olddecl);
13326 if (DECL_CONTEXT (olddecl) == 0
13327 && TREE_CODE (newdecl) != FUNCTION_DECL)
13328 DECL_CONTEXT (newdecl) = 0;
13331 /* Merge the unused-warning information. */
13332 if (DECL_IN_SYSTEM_HEADER (olddecl))
13333 DECL_IN_SYSTEM_HEADER (newdecl) = 1;
13334 else if (DECL_IN_SYSTEM_HEADER (newdecl))
13335 DECL_IN_SYSTEM_HEADER (olddecl) = 1;
13337 /* Merge the initialization information. */
13338 if (DECL_INITIAL (newdecl) == 0)
13339 DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
13341 /* Merge the section attribute.
13342 We want to issue an error if the sections conflict but that must be
13343 done later in decl_attributes since we are called before attributes
13345 if (DECL_SECTION_NAME (newdecl) == NULL_TREE)
13346 DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl);
13348 if (TREE_CODE (newdecl) == FUNCTION_DECL)
13350 DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl);
13351 DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
13354 /* If cannot merge, then use the new type and qualifiers,
13355 and don't preserve the old rtl. */
13358 TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
13359 TREE_READONLY (olddecl) = TREE_READONLY (newdecl);
13360 TREE_THIS_VOLATILE (olddecl) = TREE_THIS_VOLATILE (newdecl);
13361 TREE_SIDE_EFFECTS (olddecl) = TREE_SIDE_EFFECTS (newdecl);
13364 /* Merge the storage class information. */
13365 /* For functions, static overrides non-static. */
13366 if (TREE_CODE (newdecl) == FUNCTION_DECL)
13368 TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl);
13369 /* This is since we don't automatically
13370 copy the attributes of NEWDECL into OLDDECL. */
13371 TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
13372 /* If this clears `static', clear it in the identifier too. */
13373 if (! TREE_PUBLIC (olddecl))
13374 TREE_PUBLIC (DECL_NAME (olddecl)) = 0;
13376 if (DECL_EXTERNAL (newdecl))
13378 TREE_STATIC (newdecl) = TREE_STATIC (olddecl);
13379 DECL_EXTERNAL (newdecl) = DECL_EXTERNAL (olddecl);
13380 /* An extern decl does not override previous storage class. */
13381 TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
13385 TREE_STATIC (olddecl) = TREE_STATIC (newdecl);
13386 TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
13389 /* If either decl says `inline', this fn is inline,
13390 unless its definition was passed already. */
13391 if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == 0)
13392 DECL_INLINE (olddecl) = 1;
13393 DECL_INLINE (newdecl) = DECL_INLINE (olddecl);
13395 /* Get rid of any built-in function if new arg types don't match it
13396 or if we have a function definition. */
13397 if (TREE_CODE (newdecl) == FUNCTION_DECL
13398 && DECL_BUILT_IN (olddecl)
13399 && (!types_match || new_is_definition))
13401 TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
13402 DECL_BUILT_IN_CLASS (olddecl) = NOT_BUILT_IN;
13405 /* If redeclaring a builtin function, and not a definition,
13407 Also preserve various other info from the definition. */
13408 if (TREE_CODE (newdecl) == FUNCTION_DECL && !new_is_definition)
13410 if (DECL_BUILT_IN (olddecl))
13412 DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl);
13413 DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
13416 DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
13417 DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
13418 DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl);
13419 DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
13422 /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
13423 But preserve olddecl's DECL_UID. */
13425 register unsigned olddecl_uid = DECL_UID (olddecl);
13427 memcpy ((char *) olddecl + sizeof (struct tree_common),
13428 (char *) newdecl + sizeof (struct tree_common),
13429 sizeof (struct tree_decl) - sizeof (struct tree_common));
13430 DECL_UID (olddecl) = olddecl_uid;
13436 /* Finish processing of a declaration;
13437 install its initial value.
13438 If the length of an array type is not known before,
13439 it must be determined now, from the initial value, or it is an error. */
13442 finish_decl (tree decl, tree init, bool is_top_level)
13444 register tree type = TREE_TYPE (decl);
13445 int was_incomplete = (DECL_SIZE (decl) == 0);
13446 bool at_top_level = (current_binding_level == global_binding_level);
13447 bool top_level = is_top_level || at_top_level;
13449 /* Caller should pass TRUE for is_top_level only if we wouldn't be at top
13451 assert (!is_top_level || !at_top_level);
13453 if (TREE_CODE (decl) == PARM_DECL)
13454 assert (init == NULL_TREE);
13455 /* Remember that PARM_DECL doesn't have a DECL_INITIAL field per se -- it
13456 overlaps DECL_ARG_TYPE. */
13457 else if (init == NULL_TREE)
13458 assert (DECL_INITIAL (decl) == NULL_TREE);
13460 assert (DECL_INITIAL (decl) == error_mark_node);
13462 if (init != NULL_TREE)
13464 if (TREE_CODE (decl) != TYPE_DECL)
13465 DECL_INITIAL (decl) = init;
13468 /* typedef foo = bar; store the type of bar as the type of foo. */
13469 TREE_TYPE (decl) = TREE_TYPE (init);
13470 DECL_INITIAL (decl) = init = 0;
13474 /* Deduce size of array from initialization, if not already known */
13476 if (TREE_CODE (type) == ARRAY_TYPE
13477 && TYPE_DOMAIN (type) == 0
13478 && TREE_CODE (decl) != TYPE_DECL)
13480 assert (top_level);
13481 assert (was_incomplete);
13483 layout_decl (decl, 0);
13486 if (TREE_CODE (decl) == VAR_DECL)
13488 if (DECL_SIZE (decl) == NULL_TREE
13489 && TYPE_SIZE (TREE_TYPE (decl)) != NULL_TREE)
13490 layout_decl (decl, 0);
13492 if (DECL_SIZE (decl) == NULL_TREE
13493 && (TREE_STATIC (decl)
13495 /* A static variable with an incomplete type is an error if it is
13496 initialized. Also if it is not file scope. Otherwise, let it
13497 through, but if it is not `extern' then it may cause an error
13499 (DECL_INITIAL (decl) != 0 || DECL_CONTEXT (decl) != 0)
13501 /* An automatic variable with an incomplete type is an error. */
13502 !DECL_EXTERNAL (decl)))
13504 assert ("storage size not known" == NULL);
13508 if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl))
13509 && (DECL_SIZE (decl) != 0)
13510 && (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST))
13512 assert ("storage size not constant" == NULL);
13517 /* Output the assembler code and/or RTL code for variables and functions,
13518 unless the type is an undefined structure or union. If not, it will get
13519 done when the type is completed. */
13521 if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)
13523 rest_of_decl_compilation (decl, NULL,
13524 DECL_CONTEXT (decl) == 0,
13527 if (DECL_CONTEXT (decl) != 0)
13529 /* Recompute the RTL of a local array now if it used to be an
13530 incomplete type. */
13532 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
13534 /* If we used it already as memory, it must stay in memory. */
13535 TREE_ADDRESSABLE (decl) = TREE_USED (decl);
13536 /* If it's still incomplete now, no init will save it. */
13537 if (DECL_SIZE (decl) == 0)
13538 DECL_INITIAL (decl) = 0;
13539 expand_decl (decl);
13541 /* Compute and store the initial value. */
13542 if (TREE_CODE (decl) != FUNCTION_DECL)
13543 expand_decl_init (decl);
13546 else if (TREE_CODE (decl) == TYPE_DECL)
13548 rest_of_decl_compilation (decl, NULL,
13549 DECL_CONTEXT (decl) == 0,
13553 /* At the end of a declaration, throw away any variable type sizes of types
13554 defined inside that declaration. There is no use computing them in the
13555 following function definition. */
13556 if (current_binding_level == global_binding_level)
13557 get_pending_sizes ();
13560 /* Finish up a function declaration and compile that function
13561 all the way to assembler language output. The free the storage
13562 for the function definition.
13564 This is called after parsing the body of the function definition.
13566 NESTED is nonzero if the function being finished is nested in another. */
13569 finish_function (int nested)
13571 register tree fndecl = current_function_decl;
13573 assert (fndecl != NULL_TREE);
13574 if (TREE_CODE (fndecl) != ERROR_MARK)
13577 assert (DECL_CONTEXT (fndecl) != NULL_TREE);
13579 assert (DECL_CONTEXT (fndecl) == NULL_TREE);
13582 /* TREE_READONLY (fndecl) = 1;
13583 This caused &foo to be of type ptr-to-const-function
13584 which then got a warning when stored in a ptr-to-function variable. */
13586 poplevel (1, 0, 1);
13588 if (TREE_CODE (fndecl) != ERROR_MARK)
13590 BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
13592 /* Must mark the RESULT_DECL as being in this function. */
13594 DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;
13596 /* Obey `register' declarations if `setjmp' is called in this fn. */
13597 /* Generate rtl for function exit. */
13598 expand_function_end (input_filename, lineno, 0);
13600 /* If this is a nested function, protect the local variables in the stack
13601 above us from being collected while we're compiling this function. */
13603 ggc_push_context ();
13605 /* Run the optimizers and output the assembler code for this function. */
13606 rest_of_compilation (fndecl);
13608 /* Undo the GC context switch. */
13610 ggc_pop_context ();
13613 if (TREE_CODE (fndecl) != ERROR_MARK
13615 && DECL_SAVED_INSNS (fndecl) == 0)
13617 /* Stop pointing to the local nodes about to be freed. */
13618 /* But DECL_INITIAL must remain nonzero so we know this was an actual
13619 function definition. */
13620 /* For a nested function, this is done in pop_f_function_context. */
13621 /* If rest_of_compilation set this to 0, leave it 0. */
13622 if (DECL_INITIAL (fndecl) != 0)
13623 DECL_INITIAL (fndecl) = error_mark_node;
13624 DECL_ARGUMENTS (fndecl) = 0;
13629 /* Let the error reporting routines know that we're outside a function.
13630 For a nested function, this value is used in pop_c_function_context
13631 and then reset via pop_function_context. */
13632 ffecom_outer_function_decl_ = current_function_decl = NULL;
13636 /* Plug-in replacement for identifying the name of a decl and, for a
13637 function, what we call it in diagnostics. For now, "program unit"
13638 should suffice, since it's a bit of a hassle to figure out which
13639 of several kinds of things it is. Note that it could conceivably
13640 be a statement function, which probably isn't really a program unit
13641 per se, but if that comes up, it should be easy to check (being a
13642 nested function and all). */
13644 static const char *
13645 ffe_printable_name (tree decl, int v)
13647 /* Just to keep GCC quiet about the unused variable.
13648 In theory, differing values of V should produce different
13653 if (TREE_CODE (decl) == ERROR_MARK)
13654 return "erroneous code";
13655 return IDENTIFIER_POINTER (DECL_NAME (decl));
13659 /* g77's function to print out name of current function that caused
13663 ffe_print_error_function (diagnostic_context *context __attribute__((unused)),
13666 static ffeglobal last_g = NULL;
13667 static ffesymbol last_s = NULL;
13672 if ((ffecom_primary_entry_ == NULL)
13673 || (ffesymbol_global (ffecom_primary_entry_) == NULL))
13681 g = ffesymbol_global (ffecom_primary_entry_);
13682 if (ffecom_nested_entry_ == NULL)
13684 s = ffecom_primary_entry_;
13685 kind = _(ffeinfo_kind_message (ffesymbol_kind (s)));
13689 s = ffecom_nested_entry_;
13690 kind = _("In statement function");
13694 if ((last_g != g) || (last_s != s))
13697 fprintf (stderr, "%s: ", file);
13700 fprintf (stderr, _("Outside of any program unit:\n"));
13703 const char *name = ffesymbol_text (s);
13705 fprintf (stderr, "%s `%s':\n", kind, name);
13713 /* Similar to `lookup_name' but look only at current binding level. */
13716 lookup_name_current_level (tree name)
13720 if (current_binding_level == global_binding_level)
13721 return IDENTIFIER_GLOBAL_VALUE (name);
13723 if (IDENTIFIER_LOCAL_VALUE (name) == 0)
13726 for (t = current_binding_level->names; t; t = TREE_CHAIN (t))
13727 if (DECL_NAME (t) == name)
13733 /* Create a new `struct f_binding_level'. */
13735 static struct f_binding_level *
13736 make_binding_level ()
13739 return ggc_alloc (sizeof (struct f_binding_level));
13742 /* Save and restore the variables in this file and elsewhere
13743 that keep track of the progress of compilation of the current function.
13744 Used for nested functions. */
13748 struct f_function *next;
13750 tree shadowed_labels;
13751 struct f_binding_level *binding_level;
13754 struct f_function *f_function_chain;
13756 /* Restore the variables used during compilation of a C function. */
13759 pop_f_function_context ()
13761 struct f_function *p = f_function_chain;
13764 /* Bring back all the labels that were shadowed. */
13765 for (link = shadowed_labels; link; link = TREE_CHAIN (link))
13766 if (DECL_NAME (TREE_VALUE (link)) != 0)
13767 IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link)))
13768 = TREE_VALUE (link);
13770 if (current_function_decl != error_mark_node
13771 && DECL_SAVED_INSNS (current_function_decl) == 0)
13773 /* Stop pointing to the local nodes about to be freed. */
13774 /* But DECL_INITIAL must remain nonzero so we know this was an actual
13775 function definition. */
13776 DECL_INITIAL (current_function_decl) = error_mark_node;
13777 DECL_ARGUMENTS (current_function_decl) = 0;
13780 pop_function_context ();
13782 f_function_chain = p->next;
13784 named_labels = p->named_labels;
13785 shadowed_labels = p->shadowed_labels;
13786 current_binding_level = p->binding_level;
13791 /* Save and reinitialize the variables
13792 used during compilation of a C function. */
13795 push_f_function_context ()
13797 struct f_function *p
13798 = (struct f_function *) xmalloc (sizeof (struct f_function));
13800 push_function_context ();
13802 p->next = f_function_chain;
13803 f_function_chain = p;
13805 p->named_labels = named_labels;
13806 p->shadowed_labels = shadowed_labels;
13807 p->binding_level = current_binding_level;
13811 push_parm_decl (tree parm)
13813 int old_immediate_size_expand = immediate_size_expand;
13815 /* Don't try computing parm sizes now -- wait till fn is called. */
13817 immediate_size_expand = 0;
13819 /* Fill in arg stuff. */
13821 DECL_ARG_TYPE (parm) = TREE_TYPE (parm);
13822 DECL_ARG_TYPE_AS_WRITTEN (parm) = TREE_TYPE (parm);
13823 TREE_READONLY (parm) = 1; /* All implementation args are read-only. */
13825 parm = pushdecl (parm);
13827 immediate_size_expand = old_immediate_size_expand;
13829 finish_decl (parm, NULL_TREE, FALSE);
13832 /* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL, if appropriate. */
13835 pushdecl_top_level (x)
13839 register struct f_binding_level *b = current_binding_level;
13840 register tree f = current_function_decl;
13842 current_binding_level = global_binding_level;
13843 current_function_decl = NULL_TREE;
13845 current_binding_level = b;
13846 current_function_decl = f;
13850 /* Store the list of declarations of the current level.
13851 This is done for the parameter declarations of a function being defined,
13852 after they are modified in the light of any missing parameters. */
13858 return current_binding_level->names = decls;
13861 /* Store the parameter declarations into the current function declaration.
13862 This is called after parsing the parameter declarations, before
13863 digesting the body of the function.
13865 For an old-style definition, modify the function's type
13866 to specify at least the number of arguments. */
13869 store_parm_decls (int is_main_program UNUSED)
13871 register tree fndecl = current_function_decl;
13873 if (fndecl == error_mark_node)
13876 /* This is a chain of PARM_DECLs from old-style parm declarations. */
13877 DECL_ARGUMENTS (fndecl) = storedecls (nreverse (getdecls ()));
13879 /* Initialize the RTL code for the function. */
13881 init_function_start (fndecl, input_filename, lineno);
13883 /* Set up parameters and prepare for return, for the function. */
13885 expand_function_start (fndecl, 0);
13889 start_decl (tree decl, bool is_top_level)
13892 bool at_top_level = (current_binding_level == global_binding_level);
13893 bool top_level = is_top_level || at_top_level;
13895 /* Caller should pass TRUE for is_top_level only if we wouldn't be at top
13897 assert (!is_top_level || !at_top_level);
13899 if (DECL_INITIAL (decl) != NULL_TREE)
13901 assert (DECL_INITIAL (decl) == error_mark_node);
13902 assert (!DECL_EXTERNAL (decl));
13904 else if (top_level)
13905 assert ((TREE_STATIC (decl) == 1) || DECL_EXTERNAL (decl) == 1);
13907 /* For Fortran, we by default put things in .common when possible. */
13908 DECL_COMMON (decl) = 1;
13910 /* Add this decl to the current binding level. TEM may equal DECL or it may
13911 be a previous decl of the same name. */
13913 tem = pushdecl_top_level (decl);
13915 tem = pushdecl (decl);
13917 /* For a local variable, define the RTL now. */
13919 /* But not if this is a duplicate decl and we preserved the rtl from the
13920 previous one (which may or may not happen). */
13921 && !DECL_RTL_SET_P (tem))
13923 if (TYPE_SIZE (TREE_TYPE (tem)) != 0)
13925 else if (TREE_CODE (TREE_TYPE (tem)) == ARRAY_TYPE
13926 && DECL_INITIAL (tem) != 0)
13933 /* Create the FUNCTION_DECL for a function definition.
13934 DECLSPECS and DECLARATOR are the parts of the declaration;
13935 they describe the function's name and the type it returns,
13936 but twisted together in a fashion that parallels the syntax of C.
13938 This function creates a binding context for the function body
13939 as well as setting up the FUNCTION_DECL in current_function_decl.
13941 Returns 1 on success. If the DECLARATOR is not suitable for a function
13942 (it defines a datum instead), we return 0, which tells
13943 ffe_parse_file to report a parse error.
13945 NESTED is nonzero for a function nested within another function. */
13948 start_function (tree name, tree type, int nested, int public)
13952 int old_immediate_size_expand = immediate_size_expand;
13955 shadowed_labels = 0;
13957 /* Don't expand any sizes in the return type of the function. */
13958 immediate_size_expand = 0;
13963 assert (current_function_decl != NULL_TREE);
13964 assert (DECL_CONTEXT (current_function_decl) == NULL_TREE);
13968 assert (current_function_decl == NULL_TREE);
13971 if (TREE_CODE (type) == ERROR_MARK)
13972 decl1 = current_function_decl = error_mark_node;
13975 decl1 = build_decl (FUNCTION_DECL,
13978 TREE_PUBLIC (decl1) = public ? 1 : 0;
13980 DECL_INLINE (decl1) = 1;
13981 TREE_STATIC (decl1) = 1;
13982 DECL_EXTERNAL (decl1) = 0;
13984 announce_function (decl1);
13986 /* Make the init_value nonzero so pushdecl knows this is not tentative.
13987 error_mark_node is replaced below (in poplevel) with the BLOCK. */
13988 DECL_INITIAL (decl1) = error_mark_node;
13990 /* Record the decl so that the function name is defined. If we already have
13991 a decl for this name, and it is a FUNCTION_DECL, use the old decl. */
13993 current_function_decl = pushdecl (decl1);
13997 ffecom_outer_function_decl_ = current_function_decl;
14000 current_binding_level->prep_state = 2;
14002 if (TREE_CODE (current_function_decl) != ERROR_MARK)
14004 make_decl_rtl (current_function_decl, NULL);
14006 restype = TREE_TYPE (TREE_TYPE (current_function_decl));
14007 DECL_RESULT (current_function_decl)
14008 = build_decl (RESULT_DECL, NULL_TREE, restype);
14011 if (!nested && (TREE_CODE (current_function_decl) != ERROR_MARK))
14012 TREE_ADDRESSABLE (current_function_decl) = 1;
14014 immediate_size_expand = old_immediate_size_expand;
14017 /* Here are the public functions the GNU back end needs. */
14020 convert (type, expr)
14023 register tree e = expr;
14024 register enum tree_code code = TREE_CODE (type);
14026 if (type == TREE_TYPE (e)
14027 || TREE_CODE (e) == ERROR_MARK)
14029 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
14030 return fold (build1 (NOP_EXPR, type, e));
14031 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
14032 || code == ERROR_MARK)
14033 return error_mark_node;
14034 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
14036 assert ("void value not ignored as it ought to be" == NULL);
14037 return error_mark_node;
14039 if (code == VOID_TYPE)
14040 return build1 (CONVERT_EXPR, type, e);
14041 if ((code != RECORD_TYPE)
14042 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
14043 e = ffecom_1 (REALPART_EXPR, TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e))),
14045 if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)
14046 return fold (convert_to_integer (type, e));
14047 if (code == POINTER_TYPE)
14048 return fold (convert_to_pointer (type, e));
14049 if (code == REAL_TYPE)
14050 return fold (convert_to_real (type, e));
14051 if (code == COMPLEX_TYPE)
14052 return fold (convert_to_complex (type, e));
14053 if (code == RECORD_TYPE)
14054 return fold (ffecom_convert_to_complex_ (type, e));
14056 assert ("conversion to non-scalar type requested" == NULL);
14057 return error_mark_node;
14060 /* Return the list of declarations of the current level.
14061 Note that this list is in reverse order unless/until
14062 you nreverse it; and when you do nreverse it, you must
14063 store the result back using `storedecls' or you will lose. */
14068 return current_binding_level->names;
14071 /* Nonzero if we are currently in the global binding level. */
14074 global_bindings_p ()
14076 return current_binding_level == global_binding_level;
14080 ffecom_init_decl_processing ()
14087 /* Delete the node BLOCK from the current binding level.
14088 This is used for the block inside a stmt expr ({...})
14089 so that the block can be reinserted where appropriate. */
14092 delete_block (block)
14096 if (current_binding_level->blocks == block)
14097 current_binding_level->blocks = TREE_CHAIN (block);
14098 for (t = current_binding_level->blocks; t;)
14100 if (TREE_CHAIN (t) == block)
14101 TREE_CHAIN (t) = TREE_CHAIN (block);
14103 t = TREE_CHAIN (t);
14105 TREE_CHAIN (block) = NULL;
14106 /* Clear TREE_USED which is always set by poplevel.
14107 The flag is set again if insert_block is called. */
14108 TREE_USED (block) = 0;
14112 insert_block (block)
14115 TREE_USED (block) = 1;
14116 current_binding_level->blocks
14117 = chainon (current_binding_level->blocks, block);
14120 /* Each front end provides its own. */
14121 static const char *ffe_init PARAMS ((const char *));
14122 static void ffe_finish PARAMS ((void));
14123 static void ffe_init_options PARAMS ((void));
14124 static void ffe_print_identifier PARAMS ((FILE *, tree, int));
14126 struct language_function GTY(())
14131 #undef LANG_HOOKS_NAME
14132 #define LANG_HOOKS_NAME "GNU F77"
14133 #undef LANG_HOOKS_INIT
14134 #define LANG_HOOKS_INIT ffe_init
14135 #undef LANG_HOOKS_FINISH
14136 #define LANG_HOOKS_FINISH ffe_finish
14137 #undef LANG_HOOKS_INIT_OPTIONS
14138 #define LANG_HOOKS_INIT_OPTIONS ffe_init_options
14139 #undef LANG_HOOKS_DECODE_OPTION
14140 #define LANG_HOOKS_DECODE_OPTION ffe_decode_option
14141 #undef LANG_HOOKS_PARSE_FILE
14142 #define LANG_HOOKS_PARSE_FILE ffe_parse_file
14143 #undef LANG_HOOKS_MARK_ADDRESSABLE
14144 #define LANG_HOOKS_MARK_ADDRESSABLE ffe_mark_addressable
14145 #undef LANG_HOOKS_PRINT_IDENTIFIER
14146 #define LANG_HOOKS_PRINT_IDENTIFIER ffe_print_identifier
14147 #undef LANG_HOOKS_DECL_PRINTABLE_NAME
14148 #define LANG_HOOKS_DECL_PRINTABLE_NAME ffe_printable_name
14149 #undef LANG_HOOKS_PRINT_ERROR_FUNCTION
14150 #define LANG_HOOKS_PRINT_ERROR_FUNCTION ffe_print_error_function
14151 #undef LANG_HOOKS_TRUTHVALUE_CONVERSION
14152 #define LANG_HOOKS_TRUTHVALUE_CONVERSION ffe_truthvalue_conversion
14154 #undef LANG_HOOKS_TYPE_FOR_MODE
14155 #define LANG_HOOKS_TYPE_FOR_MODE ffe_type_for_mode
14156 #undef LANG_HOOKS_TYPE_FOR_SIZE
14157 #define LANG_HOOKS_TYPE_FOR_SIZE ffe_type_for_size
14158 #undef LANG_HOOKS_SIGNED_TYPE
14159 #define LANG_HOOKS_SIGNED_TYPE ffe_signed_type
14160 #undef LANG_HOOKS_UNSIGNED_TYPE
14161 #define LANG_HOOKS_UNSIGNED_TYPE ffe_unsigned_type
14162 #undef LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE
14163 #define LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE ffe_signed_or_unsigned_type
14165 /* We do not wish to use alias-set based aliasing at all. Used in the
14166 extreme (every object with its own set, with equivalences recorded) it
14167 might be helpful, but there are problems when it comes to inlining. We
14168 get on ok with flag_argument_noalias, and alias-set aliasing does
14169 currently limit how stack slots can be reused, which is a lose. */
14170 #undef LANG_HOOKS_GET_ALIAS_SET
14171 #define LANG_HOOKS_GET_ALIAS_SET hook_get_alias_set_0
14173 const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
14175 /* Table indexed by tree code giving a string containing a character
14176 classifying the tree code. Possibilities are
14177 t, d, s, c, r, <, 1, 2 and e. See tree.def for details. */
14179 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
14181 const char tree_code_type[] = {
14182 #include "tree.def"
14186 /* Table indexed by tree code giving number of expression
14187 operands beyond the fixed part of the node structure.
14188 Not used for types or decls. */
14190 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
14192 const unsigned char tree_code_length[] = {
14193 #include "tree.def"
14197 /* Names of tree components.
14198 Used for printing out the tree and error messages. */
14199 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
14201 const char *const tree_code_name[] = {
14202 #include "tree.def"
14206 static const char *
14207 ffe_init (filename)
14208 const char *filename;
14210 /* Open input file. */
14211 if (filename == 0 || !strcmp (filename, "-"))
14214 filename = "stdin";
14217 finput = fopen (filename, "r");
14219 fatal_io_error ("can't open %s", filename);
14221 #ifdef IO_BUFFER_SIZE
14222 setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
14225 ffecom_init_decl_processing ();
14227 /* If the file is output from cpp, it should contain a first line
14228 `# 1 "real-filename"', and the current design of gcc (toplev.c
14229 in particular and the way it sets up information relied on by
14230 INCLUDE) requires that we read this now, and store the
14231 "real-filename" info in master_input_filename. Ask the lexer
14232 to try doing this. */
14233 ffelex_hash_kludge (finput);
14235 /* FIXME: The ffelex_hash_kludge code needs to be cleaned up to
14236 return the new file name. */
14237 if (main_input_filename)
14238 filename = main_input_filename;
14246 ffe_terminate_0 ();
14248 if (ffe_is_ffedebug ())
14249 malloc_pool_display (malloc_pool_image ());
14255 ffe_init_options ()
14257 /* Set default options for Fortran. */
14258 flag_move_all_movables = 1;
14259 flag_reduce_all_givs = 1;
14260 flag_argument_noalias = 2;
14261 flag_merge_constants = 2;
14262 flag_errno_math = 0;
14263 flag_complex_divide_method = 1;
14267 ffe_mark_addressable (exp)
14270 register tree x = exp;
14272 switch (TREE_CODE (x))
14275 case COMPONENT_REF:
14277 x = TREE_OPERAND (x, 0);
14281 TREE_ADDRESSABLE (x) = 1;
14288 if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
14289 && DECL_NONLOCAL (x))
14291 if (TREE_PUBLIC (x))
14293 assert ("address of global register var requested" == NULL);
14296 assert ("address of register variable requested" == NULL);
14298 else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x))
14300 if (TREE_PUBLIC (x))
14302 assert ("address of global register var requested" == NULL);
14305 assert ("address of register var requested" == NULL);
14307 put_var_into_stack (x);
14310 case FUNCTION_DECL:
14311 TREE_ADDRESSABLE (x) = 1;
14312 #if 0 /* poplevel deals with this now. */
14313 if (DECL_CONTEXT (x) == 0)
14314 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (x)) = 1;
14322 /* Exit a binding level.
14323 Pop the level off, and restore the state of the identifier-decl mappings
14324 that were in effect when this level was entered.
14326 If KEEP is nonzero, this level had explicit declarations, so
14327 and create a "block" (a BLOCK node) for the level
14328 to record its declarations and subblocks for symbol table output.
14330 If FUNCTIONBODY is nonzero, this level is the body of a function,
14331 so create a block as if KEEP were set and also clear out all
14334 If REVERSE is nonzero, reverse the order of decls before putting
14335 them into the BLOCK. */
14338 poplevel (keep, reverse, functionbody)
14343 register tree link;
14344 /* The chain of decls was accumulated in reverse order.
14345 Put it into forward order, just for cleanliness. */
14347 tree subblocks = current_binding_level->blocks;
14350 int block_previously_created;
14352 /* Get the decls in the order they were written.
14353 Usually current_binding_level->names is in reverse order.
14354 But parameter decls were previously put in forward order. */
14357 current_binding_level->names
14358 = decls = nreverse (current_binding_level->names);
14360 decls = current_binding_level->names;
14362 /* Output any nested inline functions within this block
14363 if they weren't already output. */
14365 for (decl = decls; decl; decl = TREE_CHAIN (decl))
14366 if (TREE_CODE (decl) == FUNCTION_DECL
14367 && ! TREE_ASM_WRITTEN (decl)
14368 && DECL_INITIAL (decl) != 0
14369 && TREE_ADDRESSABLE (decl))
14371 /* If this decl was copied from a file-scope decl
14372 on account of a block-scope extern decl,
14373 propagate TREE_ADDRESSABLE to the file-scope decl.
14375 DECL_ABSTRACT_ORIGIN can be set to itself if warn_return_type is
14376 true, since then the decl goes through save_for_inline_copying. */
14377 if (DECL_ABSTRACT_ORIGIN (decl) != 0
14378 && DECL_ABSTRACT_ORIGIN (decl) != decl)
14379 TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1;
14380 else if (DECL_SAVED_INSNS (decl) != 0)
14382 push_function_context ();
14383 output_inline_function (decl);
14384 pop_function_context ();
14388 /* If there were any declarations or structure tags in that level,
14389 or if this level is a function body,
14390 create a BLOCK to record them for the life of this function. */
14393 block_previously_created = (current_binding_level->this_block != 0);
14394 if (block_previously_created)
14395 block = current_binding_level->this_block;
14396 else if (keep || functionbody)
14397 block = make_node (BLOCK);
14400 BLOCK_VARS (block) = decls;
14401 BLOCK_SUBBLOCKS (block) = subblocks;
14404 /* In each subblock, record that this is its superior. */
14406 for (link = subblocks; link; link = TREE_CHAIN (link))
14407 BLOCK_SUPERCONTEXT (link) = block;
14409 /* Clear out the meanings of the local variables of this level. */
14411 for (link = decls; link; link = TREE_CHAIN (link))
14413 if (DECL_NAME (link) != 0)
14415 /* If the ident. was used or addressed via a local extern decl,
14416 don't forget that fact. */
14417 if (DECL_EXTERNAL (link))
14419 if (TREE_USED (link))
14420 TREE_USED (DECL_NAME (link)) = 1;
14421 if (TREE_ADDRESSABLE (link))
14422 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (link)) = 1;
14424 IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = 0;
14428 /* If the level being exited is the top level of a function,
14429 check over all the labels, and clear out the current
14430 (function local) meanings of their names. */
14434 /* If this is the top level block of a function,
14435 the vars are the function's parameters.
14436 Don't leave them in the BLOCK because they are
14437 found in the FUNCTION_DECL instead. */
14439 BLOCK_VARS (block) = 0;
14442 /* Pop the current level, and free the structure for reuse. */
14445 register struct f_binding_level *level = current_binding_level;
14446 current_binding_level = current_binding_level->level_chain;
14448 level->level_chain = free_binding_level;
14449 free_binding_level = level;
14452 /* Dispose of the block that we just made inside some higher level. */
14454 && current_function_decl != error_mark_node)
14455 DECL_INITIAL (current_function_decl) = block;
14458 if (!block_previously_created)
14459 current_binding_level->blocks
14460 = chainon (current_binding_level->blocks, block);
14462 /* If we did not make a block for the level just exited,
14463 any blocks made for inner levels
14464 (since they cannot be recorded as subblocks in that level)
14465 must be carried forward so they will later become subblocks
14466 of something else. */
14467 else if (subblocks)
14468 current_binding_level->blocks
14469 = chainon (current_binding_level->blocks, subblocks);
14472 TREE_USED (block) = 1;
14477 ffe_print_identifier (file, node, indent)
14482 print_node (file, "global", IDENTIFIER_GLOBAL_VALUE (node), indent + 4);
14483 print_node (file, "local", IDENTIFIER_LOCAL_VALUE (node), indent + 4);
14486 /* Record a decl-node X as belonging to the current lexical scope.
14487 Check for errors (such as an incompatible declaration for the same
14488 name already seen in the same scope).
14490 Returns either X or an old decl for the same name.
14491 If an old decl is returned, it may have been smashed
14492 to agree with what X says. */
14499 register tree name = DECL_NAME (x);
14500 register struct f_binding_level *b = current_binding_level;
14502 if ((TREE_CODE (x) == FUNCTION_DECL)
14503 && (DECL_INITIAL (x) == 0)
14504 && DECL_EXTERNAL (x))
14505 DECL_CONTEXT (x) = NULL_TREE;
14507 DECL_CONTEXT (x) = current_function_decl;
14511 if (IDENTIFIER_INVENTED (name))
14513 DECL_ARTIFICIAL (x) = 1;
14514 DECL_IN_SYSTEM_HEADER (x) = 1;
14517 t = lookup_name_current_level (name);
14519 assert ((t == NULL_TREE) || (DECL_CONTEXT (x) == NULL_TREE));
14521 /* Don't push non-parms onto list for parms until we understand
14522 why we're doing this and whether it works. */
14524 assert ((b == global_binding_level)
14525 || !ffecom_transform_only_dummies_
14526 || TREE_CODE (x) == PARM_DECL);
14528 if ((t != NULL_TREE) && duplicate_decls (x, t))
14531 /* If we are processing a typedef statement, generate a whole new
14532 ..._TYPE node (which will be just an variant of the existing
14533 ..._TYPE node with identical properties) and then install the
14534 TYPE_DECL node generated to represent the typedef name as the
14535 TYPE_NAME of this brand new (duplicate) ..._TYPE node.
14537 The whole point here is to end up with a situation where each and every
14538 ..._TYPE node the compiler creates will be uniquely associated with
14539 AT MOST one node representing a typedef name. This way, even though
14540 the compiler substitutes corresponding ..._TYPE nodes for TYPE_DECL
14541 (i.e. "typedef name") nodes very early on, later parts of the
14542 compiler can always do the reverse translation and get back the
14543 corresponding typedef name. For example, given:
14545 typedef struct S MY_TYPE; MY_TYPE object;
14547 Later parts of the compiler might only know that `object' was of type
14548 `struct S' if it were not for code just below. With this code
14549 however, later parts of the compiler see something like:
14551 struct S' == struct S typedef struct S' MY_TYPE; struct S' object;
14553 And they can then deduce (from the node for type struct S') that the
14554 original object declaration was:
14558 Being able to do this is important for proper support of protoize, and
14559 also for generating precise symbolic debugging information which
14560 takes full account of the programmer's (typedef) vocabulary.
14562 Obviously, we don't want to generate a duplicate ..._TYPE node if the
14563 TYPE_DECL node that we are now processing really represents a
14564 standard built-in type.
14566 Since all standard types are effectively declared at line zero in the
14567 source file, we can easily check to see if we are working on a
14568 standard type by checking the current value of lineno. */
14570 if (TREE_CODE (x) == TYPE_DECL)
14572 if (DECL_SOURCE_LINE (x) == 0)
14574 if (TYPE_NAME (TREE_TYPE (x)) == 0)
14575 TYPE_NAME (TREE_TYPE (x)) = x;
14577 else if (TREE_TYPE (x) != error_mark_node)
14579 tree tt = TREE_TYPE (x);
14581 tt = build_type_copy (tt);
14582 TYPE_NAME (tt) = x;
14583 TREE_TYPE (x) = tt;
14587 /* This name is new in its binding level. Install the new declaration
14589 if (b == global_binding_level)
14590 IDENTIFIER_GLOBAL_VALUE (name) = x;
14592 IDENTIFIER_LOCAL_VALUE (name) = x;
14595 /* Put decls on list in reverse order. We will reverse them later if
14597 TREE_CHAIN (x) = b->names;
14603 /* Nonzero if the current level needs to have a BLOCK made. */
14610 for (decl = current_binding_level->names;
14612 decl = TREE_CHAIN (decl))
14614 if (TREE_USED (decl) || TREE_CODE (decl) != VAR_DECL
14615 || (DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl)))
14616 /* Currently, there aren't supposed to be non-artificial names
14617 at other than the top block for a function -- they're
14618 believed to always be temps. But it's wise to check anyway. */
14624 /* Enter a new binding level.
14625 If TAG_TRANSPARENT is nonzero, do so only for the name space of variables,
14626 not for that of tags. */
14629 pushlevel (tag_transparent)
14630 int tag_transparent;
14632 register struct f_binding_level *newlevel = NULL_BINDING_LEVEL;
14634 assert (! tag_transparent);
14636 if (current_binding_level == global_binding_level)
14641 /* Reuse or create a struct for this binding level. */
14643 if (free_binding_level)
14645 newlevel = free_binding_level;
14646 free_binding_level = free_binding_level->level_chain;
14650 newlevel = make_binding_level ();
14653 /* Add this level to the front of the chain (stack) of levels that
14656 *newlevel = clear_binding_level;
14657 newlevel->level_chain = current_binding_level;
14658 current_binding_level = newlevel;
14661 /* Set the BLOCK node for the innermost scope
14662 (the one we are currently in). */
14666 register tree block;
14668 current_binding_level->this_block = block;
14669 current_binding_level->names = chainon (current_binding_level->names,
14670 BLOCK_VARS (block));
14671 current_binding_level->blocks = chainon (current_binding_level->blocks,
14672 BLOCK_SUBBLOCKS (block));
14676 ffe_signed_or_unsigned_type (unsignedp, type)
14682 if (! INTEGRAL_TYPE_P (type))
14684 if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node))
14685 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
14686 if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
14687 return unsignedp ? unsigned_type_node : integer_type_node;
14688 if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node))
14689 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
14690 if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node))
14691 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
14692 if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node))
14693 return (unsignedp ? long_long_unsigned_type_node
14694 : long_long_integer_type_node);
14696 type2 = ffe_type_for_size (TYPE_PRECISION (type), unsignedp);
14697 if (type2 == NULL_TREE)
14704 ffe_signed_type (type)
14707 tree type1 = TYPE_MAIN_VARIANT (type);
14708 ffeinfoKindtype kt;
14711 if (type1 == unsigned_char_type_node || type1 == char_type_node)
14712 return signed_char_type_node;
14713 if (type1 == unsigned_type_node)
14714 return integer_type_node;
14715 if (type1 == short_unsigned_type_node)
14716 return short_integer_type_node;
14717 if (type1 == long_unsigned_type_node)
14718 return long_integer_type_node;
14719 if (type1 == long_long_unsigned_type_node)
14720 return long_long_integer_type_node;
14721 #if 0 /* gcc/c-* files only */
14722 if (type1 == unsigned_intDI_type_node)
14723 return intDI_type_node;
14724 if (type1 == unsigned_intSI_type_node)
14725 return intSI_type_node;
14726 if (type1 == unsigned_intHI_type_node)
14727 return intHI_type_node;
14728 if (type1 == unsigned_intQI_type_node)
14729 return intQI_type_node;
14732 type2 = ffe_type_for_size (TYPE_PRECISION (type1), 0);
14733 if (type2 != NULL_TREE)
14736 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
14738 type2 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
14740 if (type1 == type2)
14741 return ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
14747 /* Prepare expr to be an argument of a TRUTH_NOT_EXPR,
14748 or validate its data type for an `if' or `while' statement or ?..: exp.
14750 This preparation consists of taking the ordinary
14751 representation of an expression expr and producing a valid tree
14752 boolean expression describing whether expr is nonzero. We could
14753 simply always do build_binary_op (NE_EXPR, expr, integer_zero_node, 1),
14754 but we optimize comparisons, &&, ||, and !.
14756 The resulting type should always be `integer_type_node'. */
14759 ffe_truthvalue_conversion (expr)
14762 if (TREE_CODE (expr) == ERROR_MARK)
14765 #if 0 /* This appears to be wrong for C++. */
14766 /* These really should return error_mark_node after 2.4 is stable.
14767 But not all callers handle ERROR_MARK properly. */
14768 switch (TREE_CODE (TREE_TYPE (expr)))
14771 error ("struct type value used where scalar is required");
14772 return integer_zero_node;
14775 error ("union type value used where scalar is required");
14776 return integer_zero_node;
14779 error ("array type value used where scalar is required");
14780 return integer_zero_node;
14787 switch (TREE_CODE (expr))
14789 /* It is simpler and generates better code to have only TRUTH_*_EXPR
14790 or comparison expressions as truth values at this level. */
14792 case COMPONENT_REF:
14793 /* A one-bit unsigned bit-field is already acceptable. */
14794 if (1 == TREE_INT_CST_LOW (DECL_SIZE (TREE_OPERAND (expr, 1)))
14795 && TREE_UNSIGNED (TREE_OPERAND (expr, 1)))
14801 /* It is simpler and generates better code to have only TRUTH_*_EXPR
14802 or comparison expressions as truth values at this level. */
14804 if (integer_zerop (TREE_OPERAND (expr, 1)))
14805 return build_unary_op (TRUTH_NOT_EXPR, TREE_OPERAND (expr, 0), 0);
14807 case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
14808 case TRUTH_ANDIF_EXPR:
14809 case TRUTH_ORIF_EXPR:
14810 case TRUTH_AND_EXPR:
14811 case TRUTH_OR_EXPR:
14812 case TRUTH_XOR_EXPR:
14813 TREE_TYPE (expr) = integer_type_node;
14820 return integer_zerop (expr) ? integer_zero_node : integer_one_node;
14823 return real_zerop (expr) ? integer_zero_node : integer_one_node;
14826 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 0)))
14827 return build (COMPOUND_EXPR, integer_type_node,
14828 TREE_OPERAND (expr, 0), integer_one_node);
14830 return integer_one_node;
14833 return ffecom_2 ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))
14834 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
14836 ffe_truthvalue_conversion (TREE_OPERAND (expr, 0)),
14837 ffe_truthvalue_conversion (TREE_OPERAND (expr, 1)));
14843 /* These don't change whether an object is non-zero or zero. */
14844 return ffe_truthvalue_conversion (TREE_OPERAND (expr, 0));
14848 /* These don't change whether an object is zero or non-zero, but
14849 we can't ignore them if their second arg has side-effects. */
14850 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)))
14851 return build (COMPOUND_EXPR, integer_type_node, TREE_OPERAND (expr, 1),
14852 ffe_truthvalue_conversion (TREE_OPERAND (expr, 0)));
14854 return ffe_truthvalue_conversion (TREE_OPERAND (expr, 0));
14857 /* Distribute the conversion into the arms of a COND_EXPR. */
14858 return fold (build (COND_EXPR, integer_type_node, TREE_OPERAND (expr, 0),
14859 ffe_truthvalue_conversion (TREE_OPERAND (expr, 1)),
14860 ffe_truthvalue_conversion (TREE_OPERAND (expr, 2))));
14863 /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
14864 since that affects how `default_conversion' will behave. */
14865 if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE
14866 || TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)
14868 /* fall through... */
14870 /* If this is widening the argument, we can ignore it. */
14871 if (TYPE_PRECISION (TREE_TYPE (expr))
14872 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
14873 return ffe_truthvalue_conversion (TREE_OPERAND (expr, 0));
14877 /* With IEEE arithmetic, x - x may not equal 0, so we can't optimize
14879 if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
14880 && TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE)
14882 /* fall through... */
14884 /* This and MINUS_EXPR can be changed into a comparison of the
14886 if (TREE_TYPE (TREE_OPERAND (expr, 0))
14887 == TREE_TYPE (TREE_OPERAND (expr, 1)))
14888 return ffecom_2 (NE_EXPR, integer_type_node,
14889 TREE_OPERAND (expr, 0),
14890 TREE_OPERAND (expr, 1));
14891 return ffecom_2 (NE_EXPR, integer_type_node,
14892 TREE_OPERAND (expr, 0),
14893 fold (build1 (NOP_EXPR,
14894 TREE_TYPE (TREE_OPERAND (expr, 0)),
14895 TREE_OPERAND (expr, 1))));
14898 if (integer_onep (TREE_OPERAND (expr, 1)))
14903 #if 0 /* No such thing in Fortran. */
14904 if (warn_parentheses && C_EXP_ORIGINAL_CODE (expr) == MODIFY_EXPR)
14905 warning ("suggest parentheses around assignment used as truth value");
14913 if (TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE)
14915 ((TREE_SIDE_EFFECTS (expr)
14916 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
14918 ffe_truthvalue_conversion (ffecom_1 (REALPART_EXPR,
14919 TREE_TYPE (TREE_TYPE (expr)),
14921 ffe_truthvalue_conversion (ffecom_1 (IMAGPART_EXPR,
14922 TREE_TYPE (TREE_TYPE (expr)),
14925 return ffecom_2 (NE_EXPR, integer_type_node,
14927 convert (TREE_TYPE (expr), integer_zero_node));
14931 ffe_type_for_mode (mode, unsignedp)
14932 enum machine_mode mode;
14939 if (mode == TYPE_MODE (integer_type_node))
14940 return unsignedp ? unsigned_type_node : integer_type_node;
14942 if (mode == TYPE_MODE (signed_char_type_node))
14943 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
14945 if (mode == TYPE_MODE (short_integer_type_node))
14946 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
14948 if (mode == TYPE_MODE (long_integer_type_node))
14949 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
14951 if (mode == TYPE_MODE (long_long_integer_type_node))
14952 return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node;
14954 #if HOST_BITS_PER_WIDE_INT >= 64
14955 if (mode == TYPE_MODE (intTI_type_node))
14956 return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
14959 if (mode == TYPE_MODE (float_type_node))
14960 return float_type_node;
14962 if (mode == TYPE_MODE (double_type_node))
14963 return double_type_node;
14965 if (mode == TYPE_MODE (build_pointer_type (char_type_node)))
14966 return build_pointer_type (char_type_node);
14968 if (mode == TYPE_MODE (build_pointer_type (integer_type_node)))
14969 return build_pointer_type (integer_type_node);
14971 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
14972 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
14974 if (((t = ffecom_tree_type[i][j]) != NULL_TREE)
14975 && (mode == TYPE_MODE (t)))
14977 if ((i == FFEINFO_basictypeINTEGER) && unsignedp)
14978 return ffecom_tree_type[FFEINFO_basictypeHOLLERITH][j];
14988 ffe_type_for_size (bits, unsignedp)
14992 ffeinfoKindtype kt;
14995 if (bits == TYPE_PRECISION (integer_type_node))
14996 return unsignedp ? unsigned_type_node : integer_type_node;
14998 if (bits == TYPE_PRECISION (signed_char_type_node))
14999 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
15001 if (bits == TYPE_PRECISION (short_integer_type_node))
15002 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
15004 if (bits == TYPE_PRECISION (long_integer_type_node))
15005 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
15007 if (bits == TYPE_PRECISION (long_long_integer_type_node))
15008 return (unsignedp ? long_long_unsigned_type_node
15009 : long_long_integer_type_node);
15011 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
15013 type_node = ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
15015 if ((type_node != NULL_TREE) && (bits == TYPE_PRECISION (type_node)))
15016 return unsignedp ? ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt]
15024 ffe_unsigned_type (type)
15027 tree type1 = TYPE_MAIN_VARIANT (type);
15028 ffeinfoKindtype kt;
15031 if (type1 == signed_char_type_node || type1 == char_type_node)
15032 return unsigned_char_type_node;
15033 if (type1 == integer_type_node)
15034 return unsigned_type_node;
15035 if (type1 == short_integer_type_node)
15036 return short_unsigned_type_node;
15037 if (type1 == long_integer_type_node)
15038 return long_unsigned_type_node;
15039 if (type1 == long_long_integer_type_node)
15040 return long_long_unsigned_type_node;
15041 #if 0 /* gcc/c-* files only */
15042 if (type1 == intDI_type_node)
15043 return unsigned_intDI_type_node;
15044 if (type1 == intSI_type_node)
15045 return unsigned_intSI_type_node;
15046 if (type1 == intHI_type_node)
15047 return unsigned_intHI_type_node;
15048 if (type1 == intQI_type_node)
15049 return unsigned_intQI_type_node;
15052 type2 = ffe_type_for_size (TYPE_PRECISION (type1), 1);
15053 if (type2 != NULL_TREE)
15056 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
15058 type2 = ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
15060 if (type1 == type2)
15061 return ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
15067 /* From gcc/cccp.c, the code to handle -I. */
15069 /* Skip leading "./" from a directory name.
15070 This may yield the empty string, which represents the current directory. */
15072 static const char *
15073 skip_redundant_dir_prefix (const char *dir)
15075 while (dir[0] == '.' && dir[1] == '/')
15076 for (dir += 2; *dir == '/'; dir++)
15078 if (dir[0] == '.' && !dir[1])
15083 /* The file_name_map structure holds a mapping of file names for a
15084 particular directory. This mapping is read from the file named
15085 FILE_NAME_MAP_FILE in that directory. Such a file can be used to
15086 map filenames on a file system with severe filename restrictions,
15087 such as DOS. The format of the file name map file is just a series
15088 of lines with two tokens on each line. The first token is the name
15089 to map, and the second token is the actual name to use. */
15091 struct file_name_map
15093 struct file_name_map *map_next;
15098 #define FILE_NAME_MAP_FILE "header.gcc"
15100 /* Current maximum length of directory names in the search path
15101 for include files. (Altered as we get more of them.) */
15103 static int max_include_len = 0;
15105 struct file_name_list
15107 struct file_name_list *next;
15109 /* Mapping of file names for this directory. */
15110 struct file_name_map *name_map;
15111 /* Non-zero if name_map is valid. */
15115 static struct file_name_list *include = NULL; /* First dir to search */
15116 static struct file_name_list *last_include = NULL; /* Last in chain */
15118 /* I/O buffer structure.
15119 The `fname' field is nonzero for source files and #include files
15120 and for the dummy text used for -D and -U.
15121 It is zero for rescanning results of macro expansion
15122 and for expanding macro arguments. */
15123 #define INPUT_STACK_MAX 400
15124 static struct file_buf {
15126 /* Filename specified with #line command. */
15127 const char *nominal_fname;
15128 /* Record where in the search path this file was found.
15129 For #include_next. */
15130 struct file_name_list *dir;
15132 ffewhereColumn column;
15133 } instack[INPUT_STACK_MAX];
15135 static int last_error_tick = 0; /* Incremented each time we print it. */
15136 static int input_file_stack_tick = 0; /* Incremented when status changes. */
15138 /* Current nesting level of input sources.
15139 `instack[indepth]' is the level currently being read. */
15140 static int indepth = -1;
15142 typedef struct file_buf FILE_BUF;
15144 /* Nonzero means -I- has been seen,
15145 so don't look for #include "foo" the source-file directory. */
15146 static int ignore_srcdir;
15148 #ifndef INCLUDE_LEN_FUDGE
15149 #define INCLUDE_LEN_FUDGE 0
15152 static void append_include_chain (struct file_name_list *first,
15153 struct file_name_list *last);
15154 static FILE *open_include_file (char *filename,
15155 struct file_name_list *searchptr);
15156 static void print_containing_files (ffebadSeverity sev);
15157 static char *read_filename_string (int ch, FILE *f);
15158 static struct file_name_map *read_name_map (const char *dirname);
15160 /* Append a chain of `struct file_name_list's
15161 to the end of the main include chain.
15162 FIRST is the beginning of the chain to append, and LAST is the end. */
15165 append_include_chain (first, last)
15166 struct file_name_list *first, *last;
15168 struct file_name_list *dir;
15170 if (!first || !last)
15176 last_include->next = first;
15178 for (dir = first; ; dir = dir->next) {
15179 int len = strlen (dir->fname) + INCLUDE_LEN_FUDGE;
15180 if (len > max_include_len)
15181 max_include_len = len;
15187 last_include = last;
15190 /* Try to open include file FILENAME. SEARCHPTR is the directory
15191 being tried from the include file search path. This function maps
15192 filenames on file systems based on information read by
15196 open_include_file (filename, searchptr)
15198 struct file_name_list *searchptr;
15200 register struct file_name_map *map;
15201 register char *from;
15204 if (searchptr && ! searchptr->got_name_map)
15206 searchptr->name_map = read_name_map (searchptr->fname
15207 ? searchptr->fname : ".");
15208 searchptr->got_name_map = 1;
15211 /* First check the mapping for the directory we are using. */
15212 if (searchptr && searchptr->name_map)
15215 if (searchptr->fname)
15216 from += strlen (searchptr->fname) + 1;
15217 for (map = searchptr->name_map; map; map = map->map_next)
15219 if (! strcmp (map->map_from, from))
15221 /* Found a match. */
15222 return fopen (map->map_to, "r");
15227 /* Try to find a mapping file for the particular directory we are
15228 looking in. Thus #include <sys/types.h> will look up sys/types.h
15229 in /usr/include/header.gcc and look up types.h in
15230 /usr/include/sys/header.gcc. */
15231 p = strrchr (filename, '/');
15232 #ifdef DIR_SEPARATOR
15233 if (! p) p = strrchr (filename, DIR_SEPARATOR);
15235 char *tmp = strrchr (filename, DIR_SEPARATOR);
15236 if (tmp != NULL && tmp > p) p = tmp;
15242 && searchptr->fname
15243 && strlen (searchptr->fname) == (size_t) (p - filename)
15244 && ! strncmp (searchptr->fname, filename, (int) (p - filename)))
15246 /* FILENAME is in SEARCHPTR, which we've already checked. */
15247 return fopen (filename, "r");
15253 map = read_name_map (".");
15257 dir = (char *) xmalloc (p - filename + 1);
15258 memcpy (dir, filename, p - filename);
15259 dir[p - filename] = '\0';
15261 map = read_name_map (dir);
15264 for (; map; map = map->map_next)
15265 if (! strcmp (map->map_from, from))
15266 return fopen (map->map_to, "r");
15268 return fopen (filename, "r");
15271 /* Print the file names and line numbers of the #include
15272 commands which led to the current file. */
15275 print_containing_files (ffebadSeverity sev)
15277 FILE_BUF *ip = NULL;
15283 /* If stack of files hasn't changed since we last printed
15284 this info, don't repeat it. */
15285 if (last_error_tick == input_file_stack_tick)
15288 for (i = indepth; i >= 0; i--)
15289 if (instack[i].fname != NULL) {
15294 /* Give up if we don't find a source file. */
15298 /* Find the other, outer source files. */
15299 for (i--; i >= 0; i--)
15300 if (instack[i].fname != NULL)
15306 str1 = "In file included";
15318 /* xgettext:no-c-format */
15319 ffebad_start_msg ("%A from %B at %0%C", sev);
15320 ffebad_here (0, ip->line, ip->column);
15321 ffebad_string (str1);
15322 ffebad_string (ip->nominal_fname);
15323 ffebad_string (str2);
15327 /* Record we have printed the status as of this time. */
15328 last_error_tick = input_file_stack_tick;
15331 /* Read a space delimited string of unlimited length from a stdio
15335 read_filename_string (ch, f)
15343 set = alloc = xmalloc (len + 1);
15344 if (! ISSPACE (ch))
15347 while ((ch = getc (f)) != EOF && ! ISSPACE (ch))
15349 if (set - alloc == len)
15352 alloc = xrealloc (alloc, len + 1);
15353 set = alloc + len / 2;
15363 /* Read the file name map file for DIRNAME. */
15365 static struct file_name_map *
15366 read_name_map (dirname)
15367 const char *dirname;
15369 /* This structure holds a linked list of file name maps, one per
15371 struct file_name_map_list
15373 struct file_name_map_list *map_list_next;
15374 char *map_list_name;
15375 struct file_name_map *map_list_map;
15377 static struct file_name_map_list *map_list;
15378 register struct file_name_map_list *map_list_ptr;
15382 int separator_needed;
15384 dirname = skip_redundant_dir_prefix (dirname);
15386 for (map_list_ptr = map_list; map_list_ptr;
15387 map_list_ptr = map_list_ptr->map_list_next)
15388 if (! strcmp (map_list_ptr->map_list_name, dirname))
15389 return map_list_ptr->map_list_map;
15391 map_list_ptr = ((struct file_name_map_list *)
15392 xmalloc (sizeof (struct file_name_map_list)));
15393 map_list_ptr->map_list_name = xstrdup (dirname);
15394 map_list_ptr->map_list_map = NULL;
15396 dirlen = strlen (dirname);
15397 separator_needed = dirlen != 0 && dirname[dirlen - 1] != '/';
15398 name = (char *) xmalloc (dirlen + strlen (FILE_NAME_MAP_FILE) + 2);
15399 strcpy (name, dirname);
15400 name[dirlen] = '/';
15401 strcpy (name + dirlen + separator_needed, FILE_NAME_MAP_FILE);
15402 f = fopen (name, "r");
15405 map_list_ptr->map_list_map = NULL;
15410 while ((ch = getc (f)) != EOF)
15413 struct file_name_map *ptr;
15417 from = read_filename_string (ch, f);
15418 while ((ch = getc (f)) != EOF && ISSPACE (ch) && ch != '\n')
15420 to = read_filename_string (ch, f);
15422 ptr = ((struct file_name_map *)
15423 xmalloc (sizeof (struct file_name_map)));
15424 ptr->map_from = from;
15426 /* Make the real filename absolute. */
15431 ptr->map_to = xmalloc (dirlen + strlen (to) + 2);
15432 strcpy (ptr->map_to, dirname);
15433 ptr->map_to[dirlen] = '/';
15434 strcpy (ptr->map_to + dirlen + separator_needed, to);
15438 ptr->map_next = map_list_ptr->map_list_map;
15439 map_list_ptr->map_list_map = ptr;
15441 while ((ch = getc (f)) != '\n')
15448 map_list_ptr->map_list_next = map_list;
15449 map_list = map_list_ptr;
15451 return map_list_ptr->map_list_map;
15455 ffecom_file_ (const char *name)
15459 /* Do partial setup of input buffer for the sake of generating
15460 early #line directives (when -g is in effect). */
15462 fp = &instack[++indepth];
15463 memset ((char *) fp, 0, sizeof (FILE_BUF));
15466 fp->nominal_fname = fp->fname = name;
15470 ffecom_close_include_ (FILE *f)
15475 input_file_stack_tick++;
15477 ffewhere_line_kill (instack[indepth].line);
15478 ffewhere_column_kill (instack[indepth].column);
15482 ffecom_decode_include_option_ (char *spec)
15484 struct file_name_list *dirtmp;
15486 if (! ignore_srcdir && !strcmp (spec, "-"))
15490 dirtmp = (struct file_name_list *)
15491 xmalloc (sizeof (struct file_name_list));
15492 dirtmp->next = 0; /* New one goes on the end */
15493 dirtmp->fname = spec;
15494 dirtmp->got_name_map = 0;
15496 error ("directory name must immediately follow -I");
15498 append_include_chain (dirtmp, dirtmp);
15503 /* Open INCLUDEd file. */
15506 ffecom_open_include_ (char *name, ffewhereLine l, ffewhereColumn c)
15509 size_t flen = strlen (fbeg);
15510 struct file_name_list *search_start = include; /* Chain of dirs to search */
15511 struct file_name_list dsp[1]; /* First in chain, if #include "..." */
15512 struct file_name_list *searchptr = 0;
15513 char *fname; /* Dynamically allocated fname buffer */
15520 dsp[0].fname = NULL;
15522 /* If -I- was specified, don't search current dir, only spec'd ones. */
15523 if (!ignore_srcdir)
15525 for (fp = &instack[indepth]; fp >= instack; fp--)
15531 if ((nam = fp->nominal_fname) != NULL)
15533 /* Found a named file. Figure out dir of the file,
15534 and put it in front of the search list. */
15535 dsp[0].next = search_start;
15536 search_start = dsp;
15538 ep = strrchr (nam, '/');
15539 #ifdef DIR_SEPARATOR
15540 if (ep == NULL) ep = strrchr (nam, DIR_SEPARATOR);
15542 char *tmp = strrchr (nam, DIR_SEPARATOR);
15543 if (tmp != NULL && tmp > ep) ep = tmp;
15547 ep = strrchr (nam, ']');
15548 if (ep == NULL) ep = strrchr (nam, '>');
15549 if (ep == NULL) ep = strrchr (nam, ':');
15550 if (ep != NULL) ep++;
15555 dsp[0].fname = (char *) xmalloc (n + 1);
15556 strncpy (dsp[0].fname, nam, n);
15557 dsp[0].fname[n] = '\0';
15558 if (n + INCLUDE_LEN_FUDGE > max_include_len)
15559 max_include_len = n + INCLUDE_LEN_FUDGE;
15562 dsp[0].fname = NULL; /* Current directory */
15563 dsp[0].got_name_map = 0;
15569 /* Allocate this permanently, because it gets stored in the definitions
15571 fname = xmalloc (max_include_len + flen + 4);
15572 /* + 2 above for slash and terminating null. */
15573 /* + 2 added for '.h' on VMS (to support '#include filename') (NOT USED
15576 /* If specified file name is absolute, just open it. */
15579 #ifdef DIR_SEPARATOR
15580 || *fbeg == DIR_SEPARATOR
15584 strncpy (fname, (char *) fbeg, flen);
15586 f = open_include_file (fname, NULL);
15592 /* Search directory path, trying to open the file.
15593 Copy each filename tried into FNAME. */
15595 for (searchptr = search_start; searchptr; searchptr = searchptr->next)
15597 if (searchptr->fname)
15599 /* The empty string in a search path is ignored.
15600 This makes it possible to turn off entirely
15601 a standard piece of the list. */
15602 if (searchptr->fname[0] == 0)
15604 strcpy (fname, skip_redundant_dir_prefix (searchptr->fname));
15605 if (fname[0] && fname[strlen (fname) - 1] != '/')
15606 strcat (fname, "/");
15607 fname[strlen (fname) + flen] = 0;
15612 strncat (fname, fbeg, flen);
15614 /* Change this 1/2 Unix 1/2 VMS file specification into a
15615 full VMS file specification */
15616 if (searchptr->fname && (searchptr->fname[0] != 0))
15618 /* Fix up the filename */
15619 hack_vms_include_specification (fname);
15623 /* This is a normal VMS filespec, so use it unchanged. */
15624 strncpy (fname, (char *) fbeg, flen);
15626 #if 0 /* Not for g77. */
15627 /* if it's '#include filename', add the missing .h */
15628 if (strchr (fname, '.') == NULL)
15629 strcat (fname, ".h");
15633 f = open_include_file (fname, searchptr);
15635 if (f == NULL && errno == EACCES)
15637 print_containing_files (FFEBAD_severityWARNING);
15638 /* xgettext:no-c-format */
15639 ffebad_start_msg ("At %0, INCLUDE file %A exists, but is not readable",
15640 FFEBAD_severityWARNING);
15641 ffebad_string (fname);
15642 ffebad_here (0, l, c);
15653 /* A file that was not found. */
15655 strncpy (fname, (char *) fbeg, flen);
15657 print_containing_files (ffebad_severity (FFEBAD_OPEN_INCLUDE));
15658 ffebad_start (FFEBAD_OPEN_INCLUDE);
15659 ffebad_here (0, l, c);
15660 ffebad_string (fname);
15664 if (dsp[0].fname != NULL)
15665 free (dsp[0].fname);
15670 if (indepth >= (INPUT_STACK_MAX - 1))
15672 print_containing_files (FFEBAD_severityFATAL);
15673 /* xgettext:no-c-format */
15674 ffebad_start_msg ("At %0, INCLUDE nesting too deep",
15675 FFEBAD_severityFATAL);
15676 ffebad_string (fname);
15677 ffebad_here (0, l, c);
15682 instack[indepth].line = ffewhere_line_use (l);
15683 instack[indepth].column = ffewhere_column_use (c);
15685 fp = &instack[indepth + 1];
15686 memset ((char *) fp, 0, sizeof (FILE_BUF));
15687 fp->nominal_fname = fp->fname = fname;
15688 fp->dir = searchptr;
15691 input_file_stack_tick++;
15696 /**INDENT* (Do not reformat this comment even with -fca option.)
15697 Data-gathering files: Given the source file listed below, compiled with
15698 f2c I obtained the output file listed after that, and from the output
15699 file I derived the above code.
15701 -------- (begin input file to f2c)
15707 double precision D1,D2
15709 call getem(A1,A2,C1,C2,I1,I2,R1,R2,D1,D2)
15736 c FFEINTRIN_impACOS
15737 call fooR(ACOS(R1))
15738 c FFEINTRIN_impAIMAG
15739 call fooR(AIMAG(C1))
15740 c FFEINTRIN_impAINT
15741 call fooR(AINT(R1))
15742 c FFEINTRIN_impALOG
15743 call fooR(ALOG(R1))
15744 c FFEINTRIN_impALOG10
15745 call fooR(ALOG10(R1))
15746 c FFEINTRIN_impAMAX0
15747 call fooR(AMAX0(I1,I2))
15748 c FFEINTRIN_impAMAX1
15749 call fooR(AMAX1(R1,R2))
15750 c FFEINTRIN_impAMIN0
15751 call fooR(AMIN0(I1,I2))
15752 c FFEINTRIN_impAMIN1
15753 call fooR(AMIN1(R1,R2))
15754 c FFEINTRIN_impAMOD
15755 call fooR(AMOD(R1,R2))
15756 c FFEINTRIN_impANINT
15757 call fooR(ANINT(R1))
15758 c FFEINTRIN_impASIN
15759 call fooR(ASIN(R1))
15760 c FFEINTRIN_impATAN
15761 call fooR(ATAN(R1))
15762 c FFEINTRIN_impATAN2
15763 call fooR(ATAN2(R1,R2))
15764 c FFEINTRIN_impCABS
15765 call fooR(CABS(C1))
15766 c FFEINTRIN_impCCOS
15767 call fooC(CCOS(C1))
15768 c FFEINTRIN_impCEXP
15769 call fooC(CEXP(C1))
15770 c FFEINTRIN_impCHAR
15771 call fooA(CHAR(I1))
15772 c FFEINTRIN_impCLOG
15773 call fooC(CLOG(C1))
15774 c FFEINTRIN_impCONJG
15775 call fooC(CONJG(C1))
15778 c FFEINTRIN_impCOSH
15779 call fooR(COSH(R1))
15780 c FFEINTRIN_impCSIN
15781 call fooC(CSIN(C1))
15782 c FFEINTRIN_impCSQRT
15783 call fooC(CSQRT(C1))
15784 c FFEINTRIN_impDABS
15785 call fooD(DABS(D1))
15786 c FFEINTRIN_impDACOS
15787 call fooD(DACOS(D1))
15788 c FFEINTRIN_impDASIN
15789 call fooD(DASIN(D1))
15790 c FFEINTRIN_impDATAN
15791 call fooD(DATAN(D1))
15792 c FFEINTRIN_impDATAN2
15793 call fooD(DATAN2(D1,D2))
15794 c FFEINTRIN_impDCOS
15795 call fooD(DCOS(D1))
15796 c FFEINTRIN_impDCOSH
15797 call fooD(DCOSH(D1))
15798 c FFEINTRIN_impDDIM
15799 call fooD(DDIM(D1,D2))
15800 c FFEINTRIN_impDEXP
15801 call fooD(DEXP(D1))
15803 call fooR(DIM(R1,R2))
15804 c FFEINTRIN_impDINT
15805 call fooD(DINT(D1))
15806 c FFEINTRIN_impDLOG
15807 call fooD(DLOG(D1))
15808 c FFEINTRIN_impDLOG10
15809 call fooD(DLOG10(D1))
15810 c FFEINTRIN_impDMAX1
15811 call fooD(DMAX1(D1,D2))
15812 c FFEINTRIN_impDMIN1
15813 call fooD(DMIN1(D1,D2))
15814 c FFEINTRIN_impDMOD
15815 call fooD(DMOD(D1,D2))
15816 c FFEINTRIN_impDNINT
15817 call fooD(DNINT(D1))
15818 c FFEINTRIN_impDPROD
15819 call fooD(DPROD(R1,R2))
15820 c FFEINTRIN_impDSIGN
15821 call fooD(DSIGN(D1,D2))
15822 c FFEINTRIN_impDSIN
15823 call fooD(DSIN(D1))
15824 c FFEINTRIN_impDSINH
15825 call fooD(DSINH(D1))
15826 c FFEINTRIN_impDSQRT
15827 call fooD(DSQRT(D1))
15828 c FFEINTRIN_impDTAN
15829 call fooD(DTAN(D1))
15830 c FFEINTRIN_impDTANH
15831 call fooD(DTANH(D1))
15834 c FFEINTRIN_impIABS
15835 call fooI(IABS(I1))
15836 c FFEINTRIN_impICHAR
15837 call fooI(ICHAR(A1))
15838 c FFEINTRIN_impIDIM
15839 call fooI(IDIM(I1,I2))
15840 c FFEINTRIN_impIDNINT
15841 call fooI(IDNINT(D1))
15842 c FFEINTRIN_impINDEX
15843 call fooI(INDEX(A1,A2))
15844 c FFEINTRIN_impISIGN
15845 call fooI(ISIGN(I1,I2))
15849 call fooL(LGE(A1,A2))
15851 call fooL(LGT(A1,A2))
15853 call fooL(LLE(A1,A2))
15855 call fooL(LLT(A1,A2))
15856 c FFEINTRIN_impMAX0
15857 call fooI(MAX0(I1,I2))
15858 c FFEINTRIN_impMAX1
15859 call fooI(MAX1(R1,R2))
15860 c FFEINTRIN_impMIN0
15861 call fooI(MIN0(I1,I2))
15862 c FFEINTRIN_impMIN1
15863 call fooI(MIN1(R1,R2))
15865 call fooI(MOD(I1,I2))
15866 c FFEINTRIN_impNINT
15867 call fooI(NINT(R1))
15868 c FFEINTRIN_impSIGN
15869 call fooR(SIGN(R1,R2))
15872 c FFEINTRIN_impSINH
15873 call fooR(SINH(R1))
15874 c FFEINTRIN_impSQRT
15875 call fooR(SQRT(R1))
15878 c FFEINTRIN_impTANH
15879 call fooR(TANH(R1))
15880 c FFEINTRIN_imp_CMPLX_C
15881 call fooC(cmplx(C1,C2))
15882 c FFEINTRIN_imp_CMPLX_D
15883 call fooZ(cmplx(D1,D2))
15884 c FFEINTRIN_imp_CMPLX_I
15885 call fooC(cmplx(I1,I2))
15886 c FFEINTRIN_imp_CMPLX_R
15887 call fooC(cmplx(R1,R2))
15888 c FFEINTRIN_imp_DBLE_C
15889 call fooD(dble(C1))
15890 c FFEINTRIN_imp_DBLE_D
15891 call fooD(dble(D1))
15892 c FFEINTRIN_imp_DBLE_I
15893 call fooD(dble(I1))
15894 c FFEINTRIN_imp_DBLE_R
15895 call fooD(dble(R1))
15896 c FFEINTRIN_imp_INT_C
15898 c FFEINTRIN_imp_INT_D
15900 c FFEINTRIN_imp_INT_I
15902 c FFEINTRIN_imp_INT_R
15904 c FFEINTRIN_imp_REAL_C
15905 call fooR(real(C1))
15906 c FFEINTRIN_imp_REAL_D
15907 call fooR(real(D1))
15908 c FFEINTRIN_imp_REAL_I
15909 call fooR(real(I1))
15910 c FFEINTRIN_imp_REAL_R
15911 call fooR(real(R1))
15913 c FFEINTRIN_imp_INT_D:
15915 c FFEINTRIN_specIDINT
15916 call fooI(IDINT(D1))
15918 c FFEINTRIN_imp_INT_R:
15920 c FFEINTRIN_specIFIX
15921 call fooI(IFIX(R1))
15922 c FFEINTRIN_specINT
15925 c FFEINTRIN_imp_REAL_D:
15927 c FFEINTRIN_specSNGL
15928 call fooR(SNGL(D1))
15930 c FFEINTRIN_imp_REAL_I:
15932 c FFEINTRIN_specFLOAT
15933 call fooR(FLOAT(I1))
15934 c FFEINTRIN_specREAL
15935 call fooR(REAL(I1))
15938 -------- (end input file to f2c)
15940 -------- (begin output from providing above input file as input to:
15941 -------- `f2c | gcc -E -C - | sed -e "s:/[*]*://:g" -e "s:[*]*[/]://:g" \
15942 -------- -e "s:^#.*$::g"')
15944 // -- translated by f2c (version 19950223).
15945 You must link the resulting object file with the libraries:
15946 -lf2c -lm (in that order)
15950 // f2c.h -- Standard Fortran to C header file //
15952 /// barf [ba:rf] 2. "He suggested using FORTRAN, and everybody barfed."
15954 - From The Shogakukan DICTIONARY OF NEW ENGLISH (Second edition) //
15959 // F2C_INTEGER will normally be `int' but would be `long' on 16-bit systems //
15960 // we assume short, float are OK //
15961 typedef long int // long int // integer;
15962 typedef char *address;
15963 typedef short int shortint;
15964 typedef float real;
15965 typedef double doublereal;
15966 typedef struct { real r, i; } complex;
15967 typedef struct { doublereal r, i; } doublecomplex;
15968 typedef long int // long int // logical;
15969 typedef short int shortlogical;
15970 typedef char logical1;
15971 typedef char integer1;
15972 // typedef long long longint; // // system-dependent //
15977 // Extern is for use with -E //
15991 typedef long int // int or long int // flag;
15992 typedef long int // int or long int // ftnlen;
15993 typedef long int // int or long int // ftnint;
15996 //external read, write//
16005 //internal read, write//
16035 //rewind, backspace, endfile//
16047 ftnint *inex; //parameters in standard's order//
16073 union Multitype { // for multiple entry points //
16084 typedef union Multitype Multitype;
16086 typedef long Long; // No longer used; formerly in Namelist //
16088 struct Vardesc { // for Namelist //
16094 typedef struct Vardesc Vardesc;
16101 typedef struct Namelist Namelist;
16110 // procedure parameter types for -A and -C++ //
16115 typedef int // Unknown procedure type // (*U_fp)();
16116 typedef shortint (*J_fp)();
16117 typedef integer (*I_fp)();
16118 typedef real (*R_fp)();
16119 typedef doublereal (*D_fp)(), (*E_fp)();
16120 typedef // Complex // void (*C_fp)();
16121 typedef // Double Complex // void (*Z_fp)();
16122 typedef logical (*L_fp)();
16123 typedef shortlogical (*K_fp)();
16124 typedef // Character // void (*H_fp)();
16125 typedef // Subroutine // int (*S_fp)();
16127 // E_fp is for real functions when -R is not specified //
16128 typedef void C_f; // complex function //
16129 typedef void H_f; // character function //
16130 typedef void Z_f; // double complex function //
16131 typedef doublereal E_f; // real function with -R not specified //
16133 // undef any lower-case symbols that your C compiler predefines, e.g.: //
16136 // (No such symbols should be defined in a strict ANSI C compiler.
16137 We can avoid trouble with f2c-translated code by using
16162 // Main program // MAIN__()
16164 // System generated locals //
16167 doublereal d__1, d__2;
16169 doublecomplex z__1, z__2, z__3;
16173 // Builtin functions //
16176 double pow_ri(), pow_di();
16180 double acos(), r_imag(), r_int(), log(), r_lg10(), r_mod(), r_nint(),
16181 asin(), atan(), atan2(), c_abs();
16182 void c_cos(), c_exp(), c_log(), r_cnjg();
16183 double cos(), cosh();
16184 void c_sin(), c_sqrt();
16185 double d_dim(), exp(), r_dim(), d_int(), d_lg10(), d_mod(), d_nint(),
16186 d_sign(), sin(), sinh(), sqrt(), tan(), tanh();
16187 integer i_dim(), i_dnnt(), i_indx(), i_sign(), i_len();
16188 logical l_ge(), l_gt(), l_le(), l_lt();
16192 // Local variables //
16193 extern // Subroutine // int fooa_(), fooc_(), food_(), fooi_(), foor_(),
16194 fool_(), fooz_(), getem_();
16195 static char a1[10], a2[10];
16196 static complex c1, c2;
16197 static doublereal d1, d2;
16198 static integer i1, i2;
16199 static real r1, r2;
16202 getem_(a1, a2, &c1, &c2, &i1, &i2, &r1, &r2, &d1, &d2, 10L, 10L);
16210 d__1 = (doublereal) i1;
16211 q__1.r = c1.r / d__1, q__1.i = c1.i / d__1;
16221 c_div(&q__1, &c1, &c2);
16223 q__1.r = c1.r / r1, q__1.i = c1.i / r1;
16225 z__1.r = c1.r / d1, z__1.i = c1.i / d1;
16228 i__1 = pow_ii(&i1, &i2);
16230 r__1 = pow_ri(&r1, &i1);
16232 d__1 = pow_di(&d1, &i1);
16234 pow_ci(&q__1, &c1, &i1);
16236 d__1 = (doublereal) r1;
16237 d__2 = (doublereal) r2;
16238 r__1 = pow_dd(&d__1, &d__2);
16240 d__2 = (doublereal) r1;
16241 d__1 = pow_dd(&d__2, &d1);
16243 d__1 = pow_dd(&d1, &d2);
16245 d__2 = (doublereal) r1;
16246 d__1 = pow_dd(&d1, &d__2);
16248 z__2.r = c1.r, z__2.i = c1.i;
16249 z__3.r = c2.r, z__3.i = c2.i;
16250 pow_zz(&z__1, &z__2, &z__3);
16251 q__1.r = z__1.r, q__1.i = z__1.i;
16253 z__2.r = c1.r, z__2.i = c1.i;
16254 z__3.r = r1, z__3.i = 0.;
16255 pow_zz(&z__1, &z__2, &z__3);
16256 q__1.r = z__1.r, q__1.i = z__1.i;
16258 z__2.r = c1.r, z__2.i = c1.i;
16259 z__3.r = d1, z__3.i = 0.;
16260 pow_zz(&z__1, &z__2, &z__3);
16262 // FFEINTRIN_impABS //
16263 r__1 = (doublereal)(( r1 ) >= 0 ? ( r1 ) : -( r1 )) ;
16265 // FFEINTRIN_impACOS //
16268 // FFEINTRIN_impAIMAG //
16269 r__1 = r_imag(&c1);
16271 // FFEINTRIN_impAINT //
16274 // FFEINTRIN_impALOG //
16277 // FFEINTRIN_impALOG10 //
16278 r__1 = r_lg10(&r1);
16280 // FFEINTRIN_impAMAX0 //
16281 r__1 = (real) (( i1 ) >= ( i2 ) ? ( i1 ) : ( i2 )) ;
16283 // FFEINTRIN_impAMAX1 //
16284 r__1 = (doublereal)(( r1 ) >= ( r2 ) ? ( r1 ) : ( r2 )) ;
16286 // FFEINTRIN_impAMIN0 //
16287 r__1 = (real) (( i1 ) <= ( i2 ) ? ( i1 ) : ( i2 )) ;
16289 // FFEINTRIN_impAMIN1 //
16290 r__1 = (doublereal)(( r1 ) <= ( r2 ) ? ( r1 ) : ( r2 )) ;
16292 // FFEINTRIN_impAMOD //
16293 r__1 = r_mod(&r1, &r2);
16295 // FFEINTRIN_impANINT //
16296 r__1 = r_nint(&r1);
16298 // FFEINTRIN_impASIN //
16301 // FFEINTRIN_impATAN //
16304 // FFEINTRIN_impATAN2 //
16305 r__1 = atan2(r1, r2);
16307 // FFEINTRIN_impCABS //
16310 // FFEINTRIN_impCCOS //
16313 // FFEINTRIN_impCEXP //
16316 // FFEINTRIN_impCHAR //
16317 *(unsigned char *)&ch__1[0] = i1;
16319 // FFEINTRIN_impCLOG //
16322 // FFEINTRIN_impCONJG //
16323 r_cnjg(&q__1, &c1);
16325 // FFEINTRIN_impCOS //
16328 // FFEINTRIN_impCOSH //
16331 // FFEINTRIN_impCSIN //
16334 // FFEINTRIN_impCSQRT //
16335 c_sqrt(&q__1, &c1);
16337 // FFEINTRIN_impDABS //
16338 d__1 = (( d1 ) >= 0 ? ( d1 ) : -( d1 )) ;
16340 // FFEINTRIN_impDACOS //
16343 // FFEINTRIN_impDASIN //
16346 // FFEINTRIN_impDATAN //
16349 // FFEINTRIN_impDATAN2 //
16350 d__1 = atan2(d1, d2);
16352 // FFEINTRIN_impDCOS //
16355 // FFEINTRIN_impDCOSH //
16358 // FFEINTRIN_impDDIM //
16359 d__1 = d_dim(&d1, &d2);
16361 // FFEINTRIN_impDEXP //
16364 // FFEINTRIN_impDIM //
16365 r__1 = r_dim(&r1, &r2);
16367 // FFEINTRIN_impDINT //
16370 // FFEINTRIN_impDLOG //
16373 // FFEINTRIN_impDLOG10 //
16374 d__1 = d_lg10(&d1);
16376 // FFEINTRIN_impDMAX1 //
16377 d__1 = (( d1 ) >= ( d2 ) ? ( d1 ) : ( d2 )) ;
16379 // FFEINTRIN_impDMIN1 //
16380 d__1 = (( d1 ) <= ( d2 ) ? ( d1 ) : ( d2 )) ;
16382 // FFEINTRIN_impDMOD //
16383 d__1 = d_mod(&d1, &d2);
16385 // FFEINTRIN_impDNINT //
16386 d__1 = d_nint(&d1);
16388 // FFEINTRIN_impDPROD //
16389 d__1 = (doublereal) r1 * r2;
16391 // FFEINTRIN_impDSIGN //
16392 d__1 = d_sign(&d1, &d2);
16394 // FFEINTRIN_impDSIN //
16397 // FFEINTRIN_impDSINH //
16400 // FFEINTRIN_impDSQRT //
16403 // FFEINTRIN_impDTAN //
16406 // FFEINTRIN_impDTANH //
16409 // FFEINTRIN_impEXP //
16412 // FFEINTRIN_impIABS //
16413 i__1 = (( i1 ) >= 0 ? ( i1 ) : -( i1 )) ;
16415 // FFEINTRIN_impICHAR //
16416 i__1 = *(unsigned char *)a1;
16418 // FFEINTRIN_impIDIM //
16419 i__1 = i_dim(&i1, &i2);
16421 // FFEINTRIN_impIDNINT //
16422 i__1 = i_dnnt(&d1);
16424 // FFEINTRIN_impINDEX //
16425 i__1 = i_indx(a1, a2, 10L, 10L);
16427 // FFEINTRIN_impISIGN //
16428 i__1 = i_sign(&i1, &i2);
16430 // FFEINTRIN_impLEN //
16431 i__1 = i_len(a1, 10L);
16433 // FFEINTRIN_impLGE //
16434 L__1 = l_ge(a1, a2, 10L, 10L);
16436 // FFEINTRIN_impLGT //
16437 L__1 = l_gt(a1, a2, 10L, 10L);
16439 // FFEINTRIN_impLLE //
16440 L__1 = l_le(a1, a2, 10L, 10L);
16442 // FFEINTRIN_impLLT //
16443 L__1 = l_lt(a1, a2, 10L, 10L);
16445 // FFEINTRIN_impMAX0 //
16446 i__1 = (( i1 ) >= ( i2 ) ? ( i1 ) : ( i2 )) ;
16448 // FFEINTRIN_impMAX1 //
16449 i__1 = (integer) (doublereal)(( r1 ) >= ( r2 ) ? ( r1 ) : ( r2 )) ;
16451 // FFEINTRIN_impMIN0 //
16452 i__1 = (( i1 ) <= ( i2 ) ? ( i1 ) : ( i2 )) ;
16454 // FFEINTRIN_impMIN1 //
16455 i__1 = (integer) (doublereal)(( r1 ) <= ( r2 ) ? ( r1 ) : ( r2 )) ;
16457 // FFEINTRIN_impMOD //
16460 // FFEINTRIN_impNINT //
16461 i__1 = i_nint(&r1);
16463 // FFEINTRIN_impSIGN //
16464 r__1 = r_sign(&r1, &r2);
16466 // FFEINTRIN_impSIN //
16469 // FFEINTRIN_impSINH //
16472 // FFEINTRIN_impSQRT //
16475 // FFEINTRIN_impTAN //
16478 // FFEINTRIN_impTANH //
16481 // FFEINTRIN_imp_CMPLX_C //
16484 q__1.r = r__1, q__1.i = r__2;
16486 // FFEINTRIN_imp_CMPLX_D //
16487 z__1.r = d1, z__1.i = d2;
16489 // FFEINTRIN_imp_CMPLX_I //
16492 q__1.r = r__1, q__1.i = r__2;
16494 // FFEINTRIN_imp_CMPLX_R //
16495 q__1.r = r1, q__1.i = r2;
16497 // FFEINTRIN_imp_DBLE_C //
16498 d__1 = (doublereal) c1.r;
16500 // FFEINTRIN_imp_DBLE_D //
16503 // FFEINTRIN_imp_DBLE_I //
16504 d__1 = (doublereal) i1;
16506 // FFEINTRIN_imp_DBLE_R //
16507 d__1 = (doublereal) r1;
16509 // FFEINTRIN_imp_INT_C //
16510 i__1 = (integer) c1.r;
16512 // FFEINTRIN_imp_INT_D //
16513 i__1 = (integer) d1;
16515 // FFEINTRIN_imp_INT_I //
16518 // FFEINTRIN_imp_INT_R //
16519 i__1 = (integer) r1;
16521 // FFEINTRIN_imp_REAL_C //
16524 // FFEINTRIN_imp_REAL_D //
16527 // FFEINTRIN_imp_REAL_I //
16530 // FFEINTRIN_imp_REAL_R //
16534 // FFEINTRIN_imp_INT_D: //
16536 // FFEINTRIN_specIDINT //
16537 i__1 = (integer) d1;
16540 // FFEINTRIN_imp_INT_R: //
16542 // FFEINTRIN_specIFIX //
16543 i__1 = (integer) r1;
16545 // FFEINTRIN_specINT //
16546 i__1 = (integer) r1;
16549 // FFEINTRIN_imp_REAL_D: //
16551 // FFEINTRIN_specSNGL //
16555 // FFEINTRIN_imp_REAL_I: //
16557 // FFEINTRIN_specFLOAT //
16560 // FFEINTRIN_specREAL //
16566 -------- (end output file from f2c)
16570 #include "gt-f-com.h"
16571 #include "gtype-f.h"