1 /* com.c -- Implementation File (module.c template V1.0)
2 Copyright (C) 1995-1998 Free Software Foundation, Inc.
3 Contributed by James Craig Burley.
5 This file is part of GNU Fortran.
7 GNU Fortran is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Fortran is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Fortran; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
26 Contains compiler-specific functions.
31 /* Understanding this module means understanding the interface between
32 the g77 front end and the gcc back end (or, perhaps, some other
33 back end). In here are the functions called by the front end proper
34 to notify whatever back end is in place about certain things, and
35 also the back-end-specific functions. It's a bear to deal with, so
36 lately I've been trying to simplify things, especially with regard
37 to the gcc-back-end-specific stuff.
39 Building expressions generally seems quite easy, but building decls
40 has been challenging and is undergoing revision. gcc has several
43 TYPE_DECL -- a type (int, float, struct, function, etc.)
44 CONST_DECL -- a constant of some type other than function
45 LABEL_DECL -- a variable or a constant?
46 PARM_DECL -- an argument to a function (a variable that is a dummy)
47 RESULT_DECL -- the return value of a function (a variable)
48 VAR_DECL -- other variable (can hold a ptr-to-function, struct, int, etc.)
49 FUNCTION_DECL -- a function (either the actual function or an extern ref)
50 FIELD_DECL -- a field in a struct or union (goes into types)
52 g77 has a set of functions that somewhat parallels the gcc front end
53 when it comes to building decls:
55 Internal Function (one we define, not just declare as extern):
57 yes = suspend_momentary ();
58 if (is_nested) push_f_function_context ();
59 start_function (get_identifier ("function_name"), function_type,
60 is_nested, is_public);
61 // for each arg, build PARM_DECL and call push_parm_decl (decl) with it;
62 store_parm_decls (is_main_program);
63 ffecom_start_compstmt ();
64 // for stmts and decls inside function, do appropriate things;
65 ffecom_end_compstmt ();
66 finish_function (is_nested);
67 if (is_nested) pop_f_function_context ();
68 if (is_nested) resume_momentary (yes);
74 yes = suspend_momentary ();
75 // fill in external, public, static, &c for decl, and
76 // set DECL_INITIAL to error_mark_node if going to initialize
77 // set is_top_level TRUE only if not at top level and decl
78 // must go in top level (i.e. not within current function decl context)
79 d = start_decl (decl, is_top_level);
80 init = ...; // if have initializer
81 finish_decl (d, init, is_top_level);
82 resume_momentary (yes);
89 #if FFECOM_targetCURRENT == FFECOM_targetGCC
94 #include "output.j" /* Must follow tree.j so TREE_CODE is defined! */
96 #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
98 #define FFECOM_GCC_INCLUDE 1 /* Enable -I. */
100 /* BEGIN stuff from gcc/cccp.c. */
102 /* The following symbols should be autoconfigured:
109 In the mean time, we'll get by with approximations based
110 on existing GCC configuration symbols. */
113 # ifndef HAVE_STDLIB_H
114 # define HAVE_STDLIB_H 1
116 # ifndef HAVE_UNISTD_H
117 # define HAVE_UNISTD_H 1
119 # ifndef STDC_HEADERS
120 # define STDC_HEADERS 1
122 #endif /* defined (POSIX) */
124 #if defined (POSIX) || (defined (USG) && !defined (VMS))
125 # ifndef HAVE_FCNTL_H
126 # define HAVE_FCNTL_H 1
133 # if TIME_WITH_SYS_TIME
134 # include <sys/time.h>
138 # include <sys/time.h>
143 # include <sys/resource.h>
150 /* This defines "errno" properly for VMS, and gives us EACCES. */
163 /* VMS-specific definitions */
166 #define O_RDONLY 0 /* Open arg for Read/Only */
167 #define O_WRONLY 1 /* Open arg for Write/Only */
168 #define read(fd,buf,size) VMS_read (fd,buf,size)
169 #define write(fd,buf,size) VMS_write (fd,buf,size)
170 #define open(fname,mode,prot) VMS_open (fname,mode,prot)
171 #define fopen(fname,mode) VMS_fopen (fname,mode)
172 #define freopen(fname,mode,ofile) VMS_freopen (fname,mode,ofile)
173 #define strncat(dst,src,cnt) VMS_strncat (dst,src,cnt)
174 #define fstat(fd,stbuf) VMS_fstat (fd,stbuf)
175 static int VMS_fstat (), VMS_stat ();
176 static char * VMS_strncat ();
177 static int VMS_read ();
178 static int VMS_write ();
179 static int VMS_open ();
180 static FILE * VMS_fopen ();
181 static FILE * VMS_freopen ();
182 static void hack_vms_include_specification ();
183 typedef struct { unsigned :16, :16, :16; } vms_ino_t;
184 #define ino_t vms_ino_t
185 #define INCLUDE_LEN_FUDGE 10 /* leave room for VMS syntax conversion */
187 #define BSTRING /* VMS/GCC supplies the bstring routines */
188 #endif /* __GNUC__ */
195 /* END stuff from gcc/cccp.c. */
197 #define FFECOM_DETERMINE_TYPES 1 /* for com.h */
214 /* Externals defined here. */
216 #define FFECOM_FASTER_ARRAY_REFS 0 /* Generates faster code? */
218 #if FFECOM_targetCURRENT == FFECOM_targetGCC
220 /* tree.h declares a bunch of stuff that it expects the front end to
221 define. Here are the definitions, which in the C front end are
222 found in the file c-decl.c. */
224 tree integer_zero_node;
225 tree integer_one_node;
226 tree null_pointer_node;
227 tree error_mark_node;
229 tree integer_type_node;
230 tree unsigned_type_node;
232 tree current_function_decl;
234 /* ~~gcc/tree.h *should* declare this, because toplev.c and dwarfout.c
237 char *language_string = "GNU F77";
239 /* Stream for reading from the input file. */
242 /* These definitions parallel those in c-decl.c so that code from that
243 module can be used pretty much as is. Much of these defs aren't
244 otherwise used, i.e. by g77 code per se, except some of them are used
245 to build some of them that are. The ones that are global (i.e. not
246 "static") are those that ste.c and such might use (directly
247 or by using com macros that reference them in their definitions). */
249 static tree short_integer_type_node;
250 tree long_integer_type_node;
251 static tree long_long_integer_type_node;
253 static tree short_unsigned_type_node;
254 static tree long_unsigned_type_node;
255 static tree long_long_unsigned_type_node;
257 static tree unsigned_char_type_node;
258 static tree signed_char_type_node;
260 static tree float_type_node;
261 static tree double_type_node;
262 static tree complex_float_type_node;
263 tree complex_double_type_node;
264 static tree long_double_type_node;
265 static tree complex_integer_type_node;
266 static tree complex_long_double_type_node;
268 tree string_type_node;
270 static tree double_ftype_double;
271 static tree float_ftype_float;
272 static tree ldouble_ftype_ldouble;
274 /* The rest of these are inventions for g77, though there might be
275 similar things in the C front end. As they are found, these
276 inventions should be renamed to be canonical. Note that only
277 the ones currently required to be global are so. */
279 static tree ffecom_tree_fun_type_void;
280 static tree ffecom_tree_ptr_to_fun_type_void;
282 tree ffecom_integer_type_node; /* Abbrev for _tree_type[blah][blah]. */
283 tree ffecom_integer_zero_node; /* Like *_*_* with g77's integer type. */
284 tree ffecom_integer_one_node; /* " */
285 tree ffecom_tree_type[FFEINFO_basictype][FFEINFO_kindtype];
287 /* _fun_type things are the f2c-specific versions. For -fno-f2c,
288 just use build_function_type and build_pointer_type on the
289 appropriate _tree_type array element. */
291 static tree ffecom_tree_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
292 static tree ffecom_tree_ptr_to_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
293 static tree ffecom_tree_subr_type;
294 static tree ffecom_tree_ptr_to_subr_type;
295 static tree ffecom_tree_blockdata_type;
297 static tree ffecom_tree_xargc_;
299 ffecomSymbol ffecom_symbol_null_
308 ffeinfoKindtype ffecom_pointer_kind_ = FFEINFO_basictypeNONE;
309 ffeinfoKindtype ffecom_label_kind_ = FFEINFO_basictypeNONE;
311 int ffecom_f2c_typecode_[FFEINFO_basictype][FFEINFO_kindtype];
312 tree ffecom_f2c_integer_type_node;
313 tree ffecom_f2c_ptr_to_integer_type_node;
314 tree ffecom_f2c_address_type_node;
315 tree ffecom_f2c_real_type_node;
316 tree ffecom_f2c_ptr_to_real_type_node;
317 tree ffecom_f2c_doublereal_type_node;
318 tree ffecom_f2c_complex_type_node;
319 tree ffecom_f2c_doublecomplex_type_node;
320 tree ffecom_f2c_longint_type_node;
321 tree ffecom_f2c_logical_type_node;
322 tree ffecom_f2c_flag_type_node;
323 tree ffecom_f2c_ftnlen_type_node;
324 tree ffecom_f2c_ftnlen_zero_node;
325 tree ffecom_f2c_ftnlen_one_node;
326 tree ffecom_f2c_ftnlen_two_node;
327 tree ffecom_f2c_ptr_to_ftnlen_type_node;
328 tree ffecom_f2c_ftnint_type_node;
329 tree ffecom_f2c_ptr_to_ftnint_type_node;
330 #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
332 /* Simple definitions and enumerations. */
334 #ifndef FFECOM_sizeMAXSTACKITEM
335 #define FFECOM_sizeMAXSTACKITEM 32*1024 /* Keep user-declared things
336 larger than this # bytes
337 off stack if possible. */
340 /* For systems that have large enough stacks, they should define
341 this to 0, and here, for ease of use later on, we just undefine
344 #if FFECOM_sizeMAXSTACKITEM == 0
345 #undef FFECOM_sizeMAXSTACKITEM
351 FFECOM_rttypeVOIDSTAR_, /* C's `void *' type. */
352 FFECOM_rttypeFTNINT_, /* f2c's `ftnint' type. */
353 FFECOM_rttypeINTEGER_, /* f2c's `integer' type. */
354 FFECOM_rttypeLONGINT_, /* f2c's `longint' type. */
355 FFECOM_rttypeLOGICAL_, /* f2c's `logical' type. */
356 FFECOM_rttypeREAL_F2C_, /* f2c's `real' returned as `double'. */
357 FFECOM_rttypeREAL_GNU_, /* `real' returned as such. */
358 FFECOM_rttypeCOMPLEX_F2C_, /* f2c's `complex' returned via 1st arg. */
359 FFECOM_rttypeCOMPLEX_GNU_, /* f2c's `complex' returned directly. */
360 FFECOM_rttypeDOUBLE_, /* C's `double' type. */
361 FFECOM_rttypeDOUBLEREAL_, /* f2c's `doublereal' type. */
362 FFECOM_rttypeDBLCMPLX_F2C_, /* f2c's `doublecomplex' returned via 1st arg. */
363 FFECOM_rttypeDBLCMPLX_GNU_, /* f2c's `doublecomplex' returned directly. */
364 FFECOM_rttypeCHARACTER_, /* f2c `char *'/`ftnlen' pair. */
368 /* Internal typedefs. */
370 #if FFECOM_targetCURRENT == FFECOM_targetGCC
371 typedef struct _ffecom_concat_list_ ffecomConcatList_;
372 #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
374 /* Private include files. */
377 /* Internal structure definitions. */
379 #if FFECOM_targetCURRENT == FFECOM_targetGCC
380 struct _ffecom_concat_list_
385 ffetargetCharacterSize minlen;
386 ffetargetCharacterSize maxlen;
388 #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
390 /* Static functions (internal). */
392 #if FFECOM_targetCURRENT == FFECOM_targetGCC
393 static tree ffecom_arglist_expr_ (const char *argstring, ffebld args);
394 static tree ffecom_widest_expr_type_ (ffebld list);
395 static bool ffecom_overlap_ (tree dest_decl, tree dest_offset,
396 tree dest_size, tree source_tree,
397 ffebld source, bool scalar_arg);
398 static bool ffecom_args_overlapping_ (tree dest_tree, ffebld dest,
399 tree args, tree callee_commons,
401 static tree ffecom_build_f2c_string_ (int i, const char *s);
402 static tree ffecom_call_ (tree fn, ffeinfoKindtype kt,
403 bool is_f2c_complex, tree type,
404 tree args, tree dest_tree,
405 ffebld dest, bool *dest_used,
406 tree callee_commons, bool scalar_args, tree hook);
407 static tree ffecom_call_binop_ (tree fn, ffeinfoKindtype kt,
408 bool is_f2c_complex, tree type,
409 ffebld left, ffebld right,
410 tree dest_tree, ffebld dest,
411 bool *dest_used, tree callee_commons,
412 bool scalar_args, tree hook);
413 static void ffecom_char_args_x_ (tree *xitem, tree *length,
414 ffebld expr, bool with_null);
415 static tree ffecom_check_size_overflow_ (ffesymbol s, tree type, bool dummy);
416 static tree ffecom_char_enhance_arg_ (tree *xtype, ffesymbol s);
417 static ffecomConcatList_
418 ffecom_concat_list_gather_ (ffecomConcatList_ catlist,
420 ffetargetCharacterSize max);
421 static void ffecom_concat_list_kill_ (ffecomConcatList_ catlist);
422 static ffecomConcatList_ ffecom_concat_list_new_ (ffebld expr,
423 ffetargetCharacterSize max);
424 static void ffecom_debug_kludge_ (tree aggr, const char *aggr_type,
425 ffesymbol member, tree member_type,
426 ffetargetOffset offset);
427 static void ffecom_do_entry_ (ffesymbol fn, int entrynum);
428 static tree ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest,
429 bool *dest_used, bool assignp, bool widenp);
430 static tree ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree,
431 ffebld dest, bool *dest_used);
432 static tree ffecom_expr_power_integer_ (ffebld expr);
433 static void ffecom_expr_transform_ (ffebld expr);
434 static void ffecom_f2c_make_type_ (tree *type, int tcode, const char *name);
435 static void ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size,
437 static ffeglobal ffecom_finish_global_ (ffeglobal global);
438 static ffesymbol ffecom_finish_symbol_transform_ (ffesymbol s);
439 static tree ffecom_get_appended_identifier_ (char us, const char *text);
440 static tree ffecom_get_external_identifier_ (ffesymbol s);
441 static tree ffecom_get_identifier_ (const char *text);
442 static tree ffecom_gen_sfuncdef_ (ffesymbol s,
445 static const char *ffecom_gfrt_args_ (ffecomGfrt ix);
446 static tree ffecom_gfrt_tree_ (ffecomGfrt ix);
447 static tree ffecom_init_zero_ (tree decl);
448 static tree ffecom_intrinsic_ichar_ (tree tree_type, ffebld arg,
450 static tree ffecom_intrinsic_len_ (ffebld expr);
451 static void ffecom_let_char_ (tree dest_tree,
453 ffetargetCharacterSize dest_size,
455 static void ffecom_make_gfrt_ (ffecomGfrt ix);
456 static void ffecom_member_phase1_ (ffestorag mst, ffestorag st);
457 #ifdef SOMEONE_GETS_DEBUG_SUPPORT_WORKING
458 static void ffecom_member_phase2_ (ffestorag mst, ffestorag st);
460 static void ffecom_prepare_let_char_ (ffetargetCharacterSize dest_size,
462 static void ffecom_push_dummy_decls_ (ffebld dumlist,
464 static void ffecom_start_progunit_ (void);
465 static ffesymbol ffecom_sym_transform_ (ffesymbol s);
466 static ffesymbol ffecom_sym_transform_assign_ (ffesymbol s);
467 static void ffecom_transform_common_ (ffesymbol s);
468 static void ffecom_transform_equiv_ (ffestorag st);
469 static tree ffecom_transform_namelist_ (ffesymbol s);
470 static void ffecom_tree_canonize_ptr_ (tree *decl, tree *offset,
472 static void ffecom_tree_canonize_ref_ (tree *decl, tree *offset,
473 tree *size, tree tree);
474 static tree ffecom_tree_divide_ (tree tree_type, tree left, tree right,
475 tree dest_tree, ffebld dest,
476 bool *dest_used, tree hook);
477 static tree ffecom_type_localvar_ (ffesymbol s,
480 static tree ffecom_type_namelist_ (void);
482 static tree ffecom_type_permanent_copy_ (tree t);
484 static tree ffecom_type_vardesc_ (void);
485 static tree ffecom_vardesc_ (ffebld expr);
486 static tree ffecom_vardesc_array_ (ffesymbol s);
487 static tree ffecom_vardesc_dims_ (ffesymbol s);
488 static tree ffecom_convert_narrow_ (tree type, tree expr);
489 static tree ffecom_convert_widen_ (tree type, tree expr);
490 #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
492 /* These are static functions that parallel those found in the C front
493 end and thus have the same names. */
495 #if FFECOM_targetCURRENT == FFECOM_targetGCC
496 static tree bison_rule_compstmt_ (void);
497 static void bison_rule_pushlevel_ (void);
498 static tree builtin_function (const char *name, tree type,
499 enum built_in_function function_code,
500 const char *library_name);
501 static void delete_block (tree block);
502 static int duplicate_decls (tree newdecl, tree olddecl);
503 static void finish_decl (tree decl, tree init, bool is_top_level);
504 static void finish_function (int nested);
505 static char *lang_printable_name (tree decl, int v);
506 static tree lookup_name_current_level (tree name);
507 static struct binding_level *make_binding_level (void);
508 static void pop_f_function_context (void);
509 static void push_f_function_context (void);
510 static void push_parm_decl (tree parm);
511 static tree pushdecl_top_level (tree decl);
512 static int kept_level_p (void);
513 static tree storedecls (tree decls);
514 static void store_parm_decls (int is_main_program);
515 static tree start_decl (tree decl, bool is_top_level);
516 static void start_function (tree name, tree type, int nested, int public);
517 #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
518 #if FFECOM_GCC_INCLUDE
519 static void ffecom_file_ (char *name);
520 static void ffecom_initialize_char_syntax_ (void);
521 static void ffecom_close_include_ (FILE *f);
522 static int ffecom_decode_include_option_ (char *spec);
523 static FILE *ffecom_open_include_ (char *name, ffewhereLine l,
525 #endif /* FFECOM_GCC_INCLUDE */
527 /* Static objects accessed by functions in this module. */
529 static ffesymbol ffecom_primary_entry_ = NULL;
530 static ffesymbol ffecom_nested_entry_ = NULL;
531 static ffeinfoKind ffecom_primary_entry_kind_;
532 static bool ffecom_primary_entry_is_proc_;
533 #if FFECOM_targetCURRENT == FFECOM_targetGCC
534 static tree ffecom_outer_function_decl_;
535 static tree ffecom_previous_function_decl_;
536 static tree ffecom_which_entrypoint_decl_;
537 static tree ffecom_float_zero_ = NULL_TREE;
538 static tree ffecom_float_half_ = NULL_TREE;
539 static tree ffecom_double_zero_ = NULL_TREE;
540 static tree ffecom_double_half_ = NULL_TREE;
541 static tree ffecom_func_result_;/* For functions. */
542 static tree ffecom_func_length_;/* For CHARACTER fns. */
543 static ffebld ffecom_list_blockdata_;
544 static ffebld ffecom_list_common_;
545 static ffebld ffecom_master_arglist_;
546 static ffeinfoBasictype ffecom_master_bt_;
547 static ffeinfoKindtype ffecom_master_kt_;
548 static ffetargetCharacterSize ffecom_master_size_;
549 static int ffecom_num_fns_ = 0;
550 static int ffecom_num_entrypoints_ = 0;
551 static bool ffecom_is_altreturning_ = FALSE;
552 static tree ffecom_multi_type_node_;
553 static tree ffecom_multi_retval_;
555 ffecom_multi_fields_[FFEINFO_basictype][FFEINFO_kindtype];
556 static bool ffecom_member_namelisted_; /* _member_phase1_ namelisted? */
557 static bool ffecom_doing_entry_ = FALSE;
558 static bool ffecom_transform_only_dummies_ = FALSE;
560 /* Holds pointer-to-function expressions. */
562 static tree ffecom_gfrt_[FFECOM_gfrt]
565 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) NULL_TREE,
566 #include "com-rt.def"
570 /* Holds the external names of the functions. */
572 static const char *ffecom_gfrt_name_[FFECOM_gfrt]
575 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) NAME,
576 #include "com-rt.def"
580 /* Whether the function returns. */
582 static bool ffecom_gfrt_volatile_[FFECOM_gfrt]
585 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) VOLATILE,
586 #include "com-rt.def"
590 /* Whether the function returns type complex. */
592 static bool ffecom_gfrt_complex_[FFECOM_gfrt]
595 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) COMPLEX,
596 #include "com-rt.def"
600 /* Type code for the function return value. */
602 static ffecomRttype_ ffecom_gfrt_type_[FFECOM_gfrt]
605 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) TYPE,
606 #include "com-rt.def"
610 /* String of codes for the function's arguments. */
612 static const char *ffecom_gfrt_argstring_[FFECOM_gfrt]
615 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) ARGS,
616 #include "com-rt.def"
619 #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
621 /* Internal macros. */
623 #if FFECOM_targetCURRENT == FFECOM_targetGCC
625 /* We let tm.h override the types used here, to handle trivial differences
626 such as the choice of unsigned int or long unsigned int for size_t.
627 When machines start needing nontrivial differences in the size type,
628 it would be best to do something here to figure out automatically
629 from other information what type to use. */
631 /* NOTE: g77 currently doesn't use these; see setting of sizetype and
632 change that if you need to. -- jcb 09/01/91. */
634 #define ffecom_concat_list_count_(catlist) ((catlist).count)
635 #define ffecom_concat_list_expr_(catlist,i) ((catlist).exprs[(i)])
636 #define ffecom_concat_list_maxlen_(catlist) ((catlist).maxlen)
637 #define ffecom_concat_list_minlen_(catlist) ((catlist).minlen)
639 #define ffecom_char_args_(i,l,e) ffecom_char_args_x_((i),(l),(e),FALSE)
640 #define ffecom_char_args_with_null_(i,l,e) ffecom_char_args_x_((i),(l),(e),TRUE)
642 /* For each binding contour we allocate a binding_level structure
643 * which records the names defined in that contour.
646 * 1) one for each function definition,
647 * where internal declarations of the parameters appear.
649 * The current meaning of a name can be found by searching the levels from
650 * the current one out to the global one.
653 /* Note that the information in the `names' component of the global contour
654 is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */
658 /* A chain of _DECL nodes for all variables, constants, functions,
659 and typedef types. These are in the reverse of the order supplied.
663 /* For each level (except not the global one),
664 a chain of BLOCK nodes for all the levels
665 that were entered and exited one level down. */
668 /* The BLOCK node for this level, if one has been preallocated.
669 If 0, the BLOCK is allocated (if needed) when the level is popped. */
672 /* The binding level which this one is contained in (inherits from). */
673 struct binding_level *level_chain;
675 /* 0: no ffecom_prepare_* functions called at this level yet;
676 1: ffecom_prepare* functions called, except not ffecom_prepare_end;
677 2: ffecom_prepare_end called. */
681 #define NULL_BINDING_LEVEL (struct binding_level *) NULL
683 /* The binding level currently in effect. */
685 static struct binding_level *current_binding_level;
687 /* A chain of binding_level structures awaiting reuse. */
689 static struct binding_level *free_binding_level;
691 /* The outermost binding level, for names of file scope.
692 This is created when the compiler is started and exists
693 through the entire run. */
695 static struct binding_level *global_binding_level;
697 /* Binding level structures are initialized by copying this one. */
699 static struct binding_level clear_binding_level
701 {NULL, NULL, NULL, NULL_BINDING_LEVEL, 0};
703 /* Language-dependent contents of an identifier. */
705 struct lang_identifier
707 struct tree_identifier ignore;
708 tree global_value, local_value, label_value;
712 /* Macros for access to language-specific slots in an identifier. */
713 /* Each of these slots contains a DECL node or null. */
715 /* This represents the value which the identifier has in the
716 file-scope namespace. */
717 #define IDENTIFIER_GLOBAL_VALUE(NODE) \
718 (((struct lang_identifier *)(NODE))->global_value)
719 /* This represents the value which the identifier has in the current
721 #define IDENTIFIER_LOCAL_VALUE(NODE) \
722 (((struct lang_identifier *)(NODE))->local_value)
723 /* This represents the value which the identifier has as a label in
724 the current label scope. */
725 #define IDENTIFIER_LABEL_VALUE(NODE) \
726 (((struct lang_identifier *)(NODE))->label_value)
727 /* This is nonzero if the identifier was "made up" by g77 code. */
728 #define IDENTIFIER_INVENTED(NODE) \
729 (((struct lang_identifier *)(NODE))->invented)
731 /* In identifiers, C uses the following fields in a special way:
732 TREE_PUBLIC to record that there was a previous local extern decl.
733 TREE_USED to record that such a decl was used.
734 TREE_ADDRESSABLE to record that the address of such a decl was used. */
736 /* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function
737 that have names. Here so we can clear out their names' definitions
738 at the end of the function. */
740 static tree named_labels;
742 /* A list of LABEL_DECLs from outer contexts that are currently shadowed. */
744 static tree shadowed_labels;
746 #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
748 /* Return the subscript expression, modified to do range-checking.
750 `array' is the array to be checked against.
751 `element' is the subscript expression to check.
752 `dim' is the dimension number (starting at 0).
753 `total_dims' is the total number of dimensions (0 for CHARACTER substring).
757 ffecom_subscript_check_ (tree array, tree element, int dim, int total_dims,
760 tree low = TYPE_MIN_VALUE (TYPE_DOMAIN (array));
761 tree high = TYPE_MAX_VALUE (TYPE_DOMAIN (array));
766 if (element == error_mark_node)
769 element = ffecom_save_tree (element);
770 cond = ffecom_2 (LE_EXPR, integer_type_node,
775 cond = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
777 ffecom_2 (LE_EXPR, integer_type_node,
794 var = xmalloc (strlen (array_name) + 20);
795 sprintf (&var[0], "%s[%s-substring]",
797 dim ? "end" : "start");
798 len = strlen (var) + 1;
802 len = strlen (array_name) + 1;
807 var = xmalloc (strlen (array_name) + 40);
808 sprintf (&var[0], "%s[subscript-%d-of-%d]",
810 dim + 1, total_dims);
811 len = strlen (var) + 1;
815 arg1 = build_string (len, var);
821 = build_type_variant (build_array_type (char_type_node,
825 build_int_2 (len, 0))),
827 TREE_CONSTANT (arg1) = 1;
828 TREE_STATIC (arg1) = 1;
829 arg1 = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg1)),
832 /* s_rnge adds one to the element to print it, so bias against
833 that -- want to print a faithful *subscript* value. */
834 arg2 = convert (ffecom_f2c_ftnint_type_node,
835 ffecom_2 (MINUS_EXPR,
838 convert (TREE_TYPE (element),
841 proc = xmalloc ((len = strlen (input_filename)
842 + IDENTIFIER_LENGTH (DECL_NAME (current_function_decl))
845 sprintf (&proc[0], "%s/%s",
847 IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));
848 arg3 = build_string (len, proc);
853 = build_type_variant (build_array_type (char_type_node,
857 build_int_2 (len, 0))),
859 TREE_CONSTANT (arg3) = 1;
860 TREE_STATIC (arg3) = 1;
861 arg3 = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg3)),
864 arg4 = convert (ffecom_f2c_ftnint_type_node,
865 build_int_2 (lineno, 0));
867 arg1 = build_tree_list (NULL_TREE, arg1);
868 arg2 = build_tree_list (NULL_TREE, arg2);
869 arg3 = build_tree_list (NULL_TREE, arg3);
870 arg4 = build_tree_list (NULL_TREE, arg4);
871 TREE_CHAIN (arg3) = arg4;
872 TREE_CHAIN (arg2) = arg3;
873 TREE_CHAIN (arg1) = arg2;
877 die = ffecom_call_gfrt (FFECOM_gfrtRANGE,
879 TREE_SIDE_EFFECTS (die) = 1;
881 element = ffecom_3 (COND_EXPR,
890 /* Return the computed element of an array reference.
892 `item' is the array or a pointer to the array. It must be a pointer
893 to the array if ffe_is_flat_arrays ().
894 `expr' is the original opARRAYREF expression.
895 `want_ptr' is non-zero if `item' is a pointer to the element, instead of
896 the element itself, is to be returned. */
899 ffecom_arrayref_ (tree item, ffebld expr, int want_ptr)
901 ffebld dims[FFECOM_dimensionsMAX];
904 int flatten = 0 /* ~~~ ffe_is_flat_arrays () */;
905 int need_ptr = want_ptr || flatten;
910 if (ffebld_op (ffebld_left (expr)) == FFEBLD_opSYMTER)
911 array_name = ffesymbol_text (ffebld_symter (ffebld_left (expr)));
913 array_name = "[expr?]";
915 /* Build up ARRAY_REFs in reverse order (since we're column major
916 here in Fortran land). */
918 for (i = 0, expr = ffebld_right (expr);
920 expr = ffebld_trail (expr))
921 dims[i++] = ffebld_head (expr);
927 for (--i, array = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item)));
929 --i, array = TYPE_MAIN_VARIANT (TREE_TYPE (array)))
931 element = ffecom_expr (dims[i]);
932 if (ffe_is_subscript_check ())
933 element = ffecom_subscript_check_ (array, element, i, total_dims,
935 item = ffecom_2 (PLUS_EXPR,
936 build_pointer_type (TREE_TYPE (array)),
938 size_binop (MULT_EXPR,
939 size_in_bytes (TREE_TYPE (array)),
941 fold (build (MINUS_EXPR,
942 TREE_TYPE (TYPE_MIN_VALUE (TYPE_DOMAIN (array))),
944 TYPE_MIN_VALUE (TYPE_DOMAIN (array)))))));
948 item = ffecom_1 (INDIRECT_REF,
949 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item))),
959 array = TYPE_MAIN_VARIANT (TREE_TYPE (item));
961 element = ffecom_expr_ (dims[i], NULL, NULL, NULL, FALSE, TRUE);
962 if (ffe_is_subscript_check ())
963 element = ffecom_subscript_check_ (array, element, i, total_dims,
965 item = ffecom_2 (ARRAY_REF,
966 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item))),
975 /* This is like gcc's stabilize_reference -- in fact, most of the code
976 comes from that -- but it handles the situation where the reference
977 is going to have its subparts picked at, and it shouldn't change
978 (or trigger extra invocations of functions in the subtrees) due to
979 this. save_expr is a bit overzealous, because we don't need the
980 entire thing calculated and saved like a temp. So, for DECLs, no
981 change is needed, because these are stable aggregates, and ARRAY_REF
982 and such might well be stable too, but for things like calculations,
983 we do need to calculate a snapshot of a value before picking at it. */
985 #if FFECOM_targetCURRENT == FFECOM_targetGCC
987 ffecom_stabilize_aggregate_ (tree ref)
990 enum tree_code code = TREE_CODE (ref);
997 /* No action is needed in this case. */
1003 case FIX_TRUNC_EXPR:
1004 case FIX_FLOOR_EXPR:
1005 case FIX_ROUND_EXPR:
1007 result = build_nt (code, stabilize_reference (TREE_OPERAND (ref, 0)));
1011 result = build_nt (INDIRECT_REF,
1012 stabilize_reference_1 (TREE_OPERAND (ref, 0)));
1016 result = build_nt (COMPONENT_REF,
1017 stabilize_reference (TREE_OPERAND (ref, 0)),
1018 TREE_OPERAND (ref, 1));
1022 result = build_nt (BIT_FIELD_REF,
1023 stabilize_reference (TREE_OPERAND (ref, 0)),
1024 stabilize_reference_1 (TREE_OPERAND (ref, 1)),
1025 stabilize_reference_1 (TREE_OPERAND (ref, 2)));
1029 result = build_nt (ARRAY_REF,
1030 stabilize_reference (TREE_OPERAND (ref, 0)),
1031 stabilize_reference_1 (TREE_OPERAND (ref, 1)));
1035 result = build_nt (COMPOUND_EXPR,
1036 stabilize_reference_1 (TREE_OPERAND (ref, 0)),
1037 stabilize_reference (TREE_OPERAND (ref, 1)));
1041 result = build1 (INDIRECT_REF, TREE_TYPE (ref),
1042 save_expr (build1 (ADDR_EXPR,
1043 build_pointer_type (TREE_TYPE (ref)),
1049 return save_expr (ref);
1052 return error_mark_node;
1055 TREE_TYPE (result) = TREE_TYPE (ref);
1056 TREE_READONLY (result) = TREE_READONLY (ref);
1057 TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (ref);
1058 TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (ref);
1059 TREE_RAISES (result) = TREE_RAISES (ref);
1065 /* A rip-off of gcc's convert.c convert_to_complex function,
1066 reworked to handle complex implemented as C structures
1067 (RECORD_TYPE with two fields, real and imaginary `r' and `i'). */
1069 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1071 ffecom_convert_to_complex_ (tree type, tree expr)
1073 register enum tree_code form = TREE_CODE (TREE_TYPE (expr));
1076 assert (TREE_CODE (type) == RECORD_TYPE);
1078 subtype = TREE_TYPE (TYPE_FIELDS (type));
1080 if (form == REAL_TYPE || form == INTEGER_TYPE || form == ENUMERAL_TYPE)
1082 expr = convert (subtype, expr);
1083 return ffecom_2 (COMPLEX_EXPR, type, expr,
1084 convert (subtype, integer_zero_node));
1087 if (form == RECORD_TYPE)
1089 tree elt_type = TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr)));
1090 if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype))
1094 expr = save_expr (expr);
1095 return ffecom_2 (COMPLEX_EXPR,
1098 ffecom_1 (REALPART_EXPR,
1099 TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))),
1102 ffecom_1 (IMAGPART_EXPR,
1103 TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))),
1108 if (form == POINTER_TYPE || form == REFERENCE_TYPE)
1109 error ("pointer value used where a complex was expected");
1111 error ("aggregate value used where a complex was expected");
1113 return ffecom_2 (COMPLEX_EXPR, type,
1114 convert (subtype, integer_zero_node),
1115 convert (subtype, integer_zero_node));
1119 /* Like gcc's convert(), but crashes if widening might happen. */
1121 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1123 ffecom_convert_narrow_ (type, expr)
1126 register tree e = expr;
1127 register enum tree_code code = TREE_CODE (type);
1129 if (type == TREE_TYPE (e)
1130 || TREE_CODE (e) == ERROR_MARK)
1132 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
1133 return fold (build1 (NOP_EXPR, type, e));
1134 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
1135 || code == ERROR_MARK)
1136 return error_mark_node;
1137 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
1139 assert ("void value not ignored as it ought to be" == NULL);
1140 return error_mark_node;
1142 assert (code != VOID_TYPE);
1143 if ((code != RECORD_TYPE)
1144 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
1145 assert ("converting COMPLEX to REAL" == NULL);
1146 assert (code != ENUMERAL_TYPE);
1147 if (code == INTEGER_TYPE)
1149 assert ((TREE_CODE (TREE_TYPE (e)) == INTEGER_TYPE
1150 && TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (e)))
1151 || (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE
1152 && (TYPE_PRECISION (type)
1153 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e))))));
1154 return fold (convert_to_integer (type, e));
1156 if (code == POINTER_TYPE)
1158 assert (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE);
1159 return fold (convert_to_pointer (type, e));
1161 if (code == REAL_TYPE)
1163 assert (TREE_CODE (TREE_TYPE (e)) == REAL_TYPE);
1164 assert (TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (e)));
1165 return fold (convert_to_real (type, e));
1167 if (code == COMPLEX_TYPE)
1169 assert (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE);
1170 assert (TYPE_PRECISION (TREE_TYPE (type)) <= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e))));
1171 return fold (convert_to_complex (type, e));
1173 if (code == RECORD_TYPE)
1175 assert (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE);
1176 /* Check that at least the first field name agrees. */
1177 assert (DECL_NAME (TYPE_FIELDS (type))
1178 == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e))));
1179 assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1180 <= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))));
1181 if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1182 == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))))
1184 return fold (ffecom_convert_to_complex_ (type, e));
1187 assert ("conversion to non-scalar type requested" == NULL);
1188 return error_mark_node;
1192 /* Like gcc's convert(), but crashes if narrowing might happen. */
1194 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1196 ffecom_convert_widen_ (type, expr)
1199 register tree e = expr;
1200 register enum tree_code code = TREE_CODE (type);
1202 if (type == TREE_TYPE (e)
1203 || TREE_CODE (e) == ERROR_MARK)
1205 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
1206 return fold (build1 (NOP_EXPR, type, e));
1207 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
1208 || code == ERROR_MARK)
1209 return error_mark_node;
1210 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
1212 assert ("void value not ignored as it ought to be" == NULL);
1213 return error_mark_node;
1215 assert (code != VOID_TYPE);
1216 if ((code != RECORD_TYPE)
1217 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
1218 assert ("narrowing COMPLEX to REAL" == NULL);
1219 assert (code != ENUMERAL_TYPE);
1220 if (code == INTEGER_TYPE)
1222 assert ((TREE_CODE (TREE_TYPE (e)) == INTEGER_TYPE
1223 && TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (e)))
1224 || (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE
1225 && (TYPE_PRECISION (type)
1226 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e))))));
1227 return fold (convert_to_integer (type, e));
1229 if (code == POINTER_TYPE)
1231 assert (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE);
1232 return fold (convert_to_pointer (type, e));
1234 if (code == REAL_TYPE)
1236 assert (TREE_CODE (TREE_TYPE (e)) == REAL_TYPE);
1237 assert (TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (e)));
1238 return fold (convert_to_real (type, e));
1240 if (code == COMPLEX_TYPE)
1242 assert (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE);
1243 assert (TYPE_PRECISION (TREE_TYPE (type)) >= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e))));
1244 return fold (convert_to_complex (type, e));
1246 if (code == RECORD_TYPE)
1248 assert (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE);
1249 /* Check that at least the first field name agrees. */
1250 assert (DECL_NAME (TYPE_FIELDS (type))
1251 == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e))));
1252 assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1253 >= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))));
1254 if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1255 == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))))
1257 return fold (ffecom_convert_to_complex_ (type, e));
1260 assert ("conversion to non-scalar type requested" == NULL);
1261 return error_mark_node;
1265 /* Handles making a COMPLEX type, either the standard
1266 (but buggy?) gbe way, or the safer (but less elegant?)
1269 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1271 ffecom_make_complex_type_ (tree subtype)
1277 if (ffe_is_emulate_complex ())
1279 type = make_node (RECORD_TYPE);
1280 realfield = ffecom_decl_field (type, NULL_TREE, "r", subtype);
1281 imagfield = ffecom_decl_field (type, realfield, "i", subtype);
1282 TYPE_FIELDS (type) = realfield;
1287 type = make_node (COMPLEX_TYPE);
1288 TREE_TYPE (type) = subtype;
1296 /* Chooses either the gbe or the f2c way to build a
1297 complex constant. */
1299 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1301 ffecom_build_complex_constant_ (tree type, tree realpart, tree imagpart)
1305 if (ffe_is_emulate_complex ())
1307 bothparts = build_tree_list (TYPE_FIELDS (type), realpart);
1308 TREE_CHAIN (bothparts) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), imagpart);
1309 bothparts = build (CONSTRUCTOR, type, NULL_TREE, bothparts);
1313 bothparts = build_complex (type, realpart, imagpart);
1320 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1322 ffecom_arglist_expr_ (const char *c, ffebld expr)
1325 tree *plist = &list;
1326 tree trail = NULL_TREE; /* Append char length args here. */
1327 tree *ptrail = &trail;
1332 tree wanted = NULL_TREE;
1333 static char zed[] = "0";
1338 while (expr != NULL)
1361 wanted = ffecom_f2c_complex_type_node;
1365 wanted = ffecom_f2c_doublereal_type_node;
1369 wanted = ffecom_f2c_doublecomplex_type_node;
1373 wanted = ffecom_f2c_real_type_node;
1377 wanted = ffecom_f2c_integer_type_node;
1381 wanted = ffecom_f2c_longint_type_node;
1385 assert ("bad argstring code" == NULL);
1391 exprh = ffebld_head (expr);
1395 if ((wanted == NULL_TREE)
1398 (ffecom_tree_type[ffeinfo_basictype (ffebld_info (exprh))]
1399 [ffeinfo_kindtype (ffebld_info (exprh))])
1400 == TYPE_MODE (wanted))))
1402 = build_tree_list (NULL_TREE,
1403 ffecom_arg_ptr_to_expr (exprh,
1407 item = ffecom_arg_expr (exprh, &length);
1408 item = ffecom_convert_widen_ (wanted, item);
1411 item = ffecom_1 (ADDR_EXPR,
1412 build_pointer_type (TREE_TYPE (item)),
1416 = build_tree_list (NULL_TREE,
1420 plist = &TREE_CHAIN (*plist);
1421 expr = ffebld_trail (expr);
1422 if (length != NULL_TREE)
1424 *ptrail = build_tree_list (NULL_TREE, length);
1425 ptrail = &TREE_CHAIN (*ptrail);
1429 /* We've run out of args in the call; if the implementation expects
1430 more, supply null pointers for them, which the implementation can
1431 check to see if an arg was omitted. */
1433 while (*c != '\0' && *c != '0')
1438 assert ("missing arg to run-time routine!" == NULL);
1453 assert ("bad arg string code" == NULL);
1457 = build_tree_list (NULL_TREE,
1459 plist = &TREE_CHAIN (*plist);
1468 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1470 ffecom_widest_expr_type_ (ffebld list)
1473 ffebld widest = NULL;
1475 ffetype widest_type = NULL;
1478 for (; list != NULL; list = ffebld_trail (list))
1480 item = ffebld_head (list);
1483 if ((widest != NULL)
1484 && (ffeinfo_basictype (ffebld_info (item))
1485 != ffeinfo_basictype (ffebld_info (widest))))
1487 type = ffeinfo_type (ffeinfo_basictype (ffebld_info (item)),
1488 ffeinfo_kindtype (ffebld_info (item)));
1489 if ((widest == FFEINFO_kindtypeNONE)
1490 || (ffetype_size (type)
1491 > ffetype_size (widest_type)))
1498 assert (widest != NULL);
1499 t = ffecom_tree_type[ffeinfo_basictype (ffebld_info (widest))]
1500 [ffeinfo_kindtype (ffebld_info (widest))];
1501 assert (t != NULL_TREE);
1506 /* Check whether dest and source might overlap. ffebld versions of these
1507 might or might not be passed, will be NULL if not.
1509 The test is really whether source_tree is modifiable and, if modified,
1510 might overlap destination such that the value(s) in the destination might
1511 change before it is finally modified. dest_* are the canonized
1512 destination itself. */
1514 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1516 ffecom_overlap_ (tree dest_decl, tree dest_offset, tree dest_size,
1517 tree source_tree, ffebld source UNUSED,
1525 if (source_tree == NULL_TREE)
1528 switch (TREE_CODE (source_tree))
1531 case IDENTIFIER_NODE:
1542 case TRUNC_DIV_EXPR:
1544 case FLOOR_DIV_EXPR:
1545 case ROUND_DIV_EXPR:
1546 case TRUNC_MOD_EXPR:
1548 case FLOOR_MOD_EXPR:
1549 case ROUND_MOD_EXPR:
1551 case EXACT_DIV_EXPR:
1552 case FIX_TRUNC_EXPR:
1554 case FIX_FLOOR_EXPR:
1555 case FIX_ROUND_EXPR:
1570 case BIT_ANDTC_EXPR:
1572 case TRUTH_ANDIF_EXPR:
1573 case TRUTH_ORIF_EXPR:
1574 case TRUTH_AND_EXPR:
1576 case TRUTH_XOR_EXPR:
1577 case TRUTH_NOT_EXPR:
1593 return ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1594 TREE_OPERAND (source_tree, 1), NULL,
1598 return ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1599 TREE_OPERAND (source_tree, 0), NULL,
1604 case NON_LVALUE_EXPR:
1606 if (TREE_CODE (TREE_TYPE (source_tree)) != POINTER_TYPE)
1609 ffecom_tree_canonize_ptr_ (&source_decl, &source_offset,
1611 source_size = TYPE_SIZE (TREE_TYPE (TREE_TYPE (source_tree)));
1616 ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1617 TREE_OPERAND (source_tree, 1), NULL,
1619 || ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1620 TREE_OPERAND (source_tree, 2), NULL,
1625 ffecom_tree_canonize_ref_ (&source_decl, &source_offset,
1627 TREE_OPERAND (source_tree, 0));
1631 if (TREE_CODE (TREE_TYPE (source_tree)) != POINTER_TYPE)
1634 source_decl = source_tree;
1635 source_offset = size_zero_node;
1636 source_size = TYPE_SIZE (TREE_TYPE (TREE_TYPE (source_tree)));
1640 case REFERENCE_EXPR:
1641 case PREDECREMENT_EXPR:
1642 case PREINCREMENT_EXPR:
1643 case POSTDECREMENT_EXPR:
1644 case POSTINCREMENT_EXPR:
1652 /* Come here when source_decl, source_offset, and source_size filled
1653 in appropriately. */
1655 if (source_decl == NULL_TREE)
1656 return FALSE; /* No decl involved, so no overlap. */
1658 if (source_decl != dest_decl)
1659 return FALSE; /* Different decl, no overlap. */
1661 if (TREE_CODE (dest_size) == ERROR_MARK)
1662 return TRUE; /* Assignment into entire assumed-size
1663 array? Shouldn't happen.... */
1665 t = ffecom_2 (LE_EXPR, integer_type_node,
1666 ffecom_2 (PLUS_EXPR, TREE_TYPE (dest_offset),
1668 convert (TREE_TYPE (dest_offset),
1670 convert (TREE_TYPE (dest_offset),
1673 if (integer_onep (t))
1674 return FALSE; /* Destination precedes source. */
1677 || (source_size == NULL_TREE)
1678 || (TREE_CODE (source_size) == ERROR_MARK)
1679 || integer_zerop (source_size))
1680 return TRUE; /* No way to tell if dest follows source. */
1682 t = ffecom_2 (LE_EXPR, integer_type_node,
1683 ffecom_2 (PLUS_EXPR, TREE_TYPE (source_offset),
1685 convert (TREE_TYPE (source_offset),
1687 convert (TREE_TYPE (source_offset),
1690 if (integer_onep (t))
1691 return FALSE; /* Destination follows source. */
1693 return TRUE; /* Destination and source overlap. */
1697 /* Check whether dest might overlap any of a list of arguments or is
1698 in a COMMON area the callee might know about (and thus modify). */
1700 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1702 ffecom_args_overlapping_ (tree dest_tree, ffebld dest UNUSED,
1703 tree args, tree callee_commons,
1711 ffecom_tree_canonize_ref_ (&dest_decl, &dest_offset, &dest_size,
1714 if (dest_decl == NULL_TREE)
1715 return FALSE; /* Seems unlikely! */
1717 /* If the decl cannot be determined reliably, or if its in COMMON
1718 and the callee isn't known to not futz with COMMON via other
1719 means, overlap might happen. */
1721 if ((TREE_CODE (dest_decl) == ERROR_MARK)
1722 || ((callee_commons != NULL_TREE)
1723 && TREE_PUBLIC (dest_decl)))
1726 for (; args != NULL_TREE; args = TREE_CHAIN (args))
1728 if (((arg = TREE_VALUE (args)) != NULL_TREE)
1729 && ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1730 arg, NULL, scalar_args))
1738 /* Build a string for a variable name as used by NAMELIST. This means that
1739 if we're using the f2c library, we build an uppercase string, since
1742 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1744 ffecom_build_f2c_string_ (int i, const char *s)
1746 if (!ffe_is_f2c_library ())
1747 return build_string (i, s);
1756 if (((size_t) i) > ARRAY_SIZE (space))
1757 tmp = malloc_new_ks (malloc_pool_image (), "f2c_string", i);
1761 for (p = s, q = tmp; *p != '\0'; ++p, ++q)
1762 *q = ffesrc_toupper (*p);
1765 t = build_string (i, tmp);
1767 if (((size_t) i) > ARRAY_SIZE (space))
1768 malloc_kill_ks (malloc_pool_image (), tmp, i);
1775 /* Returns CALL_EXPR or equivalent with given type (pass NULL_TREE for
1776 type to just get whatever the function returns), handling the
1777 f2c value-returning convention, if required, by prepending
1778 to the arglist a pointer to a temporary to receive the return value. */
1780 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1782 ffecom_call_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex,
1783 tree type, tree args, tree dest_tree,
1784 ffebld dest, bool *dest_used, tree callee_commons,
1785 bool scalar_args, tree hook)
1790 if (dest_used != NULL)
1795 if ((dest_used == NULL)
1797 || (ffeinfo_basictype (ffebld_info (dest))
1798 != FFEINFO_basictypeCOMPLEX)
1799 || (ffeinfo_kindtype (ffebld_info (dest)) != kt)
1800 || ((type != NULL_TREE) && (TREE_TYPE (dest_tree) != type))
1801 || ffecom_args_overlapping_ (dest_tree, dest, args,
1806 tempvar = ffecom_make_tempvar (ffecom_tree_type
1807 [FFEINFO_basictypeCOMPLEX][kt],
1808 FFETARGET_charactersizeNONE,
1818 tempvar = dest_tree;
1823 = build_tree_list (NULL_TREE,
1824 ffecom_1 (ADDR_EXPR,
1825 build_pointer_type (TREE_TYPE (tempvar)),
1827 TREE_CHAIN (item) = args;
1829 item = ffecom_3s (CALL_EXPR, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), fn,
1832 if (tempvar != dest_tree)
1833 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), item, tempvar);
1836 item = ffecom_3s (CALL_EXPR, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), fn,
1839 if ((type != NULL_TREE) && (TREE_TYPE (item) != type))
1840 item = ffecom_convert_narrow_ (type, item);
1846 /* Given two arguments, transform them and make a call to the given
1847 function via ffecom_call_. */
1849 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1851 ffecom_call_binop_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex,
1852 tree type, ffebld left, ffebld right,
1853 tree dest_tree, ffebld dest, bool *dest_used,
1854 tree callee_commons, bool scalar_args, tree hook)
1861 left_tree = ffecom_arg_ptr_to_expr (left, &left_length);
1862 right_tree = ffecom_arg_ptr_to_expr (right, &right_length);
1864 left_tree = build_tree_list (NULL_TREE, left_tree);
1865 right_tree = build_tree_list (NULL_TREE, right_tree);
1866 TREE_CHAIN (left_tree) = right_tree;
1868 if (left_length != NULL_TREE)
1870 left_length = build_tree_list (NULL_TREE, left_length);
1871 TREE_CHAIN (right_tree) = left_length;
1874 if (right_length != NULL_TREE)
1876 right_length = build_tree_list (NULL_TREE, right_length);
1877 if (left_length != NULL_TREE)
1878 TREE_CHAIN (left_length) = right_length;
1880 TREE_CHAIN (right_tree) = right_length;
1883 return ffecom_call_ (fn, kt, is_f2c_complex, type, left_tree,
1884 dest_tree, dest, dest_used, callee_commons,
1889 /* Return ptr/length args for char subexpression
1891 Handles CHARACTER-type CONTER, SYMTER, SUBSTR, ARRAYREF, and FUNCREF
1892 subexpressions by constructing the appropriate trees for the ptr-to-
1893 character-text and length-of-character-text arguments in a calling
1896 Note that if with_null is TRUE, and the expression is an opCONTER,
1897 a null byte is appended to the string. */
1899 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1901 ffecom_char_args_x_ (tree *xitem, tree *length, ffebld expr, bool with_null)
1905 ffetargetCharacter1 val;
1906 ffetargetCharacterSize newlen;
1908 switch (ffebld_op (expr))
1910 case FFEBLD_opCONTER:
1911 val = ffebld_constant_character1 (ffebld_conter (expr));
1912 newlen = ffetarget_length_character1 (val);
1915 /* Begin FFETARGET-NULL-KLUDGE. */
1919 *length = build_int_2 (newlen, 0);
1920 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
1921 high = build_int_2 (newlen, 0);
1922 TREE_TYPE (high) = ffecom_f2c_ftnlen_type_node;
1923 item = build_string (newlen,
1924 ffetarget_text_character1 (val));
1925 /* End FFETARGET-NULL-KLUDGE. */
1927 = build_type_variant
1931 (ffecom_f2c_ftnlen_type_node,
1932 ffecom_f2c_ftnlen_one_node,
1935 TREE_CONSTANT (item) = 1;
1936 TREE_STATIC (item) = 1;
1937 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
1941 case FFEBLD_opSYMTER:
1943 ffesymbol s = ffebld_symter (expr);
1945 item = ffesymbol_hook (s).decl_tree;
1946 if (item == NULL_TREE)
1948 s = ffecom_sym_transform_ (s);
1949 item = ffesymbol_hook (s).decl_tree;
1951 if (ffesymbol_kind (s) == FFEINFO_kindENTITY)
1953 if (ffesymbol_size (s) == FFETARGET_charactersizeNONE)
1954 *length = ffesymbol_hook (s).length_tree;
1957 *length = build_int_2 (ffesymbol_size (s), 0);
1958 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
1961 else if (item == error_mark_node)
1962 *length = error_mark_node;
1964 /* FFEINFO_kindFUNCTION. */
1965 *length = NULL_TREE;
1966 if (!ffesymbol_hook (s).addr
1967 && (item != error_mark_node))
1968 item = ffecom_1 (ADDR_EXPR,
1969 build_pointer_type (TREE_TYPE (item)),
1974 case FFEBLD_opARRAYREF:
1976 ffecom_char_args_ (&item, length, ffebld_left (expr));
1978 if (item == error_mark_node || *length == error_mark_node)
1980 item = *length = error_mark_node;
1984 item = ffecom_arrayref_ (item, expr, 1);
1988 case FFEBLD_opSUBSTR:
1992 ffebld thing = ffebld_right (expr);
1999 assert (ffebld_op (thing) == FFEBLD_opITEM);
2000 start = ffebld_head (thing);
2001 thing = ffebld_trail (thing);
2002 assert (ffebld_trail (thing) == NULL);
2003 end = ffebld_head (thing);
2005 /* Determine name for pretty-printing range-check errors. */
2006 for (left_symter = ffebld_left (expr);
2007 left_symter && ffebld_op (left_symter) == FFEBLD_opARRAYREF;
2008 left_symter = ffebld_left (left_symter))
2010 if (ffebld_op (left_symter) == FFEBLD_opSYMTER)
2011 char_name = ffesymbol_text (ffebld_symter (left_symter));
2013 char_name = "[expr?]";
2015 ffecom_char_args_ (&item, length, ffebld_left (expr));
2017 if (item == error_mark_node || *length == error_mark_node)
2019 item = *length = error_mark_node;
2023 array = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item)));
2031 end_tree = ffecom_expr (end);
2032 if (ffe_is_subscript_check ())
2033 end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0,
2035 end_tree = convert (ffecom_f2c_ftnlen_type_node,
2038 if (end_tree == error_mark_node)
2040 item = *length = error_mark_node;
2049 start_tree = ffecom_expr (start);
2050 if (ffe_is_subscript_check ())
2051 start_tree = ffecom_subscript_check_ (array, start_tree, 0, 0,
2053 start_tree = convert (ffecom_f2c_ftnlen_type_node,
2056 if (start_tree == error_mark_node)
2058 item = *length = error_mark_node;
2062 start_tree = ffecom_save_tree (start_tree);
2064 item = ffecom_2 (PLUS_EXPR, TREE_TYPE (item),
2066 ffecom_2 (MINUS_EXPR,
2067 TREE_TYPE (start_tree),
2069 ffecom_f2c_ftnlen_one_node));
2073 *length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
2074 ffecom_f2c_ftnlen_one_node,
2075 ffecom_2 (MINUS_EXPR,
2076 ffecom_f2c_ftnlen_type_node,
2082 end_tree = ffecom_expr (end);
2083 if (ffe_is_subscript_check ())
2084 end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0,
2086 end_tree = convert (ffecom_f2c_ftnlen_type_node,
2089 if (end_tree == error_mark_node)
2091 item = *length = error_mark_node;
2095 *length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
2096 ffecom_f2c_ftnlen_one_node,
2097 ffecom_2 (MINUS_EXPR,
2098 ffecom_f2c_ftnlen_type_node,
2099 end_tree, start_tree));
2105 case FFEBLD_opFUNCREF:
2107 ffesymbol s = ffebld_symter (ffebld_left (expr));
2110 ffetargetCharacterSize size = ffeinfo_size (ffebld_info (expr));
2113 if (size == FFETARGET_charactersizeNONE)
2114 /* ~~Kludge alert! This should someday be fixed. */
2117 *length = build_int_2 (size, 0);
2118 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
2120 if (ffeinfo_where (ffebld_info (ffebld_left (expr)))
2121 == FFEINFO_whereINTRINSIC)
2125 /* Invocation of an intrinsic returning CHARACTER*1. */
2126 item = ffecom_expr_intrinsic_ (expr, NULL_TREE,
2130 ix = ffeintrin_gfrt_direct (ffebld_symter_implementation (ffebld_left (expr)));
2131 assert (ix != FFECOM_gfrt);
2132 item = ffecom_gfrt_tree_ (ix);
2137 item = ffesymbol_hook (s).decl_tree;
2138 if (item == NULL_TREE)
2140 s = ffecom_sym_transform_ (s);
2141 item = ffesymbol_hook (s).decl_tree;
2143 if (item == error_mark_node)
2145 item = *length = error_mark_node;
2149 if (!ffesymbol_hook (s).addr)
2150 item = ffecom_1_fn (item);
2154 tempvar = ffecom_push_tempvar (char_type_node, size, -1, TRUE);
2156 tempvar = ffebld_nonter_hook (expr);
2159 tempvar = ffecom_1 (ADDR_EXPR,
2160 build_pointer_type (TREE_TYPE (tempvar)),
2163 args = build_tree_list (NULL_TREE, tempvar);
2165 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT) /* Sfunc args by value. */
2166 TREE_CHAIN (args) = ffecom_list_expr (ffebld_right (expr));
2169 TREE_CHAIN (args) = build_tree_list (NULL_TREE, *length);
2170 if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC)
2172 TREE_CHAIN (TREE_CHAIN (args))
2173 = ffecom_arglist_expr_ (ffecom_gfrt_args_ (ix),
2174 ffebld_right (expr));
2178 TREE_CHAIN (TREE_CHAIN (args))
2179 = ffecom_list_ptr_to_expr (ffebld_right (expr));
2183 item = ffecom_3s (CALL_EXPR,
2184 TREE_TYPE (TREE_TYPE (TREE_TYPE (item))),
2185 item, args, NULL_TREE);
2186 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), item,
2191 case FFEBLD_opCONVERT:
2193 ffecom_char_args_ (&item, length, ffebld_left (expr));
2195 if (item == error_mark_node || *length == error_mark_node)
2197 item = *length = error_mark_node;
2201 if ((ffebld_size_known (ffebld_left (expr))
2202 == FFETARGET_charactersizeNONE)
2203 || (ffebld_size_known (ffebld_left (expr)) < (ffebld_size (expr))))
2204 { /* Possible blank-padding needed, copy into
2211 tempvar = ffecom_make_tempvar (char_type_node,
2212 ffebld_size (expr), -1);
2214 tempvar = ffebld_nonter_hook (expr);
2217 tempvar = ffecom_1 (ADDR_EXPR,
2218 build_pointer_type (TREE_TYPE (tempvar)),
2221 newlen = build_int_2 (ffebld_size (expr), 0);
2222 TREE_TYPE (newlen) = ffecom_f2c_ftnlen_type_node;
2224 args = build_tree_list (NULL_TREE, tempvar);
2225 TREE_CHAIN (args) = build_tree_list (NULL_TREE, item);
2226 TREE_CHAIN (TREE_CHAIN (args)) = build_tree_list (NULL_TREE, newlen);
2227 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (args)))
2228 = build_tree_list (NULL_TREE, *length);
2230 item = ffecom_call_gfrt (FFECOM_gfrtCOPY, args, NULL_TREE);
2231 TREE_SIDE_EFFECTS (item) = 1;
2232 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), fold (item),
2237 { /* Just truncate the length. */
2238 *length = build_int_2 (ffebld_size (expr), 0);
2239 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
2244 assert ("bad op for single char arg expr" == NULL);
2253 /* Check the size of the type to be sure it doesn't overflow the
2254 "portable" capacities of the compiler back end. `dummy' types
2255 can generally overflow the normal sizes as long as the computations
2256 themselves don't overflow. A particular target of the back end
2257 must still enforce its size requirements, though, and the back
2258 end takes care of this in stor-layout.c. */
2260 #if FFECOM_targetCURRENT == FFECOM_targetGCC
2262 ffecom_check_size_overflow_ (ffesymbol s, tree type, bool dummy)
2264 if (TREE_CODE (type) == ERROR_MARK)
2267 if (TYPE_SIZE (type) == NULL_TREE)
2270 if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
2273 if ((tree_int_cst_sgn (TYPE_SIZE (type)) < 0)
2274 || (!dummy && (((TREE_INT_CST_HIGH (TYPE_SIZE (type)) != 0))
2275 || TREE_OVERFLOW (TYPE_SIZE (type)))))
2277 ffebad_start (FFEBAD_ARRAY_LARGE);
2278 ffebad_string (ffesymbol_text (s));
2279 ffebad_here (0, ffesymbol_where_line (s), ffesymbol_where_column (s));
2282 return error_mark_node;
2289 /* Builds a length argument (PARM_DECL). Also wraps type in an array type
2290 where the dimension info is (1:size) where <size> is ffesymbol_size(s) if
2291 known, length_arg if not known (FFETARGET_charactersizeNONE). */
2293 #if FFECOM_targetCURRENT == FFECOM_targetGCC
2295 ffecom_char_enhance_arg_ (tree *xtype, ffesymbol s)
2297 ffetargetCharacterSize sz = ffesymbol_size (s);
2302 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT)
2303 tlen = NULL_TREE; /* A statement function, no length passed. */
2306 if (ffesymbol_where (s) == FFEINFO_whereDUMMY)
2307 tlen = ffecom_get_invented_identifier ("__g77_length_%s",
2308 ffesymbol_text (s), -1);
2310 tlen = ffecom_get_invented_identifier ("__g77_%s",
2312 tlen = build_decl (PARM_DECL, tlen, ffecom_f2c_ftnlen_type_node);
2314 DECL_ARTIFICIAL (tlen) = 1;
2318 if (sz == FFETARGET_charactersizeNONE)
2320 assert (tlen != NULL_TREE);
2321 highval = variable_size (tlen);
2325 highval = build_int_2 (sz, 0);
2326 TREE_TYPE (highval) = ffecom_f2c_ftnlen_type_node;
2329 type = build_array_type (type,
2330 build_range_type (ffecom_f2c_ftnlen_type_node,
2331 ffecom_f2c_ftnlen_one_node,
2339 /* ffecom_concat_list_gather_ -- Gather list of concatenated string exprs
2341 ffecomConcatList_ catlist;
2342 ffebld expr; // expr of CHARACTER basictype.
2343 ffetargetCharacterSize max; // max chars to gather or _...NONE if no max
2344 catlist = ffecom_concat_list_gather_(catlist,expr,max);
2346 Scans expr for character subexpressions, updates and returns catlist
2349 #if FFECOM_targetCURRENT == FFECOM_targetGCC
2350 static ffecomConcatList_
2351 ffecom_concat_list_gather_ (ffecomConcatList_ catlist, ffebld expr,
2352 ffetargetCharacterSize max)
2354 ffetargetCharacterSize sz;
2356 recurse: /* :::::::::::::::::::: */
2361 if ((max != FFETARGET_charactersizeNONE) && (catlist.minlen >= max))
2362 return catlist; /* Don't append any more items. */
2364 switch (ffebld_op (expr))
2366 case FFEBLD_opCONTER:
2367 case FFEBLD_opSYMTER:
2368 case FFEBLD_opARRAYREF:
2369 case FFEBLD_opFUNCREF:
2370 case FFEBLD_opSUBSTR:
2371 case FFEBLD_opCONVERT: /* Callers should strip this off beforehand
2372 if they don't need to preserve it. */
2373 if (catlist.count == catlist.max)
2374 { /* Make a (larger) list. */
2378 newmax = (catlist.max == 0) ? 8 : catlist.max * 2;
2379 newx = malloc_new_ks (malloc_pool_image (), "catlist",
2380 newmax * sizeof (newx[0]));
2381 if (catlist.max != 0)
2383 memcpy (newx, catlist.exprs, catlist.max * sizeof (newx[0]));
2384 malloc_kill_ks (malloc_pool_image (), catlist.exprs,
2385 catlist.max * sizeof (newx[0]));
2387 catlist.max = newmax;
2388 catlist.exprs = newx;
2390 if ((sz = ffebld_size_known (expr)) != FFETARGET_charactersizeNONE)
2391 catlist.minlen += sz;
2393 ++catlist.minlen; /* Not true for F90; can be 0 length. */
2394 if ((sz = ffebld_size_max (expr)) == FFETARGET_charactersizeNONE)
2395 catlist.maxlen = sz;
2397 catlist.maxlen += sz;
2398 if ((max != FFETARGET_charactersizeNONE) && (catlist.minlen > max))
2399 { /* This item overlaps (or is beyond) the end
2400 of the destination. */
2401 switch (ffebld_op (expr))
2403 case FFEBLD_opCONTER:
2404 case FFEBLD_opSYMTER:
2405 case FFEBLD_opARRAYREF:
2406 case FFEBLD_opFUNCREF:
2407 case FFEBLD_opSUBSTR:
2408 /* ~~Do useful truncations here. */
2412 assert ("op changed or inconsistent switches!" == NULL);
2416 catlist.exprs[catlist.count++] = expr;
2419 case FFEBLD_opPAREN:
2420 expr = ffebld_left (expr);
2421 goto recurse; /* :::::::::::::::::::: */
2423 case FFEBLD_opCONCATENATE:
2424 catlist = ffecom_concat_list_gather_ (catlist, ffebld_left (expr), max);
2425 expr = ffebld_right (expr);
2426 goto recurse; /* :::::::::::::::::::: */
2428 #if 0 /* Breaks passing small actual arg to larger
2429 dummy arg of sfunc */
2430 case FFEBLD_opCONVERT:
2431 expr = ffebld_left (expr);
2433 ffetargetCharacterSize cmax;
2435 cmax = catlist.len + ffebld_size_known (expr);
2437 if ((max == FFETARGET_charactersizeNONE) || (max > cmax))
2440 goto recurse; /* :::::::::::::::::::: */
2447 assert ("bad op in _gather_" == NULL);
2453 /* ffecom_concat_list_kill_ -- Kill list of concatenated string exprs
2455 ffecomConcatList_ catlist;
2456 ffecom_concat_list_kill_(catlist);
2458 Anything allocated within the list info is deallocated. */
2460 #if FFECOM_targetCURRENT == FFECOM_targetGCC
2462 ffecom_concat_list_kill_ (ffecomConcatList_ catlist)
2464 if (catlist.max != 0)
2465 malloc_kill_ks (malloc_pool_image (), catlist.exprs,
2466 catlist.max * sizeof (catlist.exprs[0]));
2470 /* Make list of concatenated string exprs.
2472 Returns a flattened list of concatenated subexpressions given a
2473 tree of such expressions. */
2475 #if FFECOM_targetCURRENT == FFECOM_targetGCC
2476 static ffecomConcatList_
2477 ffecom_concat_list_new_ (ffebld expr, ffetargetCharacterSize max)
2479 ffecomConcatList_ catlist;
2481 catlist.maxlen = catlist.minlen = catlist.max = catlist.count = 0;
2482 return ffecom_concat_list_gather_ (catlist, expr, max);
2487 /* Provide some kind of useful info on member of aggregate area,
2488 since current g77/gcc technology does not provide debug info
2489 on these members. */
2491 #if FFECOM_targetCURRENT == FFECOM_targetGCC
2493 ffecom_debug_kludge_ (tree aggr, const char *aggr_type, ffesymbol member,
2494 tree member_type UNUSED, ffetargetOffset offset)
2504 for (type_id = member_type;
2505 TREE_CODE (type_id) != IDENTIFIER_NODE;
2508 switch (TREE_CODE (type_id))
2512 type_id = TYPE_NAME (type_id);
2517 type_id = TREE_TYPE (type_id);
2521 assert ("no IDENTIFIER_NODE for type!" == NULL);
2522 type_id = error_mark_node;
2528 if (ffecom_transform_only_dummies_
2529 || !ffe_is_debug_kludge ())
2530 return; /* Can't do this yet, maybe later. */
2533 + strlen (aggr_type)
2534 + IDENTIFIER_LENGTH (DECL_NAME (aggr));
2536 + IDENTIFIER_LENGTH (type_id);
2539 if (((size_t) len) >= ARRAY_SIZE (space))
2540 buff = malloc_new_ks (malloc_pool_image (), "debug_kludge", len + 1);
2544 sprintf (&buff[0], "At (%s) `%s' plus %ld bytes",
2546 IDENTIFIER_POINTER (DECL_NAME (aggr)),
2549 value = build_string (len, buff);
2551 = build_type_variant (build_array_type (char_type_node,
2555 build_int_2 (strlen (buff), 0))),
2557 decl = build_decl (VAR_DECL,
2558 ffecom_get_identifier_ (ffesymbol_text (member)),
2560 TREE_CONSTANT (decl) = 1;
2561 TREE_STATIC (decl) = 1;
2562 DECL_INITIAL (decl) = error_mark_node;
2563 DECL_IN_SYSTEM_HEADER (decl) = 1; /* Don't let -Wunused complain. */
2564 decl = start_decl (decl, FALSE);
2565 finish_decl (decl, value, FALSE);
2567 if (buff != &space[0])
2568 malloc_kill_ks (malloc_pool_image (), buff, len + 1);
2572 /* ffecom_do_entry_ -- Do compilation of a particular entrypoint
2574 ffesymbol fn; // the SUBROUTINE, FUNCTION, or ENTRY symbol itself
2575 int i; // entry# for this entrypoint (used by master fn)
2576 ffecom_do_entrypoint_(s,i);
2578 Makes a public entry point that calls our private master fn (already
2581 #if FFECOM_targetCURRENT == FFECOM_targetGCC
2583 ffecom_do_entry_ (ffesymbol fn, int entrynum)
2586 tree type; /* Type of function. */
2587 tree multi_retval; /* Var holding return value (union). */
2588 tree result; /* Var holding result. */
2589 ffeinfoBasictype bt;
2593 bool charfunc; /* All entry points return same type
2595 bool cmplxfunc; /* Use f2c way of returning COMPLEX. */
2596 bool multi; /* Master fn has multiple return types. */
2597 bool altreturning = FALSE; /* This entry point has alternate returns. */
2599 int old_lineno = lineno;
2600 char *old_input_filename = input_filename;
2602 input_filename = ffesymbol_where_filename (fn);
2603 lineno = ffesymbol_where_filelinenum (fn);
2605 /* c-parse.y indeed does call suspend_momentary and not only ignores the
2606 return value, but also never calls resume_momentary, when starting an
2607 outer function (see "fndef:", "setspecs:", and so on). So g77 does the
2608 same thing. It shouldn't be a problem since start_function calls
2609 temporary_allocation, but it might be necessary. If it causes a problem
2610 here, then maybe there's a bug lurking in gcc. NOTE: This identical
2611 comment appears twice in thist file. */
2613 suspend_momentary ();
2615 ffecom_doing_entry_ = TRUE; /* Don't bother with array dimensions. */
2617 switch (ffecom_primary_entry_kind_)
2619 case FFEINFO_kindFUNCTION:
2621 /* Determine actual return type for function. */
2623 gt = FFEGLOBAL_typeFUNC;
2624 bt = ffesymbol_basictype (fn);
2625 kt = ffesymbol_kindtype (fn);
2626 if (bt == FFEINFO_basictypeNONE)
2628 ffeimplic_establish_symbol (fn);
2629 if (ffesymbol_funcresult (fn) != NULL)
2630 ffeimplic_establish_symbol (ffesymbol_funcresult (fn));
2631 bt = ffesymbol_basictype (fn);
2632 kt = ffesymbol_kindtype (fn);
2635 if (bt == FFEINFO_basictypeCHARACTER)
2636 charfunc = TRUE, cmplxfunc = FALSE;
2637 else if ((bt == FFEINFO_basictypeCOMPLEX)
2638 && ffesymbol_is_f2c (fn))
2639 charfunc = FALSE, cmplxfunc = TRUE;
2641 charfunc = cmplxfunc = FALSE;
2644 type = ffecom_tree_fun_type_void;
2645 else if (ffesymbol_is_f2c (fn))
2646 type = ffecom_tree_fun_type[bt][kt];
2648 type = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
2650 if ((type == NULL_TREE)
2651 || (TREE_TYPE (type) == NULL_TREE))
2652 type = ffecom_tree_fun_type_void; /* _sym_exec_transition. */
2654 multi = (ffecom_master_bt_ == FFEINFO_basictypeNONE);
2657 case FFEINFO_kindSUBROUTINE:
2658 gt = FFEGLOBAL_typeSUBR;
2659 bt = FFEINFO_basictypeNONE;
2660 kt = FFEINFO_kindtypeNONE;
2661 if (ffecom_is_altreturning_)
2662 { /* Am _I_ altreturning? */
2663 for (item = ffesymbol_dummyargs (fn);
2665 item = ffebld_trail (item))
2667 if (ffebld_op (ffebld_head (item)) == FFEBLD_opSTAR)
2669 altreturning = TRUE;
2674 type = ffecom_tree_subr_type;
2676 type = ffecom_tree_fun_type_void;
2679 type = ffecom_tree_fun_type_void;
2686 assert ("say what??" == NULL);
2688 case FFEINFO_kindANY:
2689 gt = FFEGLOBAL_typeANY;
2690 bt = FFEINFO_basictypeNONE;
2691 kt = FFEINFO_kindtypeNONE;
2692 type = error_mark_node;
2699 /* build_decl uses the current lineno and input_filename to set the decl
2700 source info. So, I've putzed with ffestd and ffeste code to update that
2701 source info to point to the appropriate statement just before calling
2702 ffecom_do_entrypoint (which calls this fn). */
2704 start_function (ffecom_get_external_identifier_ (fn),
2706 0, /* nested/inline */
2707 1); /* TREE_PUBLIC */
2709 if (((g = ffesymbol_global (fn)) != NULL)
2710 && ((ffeglobal_type (g) == gt)
2711 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
2713 ffeglobal_set_hook (g, current_function_decl);
2716 /* Reset args in master arg list so they get retransitioned. */
2718 for (item = ffecom_master_arglist_;
2720 item = ffebld_trail (item))
2725 arg = ffebld_head (item);
2726 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2727 continue; /* Alternate return or some such thing. */
2728 s = ffebld_symter (arg);
2729 ffesymbol_hook (s).decl_tree = NULL_TREE;
2730 ffesymbol_hook (s).length_tree = NULL_TREE;
2733 /* Build dummy arg list for this entry point. */
2735 yes = suspend_momentary ();
2737 if (charfunc || cmplxfunc)
2738 { /* Prepend arg for where result goes. */
2743 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
2745 type = ffecom_tree_type[FFEINFO_basictypeCOMPLEX][kt];
2747 result = ffecom_get_invented_identifier ("__g77_%s",
2750 /* Make length arg _and_ enhance type info for CHAR arg itself. */
2753 length = ffecom_char_enhance_arg_ (&type, fn);
2755 length = NULL_TREE; /* Not ref'd if !charfunc. */
2757 type = build_pointer_type (type);
2758 result = build_decl (PARM_DECL, result, type);
2760 push_parm_decl (result);
2761 ffecom_func_result_ = result;
2765 push_parm_decl (length);
2766 ffecom_func_length_ = length;
2770 result = DECL_RESULT (current_function_decl);
2772 ffecom_push_dummy_decls_ (ffesymbol_dummyargs (fn), FALSE);
2774 resume_momentary (yes);
2776 store_parm_decls (0);
2778 ffecom_start_compstmt ();
2779 /* Disallow temp vars at this level. */
2780 current_binding_level->prep_state = 2;
2782 /* Make local var to hold return type for multi-type master fn. */
2786 yes = suspend_momentary ();
2788 multi_retval = ffecom_get_invented_identifier ("__g77_%s",
2789 "multi_retval", -1);
2790 multi_retval = build_decl (VAR_DECL, multi_retval,
2791 ffecom_multi_type_node_);
2792 multi_retval = start_decl (multi_retval, FALSE);
2793 finish_decl (multi_retval, NULL_TREE, FALSE);
2795 resume_momentary (yes);
2798 multi_retval = NULL_TREE; /* Not actually ref'd if !multi. */
2800 /* Here we emit the actual code for the entry point. */
2806 tree arglist = NULL_TREE;
2807 tree *plist = &arglist;
2813 /* Prepare actual arg list based on master arg list. */
2815 for (list = ffecom_master_arglist_;
2817 list = ffebld_trail (list))
2819 arg = ffebld_head (list);
2820 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2822 s = ffebld_symter (arg);
2823 if (ffesymbol_hook (s).decl_tree == NULL_TREE
2824 || ffesymbol_hook (s).decl_tree == error_mark_node)
2825 actarg = null_pointer_node; /* We don't have this arg. */
2827 actarg = ffesymbol_hook (s).decl_tree;
2828 *plist = build_tree_list (NULL_TREE, actarg);
2829 plist = &TREE_CHAIN (*plist);
2832 /* This code appends the length arguments for character
2833 variables/arrays. */
2835 for (list = ffecom_master_arglist_;
2837 list = ffebld_trail (list))
2839 arg = ffebld_head (list);
2840 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2842 s = ffebld_symter (arg);
2843 if (ffesymbol_basictype (s) != FFEINFO_basictypeCHARACTER)
2844 continue; /* Only looking for CHARACTER arguments. */
2845 if (ffesymbol_kind (s) != FFEINFO_kindENTITY)
2846 continue; /* Only looking for variables and arrays. */
2847 if (ffesymbol_hook (s).length_tree == NULL_TREE
2848 || ffesymbol_hook (s).length_tree == error_mark_node)
2849 actarg = ffecom_f2c_ftnlen_zero_node; /* We don't have this arg. */
2851 actarg = ffesymbol_hook (s).length_tree;
2852 *plist = build_tree_list (NULL_TREE, actarg);
2853 plist = &TREE_CHAIN (*plist);
2856 /* Prepend character-value return info to actual arg list. */
2860 prepend = build_tree_list (NULL_TREE, ffecom_func_result_);
2861 TREE_CHAIN (prepend)
2862 = build_tree_list (NULL_TREE, ffecom_func_length_);
2863 TREE_CHAIN (TREE_CHAIN (prepend)) = arglist;
2867 /* Prepend multi-type return value to actual arg list. */
2872 = build_tree_list (NULL_TREE,
2873 ffecom_1 (ADDR_EXPR,
2874 build_pointer_type (TREE_TYPE (multi_retval)),
2876 TREE_CHAIN (prepend) = arglist;
2880 /* Prepend my entry-point number to the actual arg list. */
2882 prepend = build_tree_list (NULL_TREE, build_int_2 (entrynum, 0));
2883 TREE_CHAIN (prepend) = arglist;
2886 /* Build the call to the master function. */
2888 master_fn = ffecom_1_fn (ffecom_previous_function_decl_);
2889 call = ffecom_3s (CALL_EXPR,
2890 TREE_TYPE (TREE_TYPE (TREE_TYPE (master_fn))),
2891 master_fn, arglist, NULL_TREE);
2893 /* Decide whether the master function is a function or subroutine, and
2894 handle the return value for my entry point. */
2896 if (charfunc || ((ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE)
2899 expand_expr_stmt (call);
2900 expand_null_return ();
2902 else if (multi && cmplxfunc)
2904 expand_expr_stmt (call);
2906 = ffecom_1 (INDIRECT_REF,
2907 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result))),
2909 result = ffecom_modify (NULL_TREE, result,
2910 ffecom_2 (COMPONENT_REF, TREE_TYPE (result),
2912 ffecom_multi_fields_[bt][kt]));
2913 expand_expr_stmt (result);
2914 expand_null_return ();
2918 expand_expr_stmt (call);
2920 = ffecom_modify (NULL_TREE, result,
2921 convert (TREE_TYPE (result),
2922 ffecom_2 (COMPONENT_REF,
2923 ffecom_tree_type[bt][kt],
2925 ffecom_multi_fields_[bt][kt])));
2926 expand_return (result);
2931 = ffecom_1 (INDIRECT_REF,
2932 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result))),
2934 result = ffecom_modify (NULL_TREE, result, call);
2935 expand_expr_stmt (result);
2936 expand_null_return ();
2940 result = ffecom_modify (NULL_TREE,
2942 convert (TREE_TYPE (result),
2944 expand_return (result);
2950 ffecom_end_compstmt ();
2952 finish_function (0);
2954 lineno = old_lineno;
2955 input_filename = old_input_filename;
2957 ffecom_doing_entry_ = FALSE;
2961 /* Transform expr into gcc tree with possible destination
2963 Recursive descent on expr while making corresponding tree nodes and
2964 attaching type info and such. If destination supplied and compatible
2965 with temporary that would be made in certain cases, temporary isn't
2966 made, destination used instead, and dest_used flag set TRUE. */
2968 #if FFECOM_targetCURRENT == FFECOM_targetGCC
2970 ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest,
2971 bool *dest_used, bool assignp, bool widenp)
2976 ffeinfoBasictype bt;
2979 tree dt; /* decl_tree for an ffesymbol. */
2980 tree tree_type, tree_type_x;
2983 enum tree_code code;
2985 assert (expr != NULL);
2987 if (dest_used != NULL)
2990 bt = ffeinfo_basictype (ffebld_info (expr));
2991 kt = ffeinfo_kindtype (ffebld_info (expr));
2992 tree_type = ffecom_tree_type[bt][kt];
2994 /* Widen integral arithmetic as desired while preserving signedness. */
2995 tree_type_x = NULL_TREE;
2996 if (widenp && tree_type
2997 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
2998 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
2999 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
3001 switch (ffebld_op (expr))
3003 case FFEBLD_opACCTER:
3006 ffebit bits = ffebld_accter_bits (expr);
3007 ffetargetOffset source_offset = 0;
3008 ffetargetOffset dest_offset = ffebld_accter_pad (expr);
3011 assert (dest_offset == 0
3012 || (bt == FFEINFO_basictypeCHARACTER
3013 && kt == FFEINFO_kindtypeCHARACTER1));
3018 ffebldConstantUnion cu;
3021 ffebldConstantArray ca = ffebld_accter (expr);
3023 ffebit_test (bits, source_offset, &value, &length);
3029 for (i = 0; i < length; ++i)
3031 cu = ffebld_constantarray_get (ca, bt, kt,
3034 t = ffecom_constantunion (&cu, bt, kt, tree_type);
3037 && dest_offset != 0)
3038 purpose = build_int_2 (dest_offset, 0);
3040 purpose = NULL_TREE;
3042 if (list == NULL_TREE)
3043 list = item = build_tree_list (purpose, t);
3046 TREE_CHAIN (item) = build_tree_list (purpose, t);
3047 item = TREE_CHAIN (item);
3051 source_offset += length;
3052 dest_offset += length;
3056 item = build_int_2 ((ffebld_accter_size (expr)
3057 + ffebld_accter_pad (expr)) - 1, 0);
3058 ffebit_kill (ffebld_accter_bits (expr));
3059 TREE_TYPE (item) = ffecom_integer_type_node;
3063 build_range_type (ffecom_integer_type_node,
3064 ffecom_integer_zero_node,
3066 list = build (CONSTRUCTOR, item, NULL_TREE, list);
3067 TREE_CONSTANT (list) = 1;
3068 TREE_STATIC (list) = 1;
3071 case FFEBLD_opARRTER:
3076 if (ffebld_arrter_pad (expr) == 0)
3080 assert (bt == FFEINFO_basictypeCHARACTER
3081 && kt == FFEINFO_kindtypeCHARACTER1);
3083 /* Becomes PURPOSE first time through loop. */
3084 item = build_int_2 (ffebld_arrter_pad (expr), 0);
3087 for (i = 0; i < ffebld_arrter_size (expr); ++i)
3089 ffebldConstantUnion cu
3090 = ffebld_constantarray_get (ffebld_arrter (expr), bt, kt, i);
3092 t = ffecom_constantunion (&cu, bt, kt, tree_type);
3094 if (list == NULL_TREE)
3095 /* Assume item is PURPOSE first time through loop. */
3096 list = item = build_tree_list (item, t);
3099 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
3100 item = TREE_CHAIN (item);
3105 item = build_int_2 ((ffebld_arrter_size (expr)
3106 + ffebld_arrter_pad (expr)) - 1, 0);
3107 TREE_TYPE (item) = ffecom_integer_type_node;
3111 build_range_type (ffecom_integer_type_node,
3112 ffecom_integer_zero_node,
3114 list = build (CONSTRUCTOR, item, NULL_TREE, list);
3115 TREE_CONSTANT (list) = 1;
3116 TREE_STATIC (list) = 1;
3119 case FFEBLD_opCONTER:
3120 assert (ffebld_conter_pad (expr) == 0);
3122 = ffecom_constantunion (&ffebld_constant_union (ffebld_conter (expr)),
3126 case FFEBLD_opSYMTER:
3127 if ((ffebld_symter_generic (expr) != FFEINTRIN_genNONE)
3128 || (ffebld_symter_specific (expr) != FFEINTRIN_specNONE))
3129 return ffecom_ptr_to_expr (expr); /* Same as %REF(intrinsic). */
3130 s = ffebld_symter (expr);
3131 t = ffesymbol_hook (s).decl_tree;
3134 { /* ASSIGN'ed-label expr. */
3135 if (ffe_is_ugly_assign ())
3137 /* User explicitly wants ASSIGN'ed variables to be at the same
3138 memory address as the variables when used in non-ASSIGN
3139 contexts. That can make old, arcane, non-standard code
3140 work, but don't try to do it when a pointer wouldn't fit
3141 in the normal variable (take other approach, and warn,
3146 s = ffecom_sym_transform_ (s);
3147 t = ffesymbol_hook (s).decl_tree;
3148 assert (t != NULL_TREE);
3151 if (t == error_mark_node)
3154 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (t)))
3155 >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
3157 if (ffesymbol_hook (s).addr)
3158 t = ffecom_1 (INDIRECT_REF,
3159 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), t);
3163 if (ffesymbol_hook (s).assign_tree == NULL_TREE)
3165 ffebad_start_msg ("ASSIGN'ed label cannot fit into `%A' at %0 -- using wider sibling",
3166 FFEBAD_severityWARNING);
3167 ffebad_string (ffesymbol_text (s));
3168 ffebad_here (0, ffesymbol_where_line (s),
3169 ffesymbol_where_column (s));
3174 /* Don't use the normal variable's tree for ASSIGN, though mark
3175 it as in the system header (housekeeping). Use an explicit,
3176 specially created sibling that is known to be wide enough
3177 to hold pointers to labels. */
3180 && TREE_CODE (t) == VAR_DECL)
3181 DECL_IN_SYSTEM_HEADER (t) = 1; /* Don't let -Wunused complain. */
3183 t = ffesymbol_hook (s).assign_tree;
3186 s = ffecom_sym_transform_assign_ (s);
3187 t = ffesymbol_hook (s).assign_tree;
3188 assert (t != NULL_TREE);
3195 s = ffecom_sym_transform_ (s);
3196 t = ffesymbol_hook (s).decl_tree;
3197 assert (t != NULL_TREE);
3199 if (ffesymbol_hook (s).addr)
3200 t = ffecom_1 (INDIRECT_REF,
3201 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), t);
3205 case FFEBLD_opARRAYREF:
3207 if (0 /* ~~~~~ ffe_is_flat_arrays () */)
3208 t = ffecom_ptr_to_expr (ffebld_left (expr));
3210 t = ffecom_expr (ffebld_left (expr));
3212 if (t == error_mark_node)
3215 if ((ffeinfo_where (ffebld_info (expr)) == FFEINFO_whereFLEETING)
3216 && !mark_addressable (t))
3217 return error_mark_node; /* Make sure non-const ref is to
3220 t = ffecom_arrayref_ (t, expr, 0);
3225 case FFEBLD_opUPLUS:
3226 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3227 return ffecom_1 (NOP_EXPR, tree_type, left);
3229 case FFEBLD_opPAREN:
3230 /* ~~~Make sure Fortran rules respected here */
3231 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3232 return ffecom_1 (NOP_EXPR, tree_type, left);
3234 case FFEBLD_opUMINUS:
3235 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3238 tree_type = tree_type_x;
3239 left = convert (tree_type, left);
3241 return ffecom_1 (NEGATE_EXPR, tree_type, left);
3244 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3245 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
3248 tree_type = tree_type_x;
3249 left = convert (tree_type, left);
3250 right = convert (tree_type, right);
3252 return ffecom_2 (PLUS_EXPR, tree_type, left, right);
3254 case FFEBLD_opSUBTRACT:
3255 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3256 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
3259 tree_type = tree_type_x;
3260 left = convert (tree_type, left);
3261 right = convert (tree_type, right);
3263 return ffecom_2 (MINUS_EXPR, tree_type, left, right);
3265 case FFEBLD_opMULTIPLY:
3266 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3267 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
3270 tree_type = tree_type_x;
3271 left = convert (tree_type, left);
3272 right = convert (tree_type, right);
3274 return ffecom_2 (MULT_EXPR, tree_type, left, right);
3276 case FFEBLD_opDIVIDE:
3277 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3278 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
3281 tree_type = tree_type_x;
3282 left = convert (tree_type, left);
3283 right = convert (tree_type, right);
3285 return ffecom_tree_divide_ (tree_type, left, right,
3286 dest_tree, dest, dest_used,
3287 ffebld_nonter_hook (expr));
3289 case FFEBLD_opPOWER:
3291 ffebld left = ffebld_left (expr);
3292 ffebld right = ffebld_right (expr);
3294 ffeinfoKindtype rtkt;
3295 ffeinfoKindtype ltkt;
3297 switch (ffeinfo_basictype (ffebld_info (right)))
3299 case FFEINFO_basictypeINTEGER:
3302 item = ffecom_expr_power_integer_ (expr);
3303 if (item != NULL_TREE)
3307 rtkt = FFEINFO_kindtypeINTEGER1;
3308 switch (ffeinfo_basictype (ffebld_info (left)))
3310 case FFEINFO_basictypeINTEGER:
3311 if ((ffeinfo_kindtype (ffebld_info (left))
3312 == FFEINFO_kindtypeINTEGER4)
3313 || (ffeinfo_kindtype (ffebld_info (right))
3314 == FFEINFO_kindtypeINTEGER4))
3316 code = FFECOM_gfrtPOW_QQ;
3317 ltkt = FFEINFO_kindtypeINTEGER4;
3318 rtkt = FFEINFO_kindtypeINTEGER4;
3322 code = FFECOM_gfrtPOW_II;
3323 ltkt = FFEINFO_kindtypeINTEGER1;
3327 case FFEINFO_basictypeREAL:
3328 if (ffeinfo_kindtype (ffebld_info (left))
3329 == FFEINFO_kindtypeREAL1)
3331 code = FFECOM_gfrtPOW_RI;
3332 ltkt = FFEINFO_kindtypeREAL1;
3336 code = FFECOM_gfrtPOW_DI;
3337 ltkt = FFEINFO_kindtypeREAL2;
3341 case FFEINFO_basictypeCOMPLEX:
3342 if (ffeinfo_kindtype (ffebld_info (left))
3343 == FFEINFO_kindtypeREAL1)
3345 code = FFECOM_gfrtPOW_CI; /* Overlapping result okay. */
3346 ltkt = FFEINFO_kindtypeREAL1;
3350 code = FFECOM_gfrtPOW_ZI; /* Overlapping result okay. */
3351 ltkt = FFEINFO_kindtypeREAL2;
3356 assert ("bad pow_*i" == NULL);
3357 code = FFECOM_gfrtPOW_CI; /* Overlapping result okay. */
3358 ltkt = FFEINFO_kindtypeREAL1;
3361 if (ffeinfo_kindtype (ffebld_info (left)) != ltkt)
3362 left = ffeexpr_convert (left, NULL, NULL,
3363 ffeinfo_basictype (ffebld_info (left)),
3365 FFETARGET_charactersizeNONE,
3366 FFEEXPR_contextLET);
3367 if (ffeinfo_kindtype (ffebld_info (right)) != rtkt)
3368 right = ffeexpr_convert (right, NULL, NULL,
3369 FFEINFO_basictypeINTEGER,
3371 FFETARGET_charactersizeNONE,
3372 FFEEXPR_contextLET);
3375 case FFEINFO_basictypeREAL:
3376 if (ffeinfo_kindtype (ffebld_info (left)) == FFEINFO_kindtypeREAL1)
3377 left = ffeexpr_convert (left, NULL, NULL, FFEINFO_basictypeREAL,
3378 FFEINFO_kindtypeREALDOUBLE, 0,
3379 FFETARGET_charactersizeNONE,
3380 FFEEXPR_contextLET);
3381 if (ffeinfo_kindtype (ffebld_info (right))
3382 == FFEINFO_kindtypeREAL1)
3383 right = ffeexpr_convert (right, NULL, NULL,
3384 FFEINFO_basictypeREAL,
3385 FFEINFO_kindtypeREALDOUBLE, 0,
3386 FFETARGET_charactersizeNONE,
3387 FFEEXPR_contextLET);
3388 code = FFECOM_gfrtPOW_DD;
3391 case FFEINFO_basictypeCOMPLEX:
3392 if (ffeinfo_kindtype (ffebld_info (left)) == FFEINFO_kindtypeREAL1)
3393 left = ffeexpr_convert (left, NULL, NULL,
3394 FFEINFO_basictypeCOMPLEX,
3395 FFEINFO_kindtypeREALDOUBLE, 0,
3396 FFETARGET_charactersizeNONE,
3397 FFEEXPR_contextLET);
3398 if (ffeinfo_kindtype (ffebld_info (right))
3399 == FFEINFO_kindtypeREAL1)
3400 right = ffeexpr_convert (right, NULL, NULL,
3401 FFEINFO_basictypeCOMPLEX,
3402 FFEINFO_kindtypeREALDOUBLE, 0,
3403 FFETARGET_charactersizeNONE,
3404 FFEEXPR_contextLET);
3405 code = FFECOM_gfrtPOW_ZZ; /* Overlapping result okay. */
3409 assert ("bad pow_x*" == NULL);
3410 code = FFECOM_gfrtPOW_II;
3413 return ffecom_call_binop_ (ffecom_gfrt_tree_ (code),
3414 ffecom_gfrt_kindtype (code),
3415 (ffe_is_f2c_library ()
3416 && ffecom_gfrt_complex_[code]),
3417 tree_type, left, right,
3418 dest_tree, dest, dest_used,
3420 ffebld_nonter_hook (expr));
3426 case FFEINFO_basictypeLOGICAL:
3427 item = ffecom_truth_value_invert (ffecom_expr (ffebld_left (expr)));
3428 return convert (tree_type, item);
3430 case FFEINFO_basictypeINTEGER:
3431 return ffecom_1 (BIT_NOT_EXPR, tree_type,
3432 ffecom_expr (ffebld_left (expr)));
3435 assert ("NOT bad basictype" == NULL);
3437 case FFEINFO_basictypeANY:
3438 return error_mark_node;
3442 case FFEBLD_opFUNCREF:
3443 assert (ffeinfo_basictype (ffebld_info (expr))
3444 != FFEINFO_basictypeCHARACTER);
3446 case FFEBLD_opSUBRREF:
3447 if (ffeinfo_where (ffebld_info (ffebld_left (expr)))
3448 == FFEINFO_whereINTRINSIC)
3449 { /* Invocation of an intrinsic. */
3450 item = ffecom_expr_intrinsic_ (expr, dest_tree, dest,
3454 s = ffebld_symter (ffebld_left (expr));
3455 dt = ffesymbol_hook (s).decl_tree;
3456 if (dt == NULL_TREE)
3458 s = ffecom_sym_transform_ (s);
3459 dt = ffesymbol_hook (s).decl_tree;
3461 if (dt == error_mark_node)
3464 if (ffesymbol_hook (s).addr)
3467 item = ffecom_1_fn (dt);
3469 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT)
3470 args = ffecom_list_expr (ffebld_right (expr));
3472 args = ffecom_list_ptr_to_expr (ffebld_right (expr));
3474 if (args == error_mark_node)
3475 return error_mark_node;
3477 item = ffecom_call_ (item, kt,
3478 ffesymbol_is_f2c (s)
3479 && (bt == FFEINFO_basictypeCOMPLEX)
3480 && (ffesymbol_where (s)
3481 != FFEINFO_whereCONSTANT),
3484 dest_tree, dest, dest_used,
3485 error_mark_node, FALSE,
3486 ffebld_nonter_hook (expr));
3487 TREE_SIDE_EFFECTS (item) = 1;
3493 case FFEINFO_basictypeLOGICAL:
3495 = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
3496 ffecom_truth_value (ffecom_expr (ffebld_left (expr))),
3497 ffecom_truth_value (ffecom_expr (ffebld_right (expr))));
3498 return convert (tree_type, item);
3500 case FFEINFO_basictypeINTEGER:
3501 return ffecom_2 (BIT_AND_EXPR, tree_type,
3502 ffecom_expr (ffebld_left (expr)),
3503 ffecom_expr (ffebld_right (expr)));
3506 assert ("AND bad basictype" == NULL);
3508 case FFEINFO_basictypeANY:
3509 return error_mark_node;
3516 case FFEINFO_basictypeLOGICAL:
3518 = ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
3519 ffecom_truth_value (ffecom_expr (ffebld_left (expr))),
3520 ffecom_truth_value (ffecom_expr (ffebld_right (expr))));
3521 return convert (tree_type, item);
3523 case FFEINFO_basictypeINTEGER:
3524 return ffecom_2 (BIT_IOR_EXPR, tree_type,
3525 ffecom_expr (ffebld_left (expr)),
3526 ffecom_expr (ffebld_right (expr)));
3529 assert ("OR bad basictype" == NULL);
3531 case FFEINFO_basictypeANY:
3532 return error_mark_node;
3540 case FFEINFO_basictypeLOGICAL:
3542 = ffecom_2 (NE_EXPR, integer_type_node,
3543 ffecom_expr (ffebld_left (expr)),
3544 ffecom_expr (ffebld_right (expr)));
3545 return convert (tree_type, ffecom_truth_value (item));
3547 case FFEINFO_basictypeINTEGER:
3548 return ffecom_2 (BIT_XOR_EXPR, tree_type,
3549 ffecom_expr (ffebld_left (expr)),
3550 ffecom_expr (ffebld_right (expr)));
3553 assert ("XOR/NEQV bad basictype" == NULL);
3555 case FFEINFO_basictypeANY:
3556 return error_mark_node;
3563 case FFEINFO_basictypeLOGICAL:
3565 = ffecom_2 (EQ_EXPR, integer_type_node,
3566 ffecom_expr (ffebld_left (expr)),
3567 ffecom_expr (ffebld_right (expr)));
3568 return convert (tree_type, ffecom_truth_value (item));
3570 case FFEINFO_basictypeINTEGER:
3572 ffecom_1 (BIT_NOT_EXPR, tree_type,
3573 ffecom_2 (BIT_XOR_EXPR, tree_type,
3574 ffecom_expr (ffebld_left (expr)),
3575 ffecom_expr (ffebld_right (expr))));
3578 assert ("EQV bad basictype" == NULL);
3580 case FFEINFO_basictypeANY:
3581 return error_mark_node;
3585 case FFEBLD_opCONVERT:
3586 if (ffebld_op (ffebld_left (expr)) == FFEBLD_opANY)
3587 return error_mark_node;
3591 case FFEINFO_basictypeLOGICAL:
3592 case FFEINFO_basictypeINTEGER:
3593 case FFEINFO_basictypeREAL:
3594 return convert (tree_type, ffecom_expr (ffebld_left (expr)));
3596 case FFEINFO_basictypeCOMPLEX:
3597 switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr))))
3599 case FFEINFO_basictypeINTEGER:
3600 case FFEINFO_basictypeLOGICAL:
3601 case FFEINFO_basictypeREAL:
3602 item = ffecom_expr (ffebld_left (expr));
3603 if (item == error_mark_node)
3604 return error_mark_node;
3605 /* convert() takes care of converting to the subtype first,
3606 at least in gcc-2.7.2. */
3607 item = convert (tree_type, item);
3610 case FFEINFO_basictypeCOMPLEX:
3611 return convert (tree_type, ffecom_expr (ffebld_left (expr)));
3614 assert ("CONVERT COMPLEX bad basictype" == NULL);
3616 case FFEINFO_basictypeANY:
3617 return error_mark_node;
3622 assert ("CONVERT bad basictype" == NULL);
3624 case FFEINFO_basictypeANY:
3625 return error_mark_node;
3631 goto relational; /* :::::::::::::::::::: */
3635 goto relational; /* :::::::::::::::::::: */
3639 goto relational; /* :::::::::::::::::::: */
3643 goto relational; /* :::::::::::::::::::: */
3647 goto relational; /* :::::::::::::::::::: */
3652 relational: /* :::::::::::::::::::: */
3653 switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr))))
3655 case FFEINFO_basictypeLOGICAL:
3656 case FFEINFO_basictypeINTEGER:
3657 case FFEINFO_basictypeREAL:
3658 item = ffecom_2 (code, integer_type_node,
3659 ffecom_expr (ffebld_left (expr)),
3660 ffecom_expr (ffebld_right (expr)));
3661 return convert (tree_type, item);
3663 case FFEINFO_basictypeCOMPLEX:
3664 assert (code == EQ_EXPR || code == NE_EXPR);
3667 tree arg1 = ffecom_expr (ffebld_left (expr));
3668 tree arg2 = ffecom_expr (ffebld_right (expr));
3670 if (arg1 == error_mark_node || arg2 == error_mark_node)
3671 return error_mark_node;
3673 arg1 = ffecom_save_tree (arg1);
3674 arg2 = ffecom_save_tree (arg2);
3676 if (TREE_CODE (TREE_TYPE (arg1)) == COMPLEX_TYPE)
3678 real_type = TREE_TYPE (TREE_TYPE (arg1));
3679 assert (real_type == TREE_TYPE (TREE_TYPE (arg2)));
3683 real_type = TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg1)));
3684 assert (real_type == TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg2))));
3688 = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
3689 ffecom_2 (EQ_EXPR, integer_type_node,
3690 ffecom_1 (REALPART_EXPR, real_type, arg1),
3691 ffecom_1 (REALPART_EXPR, real_type, arg2)),
3692 ffecom_2 (EQ_EXPR, integer_type_node,
3693 ffecom_1 (IMAGPART_EXPR, real_type, arg1),
3694 ffecom_1 (IMAGPART_EXPR, real_type,
3696 if (code == EQ_EXPR)
3697 item = ffecom_truth_value (item);
3699 item = ffecom_truth_value_invert (item);
3700 return convert (tree_type, item);
3703 case FFEINFO_basictypeCHARACTER:
3705 ffebld left = ffebld_left (expr);
3706 ffebld right = ffebld_right (expr);
3712 /* f2c run-time functions do the implicit blank-padding for us,
3713 so we don't usually have to implement blank-padding ourselves.
3714 (The exception is when we pass an argument to a separately
3715 compiled statement function -- if we know the arg is not the
3716 same length as the dummy, we must truncate or extend it. If
3717 we "inline" statement functions, that necessity goes away as
3720 Strip off the CONVERT operators that blank-pad. (Truncation by
3721 CONVERT shouldn't happen here, but it can happen in
3724 while (ffebld_op (left) == FFEBLD_opCONVERT)
3725 left = ffebld_left (left);
3726 while (ffebld_op (right) == FFEBLD_opCONVERT)
3727 right = ffebld_left (right);
3729 left_tree = ffecom_arg_ptr_to_expr (left, &left_length);
3730 right_tree = ffecom_arg_ptr_to_expr (right, &right_length);
3732 if (left_tree == error_mark_node || left_length == error_mark_node
3733 || right_tree == error_mark_node
3734 || right_length == error_mark_node)
3735 return error_mark_node;
3737 if ((ffebld_size_known (left) == 1)
3738 && (ffebld_size_known (right) == 1))
3741 = ffecom_1 (INDIRECT_REF,
3742 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree))),
3745 = ffecom_1 (INDIRECT_REF,
3746 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree))),
3750 = ffecom_2 (code, integer_type_node,
3751 ffecom_2 (ARRAY_REF,
3752 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree))),
3755 ffecom_2 (ARRAY_REF,
3756 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree))),
3762 item = build_tree_list (NULL_TREE, left_tree);
3763 TREE_CHAIN (item) = build_tree_list (NULL_TREE, right_tree);
3764 TREE_CHAIN (TREE_CHAIN (item)) = build_tree_list (NULL_TREE,
3766 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item)))
3767 = build_tree_list (NULL_TREE, right_length);
3768 item = ffecom_call_gfrt (FFECOM_gfrtCMP, item, NULL_TREE);
3769 item = ffecom_2 (code, integer_type_node,
3771 convert (TREE_TYPE (item),
3772 integer_zero_node));
3774 item = convert (tree_type, item);
3780 assert ("relational bad basictype" == NULL);
3782 case FFEINFO_basictypeANY:
3783 return error_mark_node;
3787 case FFEBLD_opPERCENT_LOC:
3788 item = ffecom_arg_ptr_to_expr (ffebld_left (expr), &list);
3789 return convert (tree_type, item);
3793 case FFEBLD_opBOUNDS:
3794 case FFEBLD_opREPEAT:
3795 case FFEBLD_opLABTER:
3796 case FFEBLD_opLABTOK:
3797 case FFEBLD_opIMPDO:
3798 case FFEBLD_opCONCATENATE:
3799 case FFEBLD_opSUBSTR:
3801 assert ("bad op" == NULL);
3804 return error_mark_node;
3808 assert ("didn't think anything got here anymore!!" == NULL);
3810 switch (ffebld_arity (expr))
3813 TREE_OPERAND (item, 0) = ffecom_expr (ffebld_left (expr));
3814 TREE_OPERAND (item, 1) = ffecom_expr (ffebld_right (expr));
3815 if (TREE_OPERAND (item, 0) == error_mark_node
3816 || TREE_OPERAND (item, 1) == error_mark_node)
3817 return error_mark_node;
3821 TREE_OPERAND (item, 0) = ffecom_expr (ffebld_left (expr));
3822 if (TREE_OPERAND (item, 0) == error_mark_node)
3823 return error_mark_node;
3835 /* Returns the tree that does the intrinsic invocation.
3837 Note: this function applies only to intrinsics returning
3838 CHARACTER*1 or non-CHARACTER results, and to intrinsic
3841 #if FFECOM_targetCURRENT == FFECOM_targetGCC
3843 ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree,
3844 ffebld dest, bool *dest_used)
3847 tree saved_expr1; /* For those who need it. */
3848 tree saved_expr2; /* For those who need it. */
3849 ffeinfoBasictype bt;
3853 tree real_type; /* REAL type corresponding to COMPLEX. */
3855 ffebld list = ffebld_right (expr); /* List of (some) args. */
3856 ffebld arg1; /* For handy reference. */
3859 ffeintrinImp codegen_imp;
3862 assert (ffebld_op (ffebld_left (expr)) == FFEBLD_opSYMTER);
3864 if (dest_used != NULL)
3867 bt = ffeinfo_basictype (ffebld_info (expr));
3868 kt = ffeinfo_kindtype (ffebld_info (expr));
3869 tree_type = ffecom_tree_type[bt][kt];
3873 arg1 = ffebld_head (list);
3874 if (arg1 != NULL && ffebld_op (arg1) == FFEBLD_opANY)
3875 return error_mark_node;
3876 if ((list = ffebld_trail (list)) != NULL)
3878 arg2 = ffebld_head (list);
3879 if (arg2 != NULL && ffebld_op (arg2) == FFEBLD_opANY)
3880 return error_mark_node;
3881 if ((list = ffebld_trail (list)) != NULL)
3883 arg3 = ffebld_head (list);
3884 if (arg3 != NULL && ffebld_op (arg3) == FFEBLD_opANY)
3885 return error_mark_node;
3894 arg1 = arg2 = arg3 = NULL;
3896 /* <list> ends up at the opITEM of the 3rd arg, or NULL if there are < 3
3897 args. This is used by the MAX/MIN expansions. */
3900 arg1_type = ffecom_tree_type
3901 [ffeinfo_basictype (ffebld_info (arg1))]
3902 [ffeinfo_kindtype (ffebld_info (arg1))];
3904 arg1_type = NULL_TREE; /* Really not needed, but might catch bugs
3907 /* There are several ways for each of the cases in the following switch
3908 statements to exit (from simplest to use to most complicated):
3910 break; (when expr_tree == NULL)
3912 A standard call is made to the specific intrinsic just as if it had been
3913 passed in as a dummy procedure and called as any old procedure. This
3914 method can produce slower code but in some cases it's the easiest way for
3915 now. However, if a (presumably faster) direct call is available,
3916 that is used, so this is the easiest way in many more cases now.
3918 gfrt = FFECOM_gfrtWHATEVER;
3921 gfrt contains the gfrt index of a library function to call, passing the
3922 argument(s) by value rather than by reference. Used when a more
3923 careful choice of library function is needed than that provided
3924 by the vanilla `break;'.
3928 The expr_tree has been completely set up and is ready to be returned
3929 as is. No further actions are taken. Use this when the tree is not
3930 in the simple form for one of the arity_n labels. */
3932 /* For info on how the switch statement cases were written, see the files
3933 enclosed in comments below the switch statement. */
3935 codegen_imp = ffebld_symter_implementation (ffebld_left (expr));
3936 gfrt = ffeintrin_gfrt_direct (codegen_imp);
3937 if (gfrt == FFECOM_gfrt)
3938 gfrt = ffeintrin_gfrt_indirect (codegen_imp);
3940 switch (codegen_imp)
3942 case FFEINTRIN_impABS:
3943 case FFEINTRIN_impCABS:
3944 case FFEINTRIN_impCDABS:
3945 case FFEINTRIN_impDABS:
3946 case FFEINTRIN_impIABS:
3947 if (ffeinfo_basictype (ffebld_info (arg1))
3948 == FFEINFO_basictypeCOMPLEX)
3950 if (kt == FFEINFO_kindtypeREAL1)
3951 gfrt = FFECOM_gfrtCABS;
3952 else if (kt == FFEINFO_kindtypeREAL2)
3953 gfrt = FFECOM_gfrtCDABS;
3956 return ffecom_1 (ABS_EXPR, tree_type,
3957 convert (tree_type, ffecom_expr (arg1)));
3959 case FFEINTRIN_impACOS:
3960 case FFEINTRIN_impDACOS:
3963 case FFEINTRIN_impAIMAG:
3964 case FFEINTRIN_impDIMAG:
3965 case FFEINTRIN_impIMAGPART:
3966 if (TREE_CODE (arg1_type) == COMPLEX_TYPE)
3967 arg1_type = TREE_TYPE (arg1_type);
3969 arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type));
3973 ffecom_1 (IMAGPART_EXPR, arg1_type,
3974 ffecom_expr (arg1)));
3976 case FFEINTRIN_impAINT:
3977 case FFEINTRIN_impDINT:
3979 /* ~~Someday implement FIX_TRUNC_EXPR yielding same type as arg. */
3980 return ffecom_1 (FIX_TRUNC_EXPR, tree_type, ffecom_expr (arg1));
3981 #else /* in the meantime, must use floor to avoid range problems with ints */
3982 /* r__1 = r1 >= 0 ? floor(r1) : -floor(-r1); */
3983 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
3986 ffecom_3 (COND_EXPR, double_type_node,
3988 (ffecom_2 (GE_EXPR, integer_type_node,
3991 ffecom_float_zero_))),
3992 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
3993 build_tree_list (NULL_TREE,
3994 convert (double_type_node,
3997 ffecom_1 (NEGATE_EXPR, double_type_node,
3998 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
3999 build_tree_list (NULL_TREE,
4000 convert (double_type_node,
4001 ffecom_1 (NEGATE_EXPR,
4009 case FFEINTRIN_impANINT:
4010 case FFEINTRIN_impDNINT:
4011 #if 0 /* This way of doing it won't handle real
4012 numbers of large magnitudes. */
4013 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
4014 expr_tree = convert (tree_type,
4015 convert (integer_type_node,
4016 ffecom_3 (COND_EXPR, tree_type,
4021 ffecom_float_zero_)),
4022 ffecom_2 (PLUS_EXPR,
4025 ffecom_float_half_),
4026 ffecom_2 (MINUS_EXPR,
4029 ffecom_float_half_))));
4031 #else /* So we instead call floor. */
4032 /* r__1 = r1 >= 0 ? floor(r1 + .5) : -floor(.5 - r1) */
4033 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
4036 ffecom_3 (COND_EXPR, double_type_node,
4038 (ffecom_2 (GE_EXPR, integer_type_node,
4041 ffecom_float_zero_))),
4042 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
4043 build_tree_list (NULL_TREE,
4044 convert (double_type_node,
4045 ffecom_2 (PLUS_EXPR,
4049 ffecom_float_half_)))),
4051 ffecom_1 (NEGATE_EXPR, double_type_node,
4052 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
4053 build_tree_list (NULL_TREE,
4054 convert (double_type_node,
4055 ffecom_2 (MINUS_EXPR,
4058 ffecom_float_half_),
4065 case FFEINTRIN_impASIN:
4066 case FFEINTRIN_impDASIN:
4067 case FFEINTRIN_impATAN:
4068 case FFEINTRIN_impDATAN:
4069 case FFEINTRIN_impATAN2:
4070 case FFEINTRIN_impDATAN2:
4073 case FFEINTRIN_impCHAR:
4074 case FFEINTRIN_impACHAR:
4076 tempvar = ffecom_make_tempvar (char_type_node, 1, -1);
4078 tempvar = ffebld_nonter_hook (expr);
4082 tree tmv = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (tempvar)));
4084 expr_tree = ffecom_modify (tmv,
4085 ffecom_2 (ARRAY_REF, tmv, tempvar,
4087 convert (tmv, ffecom_expr (arg1)));
4089 expr_tree = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar),
4092 expr_tree = ffecom_1 (ADDR_EXPR,
4093 build_pointer_type (TREE_TYPE (expr_tree)),
4097 case FFEINTRIN_impCMPLX:
4098 case FFEINTRIN_impDCMPLX:
4101 convert (tree_type, ffecom_expr (arg1));
4103 real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
4105 ffecom_2 (COMPLEX_EXPR, tree_type,
4106 convert (real_type, ffecom_expr (arg1)),
4108 ffecom_expr (arg2)));
4110 case FFEINTRIN_impCOMPLEX:
4112 ffecom_2 (COMPLEX_EXPR, tree_type,
4114 ffecom_expr (arg2));
4116 case FFEINTRIN_impCONJG:
4117 case FFEINTRIN_impDCONJG:
4121 real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
4122 arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4124 ffecom_2 (COMPLEX_EXPR, tree_type,
4125 ffecom_1 (REALPART_EXPR, real_type, arg1_tree),
4126 ffecom_1 (NEGATE_EXPR, real_type,
4127 ffecom_1 (IMAGPART_EXPR, real_type, arg1_tree)));
4130 case FFEINTRIN_impCOS:
4131 case FFEINTRIN_impCCOS:
4132 case FFEINTRIN_impCDCOS:
4133 case FFEINTRIN_impDCOS:
4134 if (bt == FFEINFO_basictypeCOMPLEX)
4136 if (kt == FFEINFO_kindtypeREAL1)
4137 gfrt = FFECOM_gfrtCCOS; /* Overlapping result okay. */
4138 else if (kt == FFEINFO_kindtypeREAL2)
4139 gfrt = FFECOM_gfrtCDCOS; /* Overlapping result okay. */
4143 case FFEINTRIN_impCOSH:
4144 case FFEINTRIN_impDCOSH:
4147 case FFEINTRIN_impDBLE:
4148 case FFEINTRIN_impDFLOAT:
4149 case FFEINTRIN_impDREAL:
4150 case FFEINTRIN_impFLOAT:
4151 case FFEINTRIN_impIDINT:
4152 case FFEINTRIN_impIFIX:
4153 case FFEINTRIN_impINT2:
4154 case FFEINTRIN_impINT8:
4155 case FFEINTRIN_impINT:
4156 case FFEINTRIN_impLONG:
4157 case FFEINTRIN_impREAL:
4158 case FFEINTRIN_impSHORT:
4159 case FFEINTRIN_impSNGL:
4160 return convert (tree_type, ffecom_expr (arg1));
4162 case FFEINTRIN_impDIM:
4163 case FFEINTRIN_impDDIM:
4164 case FFEINTRIN_impIDIM:
4165 saved_expr1 = ffecom_save_tree (convert (tree_type,
4166 ffecom_expr (arg1)));
4167 saved_expr2 = ffecom_save_tree (convert (tree_type,
4168 ffecom_expr (arg2)));
4170 ffecom_3 (COND_EXPR, tree_type,
4172 (ffecom_2 (GT_EXPR, integer_type_node,
4175 ffecom_2 (MINUS_EXPR, tree_type,
4178 convert (tree_type, ffecom_float_zero_));
4180 case FFEINTRIN_impDPROD:
4182 ffecom_2 (MULT_EXPR, tree_type,
4183 convert (tree_type, ffecom_expr (arg1)),
4184 convert (tree_type, ffecom_expr (arg2)));
4186 case FFEINTRIN_impEXP:
4187 case FFEINTRIN_impCDEXP:
4188 case FFEINTRIN_impCEXP:
4189 case FFEINTRIN_impDEXP:
4190 if (bt == FFEINFO_basictypeCOMPLEX)
4192 if (kt == FFEINFO_kindtypeREAL1)
4193 gfrt = FFECOM_gfrtCEXP; /* Overlapping result okay. */
4194 else if (kt == FFEINFO_kindtypeREAL2)
4195 gfrt = FFECOM_gfrtCDEXP; /* Overlapping result okay. */
4199 case FFEINTRIN_impICHAR:
4200 case FFEINTRIN_impIACHAR:
4201 #if 0 /* The simple approach. */
4202 ffecom_char_args_ (&expr_tree, &saved_expr1 /* Ignored */ , arg1);
4204 = ffecom_1 (INDIRECT_REF,
4205 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
4208 = ffecom_2 (ARRAY_REF,
4209 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
4212 return convert (tree_type, expr_tree);
4213 #else /* The more interesting (and more optimal) approach. */
4214 expr_tree = ffecom_intrinsic_ichar_ (tree_type, arg1, &saved_expr1);
4215 expr_tree = ffecom_3 (COND_EXPR, tree_type,
4218 convert (tree_type, integer_zero_node));
4222 case FFEINTRIN_impINDEX:
4225 case FFEINTRIN_impLEN:
4227 break; /* The simple approach. */
4229 return ffecom_intrinsic_len_ (arg1); /* The more optimal approach. */
4232 case FFEINTRIN_impLGE:
4233 case FFEINTRIN_impLGT:
4234 case FFEINTRIN_impLLE:
4235 case FFEINTRIN_impLLT:
4238 case FFEINTRIN_impLOG:
4239 case FFEINTRIN_impALOG:
4240 case FFEINTRIN_impCDLOG:
4241 case FFEINTRIN_impCLOG:
4242 case FFEINTRIN_impDLOG:
4243 if (bt == FFEINFO_basictypeCOMPLEX)
4245 if (kt == FFEINFO_kindtypeREAL1)
4246 gfrt = FFECOM_gfrtCLOG; /* Overlapping result okay. */
4247 else if (kt == FFEINFO_kindtypeREAL2)
4248 gfrt = FFECOM_gfrtCDLOG; /* Overlapping result okay. */
4252 case FFEINTRIN_impLOG10:
4253 case FFEINTRIN_impALOG10:
4254 case FFEINTRIN_impDLOG10:
4255 if (gfrt != FFECOM_gfrt)
4256 break; /* Already picked one, stick with it. */
4258 if (kt == FFEINFO_kindtypeREAL1)
4259 gfrt = FFECOM_gfrtALOG10;
4260 else if (kt == FFEINFO_kindtypeREAL2)
4261 gfrt = FFECOM_gfrtDLOG10;
4264 case FFEINTRIN_impMAX:
4265 case FFEINTRIN_impAMAX0:
4266 case FFEINTRIN_impAMAX1:
4267 case FFEINTRIN_impDMAX1:
4268 case FFEINTRIN_impMAX0:
4269 case FFEINTRIN_impMAX1:
4270 if (bt != ffeinfo_basictype (ffebld_info (arg1)))
4271 arg1_type = ffecom_widest_expr_type_ (ffebld_right (expr));
4273 arg1_type = tree_type;
4274 expr_tree = ffecom_2 (MAX_EXPR, arg1_type,
4275 convert (arg1_type, ffecom_expr (arg1)),
4276 convert (arg1_type, ffecom_expr (arg2)));
4277 for (; list != NULL; list = ffebld_trail (list))
4279 if ((ffebld_head (list) == NULL)
4280 || (ffebld_op (ffebld_head (list)) == FFEBLD_opANY))
4282 expr_tree = ffecom_2 (MAX_EXPR, arg1_type,
4285 ffecom_expr (ffebld_head (list))));
4287 return convert (tree_type, expr_tree);
4289 case FFEINTRIN_impMIN:
4290 case FFEINTRIN_impAMIN0:
4291 case FFEINTRIN_impAMIN1:
4292 case FFEINTRIN_impDMIN1:
4293 case FFEINTRIN_impMIN0:
4294 case FFEINTRIN_impMIN1:
4295 if (bt != ffeinfo_basictype (ffebld_info (arg1)))
4296 arg1_type = ffecom_widest_expr_type_ (ffebld_right (expr));
4298 arg1_type = tree_type;
4299 expr_tree = ffecom_2 (MIN_EXPR, arg1_type,
4300 convert (arg1_type, ffecom_expr (arg1)),
4301 convert (arg1_type, ffecom_expr (arg2)));
4302 for (; list != NULL; list = ffebld_trail (list))
4304 if ((ffebld_head (list) == NULL)
4305 || (ffebld_op (ffebld_head (list)) == FFEBLD_opANY))
4307 expr_tree = ffecom_2 (MIN_EXPR, arg1_type,
4310 ffecom_expr (ffebld_head (list))));
4312 return convert (tree_type, expr_tree);
4314 case FFEINTRIN_impMOD:
4315 case FFEINTRIN_impAMOD:
4316 case FFEINTRIN_impDMOD:
4317 if (bt != FFEINFO_basictypeREAL)
4318 return ffecom_2 (TRUNC_MOD_EXPR, tree_type,
4319 convert (tree_type, ffecom_expr (arg1)),
4320 convert (tree_type, ffecom_expr (arg2)));
4322 if (kt == FFEINFO_kindtypeREAL1)
4323 gfrt = FFECOM_gfrtAMOD;
4324 else if (kt == FFEINFO_kindtypeREAL2)
4325 gfrt = FFECOM_gfrtDMOD;
4328 case FFEINTRIN_impNINT:
4329 case FFEINTRIN_impIDNINT:
4331 /* ~~Ideally FIX_ROUND_EXPR would be implemented, but it ain't yet. */
4332 return ffecom_1 (FIX_ROUND_EXPR, tree_type, ffecom_expr (arg1));
4334 /* i__1 = r1 >= 0 ? floor(r1 + .5) : -floor(.5 - r1); */
4335 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
4337 convert (ffecom_integer_type_node,
4338 ffecom_3 (COND_EXPR, arg1_type,
4340 (ffecom_2 (GE_EXPR, integer_type_node,
4343 ffecom_float_zero_))),
4344 ffecom_2 (PLUS_EXPR, arg1_type,
4347 ffecom_float_half_)),
4348 ffecom_2 (MINUS_EXPR, arg1_type,
4351 ffecom_float_half_))));
4354 case FFEINTRIN_impSIGN:
4355 case FFEINTRIN_impDSIGN:
4356 case FFEINTRIN_impISIGN:
4358 tree arg2_tree = ffecom_expr (arg2);
4362 (ffecom_1 (ABS_EXPR, tree_type,
4364 ffecom_expr (arg1))));
4366 = ffecom_3 (COND_EXPR, tree_type,
4368 (ffecom_2 (GE_EXPR, integer_type_node,
4370 convert (TREE_TYPE (arg2_tree),
4371 integer_zero_node))),
4373 ffecom_1 (NEGATE_EXPR, tree_type, saved_expr1));
4374 /* Make sure SAVE_EXPRs get referenced early enough. */
4376 = ffecom_2 (COMPOUND_EXPR, tree_type,
4377 convert (void_type_node, saved_expr1),
4382 case FFEINTRIN_impSIN:
4383 case FFEINTRIN_impCDSIN:
4384 case FFEINTRIN_impCSIN:
4385 case FFEINTRIN_impDSIN:
4386 if (bt == FFEINFO_basictypeCOMPLEX)
4388 if (kt == FFEINFO_kindtypeREAL1)
4389 gfrt = FFECOM_gfrtCSIN; /* Overlapping result okay. */
4390 else if (kt == FFEINFO_kindtypeREAL2)
4391 gfrt = FFECOM_gfrtCDSIN; /* Overlapping result okay. */
4395 case FFEINTRIN_impSINH:
4396 case FFEINTRIN_impDSINH:
4399 case FFEINTRIN_impSQRT:
4400 case FFEINTRIN_impCDSQRT:
4401 case FFEINTRIN_impCSQRT:
4402 case FFEINTRIN_impDSQRT:
4403 if (bt == FFEINFO_basictypeCOMPLEX)
4405 if (kt == FFEINFO_kindtypeREAL1)
4406 gfrt = FFECOM_gfrtCSQRT; /* Overlapping result okay. */
4407 else if (kt == FFEINFO_kindtypeREAL2)
4408 gfrt = FFECOM_gfrtCDSQRT; /* Overlapping result okay. */
4412 case FFEINTRIN_impTAN:
4413 case FFEINTRIN_impDTAN:
4414 case FFEINTRIN_impTANH:
4415 case FFEINTRIN_impDTANH:
4418 case FFEINTRIN_impREALPART:
4419 if (TREE_CODE (arg1_type) == COMPLEX_TYPE)
4420 arg1_type = TREE_TYPE (arg1_type);
4422 arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type));
4426 ffecom_1 (REALPART_EXPR, arg1_type,
4427 ffecom_expr (arg1)));
4429 case FFEINTRIN_impIAND:
4430 case FFEINTRIN_impAND:
4431 return ffecom_2 (BIT_AND_EXPR, tree_type,
4433 ffecom_expr (arg1)),
4435 ffecom_expr (arg2)));
4437 case FFEINTRIN_impIOR:
4438 case FFEINTRIN_impOR:
4439 return ffecom_2 (BIT_IOR_EXPR, tree_type,
4441 ffecom_expr (arg1)),
4443 ffecom_expr (arg2)));
4445 case FFEINTRIN_impIEOR:
4446 case FFEINTRIN_impXOR:
4447 return ffecom_2 (BIT_XOR_EXPR, tree_type,
4449 ffecom_expr (arg1)),
4451 ffecom_expr (arg2)));
4453 case FFEINTRIN_impLSHIFT:
4454 return ffecom_2 (LSHIFT_EXPR, tree_type,
4456 convert (integer_type_node,
4457 ffecom_expr (arg2)));
4459 case FFEINTRIN_impRSHIFT:
4460 return ffecom_2 (RSHIFT_EXPR, tree_type,
4462 convert (integer_type_node,
4463 ffecom_expr (arg2)));
4465 case FFEINTRIN_impNOT:
4466 return ffecom_1 (BIT_NOT_EXPR, tree_type, ffecom_expr (arg1));
4468 case FFEINTRIN_impBIT_SIZE:
4469 return convert (tree_type, TYPE_SIZE (arg1_type));
4471 case FFEINTRIN_impBTEST:
4473 ffetargetLogical1 true;
4474 ffetargetLogical1 false;
4478 ffetarget_logical1 (&true, TRUE);
4479 ffetarget_logical1 (&false, FALSE);
4481 true_tree = convert (tree_type, integer_one_node);
4483 true_tree = convert (tree_type, build_int_2 (true, 0));
4485 false_tree = convert (tree_type, integer_zero_node);
4487 false_tree = convert (tree_type, build_int_2 (false, 0));
4490 ffecom_3 (COND_EXPR, tree_type,
4492 (ffecom_2 (EQ_EXPR, integer_type_node,
4493 ffecom_2 (BIT_AND_EXPR, arg1_type,
4495 ffecom_2 (LSHIFT_EXPR, arg1_type,
4498 convert (integer_type_node,
4499 ffecom_expr (arg2)))),
4501 integer_zero_node))),
4506 case FFEINTRIN_impIBCLR:
4508 ffecom_2 (BIT_AND_EXPR, tree_type,
4510 ffecom_1 (BIT_NOT_EXPR, tree_type,
4511 ffecom_2 (LSHIFT_EXPR, tree_type,
4514 convert (integer_type_node,
4515 ffecom_expr (arg2)))));
4517 case FFEINTRIN_impIBITS:
4519 tree arg3_tree = ffecom_save_tree (convert (integer_type_node,
4520 ffecom_expr (arg3)));
4522 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4525 = ffecom_2 (BIT_AND_EXPR, tree_type,
4526 ffecom_2 (RSHIFT_EXPR, tree_type,
4528 convert (integer_type_node,
4529 ffecom_expr (arg2))),
4531 ffecom_2 (RSHIFT_EXPR, uns_type,
4532 ffecom_1 (BIT_NOT_EXPR,
4535 integer_zero_node)),
4536 ffecom_2 (MINUS_EXPR,
4538 TYPE_SIZE (uns_type),
4540 #if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4542 = ffecom_3 (COND_EXPR, tree_type,
4544 (ffecom_2 (NE_EXPR, integer_type_node,
4546 integer_zero_node)),
4548 convert (tree_type, integer_zero_node));
4553 case FFEINTRIN_impIBSET:
4555 ffecom_2 (BIT_IOR_EXPR, tree_type,
4557 ffecom_2 (LSHIFT_EXPR, tree_type,
4558 convert (tree_type, integer_one_node),
4559 convert (integer_type_node,
4560 ffecom_expr (arg2))));
4562 case FFEINTRIN_impISHFT:
4564 tree arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4565 tree arg2_tree = ffecom_save_tree (convert (integer_type_node,
4566 ffecom_expr (arg2)));
4568 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4571 = ffecom_3 (COND_EXPR, tree_type,
4573 (ffecom_2 (GE_EXPR, integer_type_node,
4575 integer_zero_node)),
4576 ffecom_2 (LSHIFT_EXPR, tree_type,
4580 ffecom_2 (RSHIFT_EXPR, uns_type,
4581 convert (uns_type, arg1_tree),
4582 ffecom_1 (NEGATE_EXPR,
4585 #if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4587 = ffecom_3 (COND_EXPR, tree_type,
4589 (ffecom_2 (NE_EXPR, integer_type_node,
4591 TYPE_SIZE (uns_type))),
4593 convert (tree_type, integer_zero_node));
4595 /* Make sure SAVE_EXPRs get referenced early enough. */
4597 = ffecom_2 (COMPOUND_EXPR, tree_type,
4598 convert (void_type_node, arg1_tree),
4599 ffecom_2 (COMPOUND_EXPR, tree_type,
4600 convert (void_type_node, arg2_tree),
4605 case FFEINTRIN_impISHFTC:
4607 tree arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4608 tree arg2_tree = ffecom_save_tree (convert (integer_type_node,
4609 ffecom_expr (arg2)));
4610 tree arg3_tree = (arg3 == NULL) ? TYPE_SIZE (tree_type)
4611 : ffecom_save_tree (convert (integer_type_node, ffecom_expr (arg3)));
4617 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4620 = ffecom_2 (LSHIFT_EXPR, tree_type,
4621 ffecom_1 (BIT_NOT_EXPR, tree_type,
4622 convert (tree_type, integer_zero_node)),
4624 #if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4626 = ffecom_3 (COND_EXPR, tree_type,
4628 (ffecom_2 (NE_EXPR, integer_type_node,
4630 TYPE_SIZE (uns_type))),
4632 convert (tree_type, integer_zero_node));
4634 mask_arg1 = ffecom_save_tree (mask_arg1);
4636 = ffecom_2 (BIT_AND_EXPR, tree_type,
4638 ffecom_1 (BIT_NOT_EXPR, tree_type,
4640 masked_arg1 = ffecom_save_tree (masked_arg1);
4642 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4644 ffecom_2 (RSHIFT_EXPR, uns_type,
4645 convert (uns_type, masked_arg1),
4646 ffecom_1 (NEGATE_EXPR,
4649 ffecom_2 (LSHIFT_EXPR, tree_type,
4651 ffecom_2 (PLUS_EXPR, integer_type_node,
4655 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4656 ffecom_2 (LSHIFT_EXPR, tree_type,
4660 ffecom_2 (RSHIFT_EXPR, uns_type,
4661 convert (uns_type, masked_arg1),
4662 ffecom_2 (MINUS_EXPR,
4667 = ffecom_3 (COND_EXPR, tree_type,
4669 (ffecom_2 (LT_EXPR, integer_type_node,
4671 integer_zero_node)),
4675 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4676 ffecom_2 (BIT_AND_EXPR, tree_type,
4679 ffecom_2 (BIT_AND_EXPR, tree_type,
4680 ffecom_1 (BIT_NOT_EXPR, tree_type,
4684 = ffecom_3 (COND_EXPR, tree_type,
4686 (ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
4687 ffecom_2 (EQ_EXPR, integer_type_node,
4692 ffecom_2 (EQ_EXPR, integer_type_node,
4694 integer_zero_node))),
4697 /* Make sure SAVE_EXPRs get referenced early enough. */
4699 = ffecom_2 (COMPOUND_EXPR, tree_type,
4700 convert (void_type_node, arg1_tree),
4701 ffecom_2 (COMPOUND_EXPR, tree_type,
4702 convert (void_type_node, arg2_tree),
4703 ffecom_2 (COMPOUND_EXPR, tree_type,
4704 convert (void_type_node,
4706 ffecom_2 (COMPOUND_EXPR, tree_type,
4707 convert (void_type_node,
4711 = ffecom_2 (COMPOUND_EXPR, tree_type,
4712 convert (void_type_node,
4718 case FFEINTRIN_impLOC:
4720 tree arg1_tree = ffecom_expr (arg1);
4723 = convert (tree_type,
4724 ffecom_1 (ADDR_EXPR,
4725 build_pointer_type (TREE_TYPE (arg1_tree)),
4730 case FFEINTRIN_impMVBITS:
4735 ffebld arg4 = ffebld_head (ffebld_trail (list));
4738 ffebld arg5 = ffebld_head (ffebld_trail (ffebld_trail (list)));
4742 tree arg5_plus_arg3;
4744 arg2_tree = convert (integer_type_node,
4745 ffecom_expr (arg2));
4746 arg3_tree = ffecom_save_tree (convert (integer_type_node,
4747 ffecom_expr (arg3)));
4748 arg4_tree = ffecom_expr_rw (NULL_TREE, arg4);
4749 arg4_type = TREE_TYPE (arg4_tree);
4751 arg1_tree = ffecom_save_tree (convert (arg4_type,
4752 ffecom_expr (arg1)));
4754 arg5_tree = ffecom_save_tree (convert (integer_type_node,
4755 ffecom_expr (arg5)));
4758 = ffecom_2 (LSHIFT_EXPR, arg4_type,
4759 ffecom_2 (BIT_AND_EXPR, arg4_type,
4760 ffecom_2 (RSHIFT_EXPR, arg4_type,
4763 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4764 ffecom_2 (LSHIFT_EXPR, arg4_type,
4765 ffecom_1 (BIT_NOT_EXPR,
4769 integer_zero_node)),
4773 = ffecom_save_tree (ffecom_2 (PLUS_EXPR, arg4_type,
4777 = ffecom_2 (LSHIFT_EXPR, arg4_type,
4778 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4780 integer_zero_node)),
4782 #if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4784 = ffecom_3 (COND_EXPR, arg4_type,
4786 (ffecom_2 (NE_EXPR, integer_type_node,
4788 convert (TREE_TYPE (arg5_plus_arg3),
4789 TYPE_SIZE (arg4_type)))),
4791 convert (arg4_type, integer_zero_node));
4794 = ffecom_2 (BIT_AND_EXPR, arg4_type,
4796 ffecom_2 (BIT_IOR_EXPR, arg4_type,
4798 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4799 ffecom_2 (LSHIFT_EXPR, arg4_type,
4800 ffecom_1 (BIT_NOT_EXPR,
4804 integer_zero_node)),
4807 = ffecom_2 (BIT_IOR_EXPR, arg4_type,
4810 #if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4812 = ffecom_3 (COND_EXPR, arg4_type,
4814 (ffecom_2 (NE_EXPR, integer_type_node,
4816 convert (TREE_TYPE (arg3_tree),
4817 integer_zero_node))),
4821 = ffecom_3 (COND_EXPR, arg4_type,
4823 (ffecom_2 (NE_EXPR, integer_type_node,
4825 convert (TREE_TYPE (arg3_tree),
4826 TYPE_SIZE (arg4_type)))),
4831 = ffecom_2s (MODIFY_EXPR, void_type_node,
4834 /* Make sure SAVE_EXPRs get referenced early enough. */
4836 = ffecom_2 (COMPOUND_EXPR, void_type_node,
4838 ffecom_2 (COMPOUND_EXPR, void_type_node,
4840 ffecom_2 (COMPOUND_EXPR, void_type_node,
4842 ffecom_2 (COMPOUND_EXPR, void_type_node,
4846 = ffecom_2 (COMPOUND_EXPR, void_type_node,
4853 case FFEINTRIN_impDERF:
4854 case FFEINTRIN_impERF:
4855 case FFEINTRIN_impDERFC:
4856 case FFEINTRIN_impERFC:
4859 case FFEINTRIN_impIARGC:
4860 /* extern int xargc; i__1 = xargc - 1; */
4861 expr_tree = ffecom_2 (MINUS_EXPR, TREE_TYPE (ffecom_tree_xargc_),
4863 convert (TREE_TYPE (ffecom_tree_xargc_),
4867 case FFEINTRIN_impSIGNAL_func:
4868 case FFEINTRIN_impSIGNAL_subr:
4874 arg1_tree = convert (ffecom_f2c_integer_type_node,
4875 ffecom_expr (arg1));
4876 arg1_tree = ffecom_1 (ADDR_EXPR,
4877 build_pointer_type (TREE_TYPE (arg1_tree)),
4880 /* Pass procedure as a pointer to it, anything else by value. */
4881 if (ffeinfo_kind (ffebld_info (arg2)) == FFEINFO_kindENTITY)
4882 arg2_tree = convert (integer_type_node, ffecom_expr (arg2));
4884 arg2_tree = ffecom_ptr_to_expr (arg2);
4885 arg2_tree = convert (TREE_TYPE (null_pointer_node),
4889 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
4891 arg3_tree = NULL_TREE;
4893 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4894 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
4895 TREE_CHAIN (arg1_tree) = arg2_tree;
4898 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4899 ffecom_gfrt_kindtype (gfrt),
4901 ((codegen_imp == FFEINTRIN_impSIGNAL_subr) ?
4905 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4906 ffebld_nonter_hook (expr));
4908 if (arg3_tree != NULL_TREE)
4910 = ffecom_modify (NULL_TREE, arg3_tree,
4911 convert (TREE_TYPE (arg3_tree),
4916 case FFEINTRIN_impALARM:
4922 arg1_tree = convert (ffecom_f2c_integer_type_node,
4923 ffecom_expr (arg1));
4924 arg1_tree = ffecom_1 (ADDR_EXPR,
4925 build_pointer_type (TREE_TYPE (arg1_tree)),
4928 /* Pass procedure as a pointer to it, anything else by value. */
4929 if (ffeinfo_kind (ffebld_info (arg2)) == FFEINFO_kindENTITY)
4930 arg2_tree = convert (integer_type_node, ffecom_expr (arg2));
4932 arg2_tree = ffecom_ptr_to_expr (arg2);
4933 arg2_tree = convert (TREE_TYPE (null_pointer_node),
4937 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
4939 arg3_tree = NULL_TREE;
4941 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4942 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
4943 TREE_CHAIN (arg1_tree) = arg2_tree;
4946 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4947 ffecom_gfrt_kindtype (gfrt),
4951 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4952 ffebld_nonter_hook (expr));
4954 if (arg3_tree != NULL_TREE)
4956 = ffecom_modify (NULL_TREE, arg3_tree,
4957 convert (TREE_TYPE (arg3_tree),
4962 case FFEINTRIN_impCHDIR_subr:
4963 case FFEINTRIN_impFDATE_subr:
4964 case FFEINTRIN_impFGET_subr:
4965 case FFEINTRIN_impFPUT_subr:
4966 case FFEINTRIN_impGETCWD_subr:
4967 case FFEINTRIN_impHOSTNM_subr:
4968 case FFEINTRIN_impSYSTEM_subr:
4969 case FFEINTRIN_impUNLINK_subr:
4971 tree arg1_len = integer_zero_node;
4975 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
4978 arg2_tree = ffecom_expr_w (NULL_TREE, arg2);
4980 arg2_tree = NULL_TREE;
4982 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4983 arg1_len = build_tree_list (NULL_TREE, arg1_len);
4984 TREE_CHAIN (arg1_tree) = arg1_len;
4987 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4988 ffecom_gfrt_kindtype (gfrt),
4992 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4993 ffebld_nonter_hook (expr));
4995 if (arg2_tree != NULL_TREE)
4997 = ffecom_modify (NULL_TREE, arg2_tree,
4998 convert (TREE_TYPE (arg2_tree),
5003 case FFEINTRIN_impEXIT:
5007 expr_tree = build_tree_list (NULL_TREE,
5008 ffecom_1 (ADDR_EXPR,
5010 (ffecom_integer_type_node),
5011 integer_zero_node));
5014 ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5015 ffecom_gfrt_kindtype (gfrt),
5019 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5020 ffebld_nonter_hook (expr));
5022 case FFEINTRIN_impFLUSH:
5024 gfrt = FFECOM_gfrtFLUSH;
5026 gfrt = FFECOM_gfrtFLUSH1;
5029 case FFEINTRIN_impCHMOD_subr:
5030 case FFEINTRIN_impLINK_subr:
5031 case FFEINTRIN_impRENAME_subr:
5032 case FFEINTRIN_impSYMLNK_subr:
5034 tree arg1_len = integer_zero_node;
5036 tree arg2_len = integer_zero_node;
5040 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
5041 arg2_tree = ffecom_arg_ptr_to_expr (arg2, &arg2_len);
5043 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5045 arg3_tree = NULL_TREE;
5047 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5048 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5049 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5050 arg2_len = build_tree_list (NULL_TREE, arg2_len);
5051 TREE_CHAIN (arg1_tree) = arg2_tree;
5052 TREE_CHAIN (arg2_tree) = arg1_len;
5053 TREE_CHAIN (arg1_len) = arg2_len;
5054 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5055 ffecom_gfrt_kindtype (gfrt),
5059 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5060 ffebld_nonter_hook (expr));
5061 if (arg3_tree != NULL_TREE)
5062 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5063 convert (TREE_TYPE (arg3_tree),
5068 case FFEINTRIN_impLSTAT_subr:
5069 case FFEINTRIN_impSTAT_subr:
5071 tree arg1_len = integer_zero_node;
5076 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
5078 arg2_tree = ffecom_ptr_to_expr (arg2);
5081 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5083 arg3_tree = NULL_TREE;
5085 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5086 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5087 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5088 TREE_CHAIN (arg1_tree) = arg2_tree;
5089 TREE_CHAIN (arg2_tree) = arg1_len;
5090 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5091 ffecom_gfrt_kindtype (gfrt),
5095 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5096 ffebld_nonter_hook (expr));
5097 if (arg3_tree != NULL_TREE)
5098 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5099 convert (TREE_TYPE (arg3_tree),
5104 case FFEINTRIN_impFGETC_subr:
5105 case FFEINTRIN_impFPUTC_subr:
5109 tree arg2_len = integer_zero_node;
5112 arg1_tree = convert (ffecom_f2c_integer_type_node,
5113 ffecom_expr (arg1));
5114 arg1_tree = ffecom_1 (ADDR_EXPR,
5115 build_pointer_type (TREE_TYPE (arg1_tree)),
5118 arg2_tree = ffecom_arg_ptr_to_expr (arg2, &arg2_len);
5119 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5121 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5122 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5123 arg2_len = build_tree_list (NULL_TREE, arg2_len);
5124 TREE_CHAIN (arg1_tree) = arg2_tree;
5125 TREE_CHAIN (arg2_tree) = arg2_len;
5127 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5128 ffecom_gfrt_kindtype (gfrt),
5132 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5133 ffebld_nonter_hook (expr));
5134 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5135 convert (TREE_TYPE (arg3_tree),
5140 case FFEINTRIN_impFSTAT_subr:
5146 arg1_tree = convert (ffecom_f2c_integer_type_node,
5147 ffecom_expr (arg1));
5148 arg1_tree = ffecom_1 (ADDR_EXPR,
5149 build_pointer_type (TREE_TYPE (arg1_tree)),
5152 arg2_tree = convert (ffecom_f2c_ptr_to_integer_type_node,
5153 ffecom_ptr_to_expr (arg2));
5156 arg3_tree = NULL_TREE;
5158 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5160 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5161 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5162 TREE_CHAIN (arg1_tree) = arg2_tree;
5163 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5164 ffecom_gfrt_kindtype (gfrt),
5168 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5169 ffebld_nonter_hook (expr));
5170 if (arg3_tree != NULL_TREE) {
5171 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5172 convert (TREE_TYPE (arg3_tree),
5178 case FFEINTRIN_impKILL_subr:
5184 arg1_tree = convert (ffecom_f2c_integer_type_node,
5185 ffecom_expr (arg1));
5186 arg1_tree = ffecom_1 (ADDR_EXPR,
5187 build_pointer_type (TREE_TYPE (arg1_tree)),
5190 arg2_tree = convert (ffecom_f2c_integer_type_node,
5191 ffecom_expr (arg2));
5192 arg2_tree = ffecom_1 (ADDR_EXPR,
5193 build_pointer_type (TREE_TYPE (arg2_tree)),
5197 arg3_tree = NULL_TREE;
5199 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5201 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5202 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5203 TREE_CHAIN (arg1_tree) = arg2_tree;
5204 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5205 ffecom_gfrt_kindtype (gfrt),
5209 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5210 ffebld_nonter_hook (expr));
5211 if (arg3_tree != NULL_TREE) {
5212 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5213 convert (TREE_TYPE (arg3_tree),
5219 case FFEINTRIN_impCTIME_subr:
5220 case FFEINTRIN_impTTYNAM_subr:
5222 tree arg1_len = integer_zero_node;
5226 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
5228 arg2_tree = convert (((gfrt == FFEINTRIN_impCTIME_subr) ?
5229 ffecom_f2c_longint_type_node :
5230 ffecom_f2c_integer_type_node),
5231 ffecom_expr (arg2));
5232 arg2_tree = ffecom_1 (ADDR_EXPR,
5233 build_pointer_type (TREE_TYPE (arg2_tree)),
5236 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5237 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5238 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5239 TREE_CHAIN (arg1_len) = arg2_tree;
5240 TREE_CHAIN (arg1_tree) = arg1_len;
5243 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5244 ffecom_gfrt_kindtype (gfrt),
5248 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5249 ffebld_nonter_hook (expr));
5253 case FFEINTRIN_impIRAND:
5254 case FFEINTRIN_impRAND:
5255 /* Arg defaults to 0 (normal random case) */
5260 arg1_tree = ffecom_integer_zero_node;
5262 arg1_tree = ffecom_expr (arg1);
5263 arg1_tree = convert (ffecom_f2c_integer_type_node,
5265 arg1_tree = ffecom_1 (ADDR_EXPR,
5266 build_pointer_type (TREE_TYPE (arg1_tree)),
5268 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5270 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5271 ffecom_gfrt_kindtype (gfrt),
5273 ((codegen_imp == FFEINTRIN_impIRAND) ?
5274 ffecom_f2c_integer_type_node :
5275 ffecom_f2c_real_type_node),
5277 dest_tree, dest, dest_used,
5279 ffebld_nonter_hook (expr));
5283 case FFEINTRIN_impFTELL_subr:
5284 case FFEINTRIN_impUMASK_subr:
5289 arg1_tree = convert (ffecom_f2c_integer_type_node,
5290 ffecom_expr (arg1));
5291 arg1_tree = ffecom_1 (ADDR_EXPR,
5292 build_pointer_type (TREE_TYPE (arg1_tree)),
5296 arg2_tree = NULL_TREE;
5298 arg2_tree = ffecom_expr_w (NULL_TREE, arg2);
5300 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5301 ffecom_gfrt_kindtype (gfrt),
5304 build_tree_list (NULL_TREE, arg1_tree),
5305 NULL_TREE, NULL, NULL, NULL_TREE,
5307 ffebld_nonter_hook (expr));
5308 if (arg2_tree != NULL_TREE) {
5309 expr_tree = ffecom_modify (NULL_TREE, arg2_tree,
5310 convert (TREE_TYPE (arg2_tree),
5316 case FFEINTRIN_impCPU_TIME:
5317 case FFEINTRIN_impSECOND_subr:
5321 arg1_tree = ffecom_expr_w (NULL_TREE, arg1);
5324 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5325 ffecom_gfrt_kindtype (gfrt),
5329 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5330 ffebld_nonter_hook (expr));
5333 = ffecom_modify (NULL_TREE, arg1_tree,
5334 convert (TREE_TYPE (arg1_tree),
5339 case FFEINTRIN_impDTIME_subr:
5340 case FFEINTRIN_impETIME_subr:
5345 arg1_tree = ffecom_expr_w (NULL_TREE, arg1);
5347 arg2_tree = ffecom_ptr_to_expr (arg2);
5349 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5350 ffecom_gfrt_kindtype (gfrt),
5353 build_tree_list (NULL_TREE, arg2_tree),
5354 NULL_TREE, NULL, NULL, NULL_TREE,
5356 ffebld_nonter_hook (expr));
5357 expr_tree = ffecom_modify (NULL_TREE, arg1_tree,
5358 convert (TREE_TYPE (arg1_tree),
5363 /* Straightforward calls of libf2c routines: */
5364 case FFEINTRIN_impABORT:
5365 case FFEINTRIN_impACCESS:
5366 case FFEINTRIN_impBESJ0:
5367 case FFEINTRIN_impBESJ1:
5368 case FFEINTRIN_impBESJN:
5369 case FFEINTRIN_impBESY0:
5370 case FFEINTRIN_impBESY1:
5371 case FFEINTRIN_impBESYN:
5372 case FFEINTRIN_impCHDIR_func:
5373 case FFEINTRIN_impCHMOD_func:
5374 case FFEINTRIN_impDATE:
5375 case FFEINTRIN_impDATE_AND_TIME:
5376 case FFEINTRIN_impDBESJ0:
5377 case FFEINTRIN_impDBESJ1:
5378 case FFEINTRIN_impDBESJN:
5379 case FFEINTRIN_impDBESY0:
5380 case FFEINTRIN_impDBESY1:
5381 case FFEINTRIN_impDBESYN:
5382 case FFEINTRIN_impDTIME_func:
5383 case FFEINTRIN_impETIME_func:
5384 case FFEINTRIN_impFGETC_func:
5385 case FFEINTRIN_impFGET_func:
5386 case FFEINTRIN_impFNUM:
5387 case FFEINTRIN_impFPUTC_func:
5388 case FFEINTRIN_impFPUT_func:
5389 case FFEINTRIN_impFSEEK:
5390 case FFEINTRIN_impFSTAT_func:
5391 case FFEINTRIN_impFTELL_func:
5392 case FFEINTRIN_impGERROR:
5393 case FFEINTRIN_impGETARG:
5394 case FFEINTRIN_impGETCWD_func:
5395 case FFEINTRIN_impGETENV:
5396 case FFEINTRIN_impGETGID:
5397 case FFEINTRIN_impGETLOG:
5398 case FFEINTRIN_impGETPID:
5399 case FFEINTRIN_impGETUID:
5400 case FFEINTRIN_impGMTIME:
5401 case FFEINTRIN_impHOSTNM_func:
5402 case FFEINTRIN_impIDATE_unix:
5403 case FFEINTRIN_impIDATE_vxt:
5404 case FFEINTRIN_impIERRNO:
5405 case FFEINTRIN_impISATTY:
5406 case FFEINTRIN_impITIME:
5407 case FFEINTRIN_impKILL_func:
5408 case FFEINTRIN_impLINK_func:
5409 case FFEINTRIN_impLNBLNK:
5410 case FFEINTRIN_impLSTAT_func:
5411 case FFEINTRIN_impLTIME:
5412 case FFEINTRIN_impMCLOCK8:
5413 case FFEINTRIN_impMCLOCK:
5414 case FFEINTRIN_impPERROR:
5415 case FFEINTRIN_impRENAME_func:
5416 case FFEINTRIN_impSECNDS:
5417 case FFEINTRIN_impSECOND_func:
5418 case FFEINTRIN_impSLEEP:
5419 case FFEINTRIN_impSRAND:
5420 case FFEINTRIN_impSTAT_func:
5421 case FFEINTRIN_impSYMLNK_func:
5422 case FFEINTRIN_impSYSTEM_CLOCK:
5423 case FFEINTRIN_impSYSTEM_func:
5424 case FFEINTRIN_impTIME8:
5425 case FFEINTRIN_impTIME_unix:
5426 case FFEINTRIN_impTIME_vxt:
5427 case FFEINTRIN_impUMASK_func:
5428 case FFEINTRIN_impUNLINK_func:
5431 case FFEINTRIN_impCTIME_func: /* CHARACTER functions not handled here. */
5432 case FFEINTRIN_impFDATE_func: /* CHARACTER functions not handled here. */
5433 case FFEINTRIN_impTTYNAM_func: /* CHARACTER functions not handled here. */
5434 case FFEINTRIN_impNONE:
5435 case FFEINTRIN_imp: /* Hush up gcc warning. */
5436 fprintf (stderr, "No %s implementation.\n",
5437 ffeintrin_name_implementation (ffebld_symter_implementation (ffebld_left (expr))));
5438 assert ("unimplemented intrinsic" == NULL);
5439 return error_mark_node;
5442 assert (gfrt != FFECOM_gfrt); /* Must have an implementation! */
5444 expr_tree = ffecom_arglist_expr_ (ffecom_gfrt_args_ (gfrt),
5445 ffebld_right (expr));
5447 return ffecom_call_ (ffecom_gfrt_tree_ (gfrt), ffecom_gfrt_kindtype (gfrt),
5448 (ffe_is_f2c_library () && ffecom_gfrt_complex_[gfrt]),
5450 expr_tree, dest_tree, dest, dest_used,
5452 ffebld_nonter_hook (expr));
5454 /* See bottom of this file for f2c transforms used to determine
5455 many of the above implementations. The info seems to confuse
5456 Emacs's C mode indentation, which is why it's been moved to
5457 the bottom of this source file. */
5461 /* For power (exponentiation) where right-hand operand is type INTEGER,
5462 generate in-line code to do it the fast way (which, if the operand
5463 is a constant, might just mean a series of multiplies). */
5465 #if FFECOM_targetCURRENT == FFECOM_targetGCC
5467 ffecom_expr_power_integer_ (ffebld expr)
5469 tree l = ffecom_expr (ffebld_left (expr));
5470 tree r = ffecom_expr (ffebld_right (expr));
5471 tree ltype = TREE_TYPE (l);
5472 tree rtype = TREE_TYPE (r);
5473 tree result = NULL_TREE;
5475 if (l == error_mark_node
5476 || r == error_mark_node)
5477 return error_mark_node;
5479 if (TREE_CODE (r) == INTEGER_CST)
5481 int sgn = tree_int_cst_sgn (r);
5484 return convert (ltype, integer_one_node);
5486 if ((TREE_CODE (ltype) == INTEGER_TYPE)
5489 /* Reciprocal of integer is either 0, -1, or 1, so after
5490 calculating that (which we leave to the back end to do
5491 or not do optimally), don't bother with any multiplying. */
5493 result = ffecom_tree_divide_ (ltype,
5494 convert (ltype, integer_one_node),
5496 NULL_TREE, NULL, NULL, NULL_TREE);
5497 r = ffecom_1 (NEGATE_EXPR,
5500 if ((TREE_INT_CST_LOW (r) & 1) == 0)
5501 result = ffecom_1 (ABS_EXPR, rtype,
5505 /* Generate appropriate series of multiplies, preceded
5506 by divide if the exponent is negative. */
5512 l = ffecom_tree_divide_ (ltype,
5513 convert (ltype, integer_one_node),
5515 NULL_TREE, NULL, NULL,
5516 ffebld_nonter_hook (expr));
5517 r = ffecom_1 (NEGATE_EXPR, rtype, r);
5518 assert (TREE_CODE (r) == INTEGER_CST);
5520 if (tree_int_cst_sgn (r) < 0)
5521 { /* The "most negative" number. */
5522 r = ffecom_1 (NEGATE_EXPR, rtype,
5523 ffecom_2 (RSHIFT_EXPR, rtype,
5527 l = ffecom_2 (MULT_EXPR, ltype,
5535 if (TREE_INT_CST_LOW (r) & 1)
5537 if (result == NULL_TREE)
5540 result = ffecom_2 (MULT_EXPR, ltype,
5545 r = ffecom_2 (RSHIFT_EXPR, rtype,
5548 if (integer_zerop (r))
5550 assert (TREE_CODE (r) == INTEGER_CST);
5553 l = ffecom_2 (MULT_EXPR, ltype,
5560 /* Though rhs isn't a constant, in-line code cannot be expanded
5561 while transforming dummies
5562 because the back end cannot be easily convinced to generate
5563 stores (MODIFY_EXPR), handle temporaries, and so on before
5564 all the appropriate rtx's have been generated for things like
5565 dummy args referenced in rhs -- which doesn't happen until
5566 store_parm_decls() is called (expand_function_start, I believe,
5567 does the actual rtx-stuffing of PARM_DECLs).
5569 So, in this case, let the caller generate the call to the
5570 run-time-library function to evaluate the power for us. */
5572 if (ffecom_transform_only_dummies_)
5575 /* Right-hand operand not a constant, expand in-line code to figure
5576 out how to do the multiplies, &c.
5578 The returned expression is expressed this way in GNU C, where l and
5581 ({ typeof (r) rtmp = r;
5582 typeof (l) ltmp = l;
5589 if ((basetypeof (l) == basetypeof (int))
5592 result = ((typeof (l)) 1) / ltmp;
5593 if ((ltmp < 0) && (((-rtmp) & 1) == 0))
5599 if ((basetypeof (l) != basetypeof (int))
5602 ltmp = ((typeof (l)) 1) / ltmp;
5606 rtmp = -(rtmp >> 1);
5614 if ((rtmp >>= 1) == 0)
5623 Note that some of the above is compile-time collapsable, such as
5624 the first part of the if statements that checks the base type of
5625 l against int. The if statements are phrased that way to suggest
5626 an easy way to generate the if/else constructs here, knowing that
5627 the back end should (and probably does) eliminate the resulting
5628 dead code (either the int case or the non-int case), something
5629 it couldn't do without the redundant phrasing, requiring explicit
5630 dead-code elimination here, which would be kind of difficult to
5637 tree basetypeof_l_is_int;
5642 = build_int_2 ((TREE_CODE (ltype) == INTEGER_TYPE), 0);
5644 se = expand_start_stmt_expr ();
5646 ffecom_start_compstmt ();
5649 rtmp = ffecom_make_tempvar ("power_r", rtype,
5650 FFETARGET_charactersizeNONE, -1);
5651 ltmp = ffecom_make_tempvar ("power_l", ltype,
5652 FFETARGET_charactersizeNONE, -1);
5653 result = ffecom_make_tempvar ("power_res", ltype,
5654 FFETARGET_charactersizeNONE, -1);
5655 if (TREE_CODE (ltype) == COMPLEX_TYPE
5656 || TREE_CODE (ltype) == RECORD_TYPE)
5657 divide = ffecom_make_tempvar ("power_div", ltype,
5658 FFETARGET_charactersizeNONE, -1);
5665 hook = ffebld_nonter_hook (expr);
5667 assert (TREE_CODE (hook) == TREE_VEC);
5668 assert (TREE_VEC_LENGTH (hook) == 4);
5669 rtmp = TREE_VEC_ELT (hook, 0);
5670 ltmp = TREE_VEC_ELT (hook, 1);
5671 result = TREE_VEC_ELT (hook, 2);
5672 divide = TREE_VEC_ELT (hook, 3);
5673 if (TREE_CODE (ltype) == COMPLEX_TYPE
5674 || TREE_CODE (ltype) == RECORD_TYPE)
5681 expand_expr_stmt (ffecom_modify (void_type_node,
5684 expand_expr_stmt (ffecom_modify (void_type_node,
5687 expand_start_cond (ffecom_truth_value
5688 (ffecom_2 (EQ_EXPR, integer_type_node,
5690 convert (rtype, integer_zero_node))),
5692 expand_expr_stmt (ffecom_modify (void_type_node,
5694 convert (ltype, integer_one_node)));
5695 expand_start_else ();
5696 if (! integer_zerop (basetypeof_l_is_int))
5698 expand_start_cond (ffecom_2 (LT_EXPR, integer_type_node,
5701 integer_zero_node)),
5703 expand_expr_stmt (ffecom_modify (void_type_node,
5707 convert (ltype, integer_one_node),
5709 NULL_TREE, NULL, NULL,
5711 expand_start_cond (ffecom_truth_value
5712 (ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
5713 ffecom_2 (LT_EXPR, integer_type_node,
5716 integer_zero_node)),
5717 ffecom_2 (EQ_EXPR, integer_type_node,
5718 ffecom_2 (BIT_AND_EXPR,
5720 ffecom_1 (NEGATE_EXPR,
5726 integer_zero_node)))),
5728 expand_expr_stmt (ffecom_modify (void_type_node,
5730 ffecom_1 (NEGATE_EXPR,
5734 expand_start_else ();
5736 expand_expr_stmt (ffecom_modify (void_type_node,
5738 convert (ltype, integer_one_node)));
5739 expand_start_cond (ffecom_truth_value
5740 (ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
5741 ffecom_truth_value_invert
5742 (basetypeof_l_is_int),
5743 ffecom_2 (LT_EXPR, integer_type_node,
5746 integer_zero_node)))),
5748 expand_expr_stmt (ffecom_modify (void_type_node,
5752 convert (ltype, integer_one_node),
5754 NULL_TREE, NULL, NULL,
5756 expand_expr_stmt (ffecom_modify (void_type_node,
5758 ffecom_1 (NEGATE_EXPR, rtype,
5760 expand_start_cond (ffecom_truth_value
5761 (ffecom_2 (LT_EXPR, integer_type_node,
5763 convert (rtype, integer_zero_node))),
5765 expand_expr_stmt (ffecom_modify (void_type_node,
5767 ffecom_1 (NEGATE_EXPR, rtype,
5768 ffecom_2 (RSHIFT_EXPR,
5771 integer_one_node))));
5772 expand_expr_stmt (ffecom_modify (void_type_node,
5774 ffecom_2 (MULT_EXPR, ltype,
5779 expand_start_loop (1);
5780 expand_start_cond (ffecom_truth_value
5781 (ffecom_2 (BIT_AND_EXPR, rtype,
5783 convert (rtype, integer_one_node))),
5785 expand_expr_stmt (ffecom_modify (void_type_node,
5787 ffecom_2 (MULT_EXPR, ltype,
5791 expand_exit_loop_if_false (NULL,
5793 (ffecom_modify (rtype,
5795 ffecom_2 (RSHIFT_EXPR,
5798 integer_one_node))));
5799 expand_expr_stmt (ffecom_modify (void_type_node,
5801 ffecom_2 (MULT_EXPR, ltype,
5806 if (!integer_zerop (basetypeof_l_is_int))
5808 expand_expr_stmt (result);
5810 t = ffecom_end_compstmt ();
5812 result = expand_end_stmt_expr (se);
5814 /* This code comes from c-parse.in, after its expand_end_stmt_expr. */
5816 if (TREE_CODE (t) == BLOCK)
5818 /* Make a BIND_EXPR for the BLOCK already made. */
5819 result = build (BIND_EXPR, TREE_TYPE (result),
5820 NULL_TREE, result, t);
5821 /* Remove the block from the tree at this point.
5822 It gets put back at the proper place
5823 when the BIND_EXPR is expanded. */
5834 /* ffecom_expr_transform_ -- Transform symbols in expr
5836 ffebld expr; // FFE expression.
5837 ffecom_expr_transform_ (expr);
5839 Recursive descent on expr while transforming any untransformed SYMTERs. */
5841 #if FFECOM_targetCURRENT == FFECOM_targetGCC
5843 ffecom_expr_transform_ (ffebld expr)
5848 tail_recurse: /* :::::::::::::::::::: */
5853 switch (ffebld_op (expr))
5855 case FFEBLD_opSYMTER:
5856 s = ffebld_symter (expr);
5857 t = ffesymbol_hook (s).decl_tree;
5858 if ((t == NULL_TREE)
5859 && ((ffesymbol_kind (s) != FFEINFO_kindNONE)
5860 || ((ffesymbol_where (s) != FFEINFO_whereNONE)
5861 && (ffesymbol_where (s) != FFEINFO_whereINTRINSIC))))
5863 s = ffecom_sym_transform_ (s);
5864 t = ffesymbol_hook (s).decl_tree; /* Sfunc expr non-dummy,
5867 break; /* Ok if (t == NULL) here. */
5870 ffecom_expr_transform_ (ffebld_head (expr));
5871 expr = ffebld_trail (expr);
5872 goto tail_recurse; /* :::::::::::::::::::: */
5878 switch (ffebld_arity (expr))
5881 ffecom_expr_transform_ (ffebld_left (expr));
5882 expr = ffebld_right (expr);
5883 goto tail_recurse; /* :::::::::::::::::::: */
5886 expr = ffebld_left (expr);
5887 goto tail_recurse; /* :::::::::::::::::::: */
5897 /* Make a type based on info in live f2c.h file. */
5899 #if FFECOM_targetCURRENT == FFECOM_targetGCC
5901 ffecom_f2c_make_type_ (tree *type, int tcode, const char *name)
5905 case FFECOM_f2ccodeCHAR:
5906 *type = make_signed_type (CHAR_TYPE_SIZE);
5909 case FFECOM_f2ccodeSHORT:
5910 *type = make_signed_type (SHORT_TYPE_SIZE);
5913 case FFECOM_f2ccodeINT:
5914 *type = make_signed_type (INT_TYPE_SIZE);
5917 case FFECOM_f2ccodeLONG:
5918 *type = make_signed_type (LONG_TYPE_SIZE);
5921 case FFECOM_f2ccodeLONGLONG:
5922 *type = make_signed_type (LONG_LONG_TYPE_SIZE);
5925 case FFECOM_f2ccodeCHARPTR:
5926 *type = build_pointer_type (DEFAULT_SIGNED_CHAR
5927 ? signed_char_type_node
5928 : unsigned_char_type_node);
5931 case FFECOM_f2ccodeFLOAT:
5932 *type = make_node (REAL_TYPE);
5933 TYPE_PRECISION (*type) = FLOAT_TYPE_SIZE;
5934 layout_type (*type);
5937 case FFECOM_f2ccodeDOUBLE:
5938 *type = make_node (REAL_TYPE);
5939 TYPE_PRECISION (*type) = DOUBLE_TYPE_SIZE;
5940 layout_type (*type);
5943 case FFECOM_f2ccodeLONGDOUBLE:
5944 *type = make_node (REAL_TYPE);
5945 TYPE_PRECISION (*type) = LONG_DOUBLE_TYPE_SIZE;
5946 layout_type (*type);
5949 case FFECOM_f2ccodeTWOREALS:
5950 *type = ffecom_make_complex_type_ (ffecom_f2c_real_type_node);
5953 case FFECOM_f2ccodeTWODOUBLEREALS:
5954 *type = ffecom_make_complex_type_ (ffecom_f2c_doublereal_type_node);
5958 assert ("unexpected FFECOM_f2ccodeXYZZY!" == NULL);
5959 *type = error_mark_node;
5963 pushdecl (build_decl (TYPE_DECL,
5964 ffecom_get_invented_identifier ("__g77_f2c_%s",
5970 #if FFECOM_targetCURRENT == FFECOM_targetGCC
5971 /* Set the f2c list-directed-I/O code for whatever (integral) type has the
5975 ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size,
5981 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
5982 if (((t = ffecom_tree_type[bt][j]) != NULL_TREE)
5983 && (TREE_INT_CST_LOW (TYPE_SIZE (t)) == size))
5985 assert (code != -1);
5986 ffecom_f2c_typecode_[bt][j] = code;
5992 /* Finish up globals after doing all program units in file
5994 Need to handle only uninitialized COMMON areas. */
5996 #if FFECOM_targetCURRENT == FFECOM_targetGCC
5998 ffecom_finish_global_ (ffeglobal global)
6004 if (ffeglobal_type (global) != FFEGLOBAL_typeCOMMON)
6007 if (ffeglobal_common_init (global))
6010 cbt = ffeglobal_hook (global);
6011 if ((cbt == NULL_TREE)
6012 || !ffeglobal_common_have_size (global))
6013 return global; /* No need to make common, never ref'd. */
6015 suspend_momentary ();
6017 DECL_EXTERNAL (cbt) = 0;
6019 /* Give the array a size now. */
6021 size = build_int_2 ((ffeglobal_common_size (global)
6022 + ffeglobal_common_pad (global)) - 1,
6025 cbtype = TREE_TYPE (cbt);
6026 TYPE_DOMAIN (cbtype) = build_range_type (integer_type_node,
6029 if (!TREE_TYPE (size))
6030 TREE_TYPE (size) = TYPE_DOMAIN (cbtype);
6031 layout_type (cbtype);
6033 cbt = start_decl (cbt, FALSE);
6034 assert (cbt == ffeglobal_hook (global));
6036 finish_decl (cbt, NULL_TREE, FALSE);
6042 /* Finish up any untransformed symbols. */
6044 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6046 ffecom_finish_symbol_transform_ (ffesymbol s)
6048 if ((s == NULL) || (TREE_CODE (current_function_decl) == ERROR_MARK))
6051 /* It's easy to know to transform an untransformed symbol, to make sure
6052 we put out debugging info for it. But COMMON variables, unlike
6053 EQUIVALENCE ones, aren't given declarations in addition to the
6054 tree expressions that specify offsets, because COMMON variables
6055 can be referenced in the outer scope where only dummy arguments
6056 (PARM_DECLs) should really be seen. To be safe, just don't do any
6057 VAR_DECLs for COMMON variables when we transform them for real
6058 use, and therefore we do all the VAR_DECL creating here. */
6060 if (ffesymbol_hook (s).decl_tree == NULL_TREE)
6062 if (ffesymbol_kind (s) != FFEINFO_kindNONE
6063 || (ffesymbol_where (s) != FFEINFO_whereNONE
6064 && ffesymbol_where (s) != FFEINFO_whereINTRINSIC
6065 && ffesymbol_where (s) != FFEINFO_whereDUMMY))
6066 /* Not transformed, and not CHARACTER*(*), and not a dummy
6067 argument, which can happen only if the entry point names
6068 it "rides in on" are all invalidated for other reasons. */
6069 s = ffecom_sym_transform_ (s);
6072 if ((ffesymbol_where (s) == FFEINFO_whereCOMMON)
6073 && (ffesymbol_hook (s).decl_tree != error_mark_node))
6075 #ifdef SOMEONE_GETS_DEBUG_SUPPORT_WORKING
6076 int yes = suspend_momentary ();
6078 /* This isn't working, at least for dbxout. The .s file looks
6079 okay to me (burley), but in gdb 4.9 at least, the variables
6080 appear to reside somewhere outside of the common area, so
6081 it doesn't make sense to mislead anyone by generating the info
6082 on those variables until this is fixed. NOTE: Same problem
6083 with EQUIVALENCE, sadly...see similar #if later. */
6084 ffecom_member_phase2_ (ffesymbol_storage (ffesymbol_common (s)),
6085 ffesymbol_storage (s));
6087 resume_momentary (yes);
6095 /* Append underscore(s) to name before calling get_identifier. "us"
6096 is nonzero if the name already contains an underscore and thus
6097 needs two underscores appended. */
6099 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6101 ffecom_get_appended_identifier_ (char us, const char *name)
6107 newname = xmalloc ((i = strlen (name)) + 1
6108 + ffe_is_underscoring ()
6110 memcpy (newname, name, i);
6112 newname[i + us] = '_';
6113 newname[i + 1 + us] = '\0';
6114 id = get_identifier (newname);
6122 /* Decide whether to append underscore to name before calling
6125 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6127 ffecom_get_external_identifier_ (ffesymbol s)
6130 const char *name = ffesymbol_text (s);
6132 /* If name is a built-in name, just return it as is. */
6134 if (!ffe_is_underscoring ()
6135 || (strcmp (name, FFETARGET_nameBLANK_COMMON) == 0)
6136 #if FFETARGET_isENFORCED_MAIN_NAME
6137 || (strcmp (name, FFETARGET_nameENFORCED_NAME) == 0)
6139 || (strcmp (name, FFETARGET_nameUNNAMED_MAIN) == 0)
6141 || (strcmp (name, FFETARGET_nameUNNAMED_BLOCK_DATA) == 0))
6142 return get_identifier (name);
6144 us = ffe_is_second_underscore ()
6145 ? (strchr (name, '_') != NULL)
6148 return ffecom_get_appended_identifier_ (us, name);
6152 /* Decide whether to append underscore to internal name before calling
6155 This is for non-external, top-function-context names only. Transform
6156 identifier so it doesn't conflict with the transformed result
6157 of using a _different_ external name. E.g. if "CALL FOO" is
6158 transformed into "FOO_();", then the variable in "FOO_ = 3"
6159 must be transformed into something that does not conflict, since
6160 these two things should be independent.
6162 The transformation is as follows. If the name does not contain
6163 an underscore, there is no possible conflict, so just return.
6164 If the name does contain an underscore, then transform it just
6165 like we transform an external identifier. */
6167 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6169 ffecom_get_identifier_ (const char *name)
6171 /* If name does not contain an underscore, just return it as is. */
6173 if (!ffe_is_underscoring ()
6174 || (strchr (name, '_') == NULL))
6175 return get_identifier (name);
6177 return ffecom_get_appended_identifier_ (ffe_is_second_underscore (),
6182 /* ffecom_gen_sfuncdef_ -- Generate definition of statement function
6185 ffesymbol s; // kindFUNCTION, whereIMMEDIATE.
6186 t = ffecom_gen_sfuncdef_(s,ffesymbol_basictype(s),
6187 ffesymbol_kindtype(s));
6189 Call after setting up containing function and getting trees for all
6192 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6194 ffecom_gen_sfuncdef_ (ffesymbol s, ffeinfoBasictype bt, ffeinfoKindtype kt)
6196 ffebld expr = ffesymbol_sfexpr (s);
6200 bool charfunc = (bt == FFEINFO_basictypeCHARACTER);
6201 static bool recurse = FALSE;
6203 int old_lineno = lineno;
6204 char *old_input_filename = input_filename;
6206 ffecom_nested_entry_ = s;
6208 /* For now, we don't have a handy pointer to where the sfunc is actually
6209 defined, though that should be easy to add to an ffesymbol. (The
6210 token/where info available might well point to the place where the type
6211 of the sfunc is declared, especially if that precedes the place where
6212 the sfunc itself is defined, which is typically the case.) We should
6213 put out a null pointer rather than point somewhere wrong, but I want to
6214 see how it works at this point. */
6216 input_filename = ffesymbol_where_filename (s);
6217 lineno = ffesymbol_where_filelinenum (s);
6219 /* Pretransform the expression so any newly discovered things belong to the
6220 outer program unit, not to the statement function. */
6222 ffecom_expr_transform_ (expr);
6224 /* Make sure no recursive invocation of this fn (a specific case of failing
6225 to pretransform an sfunc's expression, i.e. where its expression
6226 references another untransformed sfunc) happens. */
6231 yes = suspend_momentary ();
6233 push_f_function_context ();
6236 type = void_type_node;
6239 type = ffecom_tree_type[bt][kt];
6240 if (type == NULL_TREE)
6241 type = integer_type_node; /* _sym_exec_transition reports
6245 start_function (ffecom_get_identifier_ (ffesymbol_text (s)),
6246 build_function_type (type, NULL_TREE),
6247 1, /* nested/inline */
6248 0); /* TREE_PUBLIC */
6250 /* We don't worry about COMPLEX return values here, because this is
6251 entirely internal to our code, and gcc has the ability to return COMPLEX
6252 directly as a value. */
6254 yes = suspend_momentary ();
6257 { /* Prepend arg for where result goes. */
6260 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
6262 result = ffecom_get_invented_identifier ("__g77_%s",
6265 ffecom_char_enhance_arg_ (&type, s); /* Ignore returned length. */
6267 type = build_pointer_type (type);
6268 result = build_decl (PARM_DECL, result, type);
6270 push_parm_decl (result);
6273 result = NULL_TREE; /* Not ref'd if !charfunc. */
6275 ffecom_push_dummy_decls_ (ffesymbol_dummyargs (s), TRUE);
6277 resume_momentary (yes);
6279 store_parm_decls (0);
6281 ffecom_start_compstmt ();
6287 ffetargetCharacterSize sz = ffesymbol_size (s);
6290 result_length = build_int_2 (sz, 0);
6291 TREE_TYPE (result_length) = ffecom_f2c_ftnlen_type_node;
6293 ffecom_prepare_let_char_ (sz, expr);
6295 ffecom_prepare_end ();
6297 ffecom_let_char_ (result, result_length, sz, expr);
6298 expand_null_return ();
6302 ffecom_prepare_expr (expr);
6304 ffecom_prepare_end ();
6306 expand_return (ffecom_modify (NULL_TREE,
6307 DECL_RESULT (current_function_decl),
6308 ffecom_expr (expr)));
6314 ffecom_end_compstmt ();
6316 func = current_function_decl;
6317 finish_function (1);
6319 pop_f_function_context ();
6321 resume_momentary (yes);
6325 lineno = old_lineno;
6326 input_filename = old_input_filename;
6328 ffecom_nested_entry_ = NULL;
6335 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6337 ffecom_gfrt_args_ (ffecomGfrt ix)
6339 return ffecom_gfrt_argstring_[ix];
6343 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6345 ffecom_gfrt_tree_ (ffecomGfrt ix)
6347 if (ffecom_gfrt_[ix] == NULL_TREE)
6348 ffecom_make_gfrt_ (ix);
6350 return ffecom_1 (ADDR_EXPR,
6351 build_pointer_type (TREE_TYPE (ffecom_gfrt_[ix])),
6356 /* Return initialize-to-zero expression for this VAR_DECL. */
6358 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6360 ffecom_init_zero_ (tree decl)
6363 int incremental = TREE_STATIC (decl);
6364 tree type = TREE_TYPE (decl);
6368 int momentary = suspend_momentary ();
6369 push_obstacks_nochange ();
6370 if (TREE_PERMANENT (decl))
6371 end_temporary_allocation ();
6372 make_decl_rtl (decl, NULL, TREE_PUBLIC (decl) ? 1 : 0);
6373 assemble_variable (decl, TREE_PUBLIC (decl) ? 1 : 0, 0, 1);
6375 resume_momentary (momentary);
6380 if ((TREE_CODE (type) != ARRAY_TYPE)
6381 && (TREE_CODE (type) != RECORD_TYPE)
6382 && (TREE_CODE (type) != UNION_TYPE)
6384 init = convert (type, integer_zero_node);
6385 else if (!incremental)
6387 int momentary = suspend_momentary ();
6389 init = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
6390 TREE_CONSTANT (init) = 1;
6391 TREE_STATIC (init) = 1;
6393 resume_momentary (momentary);
6397 int momentary = suspend_momentary ();
6399 assemble_zeros (int_size_in_bytes (type));
6400 init = error_mark_node;
6402 resume_momentary (momentary);
6405 pop_momentary_nofree ();
6411 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6413 ffecom_intrinsic_ichar_ (tree tree_type, ffebld arg,
6419 switch (ffebld_op (arg))
6421 case FFEBLD_opCONTER: /* For F90, check 0-length. */
6422 if (ffetarget_length_character1
6423 (ffebld_constant_character1
6424 (ffebld_conter (arg))) == 0)
6426 *maybe_tree = integer_zero_node;
6427 return convert (tree_type, integer_zero_node);
6430 *maybe_tree = integer_one_node;
6431 expr_tree = build_int_2 (*ffetarget_text_character1
6432 (ffebld_constant_character1
6433 (ffebld_conter (arg))),
6435 TREE_TYPE (expr_tree) = tree_type;
6438 case FFEBLD_opSYMTER:
6439 case FFEBLD_opARRAYREF:
6440 case FFEBLD_opFUNCREF:
6441 case FFEBLD_opSUBSTR:
6442 ffecom_char_args_ (&expr_tree, &length_tree, arg);
6444 if ((expr_tree == error_mark_node)
6445 || (length_tree == error_mark_node))
6447 *maybe_tree = error_mark_node;
6448 return error_mark_node;
6451 if (integer_zerop (length_tree))
6453 *maybe_tree = integer_zero_node;
6454 return convert (tree_type, integer_zero_node);
6458 = ffecom_1 (INDIRECT_REF,
6459 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
6462 = ffecom_2 (ARRAY_REF,
6463 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
6466 expr_tree = convert (tree_type, expr_tree);
6468 if (TREE_CODE (length_tree) == INTEGER_CST)
6469 *maybe_tree = integer_one_node;
6470 else /* Must check length at run time. */
6472 = ffecom_truth_value
6473 (ffecom_2 (GT_EXPR, integer_type_node,
6475 ffecom_f2c_ftnlen_zero_node));
6478 case FFEBLD_opPAREN:
6479 case FFEBLD_opCONVERT:
6480 if (ffeinfo_size (ffebld_info (arg)) == 0)
6482 *maybe_tree = integer_zero_node;
6483 return convert (tree_type, integer_zero_node);
6485 return ffecom_intrinsic_ichar_ (tree_type, ffebld_left (arg),
6488 case FFEBLD_opCONCATENATE:
6495 expr_left = ffecom_intrinsic_ichar_ (tree_type, ffebld_left (arg),
6497 expr_right = ffecom_intrinsic_ichar_ (tree_type, ffebld_right (arg),
6499 *maybe_tree = ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
6502 expr_tree = ffecom_3 (COND_EXPR, tree_type,
6510 assert ("bad op in ICHAR" == NULL);
6511 return error_mark_node;
6516 /* ffecom_intrinsic_len_ -- Return length info for char arg (LEN())
6520 length_arg = ffecom_intrinsic_len_ (expr);
6522 Handles CHARACTER-type CONTER, SYMTER, SUBSTR, ARRAYREF, and FUNCREF
6523 subexpressions by constructing the appropriate tree for the
6524 length-of-character-text argument in a calling sequence. */
6526 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6528 ffecom_intrinsic_len_ (ffebld expr)
6530 ffetargetCharacter1 val;
6533 switch (ffebld_op (expr))
6535 case FFEBLD_opCONTER:
6536 val = ffebld_constant_character1 (ffebld_conter (expr));
6537 length = build_int_2 (ffetarget_length_character1 (val), 0);
6538 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6541 case FFEBLD_opSYMTER:
6543 ffesymbol s = ffebld_symter (expr);
6546 item = ffesymbol_hook (s).decl_tree;
6547 if (item == NULL_TREE)
6549 s = ffecom_sym_transform_ (s);
6550 item = ffesymbol_hook (s).decl_tree;
6552 if (ffesymbol_kind (s) == FFEINFO_kindENTITY)
6554 if (ffesymbol_size (s) == FFETARGET_charactersizeNONE)
6555 length = ffesymbol_hook (s).length_tree;
6558 length = build_int_2 (ffesymbol_size (s), 0);
6559 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6562 else if (item == error_mark_node)
6563 length = error_mark_node;
6564 else /* FFEINFO_kindFUNCTION: */
6569 case FFEBLD_opARRAYREF:
6570 length = ffecom_intrinsic_len_ (ffebld_left (expr));
6573 case FFEBLD_opSUBSTR:
6577 ffebld thing = ffebld_right (expr);
6581 assert (ffebld_op (thing) == FFEBLD_opITEM);
6582 start = ffebld_head (thing);
6583 thing = ffebld_trail (thing);
6584 assert (ffebld_trail (thing) == NULL);
6585 end = ffebld_head (thing);
6587 length = ffecom_intrinsic_len_ (ffebld_left (expr));
6589 if (length == error_mark_node)
6598 length = convert (ffecom_f2c_ftnlen_type_node,
6604 start_tree = convert (ffecom_f2c_ftnlen_type_node,
6605 ffecom_expr (start));
6607 if (start_tree == error_mark_node)
6609 length = error_mark_node;
6615 length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6616 ffecom_f2c_ftnlen_one_node,
6617 ffecom_2 (MINUS_EXPR,
6618 ffecom_f2c_ftnlen_type_node,
6624 end_tree = convert (ffecom_f2c_ftnlen_type_node,
6627 if (end_tree == error_mark_node)
6629 length = error_mark_node;
6633 length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6634 ffecom_f2c_ftnlen_one_node,
6635 ffecom_2 (MINUS_EXPR,
6636 ffecom_f2c_ftnlen_type_node,
6637 end_tree, start_tree));
6643 case FFEBLD_opCONCATENATE:
6645 = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6646 ffecom_intrinsic_len_ (ffebld_left (expr)),
6647 ffecom_intrinsic_len_ (ffebld_right (expr)));
6650 case FFEBLD_opFUNCREF:
6651 case FFEBLD_opCONVERT:
6652 length = build_int_2 (ffebld_size (expr), 0);
6653 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6657 assert ("bad op for single char arg expr" == NULL);
6658 length = ffecom_f2c_ftnlen_zero_node;
6662 assert (length != NULL_TREE);
6668 /* Handle CHARACTER assignments.
6670 Generates code to do the assignment. Used by ordinary assignment
6671 statement handler ffecom_let_stmt and by statement-function
6672 handler to generate code for a statement function. */
6674 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6676 ffecom_let_char_ (tree dest_tree, tree dest_length,
6677 ffetargetCharacterSize dest_size, ffebld source)
6679 ffecomConcatList_ catlist;
6684 if ((dest_tree == error_mark_node)
6685 || (dest_length == error_mark_node))
6688 assert (dest_tree != NULL_TREE);
6689 assert (dest_length != NULL_TREE);
6691 /* Source might be an opCONVERT, which just means it is a different size
6692 than the destination. Since the underlying implementation here handles
6693 that (directly or via the s_copy or s_cat run-time-library functions),
6694 we don't need the "convenience" of an opCONVERT that tells us to
6695 truncate or blank-pad, particularly since the resulting implementation
6696 would probably be slower than otherwise. */
6698 while (ffebld_op (source) == FFEBLD_opCONVERT)
6699 source = ffebld_left (source);
6701 catlist = ffecom_concat_list_new_ (source, dest_size);
6702 switch (ffecom_concat_list_count_ (catlist))
6704 case 0: /* Shouldn't happen, but in case it does... */
6705 ffecom_concat_list_kill_ (catlist);
6706 source_tree = null_pointer_node;
6707 source_length = ffecom_f2c_ftnlen_zero_node;
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 case 1: /* The (fairly) easy case. */
6723 ffecom_char_args_ (&source_tree, &source_length,
6724 ffecom_concat_list_expr_ (catlist, 0));
6725 ffecom_concat_list_kill_ (catlist);
6726 assert (source_tree != NULL_TREE);
6727 assert (source_length != NULL_TREE);
6729 if ((source_tree == error_mark_node)
6730 || (source_length == error_mark_node))
6736 = ffecom_1 (INDIRECT_REF,
6737 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6741 = ffecom_2 (ARRAY_REF,
6742 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6747 = ffecom_1 (INDIRECT_REF,
6748 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6752 = ffecom_2 (ARRAY_REF,
6753 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6758 expr_tree = ffecom_modify (void_type_node, dest_tree, source_tree);
6760 expand_expr_stmt (expr_tree);
6765 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6766 TREE_CHAIN (expr_tree) = build_tree_list (NULL_TREE, source_tree);
6767 TREE_CHAIN (TREE_CHAIN (expr_tree))
6768 = build_tree_list (NULL_TREE, dest_length);
6769 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6770 = build_tree_list (NULL_TREE, source_length);
6772 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCOPY, expr_tree, NULL_TREE);
6773 TREE_SIDE_EFFECTS (expr_tree) = 1;
6775 expand_expr_stmt (expr_tree);
6779 default: /* Must actually concatenate things. */
6783 /* Heavy-duty concatenation. */
6786 int count = ffecom_concat_list_count_ (catlist);
6798 = ffecom_push_tempvar (ffecom_f2c_ftnlen_type_node,
6799 FFETARGET_charactersizeNONE, count, TRUE);
6800 item_array = items = ffecom_push_tempvar (ffecom_f2c_address_type_node,
6801 FFETARGET_charactersizeNONE,
6807 hook = ffebld_nonter_hook (source);
6809 assert (TREE_CODE (hook) == TREE_VEC);
6810 assert (TREE_VEC_LENGTH (hook) == 2);
6811 length_array = lengths = TREE_VEC_ELT (hook, 0);
6812 item_array = items = TREE_VEC_ELT (hook, 1);
6816 for (i = 0; i < count; ++i)
6818 ffecom_char_args_ (&citem, &clength,
6819 ffecom_concat_list_expr_ (catlist, i));
6820 if ((citem == error_mark_node)
6821 || (clength == error_mark_node))
6823 ffecom_concat_list_kill_ (catlist);
6828 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (items),
6829 ffecom_modify (void_type_node,
6830 ffecom_2 (ARRAY_REF,
6831 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array))),
6833 build_int_2 (i, 0)),
6837 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (lengths),
6838 ffecom_modify (void_type_node,
6839 ffecom_2 (ARRAY_REF,
6840 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array))),
6842 build_int_2 (i, 0)),
6847 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6848 TREE_CHAIN (expr_tree)
6849 = build_tree_list (NULL_TREE,
6850 ffecom_1 (ADDR_EXPR,
6851 build_pointer_type (TREE_TYPE (items)),
6853 TREE_CHAIN (TREE_CHAIN (expr_tree))
6854 = build_tree_list (NULL_TREE,
6855 ffecom_1 (ADDR_EXPR,
6856 build_pointer_type (TREE_TYPE (lengths)),
6858 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6861 ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
6862 convert (ffecom_f2c_ftnlen_type_node,
6863 build_int_2 (count, 0))));
6864 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree))))
6865 = build_tree_list (NULL_TREE, dest_length);
6867 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCAT, expr_tree, NULL_TREE);
6868 TREE_SIDE_EFFECTS (expr_tree) = 1;
6870 expand_expr_stmt (expr_tree);
6873 ffecom_concat_list_kill_ (catlist);
6877 /* ffecom_make_gfrt_ -- Make initial info for run-time routine
6880 ffecom_make_gfrt_(ix);
6882 Assumes gfrt_[ix] is NULL_TREE, and replaces it with the FUNCTION_DECL
6883 for the indicated run-time routine (ix). */
6885 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6887 ffecom_make_gfrt_ (ffecomGfrt ix)
6892 push_obstacks_nochange ();
6893 end_temporary_allocation ();
6895 switch (ffecom_gfrt_type_[ix])
6897 case FFECOM_rttypeVOID_:
6898 ttype = void_type_node;
6901 case FFECOM_rttypeVOIDSTAR_:
6902 ttype = TREE_TYPE (null_pointer_node); /* `void *'. */
6905 case FFECOM_rttypeFTNINT_:
6906 ttype = ffecom_f2c_ftnint_type_node;
6909 case FFECOM_rttypeINTEGER_:
6910 ttype = ffecom_f2c_integer_type_node;
6913 case FFECOM_rttypeLONGINT_:
6914 ttype = ffecom_f2c_longint_type_node;
6917 case FFECOM_rttypeLOGICAL_:
6918 ttype = ffecom_f2c_logical_type_node;
6921 case FFECOM_rttypeREAL_F2C_:
6922 ttype = double_type_node;
6925 case FFECOM_rttypeREAL_GNU_:
6926 ttype = float_type_node;
6929 case FFECOM_rttypeCOMPLEX_F2C_:
6930 ttype = void_type_node;
6933 case FFECOM_rttypeCOMPLEX_GNU_:
6934 ttype = ffecom_f2c_complex_type_node;
6937 case FFECOM_rttypeDOUBLE_:
6938 ttype = double_type_node;
6941 case FFECOM_rttypeDOUBLEREAL_:
6942 ttype = ffecom_f2c_doublereal_type_node;
6945 case FFECOM_rttypeDBLCMPLX_F2C_:
6946 ttype = void_type_node;
6949 case FFECOM_rttypeDBLCMPLX_GNU_:
6950 ttype = ffecom_f2c_doublecomplex_type_node;
6953 case FFECOM_rttypeCHARACTER_:
6954 ttype = void_type_node;
6959 assert ("bad rttype" == NULL);
6963 ttype = build_function_type (ttype, NULL_TREE);
6964 t = build_decl (FUNCTION_DECL,
6965 get_identifier (ffecom_gfrt_name_[ix]),
6967 DECL_EXTERNAL (t) = 1;
6968 TREE_PUBLIC (t) = 1;
6969 TREE_THIS_VOLATILE (t) = ffecom_gfrt_volatile_[ix] ? 1 : 0;
6971 t = start_decl (t, TRUE);
6973 finish_decl (t, NULL_TREE, TRUE);
6975 resume_temporary_allocation ();
6978 ffecom_gfrt_[ix] = t;
6982 /* Phase 1 pass over each member of a COMMON/EQUIVALENCE group. */
6984 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6986 ffecom_member_phase1_ (ffestorag mst UNUSED, ffestorag st)
6988 ffesymbol s = ffestorag_symbol (st);
6990 if (ffesymbol_namelisted (s))
6991 ffecom_member_namelisted_ = TRUE;
6995 /* Phase 2 pass over each member of a COMMON/EQUIVALENCE group. Declare
6996 the member so debugger will see it. Otherwise nobody should be
6997 referencing the member. */
6999 #if FFECOM_targetCURRENT == FFECOM_targetGCC
7000 #ifdef SOMEONE_GETS_DEBUG_SUPPORT_WORKING
7002 ffecom_member_phase2_ (ffestorag mst, ffestorag st)
7010 || ((mt = ffestorag_hook (mst)) == NULL)
7011 || (mt == error_mark_node))
7015 || ((s = ffestorag_symbol (st)) == NULL))
7018 type = ffecom_type_localvar_ (s,
7019 ffesymbol_basictype (s),
7020 ffesymbol_kindtype (s));
7021 if (type == error_mark_node)
7024 t = build_decl (VAR_DECL,
7025 ffecom_get_identifier_ (ffesymbol_text (s)),
7028 TREE_STATIC (t) = TREE_STATIC (mt);
7029 DECL_INITIAL (t) = NULL_TREE;
7030 TREE_ASM_WRITTEN (t) = 1;
7033 = gen_rtx (MEM, TYPE_MODE (type),
7034 plus_constant (XEXP (DECL_RTL (mt), 0),
7035 ffestorag_modulo (mst)
7036 + ffestorag_offset (st)
7037 - ffestorag_offset (mst)));
7039 t = start_decl (t, FALSE);
7041 finish_decl (t, NULL_TREE, FALSE);
7046 /* Prepare source expression for assignment into a destination perhaps known
7047 to be of a specific size. */
7050 ffecom_prepare_let_char_ (ffetargetCharacterSize dest_size, ffebld source)
7052 ffecomConcatList_ catlist;
7057 tree tempvar = NULL_TREE;
7059 while (ffebld_op (source) == FFEBLD_opCONVERT)
7060 source = ffebld_left (source);
7062 catlist = ffecom_concat_list_new_ (source, dest_size);
7063 count = ffecom_concat_list_count_ (catlist);
7068 = ffecom_make_tempvar ("let_char_len", ffecom_f2c_ftnlen_type_node,
7069 FFETARGET_charactersizeNONE, count);
7071 = ffecom_make_tempvar ("let_char_item", ffecom_f2c_address_type_node,
7072 FFETARGET_charactersizeNONE, count);
7074 tempvar = make_tree_vec (2);
7075 TREE_VEC_ELT (tempvar, 0) = ltmp;
7076 TREE_VEC_ELT (tempvar, 1) = itmp;
7079 for (i = 0; i < count; ++i)
7080 ffecom_prepare_arg_ptr_to_expr (ffecom_concat_list_expr_ (catlist, i));
7082 ffecom_concat_list_kill_ (catlist);
7086 ffebld_nonter_set_hook (source, tempvar);
7087 current_binding_level->prep_state = 1;
7091 /* ffecom_push_dummy_decls_ -- Transform dummy args, push parm decls in order
7093 Ignores STAR (alternate-return) dummies. All other get exec-transitioned
7094 (which generates their trees) and then their trees get push_parm_decl'd.
7096 The second arg is TRUE if the dummies are for a statement function, in
7097 which case lengths are not pushed for character arguments (since they are
7098 always known by both the caller and the callee, though the code allows
7099 for someday permitting CHAR*(*) stmtfunc dummies). */
7101 #if FFECOM_targetCURRENT == FFECOM_targetGCC
7103 ffecom_push_dummy_decls_ (ffebld dummy_list, bool stmtfunc)
7110 ffecom_transform_only_dummies_ = TRUE;
7112 /* First push the parms corresponding to actual dummy "contents". */
7114 for (dumlist = dummy_list; dumlist != NULL; dumlist = ffebld_trail (dumlist))
7116 dummy = ffebld_head (dumlist);
7117 switch (ffebld_op (dummy))
7121 continue; /* Forget alternate returns. */
7126 assert (ffebld_op (dummy) == FFEBLD_opSYMTER);
7127 s = ffebld_symter (dummy);
7128 parm = ffesymbol_hook (s).decl_tree;
7129 if (parm == NULL_TREE)
7131 s = ffecom_sym_transform_ (s);
7132 parm = ffesymbol_hook (s).decl_tree;
7133 assert (parm != NULL_TREE);
7135 if (parm != error_mark_node)
7136 push_parm_decl (parm);
7139 /* Then, for CHARACTER dummies, push the parms giving their lengths. */
7141 for (dumlist = dummy_list; dumlist != NULL; dumlist = ffebld_trail (dumlist))
7143 dummy = ffebld_head (dumlist);
7144 switch (ffebld_op (dummy))
7148 continue; /* Forget alternate returns, they mean
7154 s = ffebld_symter (dummy);
7155 if (ffesymbol_basictype (s) != FFEINFO_basictypeCHARACTER)
7156 continue; /* Only looking for CHARACTER arguments. */
7157 if (stmtfunc && (ffesymbol_size (s) != FFETARGET_charactersizeNONE))
7158 continue; /* Stmtfunc arg with known size needs no
7160 if (ffesymbol_kind (s) != FFEINFO_kindENTITY)
7161 continue; /* Only looking for variables and arrays. */
7162 parm = ffesymbol_hook (s).length_tree;
7163 assert (parm != NULL_TREE);
7164 if (parm != error_mark_node)
7165 push_parm_decl (parm);
7168 ffecom_transform_only_dummies_ = FALSE;
7172 /* ffecom_start_progunit_ -- Beginning of program unit
7174 Does GNU back end stuff necessary to teach it about the start of its
7175 equivalent of a Fortran program unit. */
7177 #if FFECOM_targetCURRENT == FFECOM_targetGCC
7179 ffecom_start_progunit_ ()
7181 ffesymbol fn = ffecom_primary_entry_;
7183 tree id; /* Identifier (name) of function. */
7184 tree type; /* Type of function. */
7185 tree result; /* Result of function. */
7186 ffeinfoBasictype bt;
7190 ffeglobalType egt = FFEGLOBAL_type;
7193 bool altentries = (ffecom_num_entrypoints_ != 0);
7196 && (ffecom_primary_entry_kind_ == FFEINFO_kindFUNCTION)
7197 && (ffecom_master_bt_ == FFEINFO_basictypeNONE);
7198 bool main_program = FALSE;
7199 int old_lineno = lineno;
7200 char *old_input_filename = input_filename;
7203 assert (fn != NULL);
7204 assert (ffesymbol_hook (fn).decl_tree == NULL_TREE);
7206 input_filename = ffesymbol_where_filename (fn);
7207 lineno = ffesymbol_where_filelinenum (fn);
7209 /* c-parse.y indeed does call suspend_momentary and not only ignores the
7210 return value, but also never calls resume_momentary, when starting an
7211 outer function (see "fndef:", "setspecs:", and so on). So g77 does the
7212 same thing. It shouldn't be a problem since start_function calls
7213 temporary_allocation, but it might be necessary. If it causes a problem
7214 here, then maybe there's a bug lurking in gcc. NOTE: This identical
7215 comment appears twice in thist file. */
7217 suspend_momentary ();
7219 switch (ffecom_primary_entry_kind_)
7221 case FFEINFO_kindPROGRAM:
7222 main_program = TRUE;
7223 gt = FFEGLOBAL_typeMAIN;
7224 bt = FFEINFO_basictypeNONE;
7225 kt = FFEINFO_kindtypeNONE;
7226 type = ffecom_tree_fun_type_void;
7231 case FFEINFO_kindBLOCKDATA:
7232 gt = FFEGLOBAL_typeBDATA;
7233 bt = FFEINFO_basictypeNONE;
7234 kt = FFEINFO_kindtypeNONE;
7235 type = ffecom_tree_fun_type_void;
7240 case FFEINFO_kindFUNCTION:
7241 gt = FFEGLOBAL_typeFUNC;
7242 egt = FFEGLOBAL_typeEXT;
7243 bt = ffesymbol_basictype (fn);
7244 kt = ffesymbol_kindtype (fn);
7245 if (bt == FFEINFO_basictypeNONE)
7247 ffeimplic_establish_symbol (fn);
7248 if (ffesymbol_funcresult (fn) != NULL)
7249 ffeimplic_establish_symbol (ffesymbol_funcresult (fn));
7250 bt = ffesymbol_basictype (fn);
7251 kt = ffesymbol_kindtype (fn);
7255 charfunc = cmplxfunc = FALSE;
7256 else if (bt == FFEINFO_basictypeCHARACTER)
7257 charfunc = TRUE, cmplxfunc = FALSE;
7258 else if ((bt == FFEINFO_basictypeCOMPLEX)
7259 && ffesymbol_is_f2c (fn)
7261 charfunc = FALSE, cmplxfunc = TRUE;
7263 charfunc = cmplxfunc = FALSE;
7265 if (multi || charfunc)
7266 type = ffecom_tree_fun_type_void;
7267 else if (ffesymbol_is_f2c (fn) && !altentries)
7268 type = ffecom_tree_fun_type[bt][kt];
7270 type = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
7272 if ((type == NULL_TREE)
7273 || (TREE_TYPE (type) == NULL_TREE))
7274 type = ffecom_tree_fun_type_void; /* _sym_exec_transition. */
7277 case FFEINFO_kindSUBROUTINE:
7278 gt = FFEGLOBAL_typeSUBR;
7279 egt = FFEGLOBAL_typeEXT;
7280 bt = FFEINFO_basictypeNONE;
7281 kt = FFEINFO_kindtypeNONE;
7282 if (ffecom_is_altreturning_)
7283 type = ffecom_tree_subr_type;
7285 type = ffecom_tree_fun_type_void;
7291 assert ("say what??" == NULL);
7293 case FFEINFO_kindANY:
7294 gt = FFEGLOBAL_typeANY;
7295 bt = FFEINFO_basictypeNONE;
7296 kt = FFEINFO_kindtypeNONE;
7297 type = error_mark_node;
7305 id = ffecom_get_invented_identifier ("__g77_masterfun_%s",
7306 ffesymbol_text (fn),
7309 #if FFETARGET_isENFORCED_MAIN
7310 else if (main_program)
7311 id = get_identifier (FFETARGET_nameENFORCED_MAIN_NAME);
7314 id = ffecom_get_external_identifier_ (fn);
7318 0, /* nested/inline */
7319 !altentries); /* TREE_PUBLIC */
7321 TREE_USED (current_function_decl) = 1; /* Avoid spurious warning if altentries. */
7324 && ((g = ffesymbol_global (fn)) != NULL)
7325 && ((ffeglobal_type (g) == gt)
7326 || (ffeglobal_type (g) == egt)))
7328 ffeglobal_set_hook (g, current_function_decl);
7331 yes = suspend_momentary ();
7333 /* Arg handling needs exec-transitioned ffesymbols to work with. But
7334 exec-transitioning needs current_function_decl to be filled in. So we
7335 do these things in two phases. */
7338 { /* 1st arg identifies which entrypoint. */
7339 ffecom_which_entrypoint_decl_
7340 = build_decl (PARM_DECL,
7341 ffecom_get_invented_identifier ("__g77_%s",
7345 push_parm_decl (ffecom_which_entrypoint_decl_);
7351 { /* Arg for result (return value). */
7356 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
7358 type = ffecom_tree_type[FFEINFO_basictypeCOMPLEX][kt];
7360 type = ffecom_multi_type_node_;
7362 result = ffecom_get_invented_identifier ("__g77_%s",
7365 /* Make length arg _and_ enhance type info for CHAR arg itself. */
7368 length = ffecom_char_enhance_arg_ (&type, fn);
7370 length = NULL_TREE; /* Not ref'd if !charfunc. */
7372 type = build_pointer_type (type);
7373 result = build_decl (PARM_DECL, result, type);
7375 push_parm_decl (result);
7377 ffecom_multi_retval_ = result;
7379 ffecom_func_result_ = result;
7383 push_parm_decl (length);
7384 ffecom_func_length_ = length;
7388 if (ffecom_primary_entry_is_proc_)
7391 arglist = ffecom_master_arglist_;
7393 arglist = ffesymbol_dummyargs (fn);
7394 ffecom_push_dummy_decls_ (arglist, FALSE);
7397 resume_momentary (yes);
7399 if (TREE_CODE (current_function_decl) != ERROR_MARK)
7400 store_parm_decls (main_program ? 1 : 0);
7402 ffecom_start_compstmt ();
7403 /* Disallow temp vars at this level. */
7404 current_binding_level->prep_state = 2;
7406 lineno = old_lineno;
7407 input_filename = old_input_filename;
7409 /* This handles any symbols still untransformed, in case -g specified.
7410 This used to be done in ffecom_finish_progunit, but it turns out to
7411 be necessary to do it here so that statement functions are
7412 expanded before code. But don't bother for BLOCK DATA. */
7414 if (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA)
7415 ffesymbol_drive (ffecom_finish_symbol_transform_);
7419 /* ffecom_sym_transform_ -- Transform FFE sym into backend sym
7422 ffecom_sym_transform_(s);
7424 The ffesymbol_hook info for s is updated with appropriate backend info
7427 #if FFECOM_targetCURRENT == FFECOM_targetGCC
7429 ffecom_sym_transform_ (ffesymbol s)
7431 tree t; /* Transformed thingy. */
7432 tree tlen; /* Length if CHAR*(*). */
7433 bool addr; /* Is t the address of the thingy? */
7434 ffeinfoBasictype bt;
7438 int old_lineno = lineno;
7439 char *old_input_filename = input_filename;
7441 /* Must ensure special ASSIGN variables are declared at top of outermost
7442 block, else they'll end up in the innermost block when their first
7443 ASSIGN is seen, which leaves them out of scope when they're the
7444 subject of a GOTO or I/O statement.
7446 We make this variable even if -fugly-assign. Just let it go unused,
7447 in case it turns out there are cases where we really want to use this
7448 variable anyway (e.g. ASSIGN to INTEGER*2 variable). */
7450 if (! ffecom_transform_only_dummies_
7451 && ffesymbol_assigned (s)
7452 && ! ffesymbol_hook (s).assign_tree)
7453 s = ffecom_sym_transform_assign_ (s);
7455 if (ffesymbol_sfdummyparent (s) == NULL)
7457 input_filename = ffesymbol_where_filename (s);
7458 lineno = ffesymbol_where_filelinenum (s);
7462 ffesymbol sf = ffesymbol_sfdummyparent (s);
7464 input_filename = ffesymbol_where_filename (sf);
7465 lineno = ffesymbol_where_filelinenum (sf);
7468 bt = ffeinfo_basictype (ffebld_info (s));
7469 kt = ffeinfo_kindtype (ffebld_info (s));
7475 switch (ffesymbol_kind (s))
7477 case FFEINFO_kindNONE:
7478 switch (ffesymbol_where (s))
7480 case FFEINFO_whereDUMMY: /* Subroutine or function. */
7481 assert (ffecom_transform_only_dummies_);
7483 /* Before 0.4, this could be ENTITY/DUMMY, but see
7484 ffestu_sym_end_transition -- no longer true (in particular, if
7485 it could be an ENTITY, it _will_ be made one, so that
7486 possibility won't come through here). So we never make length
7487 arg for CHARACTER type. */
7489 t = build_decl (PARM_DECL,
7490 ffecom_get_identifier_ (ffesymbol_text (s)),
7491 ffecom_tree_ptr_to_subr_type);
7493 DECL_ARTIFICIAL (t) = 1;
7498 case FFEINFO_whereGLOBAL: /* Subroutine or function. */
7499 assert (!ffecom_transform_only_dummies_);
7501 if (((g = ffesymbol_global (s)) != NULL)
7502 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
7503 || (ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
7504 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
7505 && (ffeglobal_hook (g) != NULL_TREE)
7506 && ffe_is_globals ())
7508 t = ffeglobal_hook (g);
7512 push_obstacks_nochange ();
7513 end_temporary_allocation ();
7515 t = build_decl (FUNCTION_DECL,
7516 ffecom_get_external_identifier_ (s),
7517 ffecom_tree_subr_type); /* Assume subr. */
7518 DECL_EXTERNAL (t) = 1;
7519 TREE_PUBLIC (t) = 1;
7521 t = start_decl (t, FALSE);
7522 finish_decl (t, NULL_TREE, FALSE);
7525 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
7526 || (ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
7527 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
7528 ffeglobal_set_hook (g, t);
7530 resume_temporary_allocation ();
7536 assert ("NONE where unexpected" == NULL);
7538 case FFEINFO_whereANY:
7543 case FFEINFO_kindENTITY:
7544 switch (ffeinfo_where (ffesymbol_info (s)))
7547 case FFEINFO_whereCONSTANT:
7548 /* ~~Debugging info needed? */
7549 assert (!ffecom_transform_only_dummies_);
7550 t = error_mark_node; /* Shouldn't ever see this in expr. */
7553 case FFEINFO_whereLOCAL:
7554 assert (!ffecom_transform_only_dummies_);
7557 ffestorag st = ffesymbol_storage (s);
7561 && (ffestorag_size (st) == 0))
7563 t = error_mark_node;
7567 yes = suspend_momentary ();
7568 type = ffecom_type_localvar_ (s, bt, kt);
7569 resume_momentary (yes);
7571 if (type == error_mark_node)
7573 t = error_mark_node;
7578 && (ffestorag_parent (st) != NULL))
7579 { /* Child of EQUIVALENCE parent. */
7583 ffetargetOffset offset;
7585 est = ffestorag_parent (st);
7586 ffecom_transform_equiv_ (est);
7588 et = ffestorag_hook (est);
7589 assert (et != NULL_TREE);
7591 if (! TREE_STATIC (et))
7592 put_var_into_stack (et);
7594 yes = suspend_momentary ();
7596 offset = ffestorag_modulo (est)
7597 + ffestorag_offset (ffesymbol_storage (s))
7598 - ffestorag_offset (est);
7600 ffecom_debug_kludge_ (et, "EQUIVALENCE", s, type, offset);
7602 /* (t_type *) (((char *) &et) + offset) */
7604 t = convert (string_type_node, /* (char *) */
7605 ffecom_1 (ADDR_EXPR,
7606 build_pointer_type (TREE_TYPE (et)),
7608 t = ffecom_2 (PLUS_EXPR, TREE_TYPE (t),
7610 build_int_2 (offset, 0));
7611 t = convert (build_pointer_type (type),
7613 TREE_CONSTANT (t) = staticp (et);
7617 resume_momentary (yes);
7622 bool init = ffesymbol_is_init (s);
7624 yes = suspend_momentary ();
7626 t = build_decl (VAR_DECL,
7627 ffecom_get_identifier_ (ffesymbol_text (s)),
7631 || ffesymbol_namelisted (s)
7632 #ifdef FFECOM_sizeMAXSTACKITEM
7634 && (ffestorag_size (st) > FFECOM_sizeMAXSTACKITEM))
7636 || ((ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
7637 && (ffecom_primary_entry_kind_
7638 != FFEINFO_kindBLOCKDATA)
7639 && (ffesymbol_is_save (s) || ffe_is_saveall ())))
7640 TREE_STATIC (t) = !ffesymbol_attr (s, FFESYMBOL_attrADJUSTABLE);
7642 TREE_STATIC (t) = 0; /* No need to make static. */
7644 if (init || ffe_is_init_local_zero ())
7645 DECL_INITIAL (t) = error_mark_node;
7647 /* Keep -Wunused from complaining about var if it
7648 is used as sfunc arg or DATA implied-DO. */
7649 if (ffesymbol_attrs (s) & FFESYMBOL_attrsSFARG)
7650 DECL_IN_SYSTEM_HEADER (t) = 1;
7652 t = start_decl (t, FALSE);
7656 if (ffesymbol_init (s) != NULL)
7657 initexpr = ffecom_expr (ffesymbol_init (s));
7659 initexpr = ffecom_init_zero_ (t);
7661 else if (ffe_is_init_local_zero ())
7662 initexpr = ffecom_init_zero_ (t);
7664 initexpr = NULL_TREE; /* Not ref'd if !init. */
7666 finish_decl (t, initexpr, FALSE);
7668 if ((st != NULL) && (DECL_SIZE (t) != error_mark_node))
7672 size_tree = size_binop (CEIL_DIV_EXPR,
7674 size_int (BITS_PER_UNIT));
7675 assert (TREE_INT_CST_HIGH (size_tree) == 0);
7676 assert (TREE_INT_CST_LOW (size_tree) == ffestorag_size (st));
7679 resume_momentary (yes);
7684 case FFEINFO_whereRESULT:
7685 assert (!ffecom_transform_only_dummies_);
7687 if (bt == FFEINFO_basictypeCHARACTER)
7688 { /* Result is already in list of dummies, use
7690 t = ffecom_func_result_;
7691 tlen = ffecom_func_length_;
7695 if ((ffecom_num_entrypoints_ == 0)
7696 && (bt == FFEINFO_basictypeCOMPLEX)
7697 && (ffesymbol_is_f2c (ffecom_primary_entry_)))
7698 { /* Result is already in list of dummies, use
7700 t = ffecom_func_result_;
7704 if (ffecom_func_result_ != NULL_TREE)
7706 t = ffecom_func_result_;
7709 if ((ffecom_num_entrypoints_ != 0)
7710 && (ffecom_master_bt_ == FFEINFO_basictypeNONE))
7712 yes = suspend_momentary ();
7714 assert (ffecom_multi_retval_ != NULL_TREE);
7715 t = ffecom_1 (INDIRECT_REF, ffecom_multi_type_node_,
7716 ffecom_multi_retval_);
7717 t = ffecom_2 (COMPONENT_REF, ffecom_tree_type[bt][kt],
7718 t, ffecom_multi_fields_[bt][kt]);
7720 resume_momentary (yes);
7724 yes = suspend_momentary ();
7726 t = build_decl (VAR_DECL,
7727 ffecom_get_identifier_ (ffesymbol_text (s)),
7728 ffecom_tree_type[bt][kt]);
7729 TREE_STATIC (t) = 0; /* Put result on stack. */
7730 t = start_decl (t, FALSE);
7731 finish_decl (t, NULL_TREE, FALSE);
7733 ffecom_func_result_ = t;
7735 resume_momentary (yes);
7738 case FFEINFO_whereDUMMY:
7746 bool adjustable = FALSE; /* Conditionally adjustable? */
7748 type = ffecom_tree_type[bt][kt];
7749 if (ffesymbol_sfdummyparent (s) != NULL)
7751 if (current_function_decl == ffecom_outer_function_decl_)
7752 { /* Exec transition before sfunc
7753 context; get it later. */
7756 t = ffecom_get_identifier_ (ffesymbol_text
7757 (ffesymbol_sfdummyparent (s)));
7760 t = ffecom_get_identifier_ (ffesymbol_text (s));
7762 assert (ffecom_transform_only_dummies_);
7764 old_sizes = get_pending_sizes ();
7765 put_pending_sizes (old_sizes);
7767 if (bt == FFEINFO_basictypeCHARACTER)
7768 tlen = ffecom_char_enhance_arg_ (&type, s);
7769 type = ffecom_check_size_overflow_ (s, type, TRUE);
7771 for (dl = ffesymbol_dims (s); dl != NULL; dl = ffebld_trail (dl))
7773 if (type == error_mark_node)
7776 dim = ffebld_head (dl);
7777 assert (ffebld_op (dim) == FFEBLD_opBOUNDS);
7778 if ((ffebld_left (dim) == NULL) || ffecom_doing_entry_)
7779 low = ffecom_integer_one_node;
7781 low = ffecom_expr (ffebld_left (dim));
7782 assert (ffebld_right (dim) != NULL);
7783 if ((ffebld_op (ffebld_right (dim)) == FFEBLD_opSTAR)
7784 || ffecom_doing_entry_)
7786 /* Used to just do high=low. But for ffecom_tree_
7787 canonize_ref_, it probably is important to correctly
7788 assess the size. E.g. given COMPLEX C(*),CFUNC and
7789 C(2)=CFUNC(C), overlap can happen, while it can't
7790 for, say, C(1)=CFUNC(C(2)). */
7791 /* Even more recently used to set to INT_MAX, but that
7792 broke when some overflow checking went into the back
7793 end. Now we just leave the upper bound unspecified. */
7797 high = ffecom_expr (ffebld_right (dim));
7799 /* Determine whether array is conditionally adjustable,
7800 to decide whether back-end magic is needed.
7802 Normally the front end uses the back-end function
7803 variable_size to wrap SAVE_EXPR's around expressions
7804 affecting the size/shape of an array so that the
7805 size/shape info doesn't change during execution
7806 of the compiled code even though variables and
7807 functions referenced in those expressions might.
7809 variable_size also makes sure those saved expressions
7810 get evaluated immediately upon entry to the
7811 compiled procedure -- the front end normally doesn't
7812 have to worry about that.
7814 However, there is a problem with this that affects
7815 g77's implementation of entry points, and that is
7816 that it is _not_ true that each invocation of the
7817 compiled procedure is permitted to evaluate
7818 array size/shape info -- because it is possible
7819 that, for some invocations, that info is invalid (in
7820 which case it is "promised" -- i.e. a violation of
7821 the Fortran standard -- that the compiled code
7822 won't reference the array or its size/shape
7823 during that particular invocation).
7825 To phrase this in C terms, consider this gcc function:
7827 void foo (int *n, float (*a)[*n])
7829 // a is "pointer to array ...", fyi.
7832 Suppose that, for some invocations, it is permitted
7833 for a caller of foo to do this:
7837 Now the _written_ code for foo can take such a call
7838 into account by either testing explicitly for whether
7839 (a == NULL) || (n == NULL) -- presumably it is
7840 not permitted to reference *a in various fashions
7841 if (n == NULL) I suppose -- or it can avoid it by
7842 looking at other info (other arguments, static/global
7845 However, this won't work in gcc 2.5.8 because it'll
7846 automatically emit the code to save the "*n"
7847 expression, which'll yield a NULL dereference for
7848 the "foo (NULL, NULL)" call, something the code
7849 for foo cannot prevent.
7851 g77 definitely needs to avoid executing such
7852 code anytime the pointer to the adjustable array
7853 is NULL, because even if its bounds expressions
7854 don't have any references to possible "absent"
7855 variables like "*n" -- say all variable references
7856 are to COMMON variables, i.e. global (though in C,
7857 local static could actually make sense) -- the
7858 expressions could yield other run-time problems
7859 for allowably "dead" values in those variables.
7861 For example, let's consider a more complicated
7867 void foo (float (*a)[i/j])
7872 The above is (essentially) quite valid for Fortran
7873 but, again, for a call like "foo (NULL);", it is
7874 permitted for i and j to be undefined when the
7875 call is made. If j happened to be zero, for
7876 example, emitting the code to evaluate "i/j"
7877 could result in a run-time error.
7879 Offhand, though I don't have my F77 or F90
7880 standards handy, it might even be valid for a
7881 bounds expression to contain a function reference,
7882 in which case I doubt it is permitted for an
7883 implementation to invoke that function in the
7884 Fortran case involved here (invocation of an
7885 alternate ENTRY point that doesn't have the adjustable
7886 array as one of its arguments).
7888 So, the code that the compiler would normally emit
7889 to preevaluate the size/shape info for an
7890 adjustable array _must not_ be executed at run time
7891 in certain cases. Specifically, for Fortran,
7892 the case is when the pointer to the adjustable
7893 array == NULL. (For gnu-ish C, it might be nice
7894 for the source code itself to specify an expression
7895 that, if TRUE, inhibits execution of the code. Or
7896 reverse the sense for elegance.)
7898 (Note that g77 could use a different test than NULL,
7899 actually, since it happens to always pass an
7900 integer to the called function that specifies which
7901 entry point is being invoked. Hmm, this might
7902 solve the next problem.)
7904 One way a user could, I suppose, write "foo" so
7905 it works is to insert COND_EXPR's for the
7906 size/shape info so the dangerous stuff isn't
7907 actually done, as in:
7909 void foo (int *n, float (*a)[(a == NULL) ? 0 : *n])
7914 The next problem is that the front end needs to
7915 be able to tell the back end about the array's
7916 decl _before_ it tells it about the conditional
7917 expression to inhibit evaluation of size/shape info,
7920 To solve this, the front end needs to be able
7921 to give the back end the expression to inhibit
7922 generation of the preevaluation code _after_
7923 it makes the decl for the adjustable array.
7925 Until then, the above example using the COND_EXPR
7926 doesn't pass muster with gcc because the "(a == NULL)"
7927 part has a reference to "a", which is still
7928 undefined at that point.
7930 g77 will therefore use a different mechanism in the
7934 && ((TREE_CODE (low) != INTEGER_CST)
7935 || (high && TREE_CODE (high) != INTEGER_CST)))
7938 #if 0 /* Old approach -- see below. */
7939 if (TREE_CODE (low) != INTEGER_CST)
7940 low = ffecom_3 (COND_EXPR, integer_type_node,
7941 ffecom_adjarray_passed_ (s),
7943 ffecom_integer_zero_node);
7945 if (high && TREE_CODE (high) != INTEGER_CST)
7946 high = ffecom_3 (COND_EXPR, integer_type_node,
7947 ffecom_adjarray_passed_ (s),
7949 ffecom_integer_zero_node);
7952 /* ~~~gcc/stor-layout.c (layout_type) should do this,
7953 probably. Fixes 950302-1.f. */
7955 if (TREE_CODE (low) != INTEGER_CST)
7956 low = variable_size (low);
7958 /* ~~~Similarly, this fixes dumb0.f. The C front end
7959 does this, which is why dumb0.c would work. */
7961 if (high && TREE_CODE (high) != INTEGER_CST)
7962 high = variable_size (high);
7967 build_range_type (ffecom_integer_type_node,
7969 type = ffecom_check_size_overflow_ (s, type, TRUE);
7972 if (type == error_mark_node)
7974 t = error_mark_node;
7978 if ((ffesymbol_sfdummyparent (s) == NULL)
7979 || (ffesymbol_basictype (s) == FFEINFO_basictypeCHARACTER))
7981 type = build_pointer_type (type);
7985 t = build_decl (PARM_DECL, t, type);
7987 DECL_ARTIFICIAL (t) = 1;
7990 /* If this arg is present in every entry point's list of
7991 dummy args, then we're done. */
7993 if (ffesymbol_numentries (s)
7994 == (ffecom_num_entrypoints_ + 1))
7999 /* If variable_size in stor-layout has been called during
8000 the above, then get_pending_sizes should have the
8001 yet-to-be-evaluated saved expressions pending.
8002 Make the whole lot of them get emitted, conditionally
8003 on whether the array decl ("t" above) is not NULL. */
8006 tree sizes = get_pending_sizes ();
8011 tem = TREE_CHAIN (tem))
8013 tree temv = TREE_VALUE (tem);
8019 = ffecom_2 (COMPOUND_EXPR,
8028 = ffecom_3 (COND_EXPR,
8035 convert (TREE_TYPE (sizes),
8036 integer_zero_node));
8037 sizes = ffecom_save_tree (sizes);
8040 = tree_cons (NULL_TREE, sizes, tem);
8044 put_pending_sizes (sizes);
8050 && (ffesymbol_numentries (s)
8051 != ffecom_num_entrypoints_ + 1))
8053 = ffecom_2 (NE_EXPR, integer_type_node,
8059 && (ffesymbol_numentries (s)
8060 != ffecom_num_entrypoints_ + 1))
8062 ffebad_start (FFEBAD_MISSING_ADJARRAY_UNSUPPORTED);
8063 ffebad_here (0, ffesymbol_where_line (s),
8064 ffesymbol_where_column (s));
8065 ffebad_string (ffesymbol_text (s));
8074 case FFEINFO_whereCOMMON:
8079 ffestorag st = ffesymbol_storage (s);
8083 cs = ffesymbol_common (s); /* The COMMON area itself. */
8084 if (st != NULL) /* Else not laid out. */
8086 ffecom_transform_common_ (cs);
8087 st = ffesymbol_storage (s);
8090 yes = suspend_momentary ();
8092 type = ffecom_type_localvar_ (s, bt, kt);
8094 cg = ffesymbol_global (cs); /* The global COMMON info. */
8096 || (ffeglobal_type (cg) != FFEGLOBAL_typeCOMMON))
8099 ct = ffeglobal_hook (cg); /* The common area's tree. */
8101 if ((ct == NULL_TREE)
8103 || (type == error_mark_node))
8104 t = error_mark_node;
8107 ffetargetOffset offset;
8110 cst = ffestorag_parent (st);
8111 assert (cst == ffesymbol_storage (cs));
8113 offset = ffestorag_modulo (cst)
8114 + ffestorag_offset (st)
8115 - ffestorag_offset (cst);
8117 ffecom_debug_kludge_ (ct, "COMMON", s, type, offset);
8119 /* (t_type *) (((char *) &ct) + offset) */
8121 t = convert (string_type_node, /* (char *) */
8122 ffecom_1 (ADDR_EXPR,
8123 build_pointer_type (TREE_TYPE (ct)),
8125 t = ffecom_2 (PLUS_EXPR, TREE_TYPE (t),
8127 build_int_2 (offset, 0));
8128 t = convert (build_pointer_type (type),
8130 TREE_CONSTANT (t) = 1;
8135 resume_momentary (yes);
8139 case FFEINFO_whereIMMEDIATE:
8140 case FFEINFO_whereGLOBAL:
8141 case FFEINFO_whereFLEETING:
8142 case FFEINFO_whereFLEETING_CADDR:
8143 case FFEINFO_whereFLEETING_IADDR:
8144 case FFEINFO_whereINTRINSIC:
8145 case FFEINFO_whereCONSTANT_SUBOBJECT:
8147 assert ("ENTITY where unheard of" == NULL);
8149 case FFEINFO_whereANY:
8150 t = error_mark_node;
8155 case FFEINFO_kindFUNCTION:
8156 switch (ffeinfo_where (ffesymbol_info (s)))
8158 case FFEINFO_whereLOCAL: /* Me. */
8159 assert (!ffecom_transform_only_dummies_);
8160 t = current_function_decl;
8163 case FFEINFO_whereGLOBAL:
8164 assert (!ffecom_transform_only_dummies_);
8166 if (((g = ffesymbol_global (s)) != NULL)
8167 && ((ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
8168 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
8169 && (ffeglobal_hook (g) != NULL_TREE)
8170 && ffe_is_globals ())
8172 t = ffeglobal_hook (g);
8176 push_obstacks_nochange ();
8177 end_temporary_allocation ();
8179 if (ffesymbol_is_f2c (s)
8180 && (ffesymbol_where (s) != FFEINFO_whereCONSTANT))
8181 t = ffecom_tree_fun_type[bt][kt];
8183 t = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
8185 t = build_decl (FUNCTION_DECL,
8186 ffecom_get_external_identifier_ (s),
8188 DECL_EXTERNAL (t) = 1;
8189 TREE_PUBLIC (t) = 1;
8191 t = start_decl (t, FALSE);
8192 finish_decl (t, NULL_TREE, FALSE);
8195 && ((ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
8196 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
8197 ffeglobal_set_hook (g, t);
8199 resume_temporary_allocation ();
8204 case FFEINFO_whereDUMMY:
8205 assert (ffecom_transform_only_dummies_);
8207 if (ffesymbol_is_f2c (s)
8208 && (ffesymbol_where (s) != FFEINFO_whereCONSTANT))
8209 t = ffecom_tree_ptr_to_fun_type[bt][kt];
8211 t = build_pointer_type
8212 (build_function_type (ffecom_tree_type[bt][kt], NULL_TREE));
8214 t = build_decl (PARM_DECL,
8215 ffecom_get_identifier_ (ffesymbol_text (s)),
8218 DECL_ARTIFICIAL (t) = 1;
8223 case FFEINFO_whereCONSTANT: /* Statement function. */
8224 assert (!ffecom_transform_only_dummies_);
8225 t = ffecom_gen_sfuncdef_ (s, bt, kt);
8228 case FFEINFO_whereINTRINSIC:
8229 assert (!ffecom_transform_only_dummies_);
8230 break; /* Let actual references generate their
8234 assert ("FUNCTION where unheard of" == NULL);
8236 case FFEINFO_whereANY:
8237 t = error_mark_node;
8242 case FFEINFO_kindSUBROUTINE:
8243 switch (ffeinfo_where (ffesymbol_info (s)))
8245 case FFEINFO_whereLOCAL: /* Me. */
8246 assert (!ffecom_transform_only_dummies_);
8247 t = current_function_decl;
8250 case FFEINFO_whereGLOBAL:
8251 assert (!ffecom_transform_only_dummies_);
8253 if (((g = ffesymbol_global (s)) != NULL)
8254 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
8255 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
8256 && (ffeglobal_hook (g) != NULL_TREE)
8257 && ffe_is_globals ())
8259 t = ffeglobal_hook (g);
8263 push_obstacks_nochange ();
8264 end_temporary_allocation ();
8266 t = build_decl (FUNCTION_DECL,
8267 ffecom_get_external_identifier_ (s),
8268 ffecom_tree_subr_type);
8269 DECL_EXTERNAL (t) = 1;
8270 TREE_PUBLIC (t) = 1;
8272 t = start_decl (t, FALSE);
8273 finish_decl (t, NULL_TREE, FALSE);
8276 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
8277 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
8278 ffeglobal_set_hook (g, t);
8280 resume_temporary_allocation ();
8285 case FFEINFO_whereDUMMY:
8286 assert (ffecom_transform_only_dummies_);
8288 t = build_decl (PARM_DECL,
8289 ffecom_get_identifier_ (ffesymbol_text (s)),
8290 ffecom_tree_ptr_to_subr_type);
8292 DECL_ARTIFICIAL (t) = 1;
8297 case FFEINFO_whereINTRINSIC:
8298 assert (!ffecom_transform_only_dummies_);
8299 break; /* Let actual references generate their
8303 assert ("SUBROUTINE where unheard of" == NULL);
8305 case FFEINFO_whereANY:
8306 t = error_mark_node;
8311 case FFEINFO_kindPROGRAM:
8312 switch (ffeinfo_where (ffesymbol_info (s)))
8314 case FFEINFO_whereLOCAL: /* Me. */
8315 assert (!ffecom_transform_only_dummies_);
8316 t = current_function_decl;
8319 case FFEINFO_whereCOMMON:
8320 case FFEINFO_whereDUMMY:
8321 case FFEINFO_whereGLOBAL:
8322 case FFEINFO_whereRESULT:
8323 case FFEINFO_whereFLEETING:
8324 case FFEINFO_whereFLEETING_CADDR:
8325 case FFEINFO_whereFLEETING_IADDR:
8326 case FFEINFO_whereIMMEDIATE:
8327 case FFEINFO_whereINTRINSIC:
8328 case FFEINFO_whereCONSTANT:
8329 case FFEINFO_whereCONSTANT_SUBOBJECT:
8331 assert ("PROGRAM where unheard of" == NULL);
8333 case FFEINFO_whereANY:
8334 t = error_mark_node;
8339 case FFEINFO_kindBLOCKDATA:
8340 switch (ffeinfo_where (ffesymbol_info (s)))
8342 case FFEINFO_whereLOCAL: /* Me. */
8343 assert (!ffecom_transform_only_dummies_);
8344 t = current_function_decl;
8347 case FFEINFO_whereGLOBAL:
8348 assert (!ffecom_transform_only_dummies_);
8350 push_obstacks_nochange ();
8351 end_temporary_allocation ();
8353 t = build_decl (FUNCTION_DECL,
8354 ffecom_get_external_identifier_ (s),
8355 ffecom_tree_blockdata_type);
8356 DECL_EXTERNAL (t) = 1;
8357 TREE_PUBLIC (t) = 1;
8359 t = start_decl (t, FALSE);
8360 finish_decl (t, NULL_TREE, FALSE);
8362 resume_temporary_allocation ();
8367 case FFEINFO_whereCOMMON:
8368 case FFEINFO_whereDUMMY:
8369 case FFEINFO_whereRESULT:
8370 case FFEINFO_whereFLEETING:
8371 case FFEINFO_whereFLEETING_CADDR:
8372 case FFEINFO_whereFLEETING_IADDR:
8373 case FFEINFO_whereIMMEDIATE:
8374 case FFEINFO_whereINTRINSIC:
8375 case FFEINFO_whereCONSTANT:
8376 case FFEINFO_whereCONSTANT_SUBOBJECT:
8378 assert ("BLOCKDATA where unheard of" == NULL);
8380 case FFEINFO_whereANY:
8381 t = error_mark_node;
8386 case FFEINFO_kindCOMMON:
8387 switch (ffeinfo_where (ffesymbol_info (s)))
8389 case FFEINFO_whereLOCAL:
8390 assert (!ffecom_transform_only_dummies_);
8391 ffecom_transform_common_ (s);
8394 case FFEINFO_whereNONE:
8395 case FFEINFO_whereCOMMON:
8396 case FFEINFO_whereDUMMY:
8397 case FFEINFO_whereGLOBAL:
8398 case FFEINFO_whereRESULT:
8399 case FFEINFO_whereFLEETING:
8400 case FFEINFO_whereFLEETING_CADDR:
8401 case FFEINFO_whereFLEETING_IADDR:
8402 case FFEINFO_whereIMMEDIATE:
8403 case FFEINFO_whereINTRINSIC:
8404 case FFEINFO_whereCONSTANT:
8405 case FFEINFO_whereCONSTANT_SUBOBJECT:
8407 assert ("COMMON where unheard of" == NULL);
8409 case FFEINFO_whereANY:
8410 t = error_mark_node;
8415 case FFEINFO_kindCONSTRUCT:
8416 switch (ffeinfo_where (ffesymbol_info (s)))
8418 case FFEINFO_whereLOCAL:
8419 assert (!ffecom_transform_only_dummies_);
8422 case FFEINFO_whereNONE:
8423 case FFEINFO_whereCOMMON:
8424 case FFEINFO_whereDUMMY:
8425 case FFEINFO_whereGLOBAL:
8426 case FFEINFO_whereRESULT:
8427 case FFEINFO_whereFLEETING:
8428 case FFEINFO_whereFLEETING_CADDR:
8429 case FFEINFO_whereFLEETING_IADDR:
8430 case FFEINFO_whereIMMEDIATE:
8431 case FFEINFO_whereINTRINSIC:
8432 case FFEINFO_whereCONSTANT:
8433 case FFEINFO_whereCONSTANT_SUBOBJECT:
8435 assert ("CONSTRUCT where unheard of" == NULL);
8437 case FFEINFO_whereANY:
8438 t = error_mark_node;
8443 case FFEINFO_kindNAMELIST:
8444 switch (ffeinfo_where (ffesymbol_info (s)))
8446 case FFEINFO_whereLOCAL:
8447 assert (!ffecom_transform_only_dummies_);
8448 t = ffecom_transform_namelist_ (s);
8451 case FFEINFO_whereNONE:
8452 case FFEINFO_whereCOMMON:
8453 case FFEINFO_whereDUMMY:
8454 case FFEINFO_whereGLOBAL:
8455 case FFEINFO_whereRESULT:
8456 case FFEINFO_whereFLEETING:
8457 case FFEINFO_whereFLEETING_CADDR:
8458 case FFEINFO_whereFLEETING_IADDR:
8459 case FFEINFO_whereIMMEDIATE:
8460 case FFEINFO_whereINTRINSIC:
8461 case FFEINFO_whereCONSTANT:
8462 case FFEINFO_whereCONSTANT_SUBOBJECT:
8464 assert ("NAMELIST where unheard of" == NULL);
8466 case FFEINFO_whereANY:
8467 t = error_mark_node;
8473 assert ("kind unheard of" == NULL);
8475 case FFEINFO_kindANY:
8476 t = error_mark_node;
8480 ffesymbol_hook (s).decl_tree = t;
8481 ffesymbol_hook (s).length_tree = tlen;
8482 ffesymbol_hook (s).addr = addr;
8484 lineno = old_lineno;
8485 input_filename = old_input_filename;
8491 /* Transform into ASSIGNable symbol.
8493 Symbol has already been transformed, but for whatever reason, the
8494 resulting decl_tree has been deemed not usable for an ASSIGN target.
8495 (E.g. it isn't wide enough to hold a pointer.) So, here we invent
8496 another local symbol of type void * and stuff that in the assign_tree
8497 argument. The F77/F90 standards allow this implementation. */
8499 #if FFECOM_targetCURRENT == FFECOM_targetGCC
8501 ffecom_sym_transform_assign_ (ffesymbol s)
8503 tree t; /* Transformed thingy. */
8505 int old_lineno = lineno;
8506 char *old_input_filename = input_filename;
8508 if (ffesymbol_sfdummyparent (s) == NULL)
8510 input_filename = ffesymbol_where_filename (s);
8511 lineno = ffesymbol_where_filelinenum (s);
8515 ffesymbol sf = ffesymbol_sfdummyparent (s);
8517 input_filename = ffesymbol_where_filename (sf);
8518 lineno = ffesymbol_where_filelinenum (sf);
8521 assert (!ffecom_transform_only_dummies_);
8523 yes = suspend_momentary ();
8525 t = build_decl (VAR_DECL,
8526 ffecom_get_invented_identifier ("__g77_ASSIGN_%s",
8529 TREE_TYPE (null_pointer_node));
8531 switch (ffesymbol_where (s))
8533 case FFEINFO_whereLOCAL:
8534 /* Unlike for regular vars, SAVE status is easy to determine for
8535 ASSIGNed vars, since there's no initialization, there's no
8536 effective storage association (so "SAVE J" does not apply to
8537 K even given "EQUIVALENCE (J,K)"), there's no size issue
8538 to worry about, etc. */
8539 if ((ffesymbol_is_save (s) || ffe_is_saveall ())
8540 && (ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
8541 && (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA))
8542 TREE_STATIC (t) = 1; /* SAVEd in proc, make static. */
8544 TREE_STATIC (t) = 0; /* No need to make static. */
8547 case FFEINFO_whereCOMMON:
8548 TREE_STATIC (t) = 1; /* Assume COMMONs always SAVEd. */
8551 case FFEINFO_whereDUMMY:
8552 /* Note that twinning a DUMMY means the caller won't see
8553 the ASSIGNed value. But both F77 and F90 allow implementations
8554 to do this, i.e. disallow Fortran code that would try and
8555 take advantage of actually putting a label into a variable
8556 via a dummy argument (or any other storage association, for
8558 TREE_STATIC (t) = 0;
8562 TREE_STATIC (t) = 0;
8566 t = start_decl (t, FALSE);
8567 finish_decl (t, NULL_TREE, FALSE);
8569 resume_momentary (yes);
8571 ffesymbol_hook (s).assign_tree = t;
8573 lineno = old_lineno;
8574 input_filename = old_input_filename;
8580 /* Implement COMMON area in back end.
8582 Because COMMON-based variables can be referenced in the dimension
8583 expressions of dummy (adjustable) arrays, and because dummies
8584 (in the gcc back end) need to be put in the outer binding level
8585 of a function (which has two binding levels, the outer holding
8586 the dummies and the inner holding the other vars), special care
8587 must be taken to handle COMMON areas.
8589 The current strategy is basically to always tell the back end about
8590 the COMMON area as a top-level external reference to just a block
8591 of storage of the master type of that area (e.g. integer, real,
8592 character, whatever -- not a structure). As a distinct action,
8593 if initial values are provided, tell the back end about the area
8594 as a top-level non-external (initialized) area and remember not to
8595 allow further initialization or expansion of the area. Meanwhile,
8596 if no initialization happens at all, tell the back end about
8597 the largest size we've seen declared so the space does get reserved.
8598 (This function doesn't handle all that stuff, but it does some
8599 of the important things.)
8601 Meanwhile, for COMMON variables themselves, just keep creating
8602 references like *((float *) (&common_area + offset)) each time
8603 we reference the variable. In other words, don't make a VAR_DECL
8604 or any kind of component reference (like we used to do before 0.4),
8605 though we might do that as well just for debugging purposes (and
8606 stuff the rtl with the appropriate offset expression). */
8608 #if FFECOM_targetCURRENT == FFECOM_targetGCC
8610 ffecom_transform_common_ (ffesymbol s)
8612 ffestorag st = ffesymbol_storage (s);
8613 ffeglobal g = ffesymbol_global (s);
8618 bool is_init = ffestorag_is_init (st);
8620 assert (st != NULL);
8623 || (ffeglobal_type (g) != FFEGLOBAL_typeCOMMON))
8626 /* First update the size of the area in global terms. */
8628 ffeglobal_size_common (s, ffestorag_size (st));
8630 if (!ffeglobal_common_init (g))
8631 is_init = FALSE; /* No explicit init, don't let erroneous joins init. */
8633 cbt = ffeglobal_hook (g);
8635 /* If we already have declared this common block for a previous program
8636 unit, and either we already initialized it or we don't have new
8637 initialization for it, just return what we have without changing it. */
8639 if ((cbt != NULL_TREE)
8641 || !DECL_EXTERNAL (cbt)))
8644 /* Process inits. */
8648 if (ffestorag_init (st) != NULL)
8652 /* Set the padding for the expression, so ffecom_expr
8653 knows to insert that many zeros. */
8654 switch (ffebld_op (sexp = ffestorag_init (st)))
8656 case FFEBLD_opCONTER:
8657 ffebld_conter_set_pad (sexp, ffestorag_modulo (st));
8660 case FFEBLD_opARRTER:
8661 ffebld_arrter_set_pad (sexp, ffestorag_modulo (st));
8664 case FFEBLD_opACCTER:
8665 ffebld_accter_set_pad (sexp, ffestorag_modulo (st));
8669 assert ("bad op for cmn init (pad)" == NULL);
8673 init = ffecom_expr (sexp);
8674 if (init == error_mark_node)
8675 { /* Hopefully the back end complained! */
8677 if (cbt != NULL_TREE)
8682 init = error_mark_node;
8687 push_obstacks_nochange ();
8688 end_temporary_allocation ();
8690 /* cbtype must be permanently allocated! */
8692 /* Allocate the MAX of the areas so far, seen filewide. */
8693 high = build_int_2 ((ffeglobal_common_size (g)
8694 + ffeglobal_common_pad (g)) - 1, 0);
8695 TREE_TYPE (high) = ffecom_integer_type_node;
8698 cbtype = build_array_type (char_type_node,
8699 build_range_type (integer_type_node,
8703 cbtype = build_array_type (char_type_node, NULL_TREE);
8705 if (cbt == NULL_TREE)
8708 = build_decl (VAR_DECL,
8709 ffecom_get_external_identifier_ (s),
8711 TREE_STATIC (cbt) = 1;
8712 TREE_PUBLIC (cbt) = 1;
8717 TREE_TYPE (cbt) = cbtype;
8719 DECL_EXTERNAL (cbt) = init ? 0 : 1;
8720 DECL_INITIAL (cbt) = init ? error_mark_node : NULL_TREE;
8722 cbt = start_decl (cbt, TRUE);
8723 if (ffeglobal_hook (g) != NULL)
8724 assert (cbt == ffeglobal_hook (g));
8726 assert (!init || !DECL_EXTERNAL (cbt));
8728 /* Make sure that any type can live in COMMON and be referenced
8729 without getting a bus error. We could pick the most restrictive
8730 alignment of all entities actually placed in the COMMON, but
8731 this seems easy enough. */
8733 DECL_ALIGN (cbt) = BIGGEST_ALIGNMENT;
8735 if (is_init && (ffestorag_init (st) == NULL))
8736 init = ffecom_init_zero_ (cbt);
8738 finish_decl (cbt, init, TRUE);
8741 ffestorag_set_init (st, ffebld_new_any ());
8747 assert (DECL_SIZE (cbt) != NULL_TREE);
8748 assert (TREE_CODE (DECL_SIZE (cbt)) == INTEGER_CST);
8749 size_tree = size_binop (CEIL_DIV_EXPR,
8751 size_int (BITS_PER_UNIT));
8752 assert (TREE_INT_CST_HIGH (size_tree) == 0);
8753 assert (TREE_INT_CST_LOW (size_tree)
8754 == ffeglobal_common_size (g) + ffeglobal_common_pad (g));
8757 ffeglobal_set_hook (g, cbt);
8759 ffestorag_set_hook (st, cbt);
8761 resume_temporary_allocation ();
8766 /* Make master area for local EQUIVALENCE. */
8768 #if FFECOM_targetCURRENT == FFECOM_targetGCC
8770 ffecom_transform_equiv_ (ffestorag eqst)
8776 bool is_init = ffestorag_is_init (eqst);
8779 assert (eqst != NULL);
8781 eqt = ffestorag_hook (eqst);
8783 if (eqt != NULL_TREE)
8786 /* Process inits. */
8790 if (ffestorag_init (eqst) != NULL)
8794 /* Set the padding for the expression, so ffecom_expr
8795 knows to insert that many zeros. */
8796 switch (ffebld_op (sexp = ffestorag_init (eqst)))
8798 case FFEBLD_opCONTER:
8799 ffebld_conter_set_pad (sexp, ffestorag_modulo (eqst));
8802 case FFEBLD_opARRTER:
8803 ffebld_arrter_set_pad (sexp, ffestorag_modulo (eqst));
8806 case FFEBLD_opACCTER:
8807 ffebld_accter_set_pad (sexp, ffestorag_modulo (eqst));
8811 assert ("bad op for eqv init (pad)" == NULL);
8815 init = ffecom_expr (sexp);
8816 if (init == error_mark_node)
8817 init = NULL_TREE; /* Hopefully the back end complained! */
8820 init = error_mark_node;
8822 else if (ffe_is_init_local_zero ())
8823 init = error_mark_node;
8827 ffecom_member_namelisted_ = FALSE;
8828 ffestorag_drive (ffestorag_list_equivs (eqst),
8829 &ffecom_member_phase1_,
8832 yes = suspend_momentary ();
8834 high = build_int_2 ((ffestorag_size (eqst)
8835 + ffestorag_modulo (eqst)) - 1, 0);
8836 TREE_TYPE (high) = ffecom_integer_type_node;
8838 eqtype = build_array_type (char_type_node,
8839 build_range_type (ffecom_integer_type_node,
8840 ffecom_integer_zero_node,
8843 eqt = build_decl (VAR_DECL,
8844 ffecom_get_invented_identifier ("__g77_equiv_%s",
8850 DECL_EXTERNAL (eqt) = 0;
8852 || ffecom_member_namelisted_
8853 #ifdef FFECOM_sizeMAXSTACKITEM
8854 || (ffestorag_size (eqst) > FFECOM_sizeMAXSTACKITEM)
8856 || ((ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
8857 && (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA)
8858 && (ffestorag_is_save (eqst) || ffe_is_saveall ())))
8859 TREE_STATIC (eqt) = 1;
8861 TREE_STATIC (eqt) = 0;
8862 TREE_PUBLIC (eqt) = 0;
8863 DECL_CONTEXT (eqt) = current_function_decl;
8865 DECL_INITIAL (eqt) = error_mark_node;
8867 DECL_INITIAL (eqt) = NULL_TREE;
8869 eqt = start_decl (eqt, FALSE);
8871 /* Make sure that any type can live in EQUIVALENCE and be referenced
8872 without getting a bus error. We could pick the most restrictive
8873 alignment of all entities actually placed in the EQUIVALENCE, but
8874 this seems easy enough. */
8876 DECL_ALIGN (eqt) = BIGGEST_ALIGNMENT;
8878 if ((!is_init && ffe_is_init_local_zero ())
8879 || (is_init && (ffestorag_init (eqst) == NULL)))
8880 init = ffecom_init_zero_ (eqt);
8882 finish_decl (eqt, init, FALSE);
8885 ffestorag_set_init (eqst, ffebld_new_any ());
8890 size_tree = size_binop (CEIL_DIV_EXPR,
8892 size_int (BITS_PER_UNIT));
8893 assert (TREE_INT_CST_HIGH (size_tree) == 0);
8894 assert (TREE_INT_CST_LOW (size_tree)
8895 == ffestorag_size (eqst) + ffestorag_modulo (eqst));
8898 ffestorag_set_hook (eqst, eqt);
8900 #ifdef SOMEONE_GETS_DEBUG_SUPPORT_WORKING
8901 ffestorag_drive (ffestorag_list_equivs (eqst),
8902 &ffecom_member_phase2_,
8906 resume_momentary (yes);
8910 /* Implement NAMELIST in back end. See f2c/format.c for more info. */
8912 #if FFECOM_targetCURRENT == FFECOM_targetGCC
8914 ffecom_transform_namelist_ (ffesymbol s)
8917 tree nmltype = ffecom_type_namelist_ ();
8926 static int mynumber = 0;
8928 yes = suspend_momentary ();
8930 nmlt = build_decl (VAR_DECL,
8931 ffecom_get_invented_identifier ("__g77_namelist_%d",
8934 TREE_STATIC (nmlt) = 1;
8935 DECL_INITIAL (nmlt) = error_mark_node;
8937 nmlt = start_decl (nmlt, FALSE);
8939 /* Process inits. */
8941 i = strlen (ffesymbol_text (s));
8943 high = build_int_2 (i, 0);
8944 TREE_TYPE (high) = ffecom_f2c_ftnlen_type_node;
8946 nameinit = ffecom_build_f2c_string_ (i + 1,
8947 ffesymbol_text (s));
8948 TREE_TYPE (nameinit)
8949 = build_type_variant
8952 build_range_type (ffecom_f2c_ftnlen_type_node,
8953 ffecom_f2c_ftnlen_one_node,
8956 TREE_CONSTANT (nameinit) = 1;
8957 TREE_STATIC (nameinit) = 1;
8958 nameinit = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (nameinit)),
8961 varsinit = ffecom_vardesc_array_ (s);
8962 varsinit = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (varsinit)),
8964 TREE_CONSTANT (varsinit) = 1;
8965 TREE_STATIC (varsinit) = 1;
8970 for (i = 0, b = ffesymbol_namelist (s); b != NULL; b = ffebld_trail (b))
8973 nvarsinit = build_int_2 (i, 0);
8974 TREE_TYPE (nvarsinit) = integer_type_node;
8975 TREE_CONSTANT (nvarsinit) = 1;
8976 TREE_STATIC (nvarsinit) = 1;
8978 nmlinits = build_tree_list ((field = TYPE_FIELDS (nmltype)), nameinit);
8979 TREE_CHAIN (nmlinits) = build_tree_list ((field = TREE_CHAIN (field)),
8981 TREE_CHAIN (TREE_CHAIN (nmlinits))
8982 = build_tree_list ((field = TREE_CHAIN (field)), nvarsinit);
8984 nmlinits = build (CONSTRUCTOR, nmltype, NULL_TREE, nmlinits);
8985 TREE_CONSTANT (nmlinits) = 1;
8986 TREE_STATIC (nmlinits) = 1;
8988 finish_decl (nmlt, nmlinits, FALSE);
8990 nmlt = ffecom_1 (ADDR_EXPR, build_pointer_type (nmltype), nmlt);
8992 resume_momentary (yes);
8999 /* A subroutine of ffecom_tree_canonize_ref_. The incoming tree is
9000 analyzed on the assumption it is calculating a pointer to be
9001 indirected through. It must return the proper decl and offset,
9002 taking into account different units of measurements for offsets. */
9004 #if FFECOM_targetCURRENT == FFECOM_targetGCC
9006 ffecom_tree_canonize_ptr_ (tree *decl, tree *offset,
9009 switch (TREE_CODE (t))
9013 case NON_LVALUE_EXPR:
9014 ffecom_tree_canonize_ptr_ (decl, offset, TREE_OPERAND (t, 0));
9018 ffecom_tree_canonize_ptr_ (decl, offset, TREE_OPERAND (t, 0));
9019 if ((*decl == NULL_TREE)
9020 || (*decl == error_mark_node))
9023 if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST)
9025 /* An offset into COMMON. */
9026 *offset = size_binop (PLUS_EXPR,
9028 TREE_OPERAND (t, 1));
9029 /* Convert offset (presumably in bytes) into canonical units
9030 (presumably bits). */
9031 *offset = size_binop (MULT_EXPR,
9032 TYPE_SIZE (TREE_TYPE (TREE_TYPE (t))),
9036 /* Not a COMMON reference, so an unrecognized pattern. */
9037 *decl = error_mark_node;
9042 *offset = bitsize_int (0L, 0L);
9046 if (TREE_CODE (TREE_OPERAND (t, 0)) == VAR_DECL)
9048 /* A reference to COMMON. */
9049 *decl = TREE_OPERAND (t, 0);
9050 *offset = bitsize_int (0L, 0L);
9055 /* Not a COMMON reference, so an unrecognized pattern. */
9056 *decl = error_mark_node;
9062 /* Given a tree that is possibly intended for use as an lvalue, return
9063 information representing a canonical view of that tree as a decl, an
9064 offset into that decl, and a size for the lvalue.
9066 If there's no applicable decl, NULL_TREE is returned for the decl,
9067 and the other fields are left undefined.
9069 If the tree doesn't fit the recognizable forms, an ERROR_MARK node
9070 is returned for the decl, and the other fields are left undefined.
9072 Otherwise, the decl returned currently is either a VAR_DECL or a
9075 The offset returned is always valid, but of course not necessarily
9076 a constant, and not necessarily converted into the appropriate
9077 type, leaving that up to the caller (so as to avoid that overhead
9078 if the decls being looked at are different anyway).
9080 If the size cannot be determined (e.g. an adjustable array),
9081 an ERROR_MARK node is returned for the size. Otherwise, the
9082 size returned is valid, not necessarily a constant, and not
9083 necessarily converted into the appropriate type as with the
9086 Note that the offset and size expressions are expressed in the
9087 base storage units (usually bits) rather than in the units of
9088 the type of the decl, because two decls with different types
9089 might overlap but with apparently non-overlapping array offsets,
9090 whereas converting the array offsets to consistant offsets will
9091 reveal the overlap. */
9093 #if FFECOM_targetCURRENT == FFECOM_targetGCC
9095 ffecom_tree_canonize_ref_ (tree *decl, tree *offset,
9098 /* The default path is to report a nonexistant decl. */
9104 switch (TREE_CODE (t))
9107 case IDENTIFIER_NODE:
9116 case TRUNC_DIV_EXPR:
9118 case FLOOR_DIV_EXPR:
9119 case ROUND_DIV_EXPR:
9120 case TRUNC_MOD_EXPR:
9122 case FLOOR_MOD_EXPR:
9123 case ROUND_MOD_EXPR:
9125 case EXACT_DIV_EXPR:
9126 case FIX_TRUNC_EXPR:
9128 case FIX_FLOOR_EXPR:
9129 case FIX_ROUND_EXPR:
9144 case BIT_ANDTC_EXPR:
9146 case TRUTH_ANDIF_EXPR:
9147 case TRUTH_ORIF_EXPR:
9148 case TRUTH_AND_EXPR:
9150 case TRUTH_XOR_EXPR:
9151 case TRUTH_NOT_EXPR:
9171 *offset = bitsize_int (0L, 0L);
9172 *size = TYPE_SIZE (TREE_TYPE (t));
9177 tree array = TREE_OPERAND (t, 0);
9178 tree element = TREE_OPERAND (t, 1);
9181 if ((array == NULL_TREE)
9182 || (element == NULL_TREE))
9184 *decl = error_mark_node;
9188 ffecom_tree_canonize_ref_ (decl, &init_offset, size,
9190 if ((*decl == NULL_TREE)
9191 || (*decl == error_mark_node))
9194 *offset = size_binop (MULT_EXPR,
9195 TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))),
9196 size_binop (MINUS_EXPR,
9200 (TREE_TYPE (array)))));
9202 *offset = size_binop (PLUS_EXPR,
9206 *size = TYPE_SIZE (TREE_TYPE (t));
9212 /* Most of this code is to handle references to COMMON. And so
9213 far that is useful only for calling library functions, since
9214 external (user) functions might reference common areas. But
9215 even calling an external function, it's worthwhile to decode
9216 COMMON references because if not storing into COMMON, we don't
9217 want COMMON-based arguments to gratuitously force use of a
9220 *size = TYPE_SIZE (TREE_TYPE (t));
9222 ffecom_tree_canonize_ptr_ (decl, offset,
9223 TREE_OPERAND (t, 0));
9230 case NON_LVALUE_EXPR:
9233 case COND_EXPR: /* More cases than we can handle. */
9235 case REFERENCE_EXPR:
9236 case PREDECREMENT_EXPR:
9237 case PREINCREMENT_EXPR:
9238 case POSTDECREMENT_EXPR:
9239 case POSTINCREMENT_EXPR:
9242 *decl = error_mark_node;
9248 /* Do divide operation appropriate to type of operands. */
9250 #if FFECOM_targetCURRENT == FFECOM_targetGCC
9252 ffecom_tree_divide_ (tree tree_type, tree left, tree right,
9253 tree dest_tree, ffebld dest, bool *dest_used,
9256 if ((left == error_mark_node)
9257 || (right == error_mark_node))
9258 return error_mark_node;
9260 switch (TREE_CODE (tree_type))
9263 return ffecom_2 (TRUNC_DIV_EXPR, tree_type,
9271 if (TREE_TYPE (tree_type)
9272 == ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1])
9273 ix = FFECOM_gfrtDIV_CC; /* Overlapping result okay. */
9275 ix = FFECOM_gfrtDIV_ZZ; /* Overlapping result okay. */
9277 left = ffecom_1 (ADDR_EXPR,
9278 build_pointer_type (TREE_TYPE (left)),
9280 left = build_tree_list (NULL_TREE, left);
9281 right = ffecom_1 (ADDR_EXPR,
9282 build_pointer_type (TREE_TYPE (right)),
9284 right = build_tree_list (NULL_TREE, right);
9285 TREE_CHAIN (left) = right;
9287 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
9288 ffecom_gfrt_kindtype (ix),
9289 ffe_is_f2c_library (),
9292 dest_tree, dest, dest_used,
9293 NULL_TREE, TRUE, hook);
9301 if (TREE_TYPE (TYPE_FIELDS (tree_type))
9302 == ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1])
9303 ix = FFECOM_gfrtDIV_CC; /* Overlapping result okay. */
9305 ix = FFECOM_gfrtDIV_ZZ; /* Overlapping result okay. */
9307 left = ffecom_1 (ADDR_EXPR,
9308 build_pointer_type (TREE_TYPE (left)),
9310 left = build_tree_list (NULL_TREE, left);
9311 right = ffecom_1 (ADDR_EXPR,
9312 build_pointer_type (TREE_TYPE (right)),
9314 right = build_tree_list (NULL_TREE, right);
9315 TREE_CHAIN (left) = right;
9317 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
9318 ffecom_gfrt_kindtype (ix),
9319 ffe_is_f2c_library (),
9322 dest_tree, dest, dest_used,
9323 NULL_TREE, TRUE, hook);
9328 return ffecom_2 (RDIV_EXPR, tree_type,
9335 /* Build type info for non-dummy variable. */
9337 #if FFECOM_targetCURRENT == FFECOM_targetGCC
9339 ffecom_type_localvar_ (ffesymbol s, ffeinfoBasictype bt,
9348 type = ffecom_tree_type[bt][kt];
9349 if (bt == FFEINFO_basictypeCHARACTER)
9351 hight = build_int_2 (ffesymbol_size (s), 0);
9352 TREE_TYPE (hight) = ffecom_f2c_ftnlen_type_node;
9357 build_range_type (ffecom_f2c_ftnlen_type_node,
9358 ffecom_f2c_ftnlen_one_node,
9360 type = ffecom_check_size_overflow_ (s, type, FALSE);
9363 for (dl = ffesymbol_dims (s); dl != NULL; dl = ffebld_trail (dl))
9365 if (type == error_mark_node)
9368 dim = ffebld_head (dl);
9369 assert (ffebld_op (dim) == FFEBLD_opBOUNDS);
9371 if (ffebld_left (dim) == NULL)
9372 lowt = integer_one_node;
9374 lowt = ffecom_expr (ffebld_left (dim));
9376 if (TREE_CODE (lowt) != INTEGER_CST)
9377 lowt = variable_size (lowt);
9379 assert (ffebld_right (dim) != NULL);
9380 hight = ffecom_expr (ffebld_right (dim));
9382 if (TREE_CODE (hight) != INTEGER_CST)
9383 hight = variable_size (hight);
9385 type = build_array_type (type,
9386 build_range_type (ffecom_integer_type_node,
9388 type = ffecom_check_size_overflow_ (s, type, FALSE);
9395 /* Build Namelist type. */
9397 #if FFECOM_targetCURRENT == FFECOM_targetGCC
9399 ffecom_type_namelist_ ()
9401 static tree type = NULL_TREE;
9403 if (type == NULL_TREE)
9405 static tree namefield, varsfield, nvarsfield;
9408 vardesctype = ffecom_type_vardesc_ ();
9410 push_obstacks_nochange ();
9411 end_temporary_allocation ();
9413 type = make_node (RECORD_TYPE);
9415 vardesctype = build_pointer_type (build_pointer_type (vardesctype));
9417 namefield = ffecom_decl_field (type, NULL_TREE, "name",
9419 varsfield = ffecom_decl_field (type, namefield, "vars", vardesctype);
9420 nvarsfield = ffecom_decl_field (type, varsfield, "nvars",
9423 TYPE_FIELDS (type) = namefield;
9426 resume_temporary_allocation ();
9435 /* Make a copy of a type, assuming caller has switched to the permanent
9436 obstacks and that the type is for an aggregate (array) initializer. */
9438 #if FFECOM_targetCURRENT == FFECOM_targetGCC && 0 /* Not used now. */
9440 ffecom_type_permanent_copy_ (tree t)
9445 assert (TREE_TYPE (t) != NULL_TREE);
9447 domain = TYPE_DOMAIN (t);
9449 assert (TREE_CODE (t) == ARRAY_TYPE);
9450 assert (TREE_PERMANENT (TREE_TYPE (t)));
9451 assert (TREE_PERMANENT (TREE_TYPE (domain)));
9452 assert (TREE_PERMANENT (TYPE_MIN_VALUE (domain)));
9454 max = TYPE_MAX_VALUE (domain);
9455 if (!TREE_PERMANENT (max))
9457 assert (TREE_CODE (max) == INTEGER_CST);
9459 max = build_int_2 (TREE_INT_CST_LOW (max), TREE_INT_CST_HIGH (max));
9460 TREE_TYPE (max) = TREE_TYPE (TYPE_MIN_VALUE (domain));
9463 return build_array_type (TREE_TYPE (t),
9464 build_range_type (TREE_TYPE (domain),
9465 TYPE_MIN_VALUE (domain),
9470 /* Build Vardesc type. */
9472 #if FFECOM_targetCURRENT == FFECOM_targetGCC
9474 ffecom_type_vardesc_ ()
9476 static tree type = NULL_TREE;
9477 static tree namefield, addrfield, dimsfield, typefield;
9479 if (type == NULL_TREE)
9481 push_obstacks_nochange ();
9482 end_temporary_allocation ();
9484 type = make_node (RECORD_TYPE);
9486 namefield = ffecom_decl_field (type, NULL_TREE, "name",
9488 addrfield = ffecom_decl_field (type, namefield, "addr",
9490 dimsfield = ffecom_decl_field (type, addrfield, "dims",
9491 ffecom_f2c_ptr_to_ftnlen_type_node);
9492 typefield = ffecom_decl_field (type, dimsfield, "type",
9495 TYPE_FIELDS (type) = namefield;
9498 resume_temporary_allocation ();
9507 #if FFECOM_targetCURRENT == FFECOM_targetGCC
9509 ffecom_vardesc_ (ffebld expr)
9513 assert (ffebld_op (expr) == FFEBLD_opSYMTER);
9514 s = ffebld_symter (expr);
9516 if (ffesymbol_hook (s).vardesc_tree == NULL_TREE)
9519 tree vardesctype = ffecom_type_vardesc_ ();
9528 static int mynumber = 0;
9530 yes = suspend_momentary ();
9532 var = build_decl (VAR_DECL,
9533 ffecom_get_invented_identifier ("__g77_vardesc_%d",
9536 TREE_STATIC (var) = 1;
9537 DECL_INITIAL (var) = error_mark_node;
9539 var = start_decl (var, FALSE);
9541 /* Process inits. */
9543 nameinit = ffecom_build_f2c_string_ ((i = strlen (ffesymbol_text (s)))
9545 ffesymbol_text (s));
9546 TREE_TYPE (nameinit)
9547 = build_type_variant
9550 build_range_type (integer_type_node,
9552 build_int_2 (i, 0))),
9554 TREE_CONSTANT (nameinit) = 1;
9555 TREE_STATIC (nameinit) = 1;
9556 nameinit = ffecom_1 (ADDR_EXPR,
9557 build_pointer_type (TREE_TYPE (nameinit)),
9560 addrinit = ffecom_arg_ptr_to_expr (expr, &typeinit);
9562 dimsinit = ffecom_vardesc_dims_ (s);
9564 if (typeinit == NULL_TREE)
9566 ffeinfoBasictype bt = ffesymbol_basictype (s);
9567 ffeinfoKindtype kt = ffesymbol_kindtype (s);
9568 int tc = ffecom_f2c_typecode (bt, kt);
9571 typeinit = build_int_2 (tc, (tc < 0) ? -1 : 0);
9574 typeinit = ffecom_1 (NEGATE_EXPR, TREE_TYPE (typeinit), typeinit);
9576 varinits = build_tree_list ((field = TYPE_FIELDS (vardesctype)),
9578 TREE_CHAIN (varinits) = build_tree_list ((field = TREE_CHAIN (field)),
9580 TREE_CHAIN (TREE_CHAIN (varinits))
9581 = build_tree_list ((field = TREE_CHAIN (field)), dimsinit);
9582 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (varinits)))
9583 = build_tree_list ((field = TREE_CHAIN (field)), typeinit);
9585 varinits = build (CONSTRUCTOR, vardesctype, NULL_TREE, varinits);
9586 TREE_CONSTANT (varinits) = 1;
9587 TREE_STATIC (varinits) = 1;
9589 finish_decl (var, varinits, FALSE);
9591 var = ffecom_1 (ADDR_EXPR, build_pointer_type (vardesctype), var);
9593 resume_momentary (yes);
9595 ffesymbol_hook (s).vardesc_tree = var;
9598 return ffesymbol_hook (s).vardesc_tree;
9602 #if FFECOM_targetCURRENT == FFECOM_targetGCC
9604 ffecom_vardesc_array_ (ffesymbol s)
9608 tree item = NULL_TREE;
9612 static int mynumber = 0;
9614 for (i = 0, list = NULL_TREE, b = ffesymbol_namelist (s);
9616 b = ffebld_trail (b), ++i)
9620 t = ffecom_vardesc_ (ffebld_head (b));
9622 if (list == NULL_TREE)
9623 list = item = build_tree_list (NULL_TREE, t);
9626 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
9627 item = TREE_CHAIN (item);
9631 yes = suspend_momentary ();
9633 item = build_array_type (build_pointer_type (ffecom_type_vardesc_ ()),
9634 build_range_type (integer_type_node,
9636 build_int_2 (i, 0)));
9637 list = build (CONSTRUCTOR, item, NULL_TREE, list);
9638 TREE_CONSTANT (list) = 1;
9639 TREE_STATIC (list) = 1;
9641 var = ffecom_get_invented_identifier ("__g77_vardesc_array_%d", NULL,
9643 var = build_decl (VAR_DECL, var, item);
9644 TREE_STATIC (var) = 1;
9645 DECL_INITIAL (var) = error_mark_node;
9646 var = start_decl (var, FALSE);
9647 finish_decl (var, list, FALSE);
9649 resume_momentary (yes);
9655 #if FFECOM_targetCURRENT == FFECOM_targetGCC
9657 ffecom_vardesc_dims_ (ffesymbol s)
9659 if (ffesymbol_dims (s) == NULL)
9660 return convert (ffecom_f2c_ptr_to_ftnlen_type_node,
9668 tree item = NULL_TREE;
9673 tree baseoff = NULL_TREE;
9674 static int mynumber = 0;
9676 numdim = build_int_2 ((int) ffesymbol_rank (s), 0);
9677 TREE_TYPE (numdim) = ffecom_f2c_ftnlen_type_node;
9679 numelem = ffecom_expr (ffesymbol_arraysize (s));
9680 TREE_TYPE (numelem) = ffecom_f2c_ftnlen_type_node;
9683 backlist = NULL_TREE;
9684 for (b = ffesymbol_dims (s), e = ffesymbol_extents (s);
9686 b = ffebld_trail (b), e = ffebld_trail (e))
9692 if (ffebld_trail (b) == NULL)
9696 t = convert (ffecom_f2c_ftnlen_type_node,
9697 ffecom_expr (ffebld_head (e)));
9699 if (list == NULL_TREE)
9700 list = item = build_tree_list (NULL_TREE, t);
9703 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
9704 item = TREE_CHAIN (item);
9708 if (ffebld_left (ffebld_head (b)) == NULL)
9709 low = ffecom_integer_one_node;
9711 low = ffecom_expr (ffebld_left (ffebld_head (b)));
9712 low = convert (ffecom_f2c_ftnlen_type_node, low);
9714 back = build_tree_list (low, t);
9715 TREE_CHAIN (back) = backlist;
9719 for (item = backlist; item != NULL_TREE; item = TREE_CHAIN (item))
9721 if (TREE_VALUE (item) == NULL_TREE)
9722 baseoff = TREE_PURPOSE (item);
9724 baseoff = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
9725 TREE_PURPOSE (item),
9726 ffecom_2 (MULT_EXPR,
9727 ffecom_f2c_ftnlen_type_node,
9732 /* backlist now dead, along with all TREE_PURPOSEs on it. */
9734 baseoff = build_tree_list (NULL_TREE, baseoff);
9735 TREE_CHAIN (baseoff) = list;
9737 numelem = build_tree_list (NULL_TREE, numelem);
9738 TREE_CHAIN (numelem) = baseoff;
9740 numdim = build_tree_list (NULL_TREE, numdim);
9741 TREE_CHAIN (numdim) = numelem;
9743 yes = suspend_momentary ();
9745 item = build_array_type (ffecom_f2c_ftnlen_type_node,
9746 build_range_type (integer_type_node,
9749 ((int) ffesymbol_rank (s)
9751 list = build (CONSTRUCTOR, item, NULL_TREE, numdim);
9752 TREE_CONSTANT (list) = 1;
9753 TREE_STATIC (list) = 1;
9755 var = ffecom_get_invented_identifier ("__g77_dims_%d", NULL,
9757 var = build_decl (VAR_DECL, var, item);
9758 TREE_STATIC (var) = 1;
9759 DECL_INITIAL (var) = error_mark_node;
9760 var = start_decl (var, FALSE);
9761 finish_decl (var, list, FALSE);
9763 var = ffecom_1 (ADDR_EXPR, build_pointer_type (item), var);
9765 resume_momentary (yes);
9772 /* Essentially does a "fold (build1 (code, type, node))" while checking
9773 for certain housekeeping things.
9775 NOTE: for building an ADDR_EXPR around a FUNCTION_DECL, use
9776 ffecom_1_fn instead. */
9778 #if FFECOM_targetCURRENT == FFECOM_targetGCC
9780 ffecom_1 (enum tree_code code, tree type, tree node)
9784 if ((node == error_mark_node)
9785 || (type == error_mark_node))
9786 return error_mark_node;
9788 if (code == ADDR_EXPR)
9790 if (!mark_addressable (node))
9791 assert ("can't mark_addressable this node!" == NULL);
9794 switch (ffe_is_emulate_complex () ? code : NOP_EXPR)
9799 item = build (COMPONENT_REF, type, node, TYPE_FIELDS (TREE_TYPE (node)));
9803 item = build (COMPONENT_REF, type, node, TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (node))));
9808 if (TREE_CODE (type) != RECORD_TYPE)
9810 item = build1 (code, type, node);
9813 node = ffecom_stabilize_aggregate_ (node);
9814 realtype = TREE_TYPE (TYPE_FIELDS (type));
9816 ffecom_2 (COMPLEX_EXPR, type,
9817 ffecom_1 (NEGATE_EXPR, realtype,
9818 ffecom_1 (REALPART_EXPR, realtype,
9820 ffecom_1 (NEGATE_EXPR, realtype,
9821 ffecom_1 (IMAGPART_EXPR, realtype,
9826 item = build1 (code, type, node);
9830 if (TREE_SIDE_EFFECTS (node))
9831 TREE_SIDE_EFFECTS (item) = 1;
9832 if ((code == ADDR_EXPR) && staticp (node))
9833 TREE_CONSTANT (item) = 1;
9838 /* Like ffecom_1 (ADDR_EXPR, TREE_TYPE (node), node), except
9839 handles TREE_CODE (node) == FUNCTION_DECL. In particular,
9840 does not set TREE_ADDRESSABLE (because calling an inline
9841 function does not mean the function needs to be separately
9844 #if FFECOM_targetCURRENT == FFECOM_targetGCC
9846 ffecom_1_fn (tree node)
9851 if (node == error_mark_node)
9852 return error_mark_node;
9854 type = build_type_variant (TREE_TYPE (node),
9855 TREE_READONLY (node),
9856 TREE_THIS_VOLATILE (node));
9857 item = build1 (ADDR_EXPR,
9858 build_pointer_type (type), node);
9859 if (TREE_SIDE_EFFECTS (node))
9860 TREE_SIDE_EFFECTS (item) = 1;
9862 TREE_CONSTANT (item) = 1;
9867 /* Essentially does a "fold (build (code, type, node1, node2))" while
9868 checking for certain housekeeping things. */
9870 #if FFECOM_targetCURRENT == FFECOM_targetGCC
9872 ffecom_2 (enum tree_code code, tree type, tree node1,
9877 if ((node1 == error_mark_node)
9878 || (node2 == error_mark_node)
9879 || (type == error_mark_node))
9880 return error_mark_node;
9882 switch (ffe_is_emulate_complex () ? code : NOP_EXPR)
9884 tree a, b, c, d, realtype;
9887 assert ("no CONJ_EXPR support yet" == NULL);
9888 return error_mark_node;
9891 item = build_tree_list (TYPE_FIELDS (type), node1);
9892 TREE_CHAIN (item) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), node2);
9893 item = build (CONSTRUCTOR, type, NULL_TREE, item);
9897 if (TREE_CODE (type) != RECORD_TYPE)
9899 item = build (code, type, node1, node2);
9902 node1 = ffecom_stabilize_aggregate_ (node1);
9903 node2 = ffecom_stabilize_aggregate_ (node2);
9904 realtype = TREE_TYPE (TYPE_FIELDS (type));
9906 ffecom_2 (COMPLEX_EXPR, type,
9907 ffecom_2 (PLUS_EXPR, realtype,
9908 ffecom_1 (REALPART_EXPR, realtype,
9910 ffecom_1 (REALPART_EXPR, realtype,
9912 ffecom_2 (PLUS_EXPR, realtype,
9913 ffecom_1 (IMAGPART_EXPR, realtype,
9915 ffecom_1 (IMAGPART_EXPR, realtype,
9920 if (TREE_CODE (type) != RECORD_TYPE)
9922 item = build (code, type, node1, node2);
9925 node1 = ffecom_stabilize_aggregate_ (node1);
9926 node2 = ffecom_stabilize_aggregate_ (node2);
9927 realtype = TREE_TYPE (TYPE_FIELDS (type));
9929 ffecom_2 (COMPLEX_EXPR, type,
9930 ffecom_2 (MINUS_EXPR, realtype,
9931 ffecom_1 (REALPART_EXPR, realtype,
9933 ffecom_1 (REALPART_EXPR, realtype,
9935 ffecom_2 (MINUS_EXPR, realtype,
9936 ffecom_1 (IMAGPART_EXPR, realtype,
9938 ffecom_1 (IMAGPART_EXPR, realtype,
9943 if (TREE_CODE (type) != RECORD_TYPE)
9945 item = build (code, type, node1, node2);
9948 node1 = ffecom_stabilize_aggregate_ (node1);
9949 node2 = ffecom_stabilize_aggregate_ (node2);
9950 realtype = TREE_TYPE (TYPE_FIELDS (type));
9951 a = save_expr (ffecom_1 (REALPART_EXPR, realtype,
9953 b = save_expr (ffecom_1 (IMAGPART_EXPR, realtype,
9955 c = save_expr (ffecom_1 (REALPART_EXPR, realtype,
9957 d = save_expr (ffecom_1 (IMAGPART_EXPR, realtype,
9960 ffecom_2 (COMPLEX_EXPR, type,
9961 ffecom_2 (MINUS_EXPR, realtype,
9962 ffecom_2 (MULT_EXPR, realtype,
9965 ffecom_2 (MULT_EXPR, realtype,
9968 ffecom_2 (PLUS_EXPR, realtype,
9969 ffecom_2 (MULT_EXPR, realtype,
9972 ffecom_2 (MULT_EXPR, realtype,
9978 if ((TREE_CODE (node1) != RECORD_TYPE)
9979 && (TREE_CODE (node2) != RECORD_TYPE))
9981 item = build (code, type, node1, node2);
9984 assert (TREE_CODE (node1) == RECORD_TYPE);
9985 assert (TREE_CODE (node2) == RECORD_TYPE);
9986 node1 = ffecom_stabilize_aggregate_ (node1);
9987 node2 = ffecom_stabilize_aggregate_ (node2);
9988 realtype = TREE_TYPE (TYPE_FIELDS (type));
9990 ffecom_2 (TRUTH_ANDIF_EXPR, type,
9991 ffecom_2 (code, type,
9992 ffecom_1 (REALPART_EXPR, realtype,
9994 ffecom_1 (REALPART_EXPR, realtype,
9996 ffecom_2 (code, type,
9997 ffecom_1 (IMAGPART_EXPR, realtype,
9999 ffecom_1 (IMAGPART_EXPR, realtype,
10004 if ((TREE_CODE (node1) != RECORD_TYPE)
10005 && (TREE_CODE (node2) != RECORD_TYPE))
10007 item = build (code, type, node1, node2);
10010 assert (TREE_CODE (node1) == RECORD_TYPE);
10011 assert (TREE_CODE (node2) == RECORD_TYPE);
10012 node1 = ffecom_stabilize_aggregate_ (node1);
10013 node2 = ffecom_stabilize_aggregate_ (node2);
10014 realtype = TREE_TYPE (TYPE_FIELDS (type));
10016 ffecom_2 (TRUTH_ORIF_EXPR, type,
10017 ffecom_2 (code, type,
10018 ffecom_1 (REALPART_EXPR, realtype,
10020 ffecom_1 (REALPART_EXPR, realtype,
10022 ffecom_2 (code, type,
10023 ffecom_1 (IMAGPART_EXPR, realtype,
10025 ffecom_1 (IMAGPART_EXPR, realtype,
10030 item = build (code, type, node1, node2);
10034 if (TREE_SIDE_EFFECTS (node1) || TREE_SIDE_EFFECTS (node2))
10035 TREE_SIDE_EFFECTS (item) = 1;
10036 return fold (item);
10040 /* ffecom_2pass_advise_entrypoint -- Advise that there's this entrypoint
10042 ffesymbol s; // the ENTRY point itself
10043 if (ffecom_2pass_advise_entrypoint(s))
10044 // the ENTRY point has been accepted
10046 Does whatever compiler needs to do when it learns about the entrypoint,
10047 like determine the return type of the master function, count the
10048 number of entrypoints, etc. Returns FALSE if the return type is
10049 not compatible with the return type(s) of other entrypoint(s).
10051 NOTE: for every call to this fn that returns TRUE, _do_entrypoint must
10052 later (after _finish_progunit) be called with the same entrypoint(s)
10053 as passed to this fn for which TRUE was returned.
10056 Return FALSE if the return type conflicts with previous entrypoints. */
10058 #if FFECOM_targetCURRENT == FFECOM_targetGCC
10060 ffecom_2pass_advise_entrypoint (ffesymbol entry)
10062 ffebld list; /* opITEM. */
10063 ffebld mlist; /* opITEM. */
10064 ffebld plist; /* opITEM. */
10065 ffebld arg; /* ffebld_head(opITEM). */
10066 ffebld item; /* opITEM. */
10067 ffesymbol s; /* ffebld_symter(arg). */
10068 ffeinfoBasictype bt = ffesymbol_basictype (entry);
10069 ffeinfoKindtype kt = ffesymbol_kindtype (entry);
10070 ffetargetCharacterSize size = ffesymbol_size (entry);
10073 if (ffecom_num_entrypoints_ == 0)
10074 { /* First entrypoint, make list of main
10075 arglist's dummies. */
10076 assert (ffecom_primary_entry_ != NULL);
10078 ffecom_master_bt_ = ffesymbol_basictype (ffecom_primary_entry_);
10079 ffecom_master_kt_ = ffesymbol_kindtype (ffecom_primary_entry_);
10080 ffecom_master_size_ = ffesymbol_size (ffecom_primary_entry_);
10082 for (plist = NULL, list = ffesymbol_dummyargs (ffecom_primary_entry_);
10084 list = ffebld_trail (list))
10086 arg = ffebld_head (list);
10087 if (ffebld_op (arg) != FFEBLD_opSYMTER)
10088 continue; /* Alternate return or some such thing. */
10089 item = ffebld_new_item (arg, NULL);
10091 ffecom_master_arglist_ = item;
10093 ffebld_set_trail (plist, item);
10098 /* If necessary, scan entry arglist for alternate returns. Do this scan
10099 apparently redundantly (it's done below to UNIONize the arglists) so
10100 that we don't complain about RETURN 1 if an offending ENTRY is the only
10101 one with an alternate return. */
10103 if (!ffecom_is_altreturning_)
10105 for (list = ffesymbol_dummyargs (entry);
10107 list = ffebld_trail (list))
10109 arg = ffebld_head (list);
10110 if (ffebld_op (arg) == FFEBLD_opSTAR)
10112 ffecom_is_altreturning_ = TRUE;
10118 /* Now check type compatibility. */
10120 switch (ffecom_master_bt_)
10122 case FFEINFO_basictypeNONE:
10123 ok = (bt != FFEINFO_basictypeCHARACTER);
10126 case FFEINFO_basictypeCHARACTER:
10128 = (bt == FFEINFO_basictypeCHARACTER)
10129 && (kt == ffecom_master_kt_)
10130 && (size == ffecom_master_size_);
10133 case FFEINFO_basictypeANY:
10134 return FALSE; /* Just don't bother. */
10137 if (bt == FFEINFO_basictypeCHARACTER)
10143 if ((bt != ffecom_master_bt_) || (kt != ffecom_master_kt_))
10145 ffecom_master_bt_ = FFEINFO_basictypeNONE;
10146 ffecom_master_kt_ = FFEINFO_kindtypeNONE;
10153 ffebad_start (FFEBAD_ENTRY_CONFLICTS);
10154 ffest_ffebad_here_current_stmt (0);
10156 return FALSE; /* Can't handle entrypoint. */
10159 /* Entrypoint type compatible with previous types. */
10161 ++ffecom_num_entrypoints_;
10163 /* Master-arg-list = UNION(Master-arg-list,entry-arg-list). */
10165 for (list = ffesymbol_dummyargs (entry);
10167 list = ffebld_trail (list))
10169 arg = ffebld_head (list);
10170 if (ffebld_op (arg) != FFEBLD_opSYMTER)
10171 continue; /* Alternate return or some such thing. */
10172 s = ffebld_symter (arg);
10173 for (plist = NULL, mlist = ffecom_master_arglist_;
10175 plist = mlist, mlist = ffebld_trail (mlist))
10176 { /* plist points to previous item for easy
10177 appending of arg. */
10178 if (ffebld_symter (ffebld_head (mlist)) == s)
10179 break; /* Already have this arg in the master list. */
10182 continue; /* Already have this arg in the master list. */
10184 /* Append this arg to the master list. */
10186 item = ffebld_new_item (arg, NULL);
10188 ffecom_master_arglist_ = item;
10190 ffebld_set_trail (plist, item);
10197 /* ffecom_2pass_do_entrypoint -- Do compilation of entrypoint
10199 ffesymbol s; // the ENTRY point itself
10200 ffecom_2pass_do_entrypoint(s);
10202 Does whatever compiler needs to do to make the entrypoint actually
10203 happen. Must be called for each entrypoint after
10204 ffecom_finish_progunit is called. */
10206 #if FFECOM_targetCURRENT == FFECOM_targetGCC
10208 ffecom_2pass_do_entrypoint (ffesymbol entry)
10210 static int mfn_num = 0;
10211 static int ent_num;
10213 if (mfn_num != ffecom_num_fns_)
10214 { /* First entrypoint for this program unit. */
10216 mfn_num = ffecom_num_fns_;
10217 ffecom_do_entry_ (ffecom_primary_entry_, 0);
10222 --ffecom_num_entrypoints_;
10224 ffecom_do_entry_ (entry, ent_num);
10229 /* Essentially does a "fold (build (code, type, node1, node2))" while
10230 checking for certain housekeeping things. Always sets
10231 TREE_SIDE_EFFECTS. */
10233 #if FFECOM_targetCURRENT == FFECOM_targetGCC
10235 ffecom_2s (enum tree_code code, tree type, tree node1,
10240 if ((node1 == error_mark_node)
10241 || (node2 == error_mark_node)
10242 || (type == error_mark_node))
10243 return error_mark_node;
10245 item = build (code, type, node1, node2);
10246 TREE_SIDE_EFFECTS (item) = 1;
10247 return fold (item);
10251 /* Essentially does a "fold (build (code, type, node1, node2, node3))" while
10252 checking for certain housekeeping things. */
10254 #if FFECOM_targetCURRENT == FFECOM_targetGCC
10256 ffecom_3 (enum tree_code code, tree type, tree node1,
10257 tree node2, tree node3)
10261 if ((node1 == error_mark_node)
10262 || (node2 == error_mark_node)
10263 || (node3 == error_mark_node)
10264 || (type == error_mark_node))
10265 return error_mark_node;
10267 item = build (code, type, node1, node2, node3);
10268 if (TREE_SIDE_EFFECTS (node1) || TREE_SIDE_EFFECTS (node2)
10269 || (node3 != NULL_TREE && TREE_SIDE_EFFECTS (node3)))
10270 TREE_SIDE_EFFECTS (item) = 1;
10271 return fold (item);
10275 /* Essentially does a "fold (build (code, type, node1, node2, node3))" while
10276 checking for certain housekeeping things. Always sets
10277 TREE_SIDE_EFFECTS. */
10279 #if FFECOM_targetCURRENT == FFECOM_targetGCC
10281 ffecom_3s (enum tree_code code, tree type, tree node1,
10282 tree node2, tree node3)
10286 if ((node1 == error_mark_node)
10287 || (node2 == error_mark_node)
10288 || (node3 == error_mark_node)
10289 || (type == error_mark_node))
10290 return error_mark_node;
10292 item = build (code, type, node1, node2, node3);
10293 TREE_SIDE_EFFECTS (item) = 1;
10294 return fold (item);
10299 /* ffecom_arg_expr -- Transform argument expr into gcc tree
10301 See use by ffecom_list_expr.
10303 If expression is NULL, returns an integer zero tree. If it is not
10304 a CHARACTER expression, returns whatever ffecom_expr
10305 returns and sets the length return value to NULL_TREE. Otherwise
10306 generates code to evaluate the character expression, returns the proper
10307 pointer to the result, but does NOT set the length return value to a tree
10308 that specifies the length of the result. (In other words, the length
10309 variable is always set to NULL_TREE, because a length is never passed.)
10312 Don't set returned length, since nobody needs it (yet; someday if
10313 we allow CHARACTER*(*) dummies to statement functions, we'll need
10316 #if FFECOM_targetCURRENT == FFECOM_targetGCC
10318 ffecom_arg_expr (ffebld expr, tree *length)
10322 *length = NULL_TREE;
10325 return integer_zero_node;
10327 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10328 return ffecom_expr (expr);
10330 return ffecom_arg_ptr_to_expr (expr, &ign);
10334 /* Transform expression into constant argument-pointer-to-expression tree.
10336 If the expression can be transformed into a argument-pointer-to-expression
10337 tree that is constant, that is done, and the tree returned. Else
10338 NULL_TREE is returned.
10340 That way, a caller can attempt to provide compile-time initialization
10341 of a variable and, if that fails, *then* choose to start a new block
10342 and resort to using temporaries, as appropriate. */
10345 ffecom_arg_ptr_to_const_expr (ffebld expr, tree *length)
10348 return integer_zero_node;
10350 if (ffebld_op (expr) == FFEBLD_opANY)
10353 *length = error_mark_node;
10354 return error_mark_node;
10357 if (ffebld_arity (expr) == 0
10358 && (ffebld_op (expr) != FFEBLD_opSYMTER
10359 || ffebld_where (expr) == FFEINFO_whereCOMMON
10360 || ffebld_where (expr) == FFEINFO_whereGLOBAL
10361 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
10365 t = ffecom_arg_ptr_to_expr (expr, length);
10366 assert (TREE_CONSTANT (t));
10367 assert (! length || TREE_CONSTANT (*length));
10372 && ffebld_size (expr) != FFETARGET_charactersizeNONE)
10373 *length = build_int_2 (ffebld_size (expr), 0);
10375 *length = NULL_TREE;
10379 /* ffecom_arg_ptr_to_expr -- Transform argument expr into gcc tree
10381 See use by ffecom_list_ptr_to_expr.
10383 If expression is NULL, returns an integer zero tree. If it is not
10384 a CHARACTER expression, returns whatever ffecom_ptr_to_expr
10385 returns and sets the length return value to NULL_TREE. Otherwise
10386 generates code to evaluate the character expression, returns the proper
10387 pointer to the result, AND sets the length return value to a tree that
10388 specifies the length of the result.
10390 If the length argument is NULL, this is a slightly special
10391 case of building a FORMAT expression, that is, an expression that
10392 will be used at run time without regard to length. For the current
10393 implementation, which uses the libf2c library, this means it is nice
10394 to append a null byte to the end of the expression, where feasible,
10395 to make sure any diagnostic about the FORMAT string terminates at
10398 For now, treat %REF(char-expr) as the same as char-expr with a NULL
10399 length argument. This might even be seen as a feature, if a null
10400 byte can always be appended. */
10402 #if FFECOM_targetCURRENT == FFECOM_targetGCC
10404 ffecom_arg_ptr_to_expr (ffebld expr, tree *length)
10408 ffecomConcatList_ catlist;
10410 if (length != NULL)
10411 *length = NULL_TREE;
10414 return integer_zero_node;
10416 switch (ffebld_op (expr))
10418 case FFEBLD_opPERCENT_VAL:
10419 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10420 return ffecom_expr (ffebld_left (expr));
10425 temp_exp = ffecom_arg_ptr_to_expr (ffebld_left (expr), &temp_length);
10426 if (temp_exp == error_mark_node)
10427 return error_mark_node;
10429 return ffecom_1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (temp_exp)),
10433 case FFEBLD_opPERCENT_REF:
10434 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10435 return ffecom_ptr_to_expr (ffebld_left (expr));
10436 if (length != NULL)
10438 ign_length = NULL_TREE;
10439 length = &ign_length;
10441 expr = ffebld_left (expr);
10444 case FFEBLD_opPERCENT_DESCR:
10445 switch (ffeinfo_basictype (ffebld_info (expr)))
10447 #ifdef PASS_HOLLERITH_BY_DESCRIPTOR
10448 case FFEINFO_basictypeHOLLERITH:
10450 case FFEINFO_basictypeCHARACTER:
10451 break; /* Passed by descriptor anyway. */
10454 item = ffecom_ptr_to_expr (expr);
10455 if (item != error_mark_node)
10456 *length = TYPE_SIZE (TREE_TYPE (TREE_TYPE (item)));
10465 #ifdef PASS_HOLLERITH_BY_DESCRIPTOR
10466 if ((ffeinfo_basictype (ffebld_info (expr)) == FFEINFO_basictypeHOLLERITH)
10467 && (length != NULL))
10468 { /* Pass Hollerith by descriptor. */
10469 ffetargetHollerith h;
10471 assert (ffebld_op (expr) == FFEBLD_opCONTER);
10472 h = ffebld_cu_val_hollerith (ffebld_constant_union
10473 (ffebld_conter (expr)));
10475 = build_int_2 (h.length, 0);
10476 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
10480 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10481 return ffecom_ptr_to_expr (expr);
10483 assert (ffeinfo_kindtype (ffebld_info (expr))
10484 == FFEINFO_kindtypeCHARACTER1);
10486 catlist = ffecom_concat_list_new_ (expr, FFETARGET_charactersizeNONE);
10487 switch (ffecom_concat_list_count_ (catlist))
10489 case 0: /* Shouldn't happen, but in case it does... */
10490 if (length != NULL)
10492 *length = ffecom_f2c_ftnlen_zero_node;
10493 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
10495 ffecom_concat_list_kill_ (catlist);
10496 return null_pointer_node;
10498 case 1: /* The (fairly) easy case. */
10499 if (length == NULL)
10500 ffecom_char_args_with_null_ (&item, &ign_length,
10501 ffecom_concat_list_expr_ (catlist, 0));
10503 ffecom_char_args_ (&item, length,
10504 ffecom_concat_list_expr_ (catlist, 0));
10505 ffecom_concat_list_kill_ (catlist);
10506 assert (item != NULL_TREE);
10509 default: /* Must actually concatenate things. */
10514 int count = ffecom_concat_list_count_ (catlist);
10525 ffetargetCharacterSize sz;
10527 sz = ffecom_concat_list_maxlen_ (catlist);
10529 assert (sz != FFETARGET_charactersizeNONE);
10534 = ffecom_push_tempvar (ffecom_f2c_ftnlen_type_node,
10535 FFETARGET_charactersizeNONE, count, TRUE);
10538 = ffecom_push_tempvar (ffecom_f2c_address_type_node,
10539 FFETARGET_charactersizeNONE, count, TRUE);
10540 temporary = ffecom_push_tempvar (char_type_node,
10546 hook = ffebld_nonter_hook (expr);
10548 assert (TREE_CODE (hook) == TREE_VEC);
10549 assert (TREE_VEC_LENGTH (hook) == 3);
10550 length_array = lengths = TREE_VEC_ELT (hook, 0);
10551 item_array = items = TREE_VEC_ELT (hook, 1);
10552 temporary = TREE_VEC_ELT (hook, 2);
10556 known_length = ffecom_f2c_ftnlen_zero_node;
10558 for (i = 0; i < count; ++i)
10561 && (length == NULL))
10562 ffecom_char_args_with_null_ (&citem, &clength,
10563 ffecom_concat_list_expr_ (catlist, i));
10565 ffecom_char_args_ (&citem, &clength,
10566 ffecom_concat_list_expr_ (catlist, i));
10567 if ((citem == error_mark_node)
10568 || (clength == error_mark_node))
10570 ffecom_concat_list_kill_ (catlist);
10571 *length = error_mark_node;
10572 return error_mark_node;
10576 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (items),
10577 ffecom_modify (void_type_node,
10578 ffecom_2 (ARRAY_REF,
10579 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array))),
10581 build_int_2 (i, 0)),
10584 clength = ffecom_save_tree (clength);
10585 if (length != NULL)
10587 = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
10591 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (lengths),
10592 ffecom_modify (void_type_node,
10593 ffecom_2 (ARRAY_REF,
10594 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array))),
10596 build_int_2 (i, 0)),
10601 temporary = ffecom_1 (ADDR_EXPR,
10602 build_pointer_type (TREE_TYPE (temporary)),
10605 item = build_tree_list (NULL_TREE, temporary);
10607 = build_tree_list (NULL_TREE,
10608 ffecom_1 (ADDR_EXPR,
10609 build_pointer_type (TREE_TYPE (items)),
10611 TREE_CHAIN (TREE_CHAIN (item))
10612 = build_tree_list (NULL_TREE,
10613 ffecom_1 (ADDR_EXPR,
10614 build_pointer_type (TREE_TYPE (lengths)),
10616 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item)))
10619 ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
10620 convert (ffecom_f2c_ftnlen_type_node,
10621 build_int_2 (count, 0))));
10622 num = build_int_2 (sz, 0);
10623 TREE_TYPE (num) = ffecom_f2c_ftnlen_type_node;
10624 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item))))
10625 = build_tree_list (NULL_TREE, num);
10627 item = ffecom_call_gfrt (FFECOM_gfrtCAT, item, NULL_TREE);
10628 TREE_SIDE_EFFECTS (item) = 1;
10629 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (temporary),
10633 if (length != NULL)
10634 *length = known_length;
10637 ffecom_concat_list_kill_ (catlist);
10638 assert (item != NULL_TREE);
10643 /* Generate call to run-time function.
10645 The first arg is the GNU Fortran Run-Time function index, the second
10646 arg is the list of arguments to pass to it. Returned is the expression
10647 (WITHOUT TREE_SIDE_EFFECTS set!) that makes the call and returns the
10648 result (which may be void). */
10650 #if FFECOM_targetCURRENT == FFECOM_targetGCC
10652 ffecom_call_gfrt (ffecomGfrt ix, tree args, tree hook)
10654 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
10655 ffecom_gfrt_kindtype (ix),
10656 ffe_is_f2c_library () && ffecom_gfrt_complex_[ix],
10657 NULL_TREE, args, NULL_TREE, NULL,
10658 NULL, NULL_TREE, TRUE, hook);
10662 /* Transform constant-union to tree. */
10664 #if FFECOM_targetCURRENT == FFECOM_targetGCC
10666 ffecom_constantunion (ffebldConstantUnion *cu, ffeinfoBasictype bt,
10667 ffeinfoKindtype kt, tree tree_type)
10673 case FFEINFO_basictypeINTEGER:
10679 #if FFETARGET_okINTEGER1
10680 case FFEINFO_kindtypeINTEGER1:
10681 val = ffebld_cu_val_integer1 (*cu);
10685 #if FFETARGET_okINTEGER2
10686 case FFEINFO_kindtypeINTEGER2:
10687 val = ffebld_cu_val_integer2 (*cu);
10691 #if FFETARGET_okINTEGER3
10692 case FFEINFO_kindtypeINTEGER3:
10693 val = ffebld_cu_val_integer3 (*cu);
10697 #if FFETARGET_okINTEGER4
10698 case FFEINFO_kindtypeINTEGER4:
10699 val = ffebld_cu_val_integer4 (*cu);
10704 assert ("bad INTEGER constant kind type" == NULL);
10705 /* Fall through. */
10706 case FFEINFO_kindtypeANY:
10707 return error_mark_node;
10709 item = build_int_2 (val, (val < 0) ? -1 : 0);
10710 TREE_TYPE (item) = tree_type;
10714 case FFEINFO_basictypeLOGICAL:
10720 #if FFETARGET_okLOGICAL1
10721 case FFEINFO_kindtypeLOGICAL1:
10722 val = ffebld_cu_val_logical1 (*cu);
10726 #if FFETARGET_okLOGICAL2
10727 case FFEINFO_kindtypeLOGICAL2:
10728 val = ffebld_cu_val_logical2 (*cu);
10732 #if FFETARGET_okLOGICAL3
10733 case FFEINFO_kindtypeLOGICAL3:
10734 val = ffebld_cu_val_logical3 (*cu);
10738 #if FFETARGET_okLOGICAL4
10739 case FFEINFO_kindtypeLOGICAL4:
10740 val = ffebld_cu_val_logical4 (*cu);
10745 assert ("bad LOGICAL constant kind type" == NULL);
10746 /* Fall through. */
10747 case FFEINFO_kindtypeANY:
10748 return error_mark_node;
10750 item = build_int_2 (val, (val < 0) ? -1 : 0);
10751 TREE_TYPE (item) = tree_type;
10755 case FFEINFO_basictypeREAL:
10757 REAL_VALUE_TYPE val;
10761 #if FFETARGET_okREAL1
10762 case FFEINFO_kindtypeREAL1:
10763 val = ffetarget_value_real1 (ffebld_cu_val_real1 (*cu));
10767 #if FFETARGET_okREAL2
10768 case FFEINFO_kindtypeREAL2:
10769 val = ffetarget_value_real2 (ffebld_cu_val_real2 (*cu));
10773 #if FFETARGET_okREAL3
10774 case FFEINFO_kindtypeREAL3:
10775 val = ffetarget_value_real3 (ffebld_cu_val_real3 (*cu));
10779 #if FFETARGET_okREAL4
10780 case FFEINFO_kindtypeREAL4:
10781 val = ffetarget_value_real4 (ffebld_cu_val_real4 (*cu));
10786 assert ("bad REAL constant kind type" == NULL);
10787 /* Fall through. */
10788 case FFEINFO_kindtypeANY:
10789 return error_mark_node;
10791 item = build_real (tree_type, val);
10795 case FFEINFO_basictypeCOMPLEX:
10797 REAL_VALUE_TYPE real;
10798 REAL_VALUE_TYPE imag;
10799 tree el_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
10803 #if FFETARGET_okCOMPLEX1
10804 case FFEINFO_kindtypeREAL1:
10805 real = ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu).real);
10806 imag = ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu).imaginary);
10810 #if FFETARGET_okCOMPLEX2
10811 case FFEINFO_kindtypeREAL2:
10812 real = ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu).real);
10813 imag = ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu).imaginary);
10817 #if FFETARGET_okCOMPLEX3
10818 case FFEINFO_kindtypeREAL3:
10819 real = ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu).real);
10820 imag = ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu).imaginary);
10824 #if FFETARGET_okCOMPLEX4
10825 case FFEINFO_kindtypeREAL4:
10826 real = ffetarget_value_real4 (ffebld_cu_val_complex4 (*cu).real);
10827 imag = ffetarget_value_real4 (ffebld_cu_val_complex4 (*cu).imaginary);
10832 assert ("bad REAL constant kind type" == NULL);
10833 /* Fall through. */
10834 case FFEINFO_kindtypeANY:
10835 return error_mark_node;
10837 item = ffecom_build_complex_constant_ (tree_type,
10838 build_real (el_type, real),
10839 build_real (el_type, imag));
10843 case FFEINFO_basictypeCHARACTER:
10844 { /* Happens only in DATA and similar contexts. */
10845 ffetargetCharacter1 val;
10849 #if FFETARGET_okCHARACTER1
10850 case FFEINFO_kindtypeLOGICAL1:
10851 val = ffebld_cu_val_character1 (*cu);
10856 assert ("bad CHARACTER constant kind type" == NULL);
10857 /* Fall through. */
10858 case FFEINFO_kindtypeANY:
10859 return error_mark_node;
10861 item = build_string (ffetarget_length_character1 (val),
10862 ffetarget_text_character1 (val));
10864 = build_type_variant (build_array_type (char_type_node,
10866 (integer_type_node,
10869 (ffetarget_length_character1
10875 case FFEINFO_basictypeHOLLERITH:
10877 ffetargetHollerith h;
10879 h = ffebld_cu_val_hollerith (*cu);
10881 /* If not at least as wide as default INTEGER, widen it. */
10882 if (h.length >= FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE)
10883 item = build_string (h.length, h.text);
10886 char str[FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE];
10888 memcpy (str, h.text, h.length);
10889 memset (&str[h.length], ' ',
10890 FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE
10892 item = build_string (FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE,
10896 = build_type_variant (build_array_type (char_type_node,
10898 (integer_type_node,
10906 case FFEINFO_basictypeTYPELESS:
10908 ffetargetInteger1 ival;
10909 ffetargetTypeless tless;
10912 tless = ffebld_cu_val_typeless (*cu);
10913 error = ffetarget_convert_integer1_typeless (&ival, tless);
10914 assert (error == FFEBAD);
10916 item = build_int_2 ((int) ival, 0);
10921 assert ("not yet on constant type" == NULL);
10922 /* Fall through. */
10923 case FFEINFO_basictypeANY:
10924 return error_mark_node;
10927 TREE_CONSTANT (item) = 1;
10934 /* Transform expression into constant tree.
10936 If the expression can be transformed into a tree that is constant,
10937 that is done, and the tree returned. Else NULL_TREE is returned.
10939 That way, a caller can attempt to provide compile-time initialization
10940 of a variable and, if that fails, *then* choose to start a new block
10941 and resort to using temporaries, as appropriate. */
10944 ffecom_const_expr (ffebld expr)
10947 return integer_zero_node;
10949 if (ffebld_op (expr) == FFEBLD_opANY)
10950 return error_mark_node;
10952 if (ffebld_arity (expr) == 0
10953 && (ffebld_op (expr) != FFEBLD_opSYMTER
10955 /* ~~Enable once common/equivalence is handled properly? */
10956 || ffebld_where (expr) == FFEINFO_whereCOMMON
10958 || ffebld_where (expr) == FFEINFO_whereGLOBAL
10959 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
10963 t = ffecom_expr (expr);
10964 assert (TREE_CONSTANT (t));
10971 /* Handy way to make a field in a struct/union. */
10973 #if FFECOM_targetCURRENT == FFECOM_targetGCC
10975 ffecom_decl_field (tree context, tree prevfield,
10976 const char *name, tree type)
10980 field = build_decl (FIELD_DECL, get_identifier (name), type);
10981 DECL_CONTEXT (field) = context;
10982 DECL_FRAME_SIZE (field) = 0;
10983 if (prevfield != NULL_TREE)
10984 TREE_CHAIN (prevfield) = field;
10992 ffecom_close_include (FILE *f)
10994 #if FFECOM_GCC_INCLUDE
10995 ffecom_close_include_ (f);
11000 ffecom_decode_include_option (char *spec)
11002 #if FFECOM_GCC_INCLUDE
11003 return ffecom_decode_include_option_ (spec);
11009 /* End a compound statement (block). */
11011 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11013 ffecom_end_compstmt (void)
11015 return bison_rule_compstmt_ ();
11017 #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
11019 /* ffecom_end_transition -- Perform end transition on all symbols
11021 ffecom_end_transition();
11023 Calls ffecom_sym_end_transition for each global and local symbol. */
11026 ffecom_end_transition ()
11028 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11032 if (ffe_is_ffedebug ())
11033 fprintf (dmpout, "; end_stmt_transition\n");
11035 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11036 ffecom_list_blockdata_ = NULL;
11037 ffecom_list_common_ = NULL;
11040 ffesymbol_drive (ffecom_sym_end_transition);
11041 if (ffe_is_ffedebug ())
11043 ffestorag_report ();
11044 #if FFECOM_targetCURRENT == FFECOM_targetFFE
11045 ffesymbol_report_all ();
11049 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11050 ffecom_start_progunit_ ();
11052 for (item = ffecom_list_blockdata_;
11054 item = ffebld_trail (item))
11062 static int number = 0;
11064 callee = ffebld_head (item);
11065 s = ffebld_symter (callee);
11066 t = ffesymbol_hook (s).decl_tree;
11067 if (t == NULL_TREE)
11069 s = ffecom_sym_transform_ (s);
11070 t = ffesymbol_hook (s).decl_tree;
11073 yes = suspend_momentary ();
11075 dt = build_pointer_type (TREE_TYPE (t));
11077 var = build_decl (VAR_DECL,
11078 ffecom_get_invented_identifier ("__g77_forceload_%d",
11081 DECL_EXTERNAL (var) = 0;
11082 TREE_STATIC (var) = 1;
11083 TREE_PUBLIC (var) = 0;
11084 DECL_INITIAL (var) = error_mark_node;
11085 TREE_USED (var) = 1;
11087 var = start_decl (var, FALSE);
11089 t = ffecom_1 (ADDR_EXPR, dt, t);
11091 finish_decl (var, t, FALSE);
11093 resume_momentary (yes);
11096 /* This handles any COMMON areas that weren't referenced but have, for
11097 example, important initial data. */
11099 for (item = ffecom_list_common_;
11101 item = ffebld_trail (item))
11102 ffecom_transform_common_ (ffebld_symter (ffebld_head (item)));
11104 ffecom_list_common_ = NULL;
11108 /* ffecom_exec_transition -- Perform exec transition on all symbols
11110 ffecom_exec_transition();
11112 Calls ffecom_sym_exec_transition for each global and local symbol.
11113 Make sure error updating not inhibited. */
11116 ffecom_exec_transition ()
11120 if (ffe_is_ffedebug ())
11121 fprintf (dmpout, "; exec_stmt_transition\n");
11123 inhibited = ffebad_inhibit ();
11124 ffebad_set_inhibit (FALSE);
11126 ffesymbol_drive (ffecom_sym_exec_transition); /* Don't retract! */
11127 ffeequiv_exec_transition (); /* Handle all pending EQUIVALENCEs. */
11128 if (ffe_is_ffedebug ())
11130 ffestorag_report ();
11131 #if FFECOM_targetCURRENT == FFECOM_targetFFE
11132 ffesymbol_report_all ();
11137 ffebad_set_inhibit (TRUE);
11140 /* Handle assignment statement.
11142 Convert dest and source using ffecom_expr, then join them
11143 with an ASSIGN op and pass the whole thing to expand_expr_stmt. */
11145 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11147 ffecom_expand_let_stmt (ffebld dest, ffebld source)
11154 if (ffeinfo_basictype (ffebld_info (dest)) != FFEINFO_basictypeCHARACTER)
11158 /* This attempts to replicate the test below, but must not be
11159 true when the test below is false. (Always err on the side
11160 of creating unused temporaries, to avoid ICEs.) */
11161 if (ffebld_op (dest) != FFEBLD_opSYMTER
11162 || ((dest_tree = ffesymbol_hook (ffebld_symter (dest)).decl_tree)
11163 && (TREE_CODE (dest_tree) != VAR_DECL
11164 || TREE_ADDRESSABLE (dest_tree))))
11166 ffecom_prepare_expr_ (source, dest);
11171 ffecom_prepare_expr_ (source, NULL);
11175 ffecom_prepare_expr_w (NULL_TREE, dest);
11177 ffecom_prepare_end ();
11179 dest_tree = ffecom_expr_w (NULL_TREE, dest);
11180 if (dest_tree == error_mark_node)
11183 if ((TREE_CODE (dest_tree) != VAR_DECL)
11184 || TREE_ADDRESSABLE (dest_tree))
11185 source_tree = ffecom_expr_ (source, dest_tree, dest, &dest_used,
11189 assert (! dest_used);
11191 source_tree = ffecom_expr (source);
11193 if (source_tree == error_mark_node)
11197 expr_tree = source_tree;
11199 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
11203 expand_expr_stmt (expr_tree);
11207 ffecom_prepare_let_char_ (ffebld_size_known (dest), source);
11208 ffecom_prepare_expr_w (NULL_TREE, dest);
11210 ffecom_prepare_end ();
11212 ffecom_char_args_ (&dest_tree, &dest_length, dest);
11213 ffecom_let_char_ (dest_tree, dest_length, ffebld_size_known (dest),
11218 /* ffecom_expr -- Transform expr into gcc tree
11221 ffebld expr; // FFE expression.
11222 tree = ffecom_expr(expr);
11224 Recursive descent on expr while making corresponding tree nodes and
11225 attaching type info and such. */
11227 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11229 ffecom_expr (ffebld expr)
11231 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, FALSE, FALSE);
11235 /* Like ffecom_expr, but return tree usable for assigned GOTO or FORMAT. */
11237 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11239 ffecom_expr_assign (ffebld expr)
11241 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, TRUE, FALSE);
11245 /* Like ffecom_expr_rw, but return tree usable for ASSIGN. */
11247 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11249 ffecom_expr_assign_w (ffebld expr)
11251 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, TRUE, FALSE);
11255 /* Transform expr for use as into read/write tree and stabilize the
11256 reference. Not for use on CHARACTER expressions.
11258 Recursive descent on expr while making corresponding tree nodes and
11259 attaching type info and such. */
11261 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11263 ffecom_expr_rw (tree type, ffebld expr)
11265 assert (expr != NULL);
11266 /* Different target types not yet supported. */
11267 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
11269 return stabilize_reference (ffecom_expr (expr));
11273 /* Transform expr for use as into write tree and stabilize the
11274 reference. Not for use on CHARACTER expressions.
11276 Recursive descent on expr while making corresponding tree nodes and
11277 attaching type info and such. */
11279 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11281 ffecom_expr_w (tree type, ffebld expr)
11283 assert (expr != NULL);
11284 /* Different target types not yet supported. */
11285 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
11287 return stabilize_reference (ffecom_expr (expr));
11291 /* Do global stuff. */
11293 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11295 ffecom_finish_compile ()
11297 assert (ffecom_outer_function_decl_ == NULL_TREE);
11298 assert (current_function_decl == NULL_TREE);
11300 ffeglobal_drive (ffecom_finish_global_);
11304 /* Public entry point for front end to access finish_decl. */
11306 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11308 ffecom_finish_decl (tree decl, tree init, bool is_top_level)
11310 assert (!is_top_level);
11311 finish_decl (decl, init, FALSE);
11315 /* Finish a program unit. */
11317 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11319 ffecom_finish_progunit ()
11321 ffecom_end_compstmt ();
11323 ffecom_previous_function_decl_ = current_function_decl;
11324 ffecom_which_entrypoint_decl_ = NULL_TREE;
11326 finish_function (0);
11330 /* Wrapper for get_identifier. pattern is sprintf-like, assumed to contain
11331 one %s if text is not NULL, assumed to contain one %d if number is
11332 not -1. If both are assumed, the %s is assumed to precede the %d. */
11334 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11336 ffecom_get_invented_identifier (const char *pattern, const char *text,
11346 lenlen += strlen (text);
11349 if (text || number != -1)
11351 lenlen += strlen (pattern);
11352 if (lenlen > ARRAY_SIZE (space))
11353 nam = malloc_new_ks (malloc_pool_image (), pattern, lenlen);
11360 nam = (char *) pattern;
11366 sprintf (&nam[0], pattern, number);
11371 sprintf (&nam[0], pattern, text);
11373 sprintf (&nam[0], pattern, text, number);
11376 decl = get_identifier (nam);
11378 if (lenlen > ARRAY_SIZE (space))
11379 malloc_kill_ks (malloc_pool_image (), nam, lenlen);
11381 IDENTIFIER_INVENTED (decl) = 1;
11387 ffecom_gfrt_basictype (ffecomGfrt gfrt)
11389 assert (gfrt < FFECOM_gfrt);
11391 switch (ffecom_gfrt_type_[gfrt])
11393 case FFECOM_rttypeVOID_:
11394 case FFECOM_rttypeVOIDSTAR_:
11395 return FFEINFO_basictypeNONE;
11397 case FFECOM_rttypeFTNINT_:
11398 return FFEINFO_basictypeINTEGER;
11400 case FFECOM_rttypeINTEGER_:
11401 return FFEINFO_basictypeINTEGER;
11403 case FFECOM_rttypeLONGINT_:
11404 return FFEINFO_basictypeINTEGER;
11406 case FFECOM_rttypeLOGICAL_:
11407 return FFEINFO_basictypeLOGICAL;
11409 case FFECOM_rttypeREAL_F2C_:
11410 case FFECOM_rttypeREAL_GNU_:
11411 return FFEINFO_basictypeREAL;
11413 case FFECOM_rttypeCOMPLEX_F2C_:
11414 case FFECOM_rttypeCOMPLEX_GNU_:
11415 return FFEINFO_basictypeCOMPLEX;
11417 case FFECOM_rttypeDOUBLE_:
11418 case FFECOM_rttypeDOUBLEREAL_:
11419 return FFEINFO_basictypeREAL;
11421 case FFECOM_rttypeDBLCMPLX_F2C_:
11422 case FFECOM_rttypeDBLCMPLX_GNU_:
11423 return FFEINFO_basictypeCOMPLEX;
11425 case FFECOM_rttypeCHARACTER_:
11426 return FFEINFO_basictypeCHARACTER;
11429 return FFEINFO_basictypeANY;
11434 ffecom_gfrt_kindtype (ffecomGfrt gfrt)
11436 assert (gfrt < FFECOM_gfrt);
11438 switch (ffecom_gfrt_type_[gfrt])
11440 case FFECOM_rttypeVOID_:
11441 case FFECOM_rttypeVOIDSTAR_:
11442 return FFEINFO_kindtypeNONE;
11444 case FFECOM_rttypeFTNINT_:
11445 return FFEINFO_kindtypeINTEGER1;
11447 case FFECOM_rttypeINTEGER_:
11448 return FFEINFO_kindtypeINTEGER1;
11450 case FFECOM_rttypeLONGINT_:
11451 return FFEINFO_kindtypeINTEGER4;
11453 case FFECOM_rttypeLOGICAL_:
11454 return FFEINFO_kindtypeLOGICAL1;
11456 case FFECOM_rttypeREAL_F2C_:
11457 case FFECOM_rttypeREAL_GNU_:
11458 return FFEINFO_kindtypeREAL1;
11460 case FFECOM_rttypeCOMPLEX_F2C_:
11461 case FFECOM_rttypeCOMPLEX_GNU_:
11462 return FFEINFO_kindtypeREAL1;
11464 case FFECOM_rttypeDOUBLE_:
11465 case FFECOM_rttypeDOUBLEREAL_:
11466 return FFEINFO_kindtypeREAL2;
11468 case FFECOM_rttypeDBLCMPLX_F2C_:
11469 case FFECOM_rttypeDBLCMPLX_GNU_:
11470 return FFEINFO_kindtypeREAL2;
11472 case FFECOM_rttypeCHARACTER_:
11473 return FFEINFO_kindtypeCHARACTER1;
11476 return FFEINFO_kindtypeANY;
11491 /* This block of code comes from the now-obsolete cktyps.c. It checks
11492 whether the compiler environment is buggy in known ways, some of which
11493 would, if not explicitly checked here, result in subtle bugs in g77. */
11495 if (ffe_is_do_internal_checks ())
11497 static char names[][12]
11499 {"bar", "bletch", "foo", "foobar"};
11504 name = bsearch ("foo", &names[0], ARRAY_SIZE (names), sizeof (names[0]),
11505 (int (*)()) strcmp);
11506 if (name != (char *) &names[2])
11508 assert ("bsearch doesn't work, #define FFEPROJ_BSEARCH 0 in proj.h"
11513 ul = strtoul ("123456789", NULL, 10);
11514 if (ul != 123456789L)
11516 assert ("strtoul doesn't have enough range, #define FFEPROJ_STRTOUL 0\
11517 in proj.h" == NULL);
11521 fl = atof ("56.789");
11522 if ((fl < 56.788) || (fl > 56.79))
11524 assert ("atof not type double, fix your #include <stdio.h>"
11530 /* Set the sizetype before we do anything else. This _should_ be the
11531 first type we create. */
11533 t = make_unsigned_type (POINTER_SIZE);
11534 assert (t == sizetype);
11536 #if FFECOM_GCC_INCLUDE
11537 ffecom_initialize_char_syntax_ ();
11540 ffecom_outer_function_decl_ = NULL_TREE;
11541 current_function_decl = NULL_TREE;
11542 named_labels = NULL_TREE;
11543 current_binding_level = NULL_BINDING_LEVEL;
11544 free_binding_level = NULL_BINDING_LEVEL;
11545 /* Make the binding_level structure for global names. */
11547 global_binding_level = current_binding_level;
11548 current_binding_level->prep_state = 2;
11550 /* Define `int' and `char' first so that dbx will output them first. */
11552 integer_type_node = make_signed_type (INT_TYPE_SIZE);
11553 pushdecl (build_decl (TYPE_DECL, get_identifier ("int"),
11554 integer_type_node));
11556 char_type_node = make_unsigned_type (CHAR_TYPE_SIZE);
11557 pushdecl (build_decl (TYPE_DECL, get_identifier ("char"),
11560 long_integer_type_node = make_signed_type (LONG_TYPE_SIZE);
11561 pushdecl (build_decl (TYPE_DECL, get_identifier ("long int"),
11562 long_integer_type_node));
11564 unsigned_type_node = make_unsigned_type (INT_TYPE_SIZE);
11565 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned int"),
11566 unsigned_type_node));
11568 long_unsigned_type_node = make_unsigned_type (LONG_TYPE_SIZE);
11569 pushdecl (build_decl (TYPE_DECL, get_identifier ("long unsigned int"),
11570 long_unsigned_type_node));
11572 long_long_integer_type_node = make_signed_type (LONG_LONG_TYPE_SIZE);
11573 pushdecl (build_decl (TYPE_DECL, get_identifier ("long long int"),
11574 long_long_integer_type_node));
11576 long_long_unsigned_type_node = make_unsigned_type (LONG_LONG_TYPE_SIZE);
11577 pushdecl (build_decl (TYPE_DECL, get_identifier ("long long unsigned int"),
11578 long_long_unsigned_type_node));
11580 error_mark_node = make_node (ERROR_MARK);
11581 TREE_TYPE (error_mark_node) = error_mark_node;
11583 short_integer_type_node = make_signed_type (SHORT_TYPE_SIZE);
11584 pushdecl (build_decl (TYPE_DECL, get_identifier ("short int"),
11585 short_integer_type_node));
11587 short_unsigned_type_node = make_unsigned_type (SHORT_TYPE_SIZE);
11588 pushdecl (build_decl (TYPE_DECL, get_identifier ("short unsigned int"),
11589 short_unsigned_type_node));
11591 /* Define both `signed char' and `unsigned char'. */
11592 signed_char_type_node = make_signed_type (CHAR_TYPE_SIZE);
11593 pushdecl (build_decl (TYPE_DECL, get_identifier ("signed char"),
11594 signed_char_type_node));
11596 unsigned_char_type_node = make_unsigned_type (CHAR_TYPE_SIZE);
11597 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned char"),
11598 unsigned_char_type_node));
11600 float_type_node = make_node (REAL_TYPE);
11601 TYPE_PRECISION (float_type_node) = FLOAT_TYPE_SIZE;
11602 layout_type (float_type_node);
11603 pushdecl (build_decl (TYPE_DECL, get_identifier ("float"),
11606 double_type_node = make_node (REAL_TYPE);
11607 TYPE_PRECISION (double_type_node) = DOUBLE_TYPE_SIZE;
11608 layout_type (double_type_node);
11609 pushdecl (build_decl (TYPE_DECL, get_identifier ("double"),
11610 double_type_node));
11612 long_double_type_node = make_node (REAL_TYPE);
11613 TYPE_PRECISION (long_double_type_node) = LONG_DOUBLE_TYPE_SIZE;
11614 layout_type (long_double_type_node);
11615 pushdecl (build_decl (TYPE_DECL, get_identifier ("long double"),
11616 long_double_type_node));
11618 complex_integer_type_node = ffecom_make_complex_type_ (integer_type_node);
11619 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex int"),
11620 complex_integer_type_node));
11622 complex_float_type_node = ffecom_make_complex_type_ (float_type_node);
11623 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex float"),
11624 complex_float_type_node));
11626 complex_double_type_node = ffecom_make_complex_type_ (double_type_node);
11627 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex double"),
11628 complex_double_type_node));
11630 complex_long_double_type_node = ffecom_make_complex_type_ (long_double_type_node);
11631 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex long double"),
11632 complex_long_double_type_node));
11634 integer_zero_node = build_int_2 (0, 0);
11635 TREE_TYPE (integer_zero_node) = integer_type_node;
11636 integer_one_node = build_int_2 (1, 0);
11637 TREE_TYPE (integer_one_node) = integer_type_node;
11639 size_zero_node = build_int_2 (0, 0);
11640 TREE_TYPE (size_zero_node) = sizetype;
11641 size_one_node = build_int_2 (1, 0);
11642 TREE_TYPE (size_one_node) = sizetype;
11644 void_type_node = make_node (VOID_TYPE);
11645 pushdecl (build_decl (TYPE_DECL, get_identifier ("void"),
11647 layout_type (void_type_node); /* Uses integer_zero_node */
11648 /* We are not going to have real types in C with less than byte alignment,
11649 so we might as well not have any types that claim to have it. */
11650 TYPE_ALIGN (void_type_node) = BITS_PER_UNIT;
11652 null_pointer_node = build_int_2 (0, 0);
11653 TREE_TYPE (null_pointer_node) = build_pointer_type (void_type_node);
11654 layout_type (TREE_TYPE (null_pointer_node));
11656 string_type_node = build_pointer_type (char_type_node);
11658 ffecom_tree_fun_type_void
11659 = build_function_type (void_type_node, NULL_TREE);
11661 ffecom_tree_ptr_to_fun_type_void
11662 = build_pointer_type (ffecom_tree_fun_type_void);
11664 endlink = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
11667 = build_function_type (float_type_node,
11668 tree_cons (NULL_TREE, float_type_node, endlink));
11670 double_ftype_double
11671 = build_function_type (double_type_node,
11672 tree_cons (NULL_TREE, double_type_node, endlink));
11674 ldouble_ftype_ldouble
11675 = build_function_type (long_double_type_node,
11676 tree_cons (NULL_TREE, long_double_type_node,
11679 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11680 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11682 ffecom_tree_type[i][j] = NULL_TREE;
11683 ffecom_tree_fun_type[i][j] = NULL_TREE;
11684 ffecom_tree_ptr_to_fun_type[i][j] = NULL_TREE;
11685 ffecom_f2c_typecode_[i][j] = -1;
11688 /* Set up standard g77 types. Note that INTEGER and LOGICAL are set
11689 to size FLOAT_TYPE_SIZE because they have to be the same size as
11690 REAL, which also is FLOAT_TYPE_SIZE, according to the standard.
11691 Compiler options and other such stuff that change the ways these
11692 types are set should not affect this particular setup. */
11694 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER1]
11695 = t = make_signed_type (FLOAT_TYPE_SIZE);
11696 pushdecl (build_decl (TYPE_DECL, get_identifier ("integer"),
11698 type = ffetype_new ();
11700 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER1,
11702 ffetype_set_ams (type,
11703 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11704 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11705 ffetype_set_star (base_type,
11706 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11708 ffetype_set_kind (base_type, 1, type);
11709 assert (ffetype_size (type) == sizeof (ffetargetInteger1));
11711 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER1]
11712 = t = make_unsigned_type (FLOAT_TYPE_SIZE); /* HOLLERITH means unsigned. */
11713 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned"),
11716 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER2]
11717 = t = make_signed_type (CHAR_TYPE_SIZE);
11718 pushdecl (build_decl (TYPE_DECL, get_identifier ("byte"),
11720 type = ffetype_new ();
11721 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER2,
11723 ffetype_set_ams (type,
11724 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11725 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11726 ffetype_set_star (base_type,
11727 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11729 ffetype_set_kind (base_type, 3, type);
11730 assert (ffetype_size (type) == sizeof (ffetargetInteger2));
11732 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER2]
11733 = t = make_unsigned_type (CHAR_TYPE_SIZE);
11734 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned byte"),
11737 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER3]
11738 = t = make_signed_type (CHAR_TYPE_SIZE * 2);
11739 pushdecl (build_decl (TYPE_DECL, get_identifier ("word"),
11741 type = ffetype_new ();
11742 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER3,
11744 ffetype_set_ams (type,
11745 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11746 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11747 ffetype_set_star (base_type,
11748 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11750 ffetype_set_kind (base_type, 6, type);
11751 assert (ffetype_size (type) == sizeof (ffetargetInteger3));
11753 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER3]
11754 = t = make_unsigned_type (CHAR_TYPE_SIZE * 2);
11755 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned word"),
11758 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER4]
11759 = t = make_signed_type (FLOAT_TYPE_SIZE * 2);
11760 pushdecl (build_decl (TYPE_DECL, get_identifier ("integer4"),
11762 type = ffetype_new ();
11763 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER4,
11765 ffetype_set_ams (type,
11766 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11767 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11768 ffetype_set_star (base_type,
11769 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11771 ffetype_set_kind (base_type, 2, type);
11772 assert (ffetype_size (type) == sizeof (ffetargetInteger4));
11774 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER4]
11775 = t = make_unsigned_type (FLOAT_TYPE_SIZE * 2);
11776 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned4"),
11780 if (ffe_is_do_internal_checks ()
11781 && LONG_TYPE_SIZE != FLOAT_TYPE_SIZE
11782 && LONG_TYPE_SIZE != CHAR_TYPE_SIZE
11783 && LONG_TYPE_SIZE != SHORT_TYPE_SIZE
11784 && LONG_TYPE_SIZE != LONG_LONG_TYPE_SIZE)
11786 fprintf (stderr, "Sorry, no g77 support for LONG_TYPE_SIZE (%d bits) yet.\n",
11791 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL1]
11792 = t = make_signed_type (FLOAT_TYPE_SIZE);
11793 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical"),
11795 type = ffetype_new ();
11797 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL1,
11799 ffetype_set_ams (type,
11800 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11801 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11802 ffetype_set_star (base_type,
11803 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11805 ffetype_set_kind (base_type, 1, type);
11806 assert (ffetype_size (type) == sizeof (ffetargetLogical1));
11808 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL2]
11809 = t = make_signed_type (CHAR_TYPE_SIZE);
11810 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical2"),
11812 type = ffetype_new ();
11813 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL2,
11815 ffetype_set_ams (type,
11816 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11817 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11818 ffetype_set_star (base_type,
11819 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11821 ffetype_set_kind (base_type, 3, type);
11822 assert (ffetype_size (type) == sizeof (ffetargetLogical2));
11824 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL3]
11825 = t = make_signed_type (CHAR_TYPE_SIZE * 2);
11826 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical3"),
11828 type = ffetype_new ();
11829 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL3,
11831 ffetype_set_ams (type,
11832 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11833 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11834 ffetype_set_star (base_type,
11835 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11837 ffetype_set_kind (base_type, 6, type);
11838 assert (ffetype_size (type) == sizeof (ffetargetLogical3));
11840 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL4]
11841 = t = make_signed_type (FLOAT_TYPE_SIZE * 2);
11842 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical4"),
11844 type = ffetype_new ();
11845 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL4,
11847 ffetype_set_ams (type,
11848 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11849 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11850 ffetype_set_star (base_type,
11851 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11853 ffetype_set_kind (base_type, 2, type);
11854 assert (ffetype_size (type) == sizeof (ffetargetLogical4));
11856 ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]
11857 = t = make_node (REAL_TYPE);
11858 TYPE_PRECISION (t) = FLOAT_TYPE_SIZE;
11859 pushdecl (build_decl (TYPE_DECL, get_identifier ("real"),
11862 type = ffetype_new ();
11864 ffeinfo_set_type (FFEINFO_basictypeREAL, FFEINFO_kindtypeREAL1,
11866 ffetype_set_ams (type,
11867 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11868 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11869 ffetype_set_star (base_type,
11870 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11872 ffetype_set_kind (base_type, 1, type);
11873 ffecom_f2c_typecode_[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]
11874 = FFETARGET_f2cTYREAL;
11875 assert (ffetype_size (type) == sizeof (ffetargetReal1));
11877 ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREALDOUBLE]
11878 = t = make_node (REAL_TYPE);
11879 TYPE_PRECISION (t) = FLOAT_TYPE_SIZE * 2; /* Always twice REAL. */
11880 pushdecl (build_decl (TYPE_DECL, get_identifier ("double precision"),
11883 type = ffetype_new ();
11884 ffeinfo_set_type (FFEINFO_basictypeREAL, FFEINFO_kindtypeREALDOUBLE,
11886 ffetype_set_ams (type,
11887 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11888 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11889 ffetype_set_star (base_type,
11890 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11892 ffetype_set_kind (base_type, 2, type);
11893 ffecom_f2c_typecode_[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2]
11894 = FFETARGET_f2cTYDREAL;
11895 assert (ffetype_size (type) == sizeof (ffetargetReal2));
11897 ffecom_tree_type[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL1]
11898 = t = ffecom_make_complex_type_ (ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]);
11899 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex"),
11901 type = ffetype_new ();
11903 ffeinfo_set_type (FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREAL1,
11905 ffetype_set_ams (type,
11906 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11907 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11908 ffetype_set_star (base_type,
11909 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11911 ffetype_set_kind (base_type, 1, type);
11912 ffecom_f2c_typecode_[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL1]
11913 = FFETARGET_f2cTYCOMPLEX;
11914 assert (ffetype_size (type) == sizeof (ffetargetComplex1));
11916 ffecom_tree_type[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREALDOUBLE]
11917 = t = ffecom_make_complex_type_ (ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2]);
11918 pushdecl (build_decl (TYPE_DECL, get_identifier ("double complex"),
11920 type = ffetype_new ();
11921 ffeinfo_set_type (FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREALDOUBLE,
11923 ffetype_set_ams (type,
11924 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11925 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11926 ffetype_set_star (base_type,
11927 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11929 ffetype_set_kind (base_type, 2,
11931 ffecom_f2c_typecode_[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL2]
11932 = FFETARGET_f2cTYDCOMPLEX;
11933 assert (ffetype_size (type) == sizeof (ffetargetComplex2));
11935 /* Make function and ptr-to-function types for non-CHARACTER types. */
11937 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11938 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11940 if ((t = ffecom_tree_type[i][j]) != NULL_TREE)
11942 if (i == FFEINFO_basictypeINTEGER)
11944 /* Figure out the smallest INTEGER type that can hold
11945 a pointer on this machine. */
11946 if (GET_MODE_SIZE (TYPE_MODE (t))
11947 >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
11949 if ((ffecom_pointer_kind_ == FFEINFO_kindtypeNONE)
11950 || (GET_MODE_SIZE (TYPE_MODE (ffecom_tree_type[i][ffecom_pointer_kind_]))
11951 > GET_MODE_SIZE (TYPE_MODE (t))))
11952 ffecom_pointer_kind_ = j;
11955 else if (i == FFEINFO_basictypeCOMPLEX)
11956 t = void_type_node;
11957 /* For f2c compatibility, REAL functions are really
11958 implemented as DOUBLE PRECISION. */
11959 else if ((i == FFEINFO_basictypeREAL)
11960 && (j == FFEINFO_kindtypeREAL1))
11961 t = ffecom_tree_type
11962 [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2];
11964 t = ffecom_tree_fun_type[i][j] = build_function_type (t,
11966 ffecom_tree_ptr_to_fun_type[i][j] = build_pointer_type (t);
11970 /* Set up pointer types. */
11972 if (ffecom_pointer_kind_ == FFEINFO_basictypeNONE)
11973 fatal ("no INTEGER type can hold a pointer on this configuration");
11974 else if (0 && ffe_is_do_internal_checks ())
11975 fprintf (stderr, "Pointer type kt=%d\n", ffecom_pointer_kind_);
11976 ffetype_set_kind (ffeinfo_type (FFEINFO_basictypeINTEGER,
11977 FFEINFO_kindtypeINTEGERDEFAULT),
11979 ffeinfo_type (FFEINFO_basictypeINTEGER,
11980 ffecom_pointer_kind_));
11982 if (ffe_is_ugly_assign ())
11983 ffecom_label_kind_ = ffecom_pointer_kind_; /* Require ASSIGN etc to this. */
11985 ffecom_label_kind_ = FFEINFO_kindtypeINTEGERDEFAULT;
11986 if (0 && ffe_is_do_internal_checks ())
11987 fprintf (stderr, "Label type kt=%d\n", ffecom_label_kind_);
11989 ffecom_integer_type_node
11990 = ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER1];
11991 ffecom_integer_zero_node = convert (ffecom_integer_type_node,
11992 integer_zero_node);
11993 ffecom_integer_one_node = convert (ffecom_integer_type_node,
11996 /* Yes, the "FLOAT_TYPE_SIZE" references below are intentional.
11997 Turns out that by TYLONG, runtime/libI77/lio.h really means
11998 "whatever size an ftnint is". For consistency and sanity,
11999 com.h and runtime/f2c.h.in agree that flag, ftnint, and ftlen
12000 all are INTEGER, which we also make out of whatever back-end
12001 integer type is FLOAT_TYPE_SIZE bits wide. This change, from
12002 LONG_TYPE_SIZE, for TYLONG and TYLOGICAL, was necessary to
12003 accommodate machines like the Alpha. Note that this suggests
12004 f2c and libf2c are missing a distinction perhaps needed on
12005 some machines between "int" and "long int". -- burley 0.5.5 950215 */
12007 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, FLOAT_TYPE_SIZE,
12008 FFETARGET_f2cTYLONG);
12009 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, SHORT_TYPE_SIZE,
12010 FFETARGET_f2cTYSHORT);
12011 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, CHAR_TYPE_SIZE,
12012 FFETARGET_f2cTYINT1);
12013 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, LONG_LONG_TYPE_SIZE,
12014 FFETARGET_f2cTYQUAD);
12015 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, FLOAT_TYPE_SIZE,
12016 FFETARGET_f2cTYLOGICAL);
12017 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, SHORT_TYPE_SIZE,
12018 FFETARGET_f2cTYLOGICAL2);
12019 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, CHAR_TYPE_SIZE,
12020 FFETARGET_f2cTYLOGICAL1);
12021 /* ~~~Not really such a type in libf2c, e.g. I/O support? */
12022 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, LONG_LONG_TYPE_SIZE,
12023 FFETARGET_f2cTYQUAD);
12025 /* CHARACTER stuff is all special-cased, so it is not handled in the above
12026 loop. CHARACTER items are built as arrays of unsigned char. */
12028 ffecom_tree_type[FFEINFO_basictypeCHARACTER]
12029 [FFEINFO_kindtypeCHARACTER1] = t = char_type_node;
12030 type = ffetype_new ();
12032 ffeinfo_set_type (FFEINFO_basictypeCHARACTER,
12033 FFEINFO_kindtypeCHARACTER1,
12035 ffetype_set_ams (type,
12036 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
12037 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
12038 ffetype_set_kind (base_type, 1, type);
12039 assert (ffetype_size (type)
12040 == sizeof (((ffetargetCharacter1) { 0, NULL }).text[0]));
12042 ffecom_tree_fun_type[FFEINFO_basictypeCHARACTER]
12043 [FFEINFO_kindtypeCHARACTER1] = ffecom_tree_fun_type_void;
12044 ffecom_tree_ptr_to_fun_type[FFEINFO_basictypeCHARACTER]
12045 [FFEINFO_kindtypeCHARACTER1]
12046 = ffecom_tree_ptr_to_fun_type_void;
12047 ffecom_f2c_typecode_[FFEINFO_basictypeCHARACTER][FFEINFO_kindtypeCHARACTER1]
12048 = FFETARGET_f2cTYCHAR;
12050 ffecom_f2c_typecode_[FFEINFO_basictypeANY][FFEINFO_kindtypeANY]
12053 /* Make multi-return-value type and fields. */
12055 ffecom_multi_type_node_ = make_node (UNION_TYPE);
12059 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
12060 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
12064 if (ffecom_tree_type[i][j] == NULL_TREE)
12065 continue; /* Not supported. */
12066 sprintf (&name[0], "bt_%s_kt_%s",
12067 ffeinfo_basictype_string ((ffeinfoBasictype) i),
12068 ffeinfo_kindtype_string ((ffeinfoKindtype) j));
12069 ffecom_multi_fields_[i][j] = build_decl (FIELD_DECL,
12070 get_identifier (name),
12071 ffecom_tree_type[i][j]);
12072 DECL_CONTEXT (ffecom_multi_fields_[i][j])
12073 = ffecom_multi_type_node_;
12074 DECL_FRAME_SIZE (ffecom_multi_fields_[i][j]) = 0;
12075 TREE_CHAIN (ffecom_multi_fields_[i][j]) = field;
12076 field = ffecom_multi_fields_[i][j];
12079 TYPE_FIELDS (ffecom_multi_type_node_) = field;
12080 layout_type (ffecom_multi_type_node_);
12082 /* Subroutines usually return integer because they might have alternate
12085 ffecom_tree_subr_type
12086 = build_function_type (integer_type_node, NULL_TREE);
12087 ffecom_tree_ptr_to_subr_type
12088 = build_pointer_type (ffecom_tree_subr_type);
12089 ffecom_tree_blockdata_type
12090 = build_function_type (void_type_node, NULL_TREE);
12092 builtin_function ("__builtin_sqrtf", float_ftype_float,
12093 BUILT_IN_FSQRT, "sqrtf");
12094 builtin_function ("__builtin_fsqrt", double_ftype_double,
12095 BUILT_IN_FSQRT, "sqrt");
12096 builtin_function ("__builtin_sqrtl", ldouble_ftype_ldouble,
12097 BUILT_IN_FSQRT, "sqrtl");
12098 builtin_function ("__builtin_sinf", float_ftype_float,
12099 BUILT_IN_SIN, "sinf");
12100 builtin_function ("__builtin_sin", double_ftype_double,
12101 BUILT_IN_SIN, "sin");
12102 builtin_function ("__builtin_sinl", ldouble_ftype_ldouble,
12103 BUILT_IN_SIN, "sinl");
12104 builtin_function ("__builtin_cosf", float_ftype_float,
12105 BUILT_IN_COS, "cosf");
12106 builtin_function ("__builtin_cos", double_ftype_double,
12107 BUILT_IN_COS, "cos");
12108 builtin_function ("__builtin_cosl", ldouble_ftype_ldouble,
12109 BUILT_IN_COS, "cosl");
12112 pedantic_lvalues = FALSE;
12115 ffecom_f2c_make_type_ (&ffecom_f2c_integer_type_node,
12118 ffecom_f2c_make_type_ (&ffecom_f2c_address_type_node,
12121 ffecom_f2c_make_type_ (&ffecom_f2c_real_type_node,
12124 ffecom_f2c_make_type_ (&ffecom_f2c_doublereal_type_node,
12125 FFECOM_f2cDOUBLEREAL,
12127 ffecom_f2c_make_type_ (&ffecom_f2c_complex_type_node,
12130 ffecom_f2c_make_type_ (&ffecom_f2c_doublecomplex_type_node,
12131 FFECOM_f2cDOUBLECOMPLEX,
12133 ffecom_f2c_make_type_ (&ffecom_f2c_longint_type_node,
12136 ffecom_f2c_make_type_ (&ffecom_f2c_logical_type_node,
12139 ffecom_f2c_make_type_ (&ffecom_f2c_flag_type_node,
12142 ffecom_f2c_make_type_ (&ffecom_f2c_ftnlen_type_node,
12145 ffecom_f2c_make_type_ (&ffecom_f2c_ftnint_type_node,
12149 ffecom_f2c_ftnlen_zero_node
12150 = convert (ffecom_f2c_ftnlen_type_node, integer_zero_node);
12152 ffecom_f2c_ftnlen_one_node
12153 = convert (ffecom_f2c_ftnlen_type_node, integer_one_node);
12155 ffecom_f2c_ftnlen_two_node = build_int_2 (2, 0);
12156 TREE_TYPE (ffecom_f2c_ftnlen_two_node) = ffecom_integer_type_node;
12158 ffecom_f2c_ptr_to_ftnlen_type_node
12159 = build_pointer_type (ffecom_f2c_ftnlen_type_node);
12161 ffecom_f2c_ptr_to_ftnint_type_node
12162 = build_pointer_type (ffecom_f2c_ftnint_type_node);
12164 ffecom_f2c_ptr_to_integer_type_node
12165 = build_pointer_type (ffecom_f2c_integer_type_node);
12167 ffecom_f2c_ptr_to_real_type_node
12168 = build_pointer_type (ffecom_f2c_real_type_node);
12170 ffecom_float_zero_ = build_real (float_type_node, dconst0);
12171 ffecom_double_zero_ = build_real (double_type_node, dconst0);
12173 REAL_VALUE_TYPE point_5;
12175 #ifdef REAL_ARITHMETIC
12176 REAL_ARITHMETIC (point_5, RDIV_EXPR, dconst1, dconst2);
12180 ffecom_float_half_ = build_real (float_type_node, point_5);
12181 ffecom_double_half_ = build_real (double_type_node, point_5);
12184 /* Do "extern int xargc;". */
12186 ffecom_tree_xargc_ = build_decl (VAR_DECL,
12187 get_identifier ("f__xargc"),
12188 integer_type_node);
12189 DECL_EXTERNAL (ffecom_tree_xargc_) = 1;
12190 TREE_STATIC (ffecom_tree_xargc_) = 1;
12191 TREE_PUBLIC (ffecom_tree_xargc_) = 1;
12192 ffecom_tree_xargc_ = start_decl (ffecom_tree_xargc_, FALSE);
12193 finish_decl (ffecom_tree_xargc_, NULL_TREE, FALSE);
12195 #if 0 /* This is being fixed, and seems to be working now. */
12196 if ((FLOAT_TYPE_SIZE != 32)
12197 || (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node))) != 32))
12199 warning ("configuration: REAL, INTEGER, and LOGICAL are %d bits wide,",
12200 (int) FLOAT_TYPE_SIZE);
12201 warning ("and pointers are %d bits wide, but g77 doesn't yet work",
12202 (int) TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node))));
12203 warning ("properly unless they all are 32 bits wide.");
12204 warning ("Please keep this in mind before you report bugs. g77 should");
12205 warning ("support non-32-bit machines better as of version 0.6.");
12209 #if 0 /* Code in ste.c that would crash has been commented out. */
12210 if (TYPE_PRECISION (ffecom_f2c_ftnlen_type_node)
12211 < TYPE_PRECISION (string_type_node))
12212 /* I/O will probably crash. */
12213 warning ("configuration: char * holds %d bits, but ftnlen only %d",
12214 TYPE_PRECISION (string_type_node),
12215 TYPE_PRECISION (ffecom_f2c_ftnlen_type_node));
12218 #if 0 /* ASSIGN-related stuff has been changed to accommodate this. */
12219 if (TYPE_PRECISION (ffecom_integer_type_node)
12220 < TYPE_PRECISION (string_type_node))
12221 /* ASSIGN 10 TO I will crash. */
12222 warning ("configuration: char * holds %d bits, but INTEGER only %d --\n\
12223 ASSIGN statement might fail",
12224 TYPE_PRECISION (string_type_node),
12225 TYPE_PRECISION (ffecom_integer_type_node));
12230 /* ffecom_init_2 -- Initialize
12232 ffecom_init_2(); */
12234 #if FFECOM_targetCURRENT == FFECOM_targetGCC
12238 assert (ffecom_outer_function_decl_ == NULL_TREE);
12239 assert (current_function_decl == NULL_TREE);
12240 assert (ffecom_which_entrypoint_decl_ == NULL_TREE);
12242 ffecom_master_arglist_ = NULL;
12244 ffecom_primary_entry_ = NULL;
12245 ffecom_is_altreturning_ = FALSE;
12246 ffecom_func_result_ = NULL_TREE;
12247 ffecom_multi_retval_ = NULL_TREE;
12251 /* ffecom_list_expr -- Transform list of exprs into gcc tree
12254 ffebld expr; // FFE opITEM list.
12255 tree = ffecom_list_expr(expr);
12257 List of actual args is transformed into corresponding gcc backend list. */
12259 #if FFECOM_targetCURRENT == FFECOM_targetGCC
12261 ffecom_list_expr (ffebld expr)
12264 tree *plist = &list;
12265 tree trail = NULL_TREE; /* Append char length args here. */
12266 tree *ptrail = &trail;
12269 while (expr != NULL)
12271 tree texpr = ffecom_arg_expr (ffebld_head (expr), &length);
12273 if (texpr == error_mark_node)
12274 return error_mark_node;
12276 *plist = build_tree_list (NULL_TREE, texpr);
12277 plist = &TREE_CHAIN (*plist);
12278 expr = ffebld_trail (expr);
12279 if (length != NULL_TREE)
12281 *ptrail = build_tree_list (NULL_TREE, length);
12282 ptrail = &TREE_CHAIN (*ptrail);
12292 /* ffecom_list_ptr_to_expr -- Transform list of exprs into gcc tree
12295 ffebld expr; // FFE opITEM list.
12296 tree = ffecom_list_ptr_to_expr(expr);
12298 List of actual args is transformed into corresponding gcc backend list for
12299 use in calling an external procedure (vs. a statement function). */
12301 #if FFECOM_targetCURRENT == FFECOM_targetGCC
12303 ffecom_list_ptr_to_expr (ffebld expr)
12306 tree *plist = &list;
12307 tree trail = NULL_TREE; /* Append char length args here. */
12308 tree *ptrail = &trail;
12311 while (expr != NULL)
12313 tree texpr = ffecom_arg_ptr_to_expr (ffebld_head (expr), &length);
12315 if (texpr == error_mark_node)
12316 return error_mark_node;
12318 *plist = build_tree_list (NULL_TREE, texpr);
12319 plist = &TREE_CHAIN (*plist);
12320 expr = ffebld_trail (expr);
12321 if (length != NULL_TREE)
12323 *ptrail = build_tree_list (NULL_TREE, length);
12324 ptrail = &TREE_CHAIN (*ptrail);
12334 /* Obtain gcc's LABEL_DECL tree for label. */
12336 #if FFECOM_targetCURRENT == FFECOM_targetGCC
12338 ffecom_lookup_label (ffelab label)
12342 if (ffelab_hook (label) == NULL_TREE)
12344 char labelname[16];
12346 switch (ffelab_type (label))
12348 case FFELAB_typeLOOPEND:
12349 case FFELAB_typeNOTLOOP:
12350 case FFELAB_typeENDIF:
12351 sprintf (labelname, "%" ffelabValue_f "u", ffelab_value (label));
12352 glabel = build_decl (LABEL_DECL, get_identifier (labelname),
12354 DECL_CONTEXT (glabel) = current_function_decl;
12355 DECL_MODE (glabel) = VOIDmode;
12358 case FFELAB_typeFORMAT:
12359 push_obstacks_nochange ();
12360 end_temporary_allocation ();
12362 glabel = build_decl (VAR_DECL,
12363 ffecom_get_invented_identifier
12364 ("__g77_format_%d", NULL,
12365 (int) ffelab_value (label)),
12366 build_type_variant (build_array_type
12370 TREE_CONSTANT (glabel) = 1;
12371 TREE_STATIC (glabel) = 1;
12372 DECL_CONTEXT (glabel) = 0;
12373 DECL_INITIAL (glabel) = NULL;
12374 make_decl_rtl (glabel, NULL, 0);
12375 expand_decl (glabel);
12377 resume_temporary_allocation ();
12382 case FFELAB_typeANY:
12383 glabel = error_mark_node;
12387 assert ("bad label type" == NULL);
12391 ffelab_set_hook (label, glabel);
12395 glabel = ffelab_hook (label);
12402 /* Stabilizes the arguments. Don't use this if the lhs and rhs come from
12403 a single source specification (as in the fourth argument of MVBITS).
12404 If the type is NULL_TREE, the type of lhs is used to make the type of
12405 the MODIFY_EXPR. */
12407 #if FFECOM_targetCURRENT == FFECOM_targetGCC
12409 ffecom_modify (tree newtype, tree lhs,
12412 if (lhs == error_mark_node || rhs == error_mark_node)
12413 return error_mark_node;
12415 if (newtype == NULL_TREE)
12416 newtype = TREE_TYPE (lhs);
12418 if (TREE_SIDE_EFFECTS (lhs))
12419 lhs = stabilize_reference (lhs);
12421 return ffecom_2s (MODIFY_EXPR, newtype, lhs, rhs);
12426 /* Register source file name. */
12429 ffecom_file (char *name)
12431 #if FFECOM_GCC_INCLUDE
12432 ffecom_file_ (name);
12436 /* ffecom_notify_init_storage -- An aggregate storage is now fully init'ed
12439 ffecom_notify_init_storage(st);
12441 Gets called when all possible units in an aggregate storage area (a LOCAL
12442 with equivalences or a COMMON) have been initialized. The initialization
12443 info either is in ffestorag_init or, if that is NULL,
12444 ffestorag_accretion:
12446 ffestorag_init may contain an opCONTER or opARRTER. opCONTER may occur
12447 even for an array if the array is one element in length!
12449 ffestorag_accretion will contain an opACCTER. It is much like an
12450 opARRTER except it has an ffebit object in it instead of just a size.
12451 The back end can use the info in the ffebit object, if it wants, to
12452 reduce the amount of actual initialization, but in any case it should
12453 kill the ffebit object when done. Also, set accretion to NULL but
12454 init to a non-NULL value.
12456 After performing initialization, DO NOT set init to NULL, because that'll
12457 tell the front end it is ok for more initialization to happen. Instead,
12458 set init to an opANY expression or some such thing that you can use to
12459 tell that you've already initialized the object.
12462 Support two-pass FFE. */
12465 ffecom_notify_init_storage (ffestorag st)
12467 ffebld init; /* The initialization expression. */
12468 #if 0 && FFECOM_targetCURRENT == FFECOM_targetGCC
12469 ffetargetOffset size; /* The size of the entity. */
12470 ffetargetAlign pad; /* Its initial padding. */
12473 if (ffestorag_init (st) == NULL)
12475 init = ffestorag_accretion (st);
12476 assert (init != NULL);
12477 ffestorag_set_accretion (st, NULL);
12478 ffestorag_set_accretes (st, 0);
12480 #if 0 && FFECOM_targetCURRENT == FFECOM_targetGCC
12481 /* For GNU backend, just turn ACCTER into ARRTER and proceed. */
12482 size = ffebld_accter_size (init);
12483 pad = ffebld_accter_pad (init);
12484 ffebit_kill (ffebld_accter_bits (init));
12485 ffebld_set_op (init, FFEBLD_opARRTER);
12486 ffebld_set_arrter (init, ffebld_accter (init));
12487 ffebld_arrter_set_size (init, size);
12488 ffebld_arrter_set_pad (init, size);
12492 ffestorag_set_init (st, init);
12497 init = ffestorag_init (st);
12500 #if FFECOM_ONEPASS /* Process the inits, wipe 'em out. */
12501 ffestorag_set_init (st, ffebld_new_any ());
12503 if (ffebld_op (init) == FFEBLD_opANY)
12504 return; /* Oh, we already did this! */
12506 #if FFECOM_targetCURRENT == FFECOM_targetFFE
12510 if (ffestorag_symbol (st) != NULL)
12511 s = ffestorag_symbol (st);
12513 s = ffestorag_typesymbol (st);
12515 fprintf (dmpout, "= initialize_storage \"%s\" ",
12516 (s != NULL) ? ffesymbol_text (s) : "(unnamed)");
12517 ffebld_dump (init);
12518 fputc ('\n', dmpout);
12522 #endif /* if FFECOM_ONEPASS */
12525 /* ffecom_notify_init_symbol -- A symbol is now fully init'ed
12528 ffecom_notify_init_symbol(s);
12530 Gets called when all possible units in a symbol (not placed in COMMON
12531 or involved in EQUIVALENCE, unless it as yet has no ffestorag object)
12532 have been initialized. The initialization info either is in
12533 ffesymbol_init or, if that is NULL, ffesymbol_accretion:
12535 ffesymbol_init may contain an opCONTER or opARRTER. opCONTER may occur
12536 even for an array if the array is one element in length!
12538 ffesymbol_accretion will contain an opACCTER. It is much like an
12539 opARRTER except it has an ffebit object in it instead of just a size.
12540 The back end can use the info in the ffebit object, if it wants, to
12541 reduce the amount of actual initialization, but in any case it should
12542 kill the ffebit object when done. Also, set accretion to NULL but
12543 init to a non-NULL value.
12545 After performing initialization, DO NOT set init to NULL, because that'll
12546 tell the front end it is ok for more initialization to happen. Instead,
12547 set init to an opANY expression or some such thing that you can use to
12548 tell that you've already initialized the object.
12551 Support two-pass FFE. */
12554 ffecom_notify_init_symbol (ffesymbol s)
12556 ffebld init; /* The initialization expression. */
12557 #if 0 && FFECOM_targetCURRENT == FFECOM_targetGCC
12558 ffetargetOffset size; /* The size of the entity. */
12559 ffetargetAlign pad; /* Its initial padding. */
12562 if (ffesymbol_storage (s) == NULL)
12563 return; /* Do nothing until COMMON/EQUIVALENCE
12564 possibilities checked. */
12566 if ((ffesymbol_init (s) == NULL)
12567 && ((init = ffesymbol_accretion (s)) != NULL))
12569 ffesymbol_set_accretion (s, NULL);
12570 ffesymbol_set_accretes (s, 0);
12572 #if 0 && FFECOM_targetCURRENT == FFECOM_targetGCC
12573 /* For GNU backend, just turn ACCTER into ARRTER and proceed. */
12574 size = ffebld_accter_size (init);
12575 pad = ffebld_accter_pad (init);
12576 ffebit_kill (ffebld_accter_bits (init));
12577 ffebld_set_op (init, FFEBLD_opARRTER);
12578 ffebld_set_arrter (init, ffebld_accter (init));
12579 ffebld_arrter_set_size (init, size);
12580 ffebld_arrter_set_pad (init, size);
12584 ffesymbol_set_init (s, init);
12589 init = ffesymbol_init (s);
12593 ffesymbol_set_init (s, ffebld_new_any ());
12595 if (ffebld_op (init) == FFEBLD_opANY)
12596 return; /* Oh, we already did this! */
12598 #if FFECOM_targetCURRENT == FFECOM_targetFFE
12599 fprintf (dmpout, "= initialize_symbol \"%s\" ", ffesymbol_text (s));
12600 ffebld_dump (init);
12601 fputc ('\n', dmpout);
12604 #endif /* if FFECOM_ONEPASS */
12607 /* ffecom_notify_primary_entry -- Learn which is the primary entry point
12610 ffecom_notify_primary_entry(s);
12612 Gets called when implicit or explicit PROGRAM statement seen or when
12613 FUNCTION, SUBROUTINE, or BLOCK DATA statement seen, with the primary
12614 global symbol that serves as the entry point. */
12617 ffecom_notify_primary_entry (ffesymbol s)
12619 ffecom_primary_entry_ = s;
12620 ffecom_primary_entry_kind_ = ffesymbol_kind (s);
12622 if ((ffecom_primary_entry_kind_ == FFEINFO_kindFUNCTION)
12623 || (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE))
12624 ffecom_primary_entry_is_proc_ = TRUE;
12626 ffecom_primary_entry_is_proc_ = FALSE;
12628 if (!ffe_is_silent ())
12630 if (ffecom_primary_entry_kind_ == FFEINFO_kindPROGRAM)
12631 fprintf (stderr, "%s:\n", ffesymbol_text (s));
12633 fprintf (stderr, " %s:\n", ffesymbol_text (s));
12636 #if FFECOM_targetCURRENT == FFECOM_targetGCC
12637 if (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE)
12642 for (list = ffesymbol_dummyargs (s);
12644 list = ffebld_trail (list))
12646 arg = ffebld_head (list);
12647 if (ffebld_op (arg) == FFEBLD_opSTAR)
12649 ffecom_is_altreturning_ = TRUE;
12658 ffecom_open_include (char *name, ffewhereLine l, ffewhereColumn c)
12660 #if FFECOM_GCC_INCLUDE
12661 return ffecom_open_include_ (name, l, c);
12663 return fopen (name, "r");
12667 /* ffecom_ptr_to_expr -- Transform expr into gcc tree with & in front
12670 ffebld expr; // FFE expression.
12671 tree = ffecom_ptr_to_expr(expr);
12673 Like ffecom_expr, but sticks address-of in front of most things. */
12675 #if FFECOM_targetCURRENT == FFECOM_targetGCC
12677 ffecom_ptr_to_expr (ffebld expr)
12680 ffeinfoBasictype bt;
12681 ffeinfoKindtype kt;
12684 assert (expr != NULL);
12686 switch (ffebld_op (expr))
12688 case FFEBLD_opSYMTER:
12689 s = ffebld_symter (expr);
12690 if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC)
12694 ix = ffeintrin_gfrt_indirect (ffebld_symter_implementation (expr));
12695 assert (ix != FFECOM_gfrt);
12696 if ((item = ffecom_gfrt_[ix]) == NULL_TREE)
12698 ffecom_make_gfrt_ (ix);
12699 item = ffecom_gfrt_[ix];
12704 item = ffesymbol_hook (s).decl_tree;
12705 if (item == NULL_TREE)
12707 s = ffecom_sym_transform_ (s);
12708 item = ffesymbol_hook (s).decl_tree;
12711 assert (item != NULL);
12712 if (item == error_mark_node)
12714 if (!ffesymbol_hook (s).addr)
12715 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12719 case FFEBLD_opARRAYREF:
12721 item = ffecom_ptr_to_expr (ffebld_left (expr));
12723 if (item == error_mark_node)
12726 if ((ffebld_where (expr) == FFEINFO_whereFLEETING)
12727 && !mark_addressable (item))
12728 return error_mark_node; /* Make sure non-const ref is to
12731 item = ffecom_arrayref_ (item, expr, 1);
12735 case FFEBLD_opCONTER:
12737 bt = ffeinfo_basictype (ffebld_info (expr));
12738 kt = ffeinfo_kindtype (ffebld_info (expr));
12740 item = ffecom_constantunion (&ffebld_constant_union
12741 (ffebld_conter (expr)), bt, kt,
12742 ffecom_tree_type[bt][kt]);
12743 if (item == error_mark_node)
12744 return error_mark_node;
12745 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12750 return error_mark_node;
12753 bt = ffeinfo_basictype (ffebld_info (expr));
12754 kt = ffeinfo_kindtype (ffebld_info (expr));
12756 item = ffecom_expr (expr);
12757 if (item == error_mark_node)
12758 return error_mark_node;
12760 /* The back end currently optimizes a bit too zealously for us, in that
12761 we fail JCB001 if the following block of code is omitted. It checks
12762 to see if the transformed expression is a symbol or array reference,
12763 and encloses it in a SAVE_EXPR if that is the case. */
12766 if ((TREE_CODE (item) == VAR_DECL)
12767 || (TREE_CODE (item) == PARM_DECL)
12768 || (TREE_CODE (item) == RESULT_DECL)
12769 || (TREE_CODE (item) == INDIRECT_REF)
12770 || (TREE_CODE (item) == ARRAY_REF)
12771 || (TREE_CODE (item) == COMPONENT_REF)
12773 || (TREE_CODE (item) == OFFSET_REF)
12775 || (TREE_CODE (item) == BUFFER_REF)
12776 || (TREE_CODE (item) == REALPART_EXPR)
12777 || (TREE_CODE (item) == IMAGPART_EXPR))
12779 item = ffecom_save_tree (item);
12782 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12787 assert ("fall-through error" == NULL);
12788 return error_mark_node;
12792 /* Obtain a temp var with given data type.
12794 size is FFETARGET_charactersizeNONE for a non-CHARACTER type
12795 or >= 0 for a CHARACTER type.
12797 elements is -1 for a scalar or > 0 for an array of type. */
12799 #if FFECOM_targetCURRENT == FFECOM_targetGCC
12801 ffecom_make_tempvar (const char *commentary, tree type,
12802 ffetargetCharacterSize size, int elements)
12806 static int mynumber;
12808 assert (current_binding_level->prep_state < 2);
12810 if (type == error_mark_node)
12811 return error_mark_node;
12813 yes = suspend_momentary ();
12815 if (size != FFETARGET_charactersizeNONE)
12816 type = build_array_type (type,
12817 build_range_type (ffecom_f2c_ftnlen_type_node,
12818 ffecom_f2c_ftnlen_one_node,
12819 build_int_2 (size, 0)));
12820 if (elements != -1)
12821 type = build_array_type (type,
12822 build_range_type (integer_type_node,
12824 build_int_2 (elements - 1,
12826 t = build_decl (VAR_DECL,
12827 ffecom_get_invented_identifier ("__g77_%s_%d",
12832 t = start_decl (t, FALSE);
12833 finish_decl (t, NULL_TREE, FALSE);
12835 resume_momentary (yes);
12841 /* Prepare argument pointer to expression.
12843 Like ffecom_prepare_expr, except for expressions to be evaluated
12844 via ffecom_arg_ptr_to_expr. */
12847 ffecom_prepare_arg_ptr_to_expr (ffebld expr)
12849 /* ~~For now, it seems to be the same thing. */
12850 ffecom_prepare_expr (expr);
12854 /* End of preparations. */
12857 ffecom_prepare_end (void)
12859 int prep_state = current_binding_level->prep_state;
12861 assert (prep_state < 2);
12862 current_binding_level->prep_state = 2;
12864 return (prep_state == 1) ? TRUE : FALSE;
12867 /* Prepare expression.
12869 This is called before any code is generated for the current block.
12870 It scans the expression, declares any temporaries that might be needed
12871 during evaluation of the expression, and stores those temporaries in
12872 the appropriate "hook" fields of the expression. `dest', if not NULL,
12873 specifies the destination that ffecom_expr_ will see, in case that
12874 helps avoid generating unused temporaries.
12876 ~~Improve to avoid allocating unused temporaries by taking `dest'
12877 into account vis-a-vis aliasing requirements of complex/character
12881 ffecom_prepare_expr_ (ffebld expr, ffebld dest UNUSED)
12883 ffeinfoBasictype bt;
12884 ffeinfoKindtype kt;
12885 ffetargetCharacterSize sz;
12886 tree tempvar = NULL_TREE;
12888 assert (current_binding_level->prep_state < 2);
12893 bt = ffeinfo_basictype (ffebld_info (expr));
12894 kt = ffeinfo_kindtype (ffebld_info (expr));
12895 sz = ffeinfo_size (ffebld_info (expr));
12897 /* Generate whatever temporaries are needed to represent the result
12898 of the expression. */
12900 switch (ffebld_op (expr))
12903 /* Don't make temps for SYMTER, CONTER, etc. */
12904 if (ffebld_arity (expr) == 0)
12909 case FFEINFO_basictypeCOMPLEX:
12910 if (ffebld_op (expr) == FFEBLD_opFUNCREF)
12914 if (ffebld_op (ffebld_left (expr)) != FFEBLD_opSYMTER)
12917 s = ffebld_symter (ffebld_left (expr));
12918 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT
12919 || ! ffesymbol_is_f2c (s))
12922 else if (ffebld_op (expr) == FFEBLD_opPOWER)
12924 /* Requires special treatment. There's no POW_CC function
12925 in libg2c, so POW_ZZ is used, which means we always
12926 need a double-complex temp, not a single-complex. */
12927 kt = FFEINFO_kindtypeREAL2;
12929 else if (ffebld_op (expr) != FFEBLD_opDIVIDE)
12930 /* The other ops don't need temps for complex operands. */
12933 /* ~~~Avoid making temps for some intrinsics, such as AIMAG(C),
12934 REAL(C). See 19990325-0.f, routine `check', for cases. */
12935 tempvar = ffecom_make_tempvar ("complex",
12937 [FFEINFO_basictypeCOMPLEX][kt],
12938 FFETARGET_charactersizeNONE,
12942 case FFEINFO_basictypeCHARACTER:
12943 if (ffebld_op (expr) != FFEBLD_opFUNCREF)
12946 if (sz == FFETARGET_charactersizeNONE)
12947 /* ~~Kludge alert! This should someday be fixed. */
12950 tempvar = ffecom_make_tempvar ("char", char_type_node, sz, -1);
12959 case FFEBLD_opPOWER:
12962 tree rtmp, ltmp, result;
12964 ltype = ffecom_type_expr (ffebld_left (expr));
12965 rtype = ffecom_type_expr (ffebld_right (expr));
12967 rtmp = ffecom_make_tempvar (rtype, FFETARGET_charactersizeNONE, -1);
12968 ltmp = ffecom_make_tempvar (ltype, FFETARGET_charactersizeNONE, -1);
12969 result = ffecom_make_tempvar (ltype, FFETARGET_charactersizeNONE, -1);
12971 tempvar = make_tree_vec (3);
12972 TREE_VEC_ELT (tempvar, 0) = rtmp;
12973 TREE_VEC_ELT (tempvar, 1) = ltmp;
12974 TREE_VEC_ELT (tempvar, 2) = result;
12979 case FFEBLD_opCONCATENATE:
12981 /* This gets special handling, because only one set of temps
12982 is needed for a tree of these -- the tree is treated as
12983 a flattened list of concatenations when generating code. */
12985 ffecomConcatList_ catlist;
12986 tree ltmp, itmp, result;
12990 catlist = ffecom_concat_list_new_ (expr, FFETARGET_charactersizeNONE);
12991 count = ffecom_concat_list_count_ (catlist);
12996 = ffecom_make_tempvar ("concat_len",
12997 ffecom_f2c_ftnlen_type_node,
12998 FFETARGET_charactersizeNONE, count);
13000 = ffecom_make_tempvar ("concat_item",
13001 ffecom_f2c_address_type_node,
13002 FFETARGET_charactersizeNONE, count);
13004 = ffecom_make_tempvar ("concat_res",
13006 ffecom_concat_list_maxlen_ (catlist),
13009 tempvar = make_tree_vec (3);
13010 TREE_VEC_ELT (tempvar, 0) = ltmp;
13011 TREE_VEC_ELT (tempvar, 1) = itmp;
13012 TREE_VEC_ELT (tempvar, 2) = result;
13015 for (i = 0; i < count; ++i)
13016 ffecom_prepare_arg_ptr_to_expr (ffecom_concat_list_expr_ (catlist,
13019 ffecom_concat_list_kill_ (catlist);
13023 ffebld_nonter_set_hook (expr, tempvar);
13024 current_binding_level->prep_state = 1;
13029 case FFEBLD_opCONVERT:
13030 if (bt == FFEINFO_basictypeCHARACTER
13031 && ((ffebld_size_known (ffebld_left (expr))
13032 == FFETARGET_charactersizeNONE)
13033 || (ffebld_size_known (ffebld_left (expr)) >= sz)))
13034 tempvar = ffecom_make_tempvar ("convert", char_type_node, sz, -1);
13040 ffebld_nonter_set_hook (expr, tempvar);
13041 current_binding_level->prep_state = 1;
13044 /* Prepare subexpressions for this expr. */
13046 switch (ffebld_op (expr))
13048 case FFEBLD_opPERCENT_LOC:
13049 ffecom_prepare_ptr_to_expr (ffebld_left (expr));
13052 case FFEBLD_opPERCENT_VAL:
13053 case FFEBLD_opPERCENT_REF:
13054 ffecom_prepare_expr (ffebld_left (expr));
13057 case FFEBLD_opPERCENT_DESCR:
13058 ffecom_prepare_arg_ptr_to_expr (ffebld_left (expr));
13061 case FFEBLD_opITEM:
13067 item = ffebld_trail (item))
13068 if (ffebld_head (item) != NULL)
13069 ffecom_prepare_expr (ffebld_head (item));
13074 /* Need to handle character conversion specially. */
13075 switch (ffebld_arity (expr))
13078 ffecom_prepare_expr (ffebld_left (expr));
13079 ffecom_prepare_expr (ffebld_right (expr));
13083 ffecom_prepare_expr (ffebld_left (expr));
13094 /* Prepare expression for reading and writing.
13096 Like ffecom_prepare_expr, except for expressions to be evaluated
13097 via ffecom_expr_rw. */
13100 ffecom_prepare_expr_rw (tree type, ffebld expr)
13102 /* This is all we support for now. */
13103 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
13105 /* ~~For now, it seems to be the same thing. */
13106 ffecom_prepare_expr (expr);
13110 /* Prepare expression for writing.
13112 Like ffecom_prepare_expr, except for expressions to be evaluated
13113 via ffecom_expr_w. */
13116 ffecom_prepare_expr_w (tree type, ffebld expr)
13118 /* This is all we support for now. */
13119 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
13121 /* ~~For now, it seems to be the same thing. */
13122 ffecom_prepare_expr (expr);
13126 /* Prepare expression for returning.
13128 Like ffecom_prepare_expr, except for expressions to be evaluated
13129 via ffecom_return_expr. */
13132 ffecom_prepare_return_expr (ffebld expr)
13134 assert (current_binding_level->prep_state < 2);
13136 if (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE
13137 && ffecom_is_altreturning_
13139 ffecom_prepare_expr (expr);
13142 /* Prepare pointer to expression.
13144 Like ffecom_prepare_expr, except for expressions to be evaluated
13145 via ffecom_ptr_to_expr. */
13148 ffecom_prepare_ptr_to_expr (ffebld expr)
13150 /* ~~For now, it seems to be the same thing. */
13151 ffecom_prepare_expr (expr);
13155 /* Transform expression into constant pointer-to-expression tree.
13157 If the expression can be transformed into a pointer-to-expression tree
13158 that is constant, that is done, and the tree returned. Else NULL_TREE
13161 That way, a caller can attempt to provide compile-time initialization
13162 of a variable and, if that fails, *then* choose to start a new block
13163 and resort to using temporaries, as appropriate. */
13166 ffecom_ptr_to_const_expr (ffebld expr)
13169 return integer_zero_node;
13171 if (ffebld_op (expr) == FFEBLD_opANY)
13172 return error_mark_node;
13174 if (ffebld_arity (expr) == 0
13175 && (ffebld_op (expr) != FFEBLD_opSYMTER
13176 || ffebld_where (expr) == FFEINFO_whereCOMMON
13177 || ffebld_where (expr) == FFEINFO_whereGLOBAL
13178 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
13182 t = ffecom_ptr_to_expr (expr);
13183 assert (TREE_CONSTANT (t));
13190 /* ffecom_return_expr -- Returns return-value expr given alt return expr
13192 tree rtn; // NULL_TREE means use expand_null_return()
13193 ffebld expr; // NULL if no alt return expr to RETURN stmt
13194 rtn = ffecom_return_expr(expr);
13196 Based on the program unit type and other info (like return function
13197 type, return master function type when alternate ENTRY points,
13198 whether subroutine has any alternate RETURN points, etc), returns the
13199 appropriate expression to be returned to the caller, or NULL_TREE
13200 meaning no return value or the caller expects it to be returned somewhere
13201 else (which is handled by other parts of this module). */
13203 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13205 ffecom_return_expr (ffebld expr)
13209 switch (ffecom_primary_entry_kind_)
13211 case FFEINFO_kindPROGRAM:
13212 case FFEINFO_kindBLOCKDATA:
13216 case FFEINFO_kindSUBROUTINE:
13217 if (!ffecom_is_altreturning_)
13218 rtn = NULL_TREE; /* No alt returns, never an expr. */
13219 else if (expr == NULL)
13220 rtn = integer_zero_node;
13222 rtn = ffecom_expr (expr);
13225 case FFEINFO_kindFUNCTION:
13226 if ((ffecom_multi_retval_ != NULL_TREE)
13227 || (ffesymbol_basictype (ffecom_primary_entry_)
13228 == FFEINFO_basictypeCHARACTER)
13229 || ((ffesymbol_basictype (ffecom_primary_entry_)
13230 == FFEINFO_basictypeCOMPLEX)
13231 && (ffecom_num_entrypoints_ == 0)
13232 && ffesymbol_is_f2c (ffecom_primary_entry_)))
13233 { /* Value is returned by direct assignment
13234 into (implicit) dummy. */
13238 rtn = ffecom_func_result_;
13240 /* Spurious error if RETURN happens before first reference! So elide
13241 this code. In particular, for debugging registry, rtn should always
13242 be non-null after all, but TREE_USED won't be set until we encounter
13243 a reference in the code. Perfectly okay (but weird) code that,
13244 e.g., has "GOTO 20;10 RETURN;20 RTN=0;GOTO 10", would result in
13245 this diagnostic for no reason. Have people use -O -Wuninitialized
13246 and leave it to the back end to find obviously weird cases. */
13248 /* Used to "assert(rtn != NULL_TREE);" here, but it's kind of a valid
13249 situation; if the return value has never been referenced, it won't
13250 have a tree under 2pass mode. */
13251 if ((rtn == NULL_TREE)
13252 || !TREE_USED (rtn))
13254 ffebad_start (FFEBAD_RETURN_VALUE_UNSET);
13255 ffebad_here (0, ffesymbol_where_line (ffecom_primary_entry_),
13256 ffesymbol_where_column (ffecom_primary_entry_));
13257 ffebad_string (ffesymbol_text (ffesymbol_funcresult
13258 (ffecom_primary_entry_)));
13265 assert ("bad unit kind" == NULL);
13266 case FFEINFO_kindANY:
13267 rtn = error_mark_node;
13275 /* Do save_expr only if tree is not error_mark_node. */
13277 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13279 ffecom_save_tree (tree t)
13281 return save_expr (t);
13285 /* Start a compound statement (block). */
13287 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13289 ffecom_start_compstmt (void)
13291 bison_rule_pushlevel_ ();
13293 #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
13295 /* Public entry point for front end to access start_decl. */
13297 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13299 ffecom_start_decl (tree decl, bool is_initialized)
13301 DECL_INITIAL (decl) = is_initialized ? error_mark_node : NULL_TREE;
13302 return start_decl (decl, FALSE);
13306 /* ffecom_sym_commit -- Symbol's state being committed to reality
13309 ffecom_sym_commit(s);
13311 Does whatever the backend needs when a symbol is committed after having
13312 been backtrackable for a period of time. */
13314 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13316 ffecom_sym_commit (ffesymbol s UNUSED)
13318 assert (!ffesymbol_retractable ());
13322 /* ffecom_sym_end_transition -- Perform end transition on all symbols
13324 ffecom_sym_end_transition();
13326 Does backend-specific stuff and also calls ffest_sym_end_transition
13327 to do the necessary FFE stuff.
13329 Backtracking is never enabled when this fn is called, so don't worry
13333 ffecom_sym_end_transition (ffesymbol s)
13337 assert (!ffesymbol_retractable ());
13339 s = ffest_sym_end_transition (s);
13341 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13342 if ((ffesymbol_kind (s) == FFEINFO_kindBLOCKDATA)
13343 && (ffesymbol_where (s) == FFEINFO_whereGLOBAL))
13345 ffecom_list_blockdata_
13346 = ffebld_new_item (ffebld_new_symter (s, FFEINTRIN_genNONE,
13347 FFEINTRIN_specNONE,
13348 FFEINTRIN_impNONE),
13349 ffecom_list_blockdata_);
13353 /* This is where we finally notice that a symbol has partial initialization
13354 and finalize it. */
13356 if (ffesymbol_accretion (s) != NULL)
13358 assert (ffesymbol_init (s) == NULL);
13359 ffecom_notify_init_symbol (s);
13361 else if (((st = ffesymbol_storage (s)) != NULL)
13362 && ((st = ffestorag_parent (st)) != NULL)
13363 && (ffestorag_accretion (st) != NULL))
13365 assert (ffestorag_init (st) == NULL);
13366 ffecom_notify_init_storage (st);
13369 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13370 if ((ffesymbol_kind (s) == FFEINFO_kindCOMMON)
13371 && (ffesymbol_where (s) == FFEINFO_whereLOCAL)
13372 && (ffesymbol_storage (s) != NULL))
13374 ffecom_list_common_
13375 = ffebld_new_item (ffebld_new_symter (s, FFEINTRIN_genNONE,
13376 FFEINTRIN_specNONE,
13377 FFEINTRIN_impNONE),
13378 ffecom_list_common_);
13385 /* ffecom_sym_exec_transition -- Perform exec transition on all symbols
13387 ffecom_sym_exec_transition();
13389 Does backend-specific stuff and also calls ffest_sym_exec_transition
13390 to do the necessary FFE stuff.
13392 See the long-winded description in ffecom_sym_learned for info
13393 on handling the situation where backtracking is inhibited. */
13396 ffecom_sym_exec_transition (ffesymbol s)
13398 s = ffest_sym_exec_transition (s);
13403 /* ffecom_sym_learned -- Initial or more info gained on symbol after exec
13406 s = ffecom_sym_learned(s);
13408 Called when a new symbol is seen after the exec transition or when more
13409 info (perhaps) is gained for an UNCERTAIN symbol. The symbol state when
13410 it arrives here is that all its latest info is updated already, so its
13411 state may be UNCERTAIN or UNDERSTOOD, it might already have the hook
13412 field filled in if its gone through here or exec_transition first, and
13415 The backend probably wants to check ffesymbol_retractable() to see if
13416 backtracking is in effect. If so, the FFE's changes to the symbol may
13417 be retracted (undone) or committed (ratified), at which time the
13418 appropriate ffecom_sym_retract or _commit function will be called
13421 If the backend has its own backtracking mechanism, great, use it so that
13422 committal is a simple operation. Though it doesn't make much difference,
13423 I suppose: the reason for tentative symbol evolution in the FFE is to
13424 enable error detection in weird incorrect statements early and to disable
13425 incorrect error detection on a correct statement. The backend is not
13426 likely to introduce any information that'll get involved in these
13427 considerations, so it is probably just fine that the implementation
13428 model for this fn and for _exec_transition is to not do anything
13429 (besides the required FFE stuff) if ffesymbol_retractable() returns TRUE
13430 and instead wait until ffecom_sym_commit is called (which it never
13431 will be as long as we're using ambiguity-detecting statement analysis in
13432 the FFE, which we are initially to shake out the code, but don't depend
13433 on this), otherwise go ahead and do whatever is needed.
13435 In essence, then, when this fn and _exec_transition get called while
13436 backtracking is enabled, a general mechanism would be to flag which (or
13437 both) of these were called (and in what order? neat question as to what
13438 might happen that I'm too lame to think through right now) and then when
13439 _commit is called reproduce the original calling sequence, if any, for
13440 the two fns (at which point backtracking will, of course, be disabled). */
13443 ffecom_sym_learned (ffesymbol s)
13445 ffestorag_exec_layout (s);
13450 /* ffecom_sym_retract -- Symbol's state being retracted from reality
13453 ffecom_sym_retract(s);
13455 Does whatever the backend needs when a symbol is retracted after having
13456 been backtrackable for a period of time. */
13458 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13460 ffecom_sym_retract (ffesymbol s UNUSED)
13462 assert (!ffesymbol_retractable ());
13464 #if 0 /* GCC doesn't commit any backtrackable sins,
13465 so nothing needed here. */
13466 switch (ffesymbol_hook (s).state)
13468 case 0: /* nothing happened yet. */
13471 case 1: /* exec transition happened. */
13474 case 2: /* learned happened. */
13477 case 3: /* learned then exec. */
13480 case 4: /* exec then learned. */
13484 assert ("bad hook state" == NULL);
13491 /* Create temporary gcc label. */
13493 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13495 ffecom_temp_label ()
13498 static int mynumber = 0;
13500 glabel = build_decl (LABEL_DECL,
13501 ffecom_get_invented_identifier ("__g77_label_%d",
13505 DECL_CONTEXT (glabel) = current_function_decl;
13506 DECL_MODE (glabel) = VOIDmode;
13512 /* Return an expression that is usable as an arg in a conditional context
13513 (IF, DO WHILE, .NOT., and so on).
13515 Use the one provided for the back end as of >2.6.0. */
13517 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13519 ffecom_truth_value (tree expr)
13521 return truthvalue_conversion (expr);
13525 /* Return the inversion of a truth value (the inversion of what
13526 ffecom_truth_value builds).
13528 Apparently invert_truthvalue, which is properly in the back end, is
13529 enough for now, so just use it. */
13531 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13533 ffecom_truth_value_invert (tree expr)
13535 return invert_truthvalue (ffecom_truth_value (expr));
13540 /* Return the tree that is the type of the expression, as would be
13541 returned in TREE_TYPE(ffecom_expr(expr)), without otherwise
13542 transforming the expression, generating temporaries, etc. */
13545 ffecom_type_expr (ffebld expr)
13547 ffeinfoBasictype bt;
13548 ffeinfoKindtype kt;
13551 assert (expr != NULL);
13553 bt = ffeinfo_basictype (ffebld_info (expr));
13554 kt = ffeinfo_kindtype (ffebld_info (expr));
13555 tree_type = ffecom_tree_type[bt][kt];
13557 switch (ffebld_op (expr))
13559 case FFEBLD_opCONTER:
13560 case FFEBLD_opSYMTER:
13561 case FFEBLD_opARRAYREF:
13562 case FFEBLD_opUPLUS:
13563 case FFEBLD_opPAREN:
13564 case FFEBLD_opUMINUS:
13566 case FFEBLD_opSUBTRACT:
13567 case FFEBLD_opMULTIPLY:
13568 case FFEBLD_opDIVIDE:
13569 case FFEBLD_opPOWER:
13571 case FFEBLD_opFUNCREF:
13572 case FFEBLD_opSUBRREF:
13576 case FFEBLD_opNEQV:
13578 case FFEBLD_opCONVERT:
13585 case FFEBLD_opPERCENT_LOC:
13588 case FFEBLD_opACCTER:
13589 case FFEBLD_opARRTER:
13590 case FFEBLD_opITEM:
13591 case FFEBLD_opSTAR:
13592 case FFEBLD_opBOUNDS:
13593 case FFEBLD_opREPEAT:
13594 case FFEBLD_opLABTER:
13595 case FFEBLD_opLABTOK:
13596 case FFEBLD_opIMPDO:
13597 case FFEBLD_opCONCATENATE:
13598 case FFEBLD_opSUBSTR:
13600 assert ("bad op for ffecom_type_expr" == NULL);
13601 /* Fall through. */
13603 return error_mark_node;
13607 /* Return PARM_DECL for arg#1 of master fn containing alternate ENTRY points
13609 If the PARM_DECL already exists, return it, else create it. It's an
13610 integer_type_node argument for the master function that implements a
13611 subroutine or function with more than one entrypoint and is bound at
13612 run time with the entrypoint number (0 for SUBROUTINE/FUNCTION, 1 for
13613 first ENTRY statement, and so on). */
13615 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13617 ffecom_which_entrypoint_decl ()
13619 assert (ffecom_which_entrypoint_decl_ != NULL_TREE);
13621 return ffecom_which_entrypoint_decl_;
13626 /* The following sections consists of private and public functions
13627 that have the same names and perform roughly the same functions
13628 as counterparts in the C front end. Changes in the C front end
13629 might affect how things should be done here. Only functions
13630 needed by the back end should be public here; the rest should
13631 be private (static in the C sense). Functions needed by other
13632 g77 front-end modules should be accessed by them via public
13633 ffecom_* names, which should themselves call private versions
13634 in this section so the private versions are easy to recognize
13635 when upgrading to a new gcc and finding interesting changes
13638 Functions named after rule "foo:" in c-parse.y are named
13639 "bison_rule_foo_" so they are easy to find. */
13641 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13644 bison_rule_pushlevel_ ()
13646 emit_line_note (input_filename, lineno);
13648 clear_last_expr ();
13650 expand_start_bindings (0);
13654 bison_rule_compstmt_ ()
13657 int keep = kept_level_p ();
13659 /* Make the temps go away. */
13661 current_binding_level->names = NULL_TREE;
13663 emit_line_note (input_filename, lineno);
13664 expand_end_bindings (getdecls (), keep, 0);
13665 t = poplevel (keep, 1, 0);
13671 /* Return a definition for a builtin function named NAME and whose data type
13672 is TYPE. TYPE should be a function type with argument types.
13673 FUNCTION_CODE tells later passes how to compile calls to this function.
13674 See tree.h for its possible values.
13676 If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME,
13677 the name to be called if we can't opencode the function. */
13680 builtin_function (const char *name, tree type,
13681 enum built_in_function function_code,
13682 const char *library_name)
13684 tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
13685 DECL_EXTERNAL (decl) = 1;
13686 TREE_PUBLIC (decl) = 1;
13688 DECL_ASSEMBLER_NAME (decl) = get_identifier (library_name);
13689 make_decl_rtl (decl, NULL_PTR, 1);
13691 if (function_code != NOT_BUILT_IN)
13693 DECL_BUILT_IN (decl) = 1;
13694 DECL_FUNCTION_CODE (decl) = function_code;
13700 /* Handle when a new declaration NEWDECL
13701 has the same name as an old one OLDDECL
13702 in the same binding contour.
13703 Prints an error message if appropriate.
13705 If safely possible, alter OLDDECL to look like NEWDECL, and return 1.
13706 Otherwise, return 0. */
13709 duplicate_decls (tree newdecl, tree olddecl)
13711 int types_match = 1;
13712 int new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL
13713 && DECL_INITIAL (newdecl) != 0);
13714 tree oldtype = TREE_TYPE (olddecl);
13715 tree newtype = TREE_TYPE (newdecl);
13717 if (olddecl == newdecl)
13720 if (TREE_CODE (newtype) == ERROR_MARK
13721 || TREE_CODE (oldtype) == ERROR_MARK)
13724 /* New decl is completely inconsistent with the old one =>
13725 tell caller to replace the old one.
13726 This is always an error except in the case of shadowing a builtin. */
13727 if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
13730 /* For real parm decl following a forward decl,
13731 return 1 so old decl will be reused. */
13732 if (types_match && TREE_CODE (newdecl) == PARM_DECL
13733 && TREE_ASM_WRITTEN (olddecl) && ! TREE_ASM_WRITTEN (newdecl))
13736 /* The new declaration is the same kind of object as the old one.
13737 The declarations may partially match. Print warnings if they don't
13738 match enough. Ultimately, copy most of the information from the new
13739 decl to the old one, and keep using the old one. */
13741 if (TREE_CODE (olddecl) == FUNCTION_DECL
13742 && DECL_BUILT_IN (olddecl))
13744 /* A function declaration for a built-in function. */
13745 if (!TREE_PUBLIC (newdecl))
13747 else if (!types_match)
13749 /* Accept the return type of the new declaration if same modes. */
13750 tree oldreturntype = TREE_TYPE (TREE_TYPE (olddecl));
13751 tree newreturntype = TREE_TYPE (TREE_TYPE (newdecl));
13753 /* Make sure we put the new type in the same obstack as the old ones.
13754 If the old types are not both in the same obstack, use the
13756 if (TYPE_OBSTACK (oldtype) == TYPE_OBSTACK (newtype))
13757 push_obstacks (TYPE_OBSTACK (oldtype), TYPE_OBSTACK (oldtype));
13760 push_obstacks_nochange ();
13761 end_temporary_allocation ();
13764 if (TYPE_MODE (oldreturntype) == TYPE_MODE (newreturntype))
13766 /* Function types may be shared, so we can't just modify
13767 the return type of olddecl's function type. */
13769 = build_function_type (newreturntype,
13770 TYPE_ARG_TYPES (TREE_TYPE (olddecl)));
13774 TREE_TYPE (olddecl) = newtype;
13782 else if (TREE_CODE (olddecl) == FUNCTION_DECL
13783 && DECL_SOURCE_LINE (olddecl) == 0)
13785 /* A function declaration for a predeclared function
13786 that isn't actually built in. */
13787 if (!TREE_PUBLIC (newdecl))
13789 else if (!types_match)
13791 /* If the types don't match, preserve volatility indication.
13792 Later on, we will discard everything else about the
13793 default declaration. */
13794 TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
13798 /* Copy all the DECL_... slots specified in the new decl
13799 except for any that we copy here from the old type.
13801 Past this point, we don't change OLDTYPE and NEWTYPE
13802 even if we change the types of NEWDECL and OLDDECL. */
13806 /* Make sure we put the new type in the same obstack as the old ones.
13807 If the old types are not both in the same obstack, use the permanent
13809 if (TYPE_OBSTACK (oldtype) == TYPE_OBSTACK (newtype))
13810 push_obstacks (TYPE_OBSTACK (oldtype), TYPE_OBSTACK (oldtype));
13813 push_obstacks_nochange ();
13814 end_temporary_allocation ();
13817 /* Merge the data types specified in the two decls. */
13818 if (TREE_CODE (newdecl) != FUNCTION_DECL || !DECL_BUILT_IN (olddecl))
13819 TREE_TYPE (newdecl)
13820 = TREE_TYPE (olddecl)
13821 = TREE_TYPE (newdecl);
13823 /* Lay the type out, unless already done. */
13824 if (oldtype != TREE_TYPE (newdecl))
13826 if (TREE_TYPE (newdecl) != error_mark_node)
13827 layout_type (TREE_TYPE (newdecl));
13828 if (TREE_CODE (newdecl) != FUNCTION_DECL
13829 && TREE_CODE (newdecl) != TYPE_DECL
13830 && TREE_CODE (newdecl) != CONST_DECL)
13831 layout_decl (newdecl, 0);
13835 /* Since the type is OLDDECL's, make OLDDECL's size go with. */
13836 DECL_SIZE (newdecl) = DECL_SIZE (olddecl);
13837 if (TREE_CODE (olddecl) != FUNCTION_DECL)
13838 if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl))
13839 DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl);
13842 /* Keep the old rtl since we can safely use it. */
13843 DECL_RTL (newdecl) = DECL_RTL (olddecl);
13845 /* Merge the type qualifiers. */
13846 if (DECL_BUILT_IN_NONANSI (olddecl) && TREE_THIS_VOLATILE (olddecl)
13847 && !TREE_THIS_VOLATILE (newdecl))
13848 TREE_THIS_VOLATILE (olddecl) = 0;
13849 if (TREE_READONLY (newdecl))
13850 TREE_READONLY (olddecl) = 1;
13851 if (TREE_THIS_VOLATILE (newdecl))
13853 TREE_THIS_VOLATILE (olddecl) = 1;
13854 if (TREE_CODE (newdecl) == VAR_DECL)
13855 make_var_volatile (newdecl);
13858 /* Keep source location of definition rather than declaration.
13859 Likewise, keep decl at outer scope. */
13860 if ((DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0)
13861 || (DECL_CONTEXT (newdecl) != 0 && DECL_CONTEXT (olddecl) == 0))
13863 DECL_SOURCE_LINE (newdecl) = DECL_SOURCE_LINE (olddecl);
13864 DECL_SOURCE_FILE (newdecl) = DECL_SOURCE_FILE (olddecl);
13866 if (DECL_CONTEXT (olddecl) == 0
13867 && TREE_CODE (newdecl) != FUNCTION_DECL)
13868 DECL_CONTEXT (newdecl) = 0;
13871 /* Merge the unused-warning information. */
13872 if (DECL_IN_SYSTEM_HEADER (olddecl))
13873 DECL_IN_SYSTEM_HEADER (newdecl) = 1;
13874 else if (DECL_IN_SYSTEM_HEADER (newdecl))
13875 DECL_IN_SYSTEM_HEADER (olddecl) = 1;
13877 /* Merge the initialization information. */
13878 if (DECL_INITIAL (newdecl) == 0)
13879 DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
13881 /* Merge the section attribute.
13882 We want to issue an error if the sections conflict but that must be
13883 done later in decl_attributes since we are called before attributes
13885 if (DECL_SECTION_NAME (newdecl) == NULL_TREE)
13886 DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl);
13889 if (TREE_CODE (newdecl) == FUNCTION_DECL)
13891 DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl);
13892 DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
13898 /* If cannot merge, then use the new type and qualifiers,
13899 and don't preserve the old rtl. */
13902 TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
13903 TREE_READONLY (olddecl) = TREE_READONLY (newdecl);
13904 TREE_THIS_VOLATILE (olddecl) = TREE_THIS_VOLATILE (newdecl);
13905 TREE_SIDE_EFFECTS (olddecl) = TREE_SIDE_EFFECTS (newdecl);
13908 /* Merge the storage class information. */
13909 /* For functions, static overrides non-static. */
13910 if (TREE_CODE (newdecl) == FUNCTION_DECL)
13912 TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl);
13913 /* This is since we don't automatically
13914 copy the attributes of NEWDECL into OLDDECL. */
13915 TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
13916 /* If this clears `static', clear it in the identifier too. */
13917 if (! TREE_PUBLIC (olddecl))
13918 TREE_PUBLIC (DECL_NAME (olddecl)) = 0;
13920 if (DECL_EXTERNAL (newdecl))
13922 TREE_STATIC (newdecl) = TREE_STATIC (olddecl);
13923 DECL_EXTERNAL (newdecl) = DECL_EXTERNAL (olddecl);
13924 /* An extern decl does not override previous storage class. */
13925 TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
13929 TREE_STATIC (olddecl) = TREE_STATIC (newdecl);
13930 TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
13933 /* If either decl says `inline', this fn is inline,
13934 unless its definition was passed already. */
13935 if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == 0)
13936 DECL_INLINE (olddecl) = 1;
13937 DECL_INLINE (newdecl) = DECL_INLINE (olddecl);
13939 /* Get rid of any built-in function if new arg types don't match it
13940 or if we have a function definition. */
13941 if (TREE_CODE (newdecl) == FUNCTION_DECL
13942 && DECL_BUILT_IN (olddecl)
13943 && (!types_match || new_is_definition))
13945 TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
13946 DECL_BUILT_IN (olddecl) = 0;
13949 /* If redeclaring a builtin function, and not a definition,
13951 Also preserve various other info from the definition. */
13952 if (TREE_CODE (newdecl) == FUNCTION_DECL && !new_is_definition)
13954 if (DECL_BUILT_IN (olddecl))
13956 DECL_BUILT_IN (newdecl) = 1;
13957 DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
13960 DECL_FRAME_SIZE (newdecl) = DECL_FRAME_SIZE (olddecl);
13962 DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
13963 DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
13964 DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl);
13965 DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
13968 /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
13969 But preserve olddecl's DECL_UID. */
13971 register unsigned olddecl_uid = DECL_UID (olddecl);
13973 memcpy ((char *) olddecl + sizeof (struct tree_common),
13974 (char *) newdecl + sizeof (struct tree_common),
13975 sizeof (struct tree_decl) - sizeof (struct tree_common));
13976 DECL_UID (olddecl) = olddecl_uid;
13982 /* Finish processing of a declaration;
13983 install its initial value.
13984 If the length of an array type is not known before,
13985 it must be determined now, from the initial value, or it is an error. */
13988 finish_decl (tree decl, tree init, bool is_top_level)
13990 register tree type = TREE_TYPE (decl);
13991 int was_incomplete = (DECL_SIZE (decl) == 0);
13992 int temporary = allocation_temporary_p ();
13993 bool at_top_level = (current_binding_level == global_binding_level);
13994 bool top_level = is_top_level || at_top_level;
13996 /* Caller should pass TRUE for is_top_level only if we wouldn't be at top
13998 assert (!is_top_level || !at_top_level);
14000 if (TREE_CODE (decl) == PARM_DECL)
14001 assert (init == NULL_TREE);
14002 /* Remember that PARM_DECL doesn't have a DECL_INITIAL field per se -- it
14003 overlaps DECL_ARG_TYPE. */
14004 else if (init == NULL_TREE)
14005 assert (DECL_INITIAL (decl) == NULL_TREE);
14007 assert (DECL_INITIAL (decl) == error_mark_node);
14009 if (init != NULL_TREE)
14011 if (TREE_CODE (decl) != TYPE_DECL)
14012 DECL_INITIAL (decl) = init;
14015 /* typedef foo = bar; store the type of bar as the type of foo. */
14016 TREE_TYPE (decl) = TREE_TYPE (init);
14017 DECL_INITIAL (decl) = init = 0;
14021 /* Pop back to the obstack that is current for this binding level. This is
14022 because MAXINDEX, rtl, etc. to be made below must go in the permanent
14023 obstack. But don't discard the temporary data yet. */
14026 /* Deduce size of array from initialization, if not already known */
14028 if (TREE_CODE (type) == ARRAY_TYPE
14029 && TYPE_DOMAIN (type) == 0
14030 && TREE_CODE (decl) != TYPE_DECL)
14032 assert (top_level);
14033 assert (was_incomplete);
14035 layout_decl (decl, 0);
14038 if (TREE_CODE (decl) == VAR_DECL)
14040 if (DECL_SIZE (decl) == NULL_TREE
14041 && TYPE_SIZE (TREE_TYPE (decl)) != NULL_TREE)
14042 layout_decl (decl, 0);
14044 if (DECL_SIZE (decl) == NULL_TREE
14045 && (TREE_STATIC (decl)
14047 /* A static variable with an incomplete type is an error if it is
14048 initialized. Also if it is not file scope. Otherwise, let it
14049 through, but if it is not `extern' then it may cause an error
14051 (DECL_INITIAL (decl) != 0 || DECL_CONTEXT (decl) != 0)
14053 /* An automatic variable with an incomplete type is an error. */
14054 !DECL_EXTERNAL (decl)))
14056 assert ("storage size not known" == NULL);
14060 if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl))
14061 && (DECL_SIZE (decl) != 0)
14062 && (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST))
14064 assert ("storage size not constant" == NULL);
14069 /* Output the assembler code and/or RTL code for variables and functions,
14070 unless the type is an undefined structure or union. If not, it will get
14071 done when the type is completed. */
14073 if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)
14075 rest_of_decl_compilation (decl, NULL,
14076 DECL_CONTEXT (decl) == 0,
14079 if (DECL_CONTEXT (decl) != 0)
14081 /* Recompute the RTL of a local array now if it used to be an
14082 incomplete type. */
14084 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
14086 /* If we used it already as memory, it must stay in memory. */
14087 TREE_ADDRESSABLE (decl) = TREE_USED (decl);
14088 /* If it's still incomplete now, no init will save it. */
14089 if (DECL_SIZE (decl) == 0)
14090 DECL_INITIAL (decl) = 0;
14091 expand_decl (decl);
14093 /* Compute and store the initial value. */
14094 if (TREE_CODE (decl) != FUNCTION_DECL)
14095 expand_decl_init (decl);
14098 else if (TREE_CODE (decl) == TYPE_DECL)
14100 rest_of_decl_compilation (decl, NULL_PTR,
14101 DECL_CONTEXT (decl) == 0,
14105 /* This test used to include TREE_PERMANENT, however, we have the same
14106 problem with initializers at the function level. Such initializers get
14107 saved until the end of the function on the momentary_obstack. */
14108 if (!(TREE_CODE (decl) == FUNCTION_DECL && DECL_INLINE (decl))
14110 /* DECL_INITIAL is not defined in PARM_DECLs, since it shares space with
14112 && TREE_CODE (decl) != PARM_DECL)
14114 /* We need to remember that this array HAD an initialization, but
14115 discard the actual temporary nodes, since we can't have a permanent
14116 node keep pointing to them. */
14117 /* We make an exception for inline functions, since it's normal for a
14118 local extern redeclaration of an inline function to have a copy of
14119 the top-level decl's DECL_INLINE. */
14120 if ((DECL_INITIAL (decl) != 0)
14121 && (DECL_INITIAL (decl) != error_mark_node))
14123 /* If this is a const variable, then preserve the
14124 initializer instead of discarding it so that we can optimize
14125 references to it. */
14126 /* This test used to include TREE_STATIC, but this won't be set
14127 for function level initializers. */
14128 if (TREE_READONLY (decl))
14130 preserve_initializer ();
14131 /* Hack? Set the permanent bit for something that is
14132 permanent, but not on the permenent obstack, so as to
14133 convince output_constant_def to make its rtl on the
14134 permanent obstack. */
14135 TREE_PERMANENT (DECL_INITIAL (decl)) = 1;
14137 /* The initializer and DECL must have the same (or equivalent
14138 types), but if the initializer is a STRING_CST, its type
14139 might not be on the right obstack, so copy the type
14141 TREE_TYPE (DECL_INITIAL (decl)) = type;
14144 DECL_INITIAL (decl) = error_mark_node;
14148 /* If requested, warn about definitions of large data objects. */
14150 if (warn_larger_than
14151 && (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL)
14152 && !DECL_EXTERNAL (decl))
14154 register tree decl_size = DECL_SIZE (decl);
14156 if (decl_size && TREE_CODE (decl_size) == INTEGER_CST)
14158 unsigned units = TREE_INT_CST_LOW (decl_size) / BITS_PER_UNIT;
14160 if (units > larger_than_size)
14161 warning_with_decl (decl, "size of `%s' is %u bytes", units);
14165 /* If we have gone back from temporary to permanent allocation, actually
14166 free the temporary space that we no longer need. */
14167 if (temporary && !allocation_temporary_p ())
14168 permanent_allocation (0);
14170 /* At the end of a declaration, throw away any variable type sizes of types
14171 defined inside that declaration. There is no use computing them in the
14172 following function definition. */
14173 if (current_binding_level == global_binding_level)
14174 get_pending_sizes ();
14177 /* Finish up a function declaration and compile that function
14178 all the way to assembler language output. The free the storage
14179 for the function definition.
14181 This is called after parsing the body of the function definition.
14183 NESTED is nonzero if the function being finished is nested in another. */
14186 finish_function (int nested)
14188 register tree fndecl = current_function_decl;
14190 assert (fndecl != NULL_TREE);
14191 if (TREE_CODE (fndecl) != ERROR_MARK)
14194 assert (DECL_CONTEXT (fndecl) != NULL_TREE);
14196 assert (DECL_CONTEXT (fndecl) == NULL_TREE);
14199 /* TREE_READONLY (fndecl) = 1;
14200 This caused &foo to be of type ptr-to-const-function
14201 which then got a warning when stored in a ptr-to-function variable. */
14203 poplevel (1, 0, 1);
14205 if (TREE_CODE (fndecl) != ERROR_MARK)
14207 BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
14209 /* Must mark the RESULT_DECL as being in this function. */
14211 DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;
14213 /* Obey `register' declarations if `setjmp' is called in this fn. */
14214 /* Generate rtl for function exit. */
14215 expand_function_end (input_filename, lineno, 0);
14217 /* So we can tell if jump_optimize sets it to 1. */
14220 /* Run the optimizers and output the assembler code for this function. */
14221 rest_of_compilation (fndecl);
14224 /* Free all the tree nodes making up this function. */
14225 /* Switch back to allocating nodes permanently until we start another
14228 permanent_allocation (1);
14230 if (TREE_CODE (fndecl) != ERROR_MARK
14232 && DECL_SAVED_INSNS (fndecl) == 0)
14234 /* Stop pointing to the local nodes about to be freed. */
14235 /* But DECL_INITIAL must remain nonzero so we know this was an actual
14236 function definition. */
14237 /* For a nested function, this is done in pop_f_function_context. */
14238 /* If rest_of_compilation set this to 0, leave it 0. */
14239 if (DECL_INITIAL (fndecl) != 0)
14240 DECL_INITIAL (fndecl) = error_mark_node;
14241 DECL_ARGUMENTS (fndecl) = 0;
14246 /* Let the error reporting routines know that we're outside a function.
14247 For a nested function, this value is used in pop_c_function_context
14248 and then reset via pop_function_context. */
14249 ffecom_outer_function_decl_ = current_function_decl = NULL;
14253 /* Plug-in replacement for identifying the name of a decl and, for a
14254 function, what we call it in diagnostics. For now, "program unit"
14255 should suffice, since it's a bit of a hassle to figure out which
14256 of several kinds of things it is. Note that it could conceivably
14257 be a statement function, which probably isn't really a program unit
14258 per se, but if that comes up, it should be easy to check (being a
14259 nested function and all). */
14262 lang_printable_name (tree decl, int v)
14264 /* Just to keep GCC quiet about the unused variable.
14265 In theory, differing values of V should produce different
14270 if (TREE_CODE (decl) == ERROR_MARK)
14271 return "erroneous code";
14272 return IDENTIFIER_POINTER (DECL_NAME (decl));
14276 /* g77's function to print out name of current function that caused
14281 lang_print_error_function (file)
14284 static ffeglobal last_g = NULL;
14285 static ffesymbol last_s = NULL;
14290 if ((ffecom_primary_entry_ == NULL)
14291 || (ffesymbol_global (ffecom_primary_entry_) == NULL))
14299 g = ffesymbol_global (ffecom_primary_entry_);
14300 if (ffecom_nested_entry_ == NULL)
14302 s = ffecom_primary_entry_;
14303 switch (ffesymbol_kind (s))
14305 case FFEINFO_kindFUNCTION:
14309 case FFEINFO_kindSUBROUTINE:
14310 kind = "subroutine";
14313 case FFEINFO_kindPROGRAM:
14317 case FFEINFO_kindBLOCKDATA:
14318 kind = "block-data";
14322 kind = ffeinfo_kind_message (ffesymbol_kind (s));
14328 s = ffecom_nested_entry_;
14329 kind = "statement function";
14333 if ((last_g != g) || (last_s != s))
14336 fprintf (stderr, "%s: ", file);
14339 fprintf (stderr, "Outside of any program unit:\n");
14342 const char *name = ffesymbol_text (s);
14344 fprintf (stderr, "In %s `%s':\n", kind, name);
14353 /* Similar to `lookup_name' but look only at current binding level. */
14356 lookup_name_current_level (tree name)
14360 if (current_binding_level == global_binding_level)
14361 return IDENTIFIER_GLOBAL_VALUE (name);
14363 if (IDENTIFIER_LOCAL_VALUE (name) == 0)
14366 for (t = current_binding_level->names; t; t = TREE_CHAIN (t))
14367 if (DECL_NAME (t) == name)
14373 /* Create a new `struct binding_level'. */
14375 static struct binding_level *
14376 make_binding_level ()
14379 return (struct binding_level *) xmalloc (sizeof (struct binding_level));
14382 /* Save and restore the variables in this file and elsewhere
14383 that keep track of the progress of compilation of the current function.
14384 Used for nested functions. */
14388 struct f_function *next;
14390 tree shadowed_labels;
14391 struct binding_level *binding_level;
14394 struct f_function *f_function_chain;
14396 /* Restore the variables used during compilation of a C function. */
14399 pop_f_function_context ()
14401 struct f_function *p = f_function_chain;
14404 /* Bring back all the labels that were shadowed. */
14405 for (link = shadowed_labels; link; link = TREE_CHAIN (link))
14406 if (DECL_NAME (TREE_VALUE (link)) != 0)
14407 IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link)))
14408 = TREE_VALUE (link);
14410 if (current_function_decl != error_mark_node
14411 && DECL_SAVED_INSNS (current_function_decl) == 0)
14413 /* Stop pointing to the local nodes about to be freed. */
14414 /* But DECL_INITIAL must remain nonzero so we know this was an actual
14415 function definition. */
14416 DECL_INITIAL (current_function_decl) = error_mark_node;
14417 DECL_ARGUMENTS (current_function_decl) = 0;
14420 pop_function_context ();
14422 f_function_chain = p->next;
14424 named_labels = p->named_labels;
14425 shadowed_labels = p->shadowed_labels;
14426 current_binding_level = p->binding_level;
14431 /* Save and reinitialize the variables
14432 used during compilation of a C function. */
14435 push_f_function_context ()
14437 struct f_function *p
14438 = (struct f_function *) xmalloc (sizeof (struct f_function));
14440 push_function_context ();
14442 p->next = f_function_chain;
14443 f_function_chain = p;
14445 p->named_labels = named_labels;
14446 p->shadowed_labels = shadowed_labels;
14447 p->binding_level = current_binding_level;
14451 push_parm_decl (tree parm)
14453 int old_immediate_size_expand = immediate_size_expand;
14455 /* Don't try computing parm sizes now -- wait till fn is called. */
14457 immediate_size_expand = 0;
14459 push_obstacks_nochange ();
14461 /* Fill in arg stuff. */
14463 DECL_ARG_TYPE (parm) = TREE_TYPE (parm);
14464 DECL_ARG_TYPE_AS_WRITTEN (parm) = TREE_TYPE (parm);
14465 TREE_READONLY (parm) = 1; /* All implementation args are read-only. */
14467 parm = pushdecl (parm);
14469 immediate_size_expand = old_immediate_size_expand;
14471 finish_decl (parm, NULL_TREE, FALSE);
14474 /* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL, if appropriate. */
14477 pushdecl_top_level (x)
14481 register struct binding_level *b = current_binding_level;
14482 register tree f = current_function_decl;
14484 current_binding_level = global_binding_level;
14485 current_function_decl = NULL_TREE;
14487 current_binding_level = b;
14488 current_function_decl = f;
14492 /* Store the list of declarations of the current level.
14493 This is done for the parameter declarations of a function being defined,
14494 after they are modified in the light of any missing parameters. */
14500 return current_binding_level->names = decls;
14503 /* Store the parameter declarations into the current function declaration.
14504 This is called after parsing the parameter declarations, before
14505 digesting the body of the function.
14507 For an old-style definition, modify the function's type
14508 to specify at least the number of arguments. */
14511 store_parm_decls (int is_main_program UNUSED)
14513 register tree fndecl = current_function_decl;
14515 if (fndecl == error_mark_node)
14518 /* This is a chain of PARM_DECLs from old-style parm declarations. */
14519 DECL_ARGUMENTS (fndecl) = storedecls (nreverse (getdecls ()));
14521 /* Initialize the RTL code for the function. */
14523 init_function_start (fndecl, input_filename, lineno);
14525 /* Set up parameters and prepare for return, for the function. */
14527 expand_function_start (fndecl, 0);
14531 start_decl (tree decl, bool is_top_level)
14534 bool at_top_level = (current_binding_level == global_binding_level);
14535 bool top_level = is_top_level || at_top_level;
14537 /* Caller should pass TRUE for is_top_level only if we wouldn't be at top
14539 assert (!is_top_level || !at_top_level);
14541 /* The corresponding pop_obstacks is in finish_decl. */
14542 push_obstacks_nochange ();
14544 if (DECL_INITIAL (decl) != NULL_TREE)
14546 assert (DECL_INITIAL (decl) == error_mark_node);
14547 assert (!DECL_EXTERNAL (decl));
14549 else if (top_level)
14550 assert ((TREE_STATIC (decl) == 1) || DECL_EXTERNAL (decl) == 1);
14552 /* For Fortran, we by default put things in .common when possible. */
14553 DECL_COMMON (decl) = 1;
14555 /* Add this decl to the current binding level. TEM may equal DECL or it may
14556 be a previous decl of the same name. */
14558 tem = pushdecl_top_level (decl);
14560 tem = pushdecl (decl);
14562 /* For a local variable, define the RTL now. */
14564 /* But not if this is a duplicate decl and we preserved the rtl from the
14565 previous one (which may or may not happen). */
14566 && DECL_RTL (tem) == 0)
14568 if (TYPE_SIZE (TREE_TYPE (tem)) != 0)
14570 else if (TREE_CODE (TREE_TYPE (tem)) == ARRAY_TYPE
14571 && DECL_INITIAL (tem) != 0)
14575 if (DECL_INITIAL (tem) != NULL_TREE)
14577 /* When parsing and digesting the initializer, use temporary storage.
14578 Do this even if we will ignore the value. */
14580 temporary_allocation ();
14586 /* Create the FUNCTION_DECL for a function definition.
14587 DECLSPECS and DECLARATOR are the parts of the declaration;
14588 they describe the function's name and the type it returns,
14589 but twisted together in a fashion that parallels the syntax of C.
14591 This function creates a binding context for the function body
14592 as well as setting up the FUNCTION_DECL in current_function_decl.
14594 Returns 1 on success. If the DECLARATOR is not suitable for a function
14595 (it defines a datum instead), we return 0, which tells
14596 yyparse to report a parse error.
14598 NESTED is nonzero for a function nested within another function. */
14601 start_function (tree name, tree type, int nested, int public)
14605 int old_immediate_size_expand = immediate_size_expand;
14608 shadowed_labels = 0;
14610 /* Don't expand any sizes in the return type of the function. */
14611 immediate_size_expand = 0;
14616 assert (current_function_decl != NULL_TREE);
14617 assert (DECL_CONTEXT (current_function_decl) == NULL_TREE);
14621 assert (current_function_decl == NULL_TREE);
14624 if (TREE_CODE (type) == ERROR_MARK)
14625 decl1 = current_function_decl = error_mark_node;
14628 decl1 = build_decl (FUNCTION_DECL,
14631 TREE_PUBLIC (decl1) = public ? 1 : 0;
14633 DECL_INLINE (decl1) = 1;
14634 TREE_STATIC (decl1) = 1;
14635 DECL_EXTERNAL (decl1) = 0;
14637 announce_function (decl1);
14639 /* Make the init_value nonzero so pushdecl knows this is not tentative.
14640 error_mark_node is replaced below (in poplevel) with the BLOCK. */
14641 DECL_INITIAL (decl1) = error_mark_node;
14643 /* Record the decl so that the function name is defined. If we already have
14644 a decl for this name, and it is a FUNCTION_DECL, use the old decl. */
14646 current_function_decl = pushdecl (decl1);
14650 ffecom_outer_function_decl_ = current_function_decl;
14653 current_binding_level->prep_state = 2;
14655 if (TREE_CODE (current_function_decl) != ERROR_MARK)
14657 make_function_rtl (current_function_decl);
14659 restype = TREE_TYPE (TREE_TYPE (current_function_decl));
14660 DECL_RESULT (current_function_decl)
14661 = build_decl (RESULT_DECL, NULL_TREE, restype);
14665 /* Allocate further tree nodes temporarily during compilation of this
14667 temporary_allocation ();
14669 if (!nested && (TREE_CODE (current_function_decl) != ERROR_MARK))
14670 TREE_ADDRESSABLE (current_function_decl) = 1;
14672 immediate_size_expand = old_immediate_size_expand;
14675 /* Here are the public functions the GNU back end needs. */
14678 convert (type, expr)
14681 register tree e = expr;
14682 register enum tree_code code = TREE_CODE (type);
14684 if (type == TREE_TYPE (e)
14685 || TREE_CODE (e) == ERROR_MARK)
14687 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
14688 return fold (build1 (NOP_EXPR, type, e));
14689 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
14690 || code == ERROR_MARK)
14691 return error_mark_node;
14692 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
14694 assert ("void value not ignored as it ought to be" == NULL);
14695 return error_mark_node;
14697 if (code == VOID_TYPE)
14698 return build1 (CONVERT_EXPR, type, e);
14699 if ((code != RECORD_TYPE)
14700 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
14701 e = ffecom_1 (REALPART_EXPR, TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e))),
14703 if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)
14704 return fold (convert_to_integer (type, e));
14705 if (code == POINTER_TYPE)
14706 return fold (convert_to_pointer (type, e));
14707 if (code == REAL_TYPE)
14708 return fold (convert_to_real (type, e));
14709 if (code == COMPLEX_TYPE)
14710 return fold (convert_to_complex (type, e));
14711 if (code == RECORD_TYPE)
14712 return fold (ffecom_convert_to_complex_ (type, e));
14714 assert ("conversion to non-scalar type requested" == NULL);
14715 return error_mark_node;
14718 /* integrate_decl_tree calls this function, but since we don't use the
14719 DECL_LANG_SPECIFIC field, this is a no-op. */
14722 copy_lang_decl (node)
14727 /* Return the list of declarations of the current level.
14728 Note that this list is in reverse order unless/until
14729 you nreverse it; and when you do nreverse it, you must
14730 store the result back using `storedecls' or you will lose. */
14735 return current_binding_level->names;
14738 /* Nonzero if we are currently in the global binding level. */
14741 global_bindings_p ()
14743 return current_binding_level == global_binding_level;
14746 /* Print an error message for invalid use of an incomplete type.
14747 VALUE is the expression that was used (or 0 if that isn't known)
14748 and TYPE is the type that was invalid. */
14751 incomplete_type_error (value, type)
14755 if (TREE_CODE (type) == ERROR_MARK)
14758 assert ("incomplete type?!?" == NULL);
14762 init_decl_processing ()
14769 init_parse (filename)
14773 extern void (*print_error_function) (char *);
14776 /* Open input file. */
14777 if (filename == 0 || !strcmp (filename, "-"))
14780 filename = "stdin";
14783 finput = fopen (filename, "r");
14785 pfatal_with_name (filename);
14787 #ifdef IO_BUFFER_SIZE
14788 setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
14791 /* Make identifier nodes long enough for the language-specific slots. */
14792 set_identifier_size (sizeof (struct lang_identifier));
14793 decl_printable_name = lang_printable_name;
14795 print_error_function = lang_print_error_function;
14807 /* Delete the node BLOCK from the current binding level.
14808 This is used for the block inside a stmt expr ({...})
14809 so that the block can be reinserted where appropriate. */
14812 delete_block (block)
14816 if (current_binding_level->blocks == block)
14817 current_binding_level->blocks = TREE_CHAIN (block);
14818 for (t = current_binding_level->blocks; t;)
14820 if (TREE_CHAIN (t) == block)
14821 TREE_CHAIN (t) = TREE_CHAIN (block);
14823 t = TREE_CHAIN (t);
14825 TREE_CHAIN (block) = NULL;
14826 /* Clear TREE_USED which is always set by poplevel.
14827 The flag is set again if insert_block is called. */
14828 TREE_USED (block) = 0;
14832 insert_block (block)
14835 TREE_USED (block) = 1;
14836 current_binding_level->blocks
14837 = chainon (current_binding_level->blocks, block);
14841 lang_decode_option (argc, argv)
14845 return ffe_decode_option (argc, argv);
14848 /* used by print-tree.c */
14851 lang_print_xnode (file, node, indent)
14861 ffe_terminate_0 ();
14863 if (ffe_is_ffedebug ())
14864 malloc_pool_display (malloc_pool_image ());
14874 lang_init_options ()
14876 /* Set default options for Fortran. */
14877 flag_move_all_movables = 1;
14878 flag_reduce_all_givs = 1;
14879 flag_argument_noalias = 2;
14885 /* If the file is output from cpp, it should contain a first line
14886 `# 1 "real-filename"', and the current design of gcc (toplev.c
14887 in particular and the way it sets up information relied on by
14888 INCLUDE) requires that we read this now, and store the
14889 "real-filename" info in master_input_filename. Ask the lexer
14890 to try doing this. */
14891 ffelex_hash_kludge (finput);
14895 mark_addressable (exp)
14898 register tree x = exp;
14900 switch (TREE_CODE (x))
14903 case COMPONENT_REF:
14905 x = TREE_OPERAND (x, 0);
14909 TREE_ADDRESSABLE (x) = 1;
14916 if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
14917 && DECL_NONLOCAL (x))
14919 if (TREE_PUBLIC (x))
14921 assert ("address of global register var requested" == NULL);
14924 assert ("address of register variable requested" == NULL);
14926 else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x))
14928 if (TREE_PUBLIC (x))
14930 assert ("address of global register var requested" == NULL);
14933 assert ("address of register var requested" == NULL);
14935 put_var_into_stack (x);
14938 case FUNCTION_DECL:
14939 TREE_ADDRESSABLE (x) = 1;
14940 #if 0 /* poplevel deals with this now. */
14941 if (DECL_CONTEXT (x) == 0)
14942 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (x)) = 1;
14950 /* If DECL has a cleanup, build and return that cleanup here.
14951 This is a callback called by expand_expr. */
14954 maybe_build_cleanup (decl)
14957 /* There are no cleanups in Fortran. */
14961 /* Exit a binding level.
14962 Pop the level off, and restore the state of the identifier-decl mappings
14963 that were in effect when this level was entered.
14965 If KEEP is nonzero, this level had explicit declarations, so
14966 and create a "block" (a BLOCK node) for the level
14967 to record its declarations and subblocks for symbol table output.
14969 If FUNCTIONBODY is nonzero, this level is the body of a function,
14970 so create a block as if KEEP were set and also clear out all
14973 If REVERSE is nonzero, reverse the order of decls before putting
14974 them into the BLOCK. */
14977 poplevel (keep, reverse, functionbody)
14982 register tree link;
14983 /* The chain of decls was accumulated in reverse order.
14984 Put it into forward order, just for cleanliness. */
14986 tree subblocks = current_binding_level->blocks;
14989 int block_previously_created;
14991 /* Get the decls in the order they were written.
14992 Usually current_binding_level->names is in reverse order.
14993 But parameter decls were previously put in forward order. */
14996 current_binding_level->names
14997 = decls = nreverse (current_binding_level->names);
14999 decls = current_binding_level->names;
15001 /* Output any nested inline functions within this block
15002 if they weren't already output. */
15004 for (decl = decls; decl; decl = TREE_CHAIN (decl))
15005 if (TREE_CODE (decl) == FUNCTION_DECL
15006 && ! TREE_ASM_WRITTEN (decl)
15007 && DECL_INITIAL (decl) != 0
15008 && TREE_ADDRESSABLE (decl))
15010 /* If this decl was copied from a file-scope decl
15011 on account of a block-scope extern decl,
15012 propagate TREE_ADDRESSABLE to the file-scope decl.
15014 DECL_ABSTRACT_ORIGIN can be set to itself if warn_return_type is
15015 true, since then the decl goes through save_for_inline_copying. */
15016 if (DECL_ABSTRACT_ORIGIN (decl) != 0
15017 && DECL_ABSTRACT_ORIGIN (decl) != decl)
15018 TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1;
15019 else if (DECL_SAVED_INSNS (decl) != 0)
15021 push_function_context ();
15022 output_inline_function (decl);
15023 pop_function_context ();
15027 /* If there were any declarations or structure tags in that level,
15028 or if this level is a function body,
15029 create a BLOCK to record them for the life of this function. */
15032 block_previously_created = (current_binding_level->this_block != 0);
15033 if (block_previously_created)
15034 block = current_binding_level->this_block;
15035 else if (keep || functionbody)
15036 block = make_node (BLOCK);
15039 BLOCK_VARS (block) = decls;
15040 BLOCK_SUBBLOCKS (block) = subblocks;
15041 remember_end_note (block);
15044 /* In each subblock, record that this is its superior. */
15046 for (link = subblocks; link; link = TREE_CHAIN (link))
15047 BLOCK_SUPERCONTEXT (link) = block;
15049 /* Clear out the meanings of the local variables of this level. */
15051 for (link = decls; link; link = TREE_CHAIN (link))
15053 if (DECL_NAME (link) != 0)
15055 /* If the ident. was used or addressed via a local extern decl,
15056 don't forget that fact. */
15057 if (DECL_EXTERNAL (link))
15059 if (TREE_USED (link))
15060 TREE_USED (DECL_NAME (link)) = 1;
15061 if (TREE_ADDRESSABLE (link))
15062 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (link)) = 1;
15064 IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = 0;
15068 /* If the level being exited is the top level of a function,
15069 check over all the labels, and clear out the current
15070 (function local) meanings of their names. */
15074 /* If this is the top level block of a function,
15075 the vars are the function's parameters.
15076 Don't leave them in the BLOCK because they are
15077 found in the FUNCTION_DECL instead. */
15079 BLOCK_VARS (block) = 0;
15082 /* Pop the current level, and free the structure for reuse. */
15085 register struct binding_level *level = current_binding_level;
15086 current_binding_level = current_binding_level->level_chain;
15088 level->level_chain = free_binding_level;
15089 free_binding_level = level;
15092 /* Dispose of the block that we just made inside some higher level. */
15094 && current_function_decl != error_mark_node)
15095 DECL_INITIAL (current_function_decl) = block;
15098 if (!block_previously_created)
15099 current_binding_level->blocks
15100 = chainon (current_binding_level->blocks, block);
15102 /* If we did not make a block for the level just exited,
15103 any blocks made for inner levels
15104 (since they cannot be recorded as subblocks in that level)
15105 must be carried forward so they will later become subblocks
15106 of something else. */
15107 else if (subblocks)
15108 current_binding_level->blocks
15109 = chainon (current_binding_level->blocks, subblocks);
15112 TREE_USED (block) = 1;
15117 print_lang_decl (file, node, indent)
15125 print_lang_identifier (file, node, indent)
15130 print_node (file, "global", IDENTIFIER_GLOBAL_VALUE (node), indent + 4);
15131 print_node (file, "local", IDENTIFIER_LOCAL_VALUE (node), indent + 4);
15135 print_lang_statistics ()
15140 print_lang_type (file, node, indent)
15147 /* Record a decl-node X as belonging to the current lexical scope.
15148 Check for errors (such as an incompatible declaration for the same
15149 name already seen in the same scope).
15151 Returns either X or an old decl for the same name.
15152 If an old decl is returned, it may have been smashed
15153 to agree with what X says. */
15160 register tree name = DECL_NAME (x);
15161 register struct binding_level *b = current_binding_level;
15163 if ((TREE_CODE (x) == FUNCTION_DECL)
15164 && (DECL_INITIAL (x) == 0)
15165 && DECL_EXTERNAL (x))
15166 DECL_CONTEXT (x) = NULL_TREE;
15168 DECL_CONTEXT (x) = current_function_decl;
15172 if (IDENTIFIER_INVENTED (name))
15175 DECL_ARTIFICIAL (x) = 1;
15177 DECL_IN_SYSTEM_HEADER (x) = 1;
15180 t = lookup_name_current_level (name);
15182 assert ((t == NULL_TREE) || (DECL_CONTEXT (x) == NULL_TREE));
15184 /* Don't push non-parms onto list for parms until we understand
15185 why we're doing this and whether it works. */
15187 assert ((b == global_binding_level)
15188 || !ffecom_transform_only_dummies_
15189 || TREE_CODE (x) == PARM_DECL);
15191 if ((t != NULL_TREE) && duplicate_decls (x, t))
15194 /* If we are processing a typedef statement, generate a whole new
15195 ..._TYPE node (which will be just an variant of the existing
15196 ..._TYPE node with identical properties) and then install the
15197 TYPE_DECL node generated to represent the typedef name as the
15198 TYPE_NAME of this brand new (duplicate) ..._TYPE node.
15200 The whole point here is to end up with a situation where each and every
15201 ..._TYPE node the compiler creates will be uniquely associated with
15202 AT MOST one node representing a typedef name. This way, even though
15203 the compiler substitutes corresponding ..._TYPE nodes for TYPE_DECL
15204 (i.e. "typedef name") nodes very early on, later parts of the
15205 compiler can always do the reverse translation and get back the
15206 corresponding typedef name. For example, given:
15208 typedef struct S MY_TYPE; MY_TYPE object;
15210 Later parts of the compiler might only know that `object' was of type
15211 `struct S' if it were not for code just below. With this code
15212 however, later parts of the compiler see something like:
15214 struct S' == struct S typedef struct S' MY_TYPE; struct S' object;
15216 And they can then deduce (from the node for type struct S') that the
15217 original object declaration was:
15221 Being able to do this is important for proper support of protoize, and
15222 also for generating precise symbolic debugging information which
15223 takes full account of the programmer's (typedef) vocabulary.
15225 Obviously, we don't want to generate a duplicate ..._TYPE node if the
15226 TYPE_DECL node that we are now processing really represents a
15227 standard built-in type.
15229 Since all standard types are effectively declared at line zero in the
15230 source file, we can easily check to see if we are working on a
15231 standard type by checking the current value of lineno. */
15233 if (TREE_CODE (x) == TYPE_DECL)
15235 if (DECL_SOURCE_LINE (x) == 0)
15237 if (TYPE_NAME (TREE_TYPE (x)) == 0)
15238 TYPE_NAME (TREE_TYPE (x)) = x;
15240 else if (TREE_TYPE (x) != error_mark_node)
15242 tree tt = TREE_TYPE (x);
15244 tt = build_type_copy (tt);
15245 TYPE_NAME (tt) = x;
15246 TREE_TYPE (x) = tt;
15250 /* This name is new in its binding level. Install the new declaration
15252 if (b == global_binding_level)
15253 IDENTIFIER_GLOBAL_VALUE (name) = x;
15255 IDENTIFIER_LOCAL_VALUE (name) = x;
15258 /* Put decls on list in reverse order. We will reverse them later if
15260 TREE_CHAIN (x) = b->names;
15266 /* Nonzero if the current level needs to have a BLOCK made. */
15273 for (decl = current_binding_level->names;
15275 decl = TREE_CHAIN (decl))
15277 if (TREE_USED (decl) || TREE_CODE (decl) != VAR_DECL
15278 || (DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl)))
15279 /* Currently, there aren't supposed to be non-artificial names
15280 at other than the top block for a function -- they're
15281 believed to always be temps. But it's wise to check anyway. */
15287 /* Enter a new binding level.
15288 If TAG_TRANSPARENT is nonzero, do so only for the name space of variables,
15289 not for that of tags. */
15292 pushlevel (tag_transparent)
15293 int tag_transparent;
15295 register struct binding_level *newlevel = NULL_BINDING_LEVEL;
15297 assert (! tag_transparent);
15299 if (current_binding_level == global_binding_level)
15304 /* Reuse or create a struct for this binding level. */
15306 if (free_binding_level)
15308 newlevel = free_binding_level;
15309 free_binding_level = free_binding_level->level_chain;
15313 newlevel = make_binding_level ();
15316 /* Add this level to the front of the chain (stack) of levels that
15319 *newlevel = clear_binding_level;
15320 newlevel->level_chain = current_binding_level;
15321 current_binding_level = newlevel;
15324 /* Set the BLOCK node for the innermost scope
15325 (the one we are currently in). */
15329 register tree block;
15331 current_binding_level->this_block = block;
15334 /* ~~gcc/tree.h *should* declare this, because toplev.c references it. */
15336 /* Can't 'yydebug' a front end not generated by yacc/bison! */
15339 set_yydebug (value)
15343 fprintf (stderr, "warning: no yacc/bison-generated output to debug!\n");
15347 signed_or_unsigned_type (unsignedp, type)
15353 if (! INTEGRAL_TYPE_P (type))
15355 if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node))
15356 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
15357 if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
15358 return unsignedp ? unsigned_type_node : integer_type_node;
15359 if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node))
15360 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
15361 if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node))
15362 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
15363 if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node))
15364 return (unsignedp ? long_long_unsigned_type_node
15365 : long_long_integer_type_node);
15367 type2 = type_for_size (TYPE_PRECISION (type), unsignedp);
15368 if (type2 == NULL_TREE)
15378 tree type1 = TYPE_MAIN_VARIANT (type);
15379 ffeinfoKindtype kt;
15382 if (type1 == unsigned_char_type_node || type1 == char_type_node)
15383 return signed_char_type_node;
15384 if (type1 == unsigned_type_node)
15385 return integer_type_node;
15386 if (type1 == short_unsigned_type_node)
15387 return short_integer_type_node;
15388 if (type1 == long_unsigned_type_node)
15389 return long_integer_type_node;
15390 if (type1 == long_long_unsigned_type_node)
15391 return long_long_integer_type_node;
15392 #if 0 /* gcc/c-* files only */
15393 if (type1 == unsigned_intDI_type_node)
15394 return intDI_type_node;
15395 if (type1 == unsigned_intSI_type_node)
15396 return intSI_type_node;
15397 if (type1 == unsigned_intHI_type_node)
15398 return intHI_type_node;
15399 if (type1 == unsigned_intQI_type_node)
15400 return intQI_type_node;
15403 type2 = type_for_size (TYPE_PRECISION (type1), 0);
15404 if (type2 != NULL_TREE)
15407 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
15409 type2 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
15411 if (type1 == type2)
15412 return ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
15418 /* Prepare expr to be an argument of a TRUTH_NOT_EXPR,
15419 or validate its data type for an `if' or `while' statement or ?..: exp.
15421 This preparation consists of taking the ordinary
15422 representation of an expression expr and producing a valid tree
15423 boolean expression describing whether expr is nonzero. We could
15424 simply always do build_binary_op (NE_EXPR, expr, integer_zero_node, 1),
15425 but we optimize comparisons, &&, ||, and !.
15427 The resulting type should always be `integer_type_node'. */
15430 truthvalue_conversion (expr)
15433 if (TREE_CODE (expr) == ERROR_MARK)
15436 #if 0 /* This appears to be wrong for C++. */
15437 /* These really should return error_mark_node after 2.4 is stable.
15438 But not all callers handle ERROR_MARK properly. */
15439 switch (TREE_CODE (TREE_TYPE (expr)))
15442 error ("struct type value used where scalar is required");
15443 return integer_zero_node;
15446 error ("union type value used where scalar is required");
15447 return integer_zero_node;
15450 error ("array type value used where scalar is required");
15451 return integer_zero_node;
15458 switch (TREE_CODE (expr))
15460 /* It is simpler and generates better code to have only TRUTH_*_EXPR
15461 or comparison expressions as truth values at this level. */
15463 case COMPONENT_REF:
15464 /* A one-bit unsigned bit-field is already acceptable. */
15465 if (1 == TREE_INT_CST_LOW (DECL_SIZE (TREE_OPERAND (expr, 1)))
15466 && TREE_UNSIGNED (TREE_OPERAND (expr, 1)))
15472 /* It is simpler and generates better code to have only TRUTH_*_EXPR
15473 or comparison expressions as truth values at this level. */
15475 if (integer_zerop (TREE_OPERAND (expr, 1)))
15476 return build_unary_op (TRUTH_NOT_EXPR, TREE_OPERAND (expr, 0), 0);
15478 case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
15479 case TRUTH_ANDIF_EXPR:
15480 case TRUTH_ORIF_EXPR:
15481 case TRUTH_AND_EXPR:
15482 case TRUTH_OR_EXPR:
15483 case TRUTH_XOR_EXPR:
15484 TREE_TYPE (expr) = integer_type_node;
15491 return integer_zerop (expr) ? integer_zero_node : integer_one_node;
15494 return real_zerop (expr) ? integer_zero_node : integer_one_node;
15497 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 0)))
15498 return build (COMPOUND_EXPR, integer_type_node,
15499 TREE_OPERAND (expr, 0), integer_one_node);
15501 return integer_one_node;
15504 return ffecom_2 ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))
15505 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
15507 truthvalue_conversion (TREE_OPERAND (expr, 0)),
15508 truthvalue_conversion (TREE_OPERAND (expr, 1)));
15514 /* These don't change whether an object is non-zero or zero. */
15515 return truthvalue_conversion (TREE_OPERAND (expr, 0));
15519 /* These don't change whether an object is zero or non-zero, but
15520 we can't ignore them if their second arg has side-effects. */
15521 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)))
15522 return build (COMPOUND_EXPR, integer_type_node, TREE_OPERAND (expr, 1),
15523 truthvalue_conversion (TREE_OPERAND (expr, 0)));
15525 return truthvalue_conversion (TREE_OPERAND (expr, 0));
15528 /* Distribute the conversion into the arms of a COND_EXPR. */
15529 return fold (build (COND_EXPR, integer_type_node, TREE_OPERAND (expr, 0),
15530 truthvalue_conversion (TREE_OPERAND (expr, 1)),
15531 truthvalue_conversion (TREE_OPERAND (expr, 2))));
15534 /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
15535 since that affects how `default_conversion' will behave. */
15536 if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE
15537 || TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)
15539 /* fall through... */
15541 /* If this is widening the argument, we can ignore it. */
15542 if (TYPE_PRECISION (TREE_TYPE (expr))
15543 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
15544 return truthvalue_conversion (TREE_OPERAND (expr, 0));
15548 /* With IEEE arithmetic, x - x may not equal 0, so we can't optimize
15550 if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
15551 && TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE)
15553 /* fall through... */
15555 /* This and MINUS_EXPR can be changed into a comparison of the
15557 if (TREE_TYPE (TREE_OPERAND (expr, 0))
15558 == TREE_TYPE (TREE_OPERAND (expr, 1)))
15559 return ffecom_2 (NE_EXPR, integer_type_node,
15560 TREE_OPERAND (expr, 0),
15561 TREE_OPERAND (expr, 1));
15562 return ffecom_2 (NE_EXPR, integer_type_node,
15563 TREE_OPERAND (expr, 0),
15564 fold (build1 (NOP_EXPR,
15565 TREE_TYPE (TREE_OPERAND (expr, 0)),
15566 TREE_OPERAND (expr, 1))));
15569 if (integer_onep (TREE_OPERAND (expr, 1)))
15574 #if 0 /* No such thing in Fortran. */
15575 if (warn_parentheses && C_EXP_ORIGINAL_CODE (expr) == MODIFY_EXPR)
15576 warning ("suggest parentheses around assignment used as truth value");
15584 if (TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE)
15586 ((TREE_SIDE_EFFECTS (expr)
15587 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
15589 truthvalue_conversion (ffecom_1 (REALPART_EXPR,
15590 TREE_TYPE (TREE_TYPE (expr)),
15592 truthvalue_conversion (ffecom_1 (IMAGPART_EXPR,
15593 TREE_TYPE (TREE_TYPE (expr)),
15596 return ffecom_2 (NE_EXPR, integer_type_node,
15598 convert (TREE_TYPE (expr), integer_zero_node));
15602 type_for_mode (mode, unsignedp)
15603 enum machine_mode mode;
15610 if (mode == TYPE_MODE (integer_type_node))
15611 return unsignedp ? unsigned_type_node : integer_type_node;
15613 if (mode == TYPE_MODE (signed_char_type_node))
15614 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
15616 if (mode == TYPE_MODE (short_integer_type_node))
15617 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
15619 if (mode == TYPE_MODE (long_integer_type_node))
15620 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
15622 if (mode == TYPE_MODE (long_long_integer_type_node))
15623 return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node;
15625 if (mode == TYPE_MODE (float_type_node))
15626 return float_type_node;
15628 if (mode == TYPE_MODE (double_type_node))
15629 return double_type_node;
15631 if (mode == TYPE_MODE (build_pointer_type (char_type_node)))
15632 return build_pointer_type (char_type_node);
15634 if (mode == TYPE_MODE (build_pointer_type (integer_type_node)))
15635 return build_pointer_type (integer_type_node);
15637 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
15638 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
15640 if (((t = ffecom_tree_type[i][j]) != NULL_TREE)
15641 && (mode == TYPE_MODE (t)))
15643 if ((i == FFEINFO_basictypeINTEGER) && unsignedp)
15644 return ffecom_tree_type[FFEINFO_basictypeHOLLERITH][j];
15654 type_for_size (bits, unsignedp)
15658 ffeinfoKindtype kt;
15661 if (bits == TYPE_PRECISION (integer_type_node))
15662 return unsignedp ? unsigned_type_node : integer_type_node;
15664 if (bits == TYPE_PRECISION (signed_char_type_node))
15665 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
15667 if (bits == TYPE_PRECISION (short_integer_type_node))
15668 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
15670 if (bits == TYPE_PRECISION (long_integer_type_node))
15671 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
15673 if (bits == TYPE_PRECISION (long_long_integer_type_node))
15674 return (unsignedp ? long_long_unsigned_type_node
15675 : long_long_integer_type_node);
15677 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
15679 type_node = ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
15681 if ((type_node != NULL_TREE) && (bits == TYPE_PRECISION (type_node)))
15682 return unsignedp ? ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt]
15690 unsigned_type (type)
15693 tree type1 = TYPE_MAIN_VARIANT (type);
15694 ffeinfoKindtype kt;
15697 if (type1 == signed_char_type_node || type1 == char_type_node)
15698 return unsigned_char_type_node;
15699 if (type1 == integer_type_node)
15700 return unsigned_type_node;
15701 if (type1 == short_integer_type_node)
15702 return short_unsigned_type_node;
15703 if (type1 == long_integer_type_node)
15704 return long_unsigned_type_node;
15705 if (type1 == long_long_integer_type_node)
15706 return long_long_unsigned_type_node;
15707 #if 0 /* gcc/c-* files only */
15708 if (type1 == intDI_type_node)
15709 return unsigned_intDI_type_node;
15710 if (type1 == intSI_type_node)
15711 return unsigned_intSI_type_node;
15712 if (type1 == intHI_type_node)
15713 return unsigned_intHI_type_node;
15714 if (type1 == intQI_type_node)
15715 return unsigned_intQI_type_node;
15718 type2 = type_for_size (TYPE_PRECISION (type1), 1);
15719 if (type2 != NULL_TREE)
15722 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
15724 type2 = ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
15726 if (type1 == type2)
15727 return ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
15733 #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
15735 #if FFECOM_GCC_INCLUDE
15737 /* From gcc/cccp.c, the code to handle -I. */
15739 /* Skip leading "./" from a directory name.
15740 This may yield the empty string, which represents the current directory. */
15742 static const char *
15743 skip_redundant_dir_prefix (const char *dir)
15745 while (dir[0] == '.' && dir[1] == '/')
15746 for (dir += 2; *dir == '/'; dir++)
15748 if (dir[0] == '.' && !dir[1])
15753 /* The file_name_map structure holds a mapping of file names for a
15754 particular directory. This mapping is read from the file named
15755 FILE_NAME_MAP_FILE in that directory. Such a file can be used to
15756 map filenames on a file system with severe filename restrictions,
15757 such as DOS. The format of the file name map file is just a series
15758 of lines with two tokens on each line. The first token is the name
15759 to map, and the second token is the actual name to use. */
15761 struct file_name_map
15763 struct file_name_map *map_next;
15768 #define FILE_NAME_MAP_FILE "header.gcc"
15770 /* Current maximum length of directory names in the search path
15771 for include files. (Altered as we get more of them.) */
15773 static int max_include_len = 0;
15775 struct file_name_list
15777 struct file_name_list *next;
15779 /* Mapping of file names for this directory. */
15780 struct file_name_map *name_map;
15781 /* Non-zero if name_map is valid. */
15785 static struct file_name_list *include = NULL; /* First dir to search */
15786 static struct file_name_list *last_include = NULL; /* Last in chain */
15788 /* I/O buffer structure.
15789 The `fname' field is nonzero for source files and #include files
15790 and for the dummy text used for -D and -U.
15791 It is zero for rescanning results of macro expansion
15792 and for expanding macro arguments. */
15793 #define INPUT_STACK_MAX 400
15794 static struct file_buf {
15796 /* Filename specified with #line command. */
15797 char *nominal_fname;
15798 /* Record where in the search path this file was found.
15799 For #include_next. */
15800 struct file_name_list *dir;
15802 ffewhereColumn column;
15803 } instack[INPUT_STACK_MAX];
15805 static int last_error_tick = 0; /* Incremented each time we print it. */
15806 static int input_file_stack_tick = 0; /* Incremented when status changes. */
15808 /* Current nesting level of input sources.
15809 `instack[indepth]' is the level currently being read. */
15810 static int indepth = -1;
15812 typedef struct file_buf FILE_BUF;
15814 typedef unsigned char U_CHAR;
15816 /* table to tell if char can be part of a C identifier. */
15817 U_CHAR is_idchar[256];
15818 /* table to tell if char can be first char of a c identifier. */
15819 U_CHAR is_idstart[256];
15820 /* table to tell if c is horizontal space. */
15821 U_CHAR is_hor_space[256];
15822 /* table to tell if c is horizontal or vertical space. */
15823 static U_CHAR is_space[256];
15825 #define SKIP_WHITE_SPACE(p) do { while (is_hor_space[*p]) p++; } while (0)
15826 #define SKIP_ALL_WHITE_SPACE(p) do { while (is_space[*p]) p++; } while (0)
15828 /* Nonzero means -I- has been seen,
15829 so don't look for #include "foo" the source-file directory. */
15830 static int ignore_srcdir;
15832 #ifndef INCLUDE_LEN_FUDGE
15833 #define INCLUDE_LEN_FUDGE 0
15836 static void append_include_chain (struct file_name_list *first,
15837 struct file_name_list *last);
15838 static FILE *open_include_file (char *filename,
15839 struct file_name_list *searchptr);
15840 static void print_containing_files (ffebadSeverity sev);
15841 static const char *skip_redundant_dir_prefix (const char *);
15842 static char *read_filename_string (int ch, FILE *f);
15843 static struct file_name_map *read_name_map (const char *dirname);
15845 /* Append a chain of `struct file_name_list's
15846 to the end of the main include chain.
15847 FIRST is the beginning of the chain to append, and LAST is the end. */
15850 append_include_chain (first, last)
15851 struct file_name_list *first, *last;
15853 struct file_name_list *dir;
15855 if (!first || !last)
15861 last_include->next = first;
15863 for (dir = first; ; dir = dir->next) {
15864 int len = strlen (dir->fname) + INCLUDE_LEN_FUDGE;
15865 if (len > max_include_len)
15866 max_include_len = len;
15872 last_include = last;
15875 /* Try to open include file FILENAME. SEARCHPTR is the directory
15876 being tried from the include file search path. This function maps
15877 filenames on file systems based on information read by
15881 open_include_file (filename, searchptr)
15883 struct file_name_list *searchptr;
15885 register struct file_name_map *map;
15886 register char *from;
15889 if (searchptr && ! searchptr->got_name_map)
15891 searchptr->name_map = read_name_map (searchptr->fname
15892 ? searchptr->fname : ".");
15893 searchptr->got_name_map = 1;
15896 /* First check the mapping for the directory we are using. */
15897 if (searchptr && searchptr->name_map)
15900 if (searchptr->fname)
15901 from += strlen (searchptr->fname) + 1;
15902 for (map = searchptr->name_map; map; map = map->map_next)
15904 if (! strcmp (map->map_from, from))
15906 /* Found a match. */
15907 return fopen (map->map_to, "r");
15912 /* Try to find a mapping file for the particular directory we are
15913 looking in. Thus #include <sys/types.h> will look up sys/types.h
15914 in /usr/include/header.gcc and look up types.h in
15915 /usr/include/sys/header.gcc. */
15916 p = rindex (filename, '/');
15917 #ifdef DIR_SEPARATOR
15918 if (! p) p = rindex (filename, DIR_SEPARATOR);
15920 char *tmp = rindex (filename, DIR_SEPARATOR);
15921 if (tmp != NULL && tmp > p) p = tmp;
15927 && searchptr->fname
15928 && strlen (searchptr->fname) == (size_t) (p - filename)
15929 && ! strncmp (searchptr->fname, filename, (int) (p - filename)))
15931 /* FILENAME is in SEARCHPTR, which we've already checked. */
15932 return fopen (filename, "r");
15938 map = read_name_map (".");
15942 dir = (char *) xmalloc (p - filename + 1);
15943 memcpy (dir, filename, p - filename);
15944 dir[p - filename] = '\0';
15946 map = read_name_map (dir);
15949 for (; map; map = map->map_next)
15950 if (! strcmp (map->map_from, from))
15951 return fopen (map->map_to, "r");
15953 return fopen (filename, "r");
15956 /* Print the file names and line numbers of the #include
15957 commands which led to the current file. */
15960 print_containing_files (ffebadSeverity sev)
15962 FILE_BUF *ip = NULL;
15968 /* If stack of files hasn't changed since we last printed
15969 this info, don't repeat it. */
15970 if (last_error_tick == input_file_stack_tick)
15973 for (i = indepth; i >= 0; i--)
15974 if (instack[i].fname != NULL) {
15979 /* Give up if we don't find a source file. */
15983 /* Find the other, outer source files. */
15984 for (i--; i >= 0; i--)
15985 if (instack[i].fname != NULL)
15991 str1 = "In file included";
16003 ffebad_start_msg ("%A from %B at %0%C", sev);
16004 ffebad_here (0, ip->line, ip->column);
16005 ffebad_string (str1);
16006 ffebad_string (ip->nominal_fname);
16007 ffebad_string (str2);
16011 /* Record we have printed the status as of this time. */
16012 last_error_tick = input_file_stack_tick;
16015 /* Read a space delimited string of unlimited length from a stdio
16019 read_filename_string (ch, f)
16027 set = alloc = xmalloc (len + 1);
16028 if (! is_space[ch])
16031 while ((ch = getc (f)) != EOF && ! is_space[ch])
16033 if (set - alloc == len)
16036 alloc = xrealloc (alloc, len + 1);
16037 set = alloc + len / 2;
16047 /* Read the file name map file for DIRNAME. */
16049 static struct file_name_map *
16050 read_name_map (dirname)
16051 const char *dirname;
16053 /* This structure holds a linked list of file name maps, one per
16055 struct file_name_map_list
16057 struct file_name_map_list *map_list_next;
16058 char *map_list_name;
16059 struct file_name_map *map_list_map;
16061 static struct file_name_map_list *map_list;
16062 register struct file_name_map_list *map_list_ptr;
16066 int separator_needed;
16068 dirname = skip_redundant_dir_prefix (dirname);
16070 for (map_list_ptr = map_list; map_list_ptr;
16071 map_list_ptr = map_list_ptr->map_list_next)
16072 if (! strcmp (map_list_ptr->map_list_name, dirname))
16073 return map_list_ptr->map_list_map;
16075 map_list_ptr = ((struct file_name_map_list *)
16076 xmalloc (sizeof (struct file_name_map_list)));
16077 map_list_ptr->map_list_name = xstrdup (dirname);
16078 map_list_ptr->map_list_map = NULL;
16080 dirlen = strlen (dirname);
16081 separator_needed = dirlen != 0 && dirname[dirlen - 1] != '/';
16082 name = (char *) xmalloc (dirlen + strlen (FILE_NAME_MAP_FILE) + 2);
16083 strcpy (name, dirname);
16084 name[dirlen] = '/';
16085 strcpy (name + dirlen + separator_needed, FILE_NAME_MAP_FILE);
16086 f = fopen (name, "r");
16089 map_list_ptr->map_list_map = NULL;
16094 while ((ch = getc (f)) != EOF)
16097 struct file_name_map *ptr;
16101 from = read_filename_string (ch, f);
16102 while ((ch = getc (f)) != EOF && is_hor_space[ch])
16104 to = read_filename_string (ch, f);
16106 ptr = ((struct file_name_map *)
16107 xmalloc (sizeof (struct file_name_map)));
16108 ptr->map_from = from;
16110 /* Make the real filename absolute. */
16115 ptr->map_to = xmalloc (dirlen + strlen (to) + 2);
16116 strcpy (ptr->map_to, dirname);
16117 ptr->map_to[dirlen] = '/';
16118 strcpy (ptr->map_to + dirlen + separator_needed, to);
16122 ptr->map_next = map_list_ptr->map_list_map;
16123 map_list_ptr->map_list_map = ptr;
16125 while ((ch = getc (f)) != '\n')
16132 map_list_ptr->map_list_next = map_list;
16133 map_list = map_list_ptr;
16135 return map_list_ptr->map_list_map;
16139 ffecom_file_ (char *name)
16143 /* Do partial setup of input buffer for the sake of generating
16144 early #line directives (when -g is in effect). */
16146 fp = &instack[++indepth];
16147 memset ((char *) fp, 0, sizeof (FILE_BUF));
16150 fp->nominal_fname = fp->fname = name;
16153 /* Initialize syntactic classifications of characters. */
16156 ffecom_initialize_char_syntax_ ()
16161 * Set up is_idchar and is_idstart tables. These should be
16162 * faster than saying (is_alpha (c) || c == '_'), etc.
16163 * Set up these things before calling any routines tthat
16166 for (i = 'a'; i <= 'z'; i++) {
16167 is_idchar[i - 'a' + 'A'] = 1;
16169 is_idstart[i - 'a' + 'A'] = 1;
16172 for (i = '0'; i <= '9'; i++)
16174 is_idchar['_'] = 1;
16175 is_idstart['_'] = 1;
16177 /* horizontal space table */
16178 is_hor_space[' '] = 1;
16179 is_hor_space['\t'] = 1;
16180 is_hor_space['\v'] = 1;
16181 is_hor_space['\f'] = 1;
16182 is_hor_space['\r'] = 1;
16185 is_space['\t'] = 1;
16186 is_space['\v'] = 1;
16187 is_space['\f'] = 1;
16188 is_space['\n'] = 1;
16189 is_space['\r'] = 1;
16193 ffecom_close_include_ (FILE *f)
16198 input_file_stack_tick++;
16200 ffewhere_line_kill (instack[indepth].line);
16201 ffewhere_column_kill (instack[indepth].column);
16205 ffecom_decode_include_option_ (char *spec)
16207 struct file_name_list *dirtmp;
16209 if (! ignore_srcdir && !strcmp (spec, "-"))
16213 dirtmp = (struct file_name_list *)
16214 xmalloc (sizeof (struct file_name_list));
16215 dirtmp->next = 0; /* New one goes on the end */
16217 dirtmp->fname = spec;
16219 fatal ("Directory name must immediately follow -I option with no intervening spaces, as in `-Idir', not `-I dir'");
16220 dirtmp->got_name_map = 0;
16221 append_include_chain (dirtmp, dirtmp);
16226 /* Open INCLUDEd file. */
16229 ffecom_open_include_ (char *name, ffewhereLine l, ffewhereColumn c)
16232 size_t flen = strlen (fbeg);
16233 struct file_name_list *search_start = include; /* Chain of dirs to search */
16234 struct file_name_list dsp[1]; /* First in chain, if #include "..." */
16235 struct file_name_list *searchptr = 0;
16236 char *fname; /* Dynamically allocated fname buffer */
16243 dsp[0].fname = NULL;
16245 /* If -I- was specified, don't search current dir, only spec'd ones. */
16246 if (!ignore_srcdir)
16248 for (fp = &instack[indepth]; fp >= instack; fp--)
16254 if ((nam = fp->nominal_fname) != NULL)
16256 /* Found a named file. Figure out dir of the file,
16257 and put it in front of the search list. */
16258 dsp[0].next = search_start;
16259 search_start = dsp;
16261 ep = rindex (nam, '/');
16262 #ifdef DIR_SEPARATOR
16263 if (ep == NULL) ep = rindex (nam, DIR_SEPARATOR);
16265 char *tmp = rindex (nam, DIR_SEPARATOR);
16266 if (tmp != NULL && tmp > ep) ep = tmp;
16270 ep = rindex (nam, ']');
16271 if (ep == NULL) ep = rindex (nam, '>');
16272 if (ep == NULL) ep = rindex (nam, ':');
16273 if (ep != NULL) ep++;
16278 dsp[0].fname = (char *) xmalloc (n + 1);
16279 strncpy (dsp[0].fname, nam, n);
16280 dsp[0].fname[n] = '\0';
16281 if (n + INCLUDE_LEN_FUDGE > max_include_len)
16282 max_include_len = n + INCLUDE_LEN_FUDGE;
16285 dsp[0].fname = NULL; /* Current directory */
16286 dsp[0].got_name_map = 0;
16292 /* Allocate this permanently, because it gets stored in the definitions
16294 fname = xmalloc (max_include_len + flen + 4);
16295 /* + 2 above for slash and terminating null. */
16296 /* + 2 added for '.h' on VMS (to support '#include filename') (NOT USED
16299 /* If specified file name is absolute, just open it. */
16302 #ifdef DIR_SEPARATOR
16303 || *fbeg == DIR_SEPARATOR
16307 strncpy (fname, (char *) fbeg, flen);
16309 f = open_include_file (fname, NULL_PTR);
16315 /* Search directory path, trying to open the file.
16316 Copy each filename tried into FNAME. */
16318 for (searchptr = search_start; searchptr; searchptr = searchptr->next)
16320 if (searchptr->fname)
16322 /* The empty string in a search path is ignored.
16323 This makes it possible to turn off entirely
16324 a standard piece of the list. */
16325 if (searchptr->fname[0] == 0)
16327 strcpy (fname, skip_redundant_dir_prefix (searchptr->fname));
16328 if (fname[0] && fname[strlen (fname) - 1] != '/')
16329 strcat (fname, "/");
16330 fname[strlen (fname) + flen] = 0;
16335 strncat (fname, fbeg, flen);
16337 /* Change this 1/2 Unix 1/2 VMS file specification into a
16338 full VMS file specification */
16339 if (searchptr->fname && (searchptr->fname[0] != 0))
16341 /* Fix up the filename */
16342 hack_vms_include_specification (fname);
16346 /* This is a normal VMS filespec, so use it unchanged. */
16347 strncpy (fname, (char *) fbeg, flen);
16349 #if 0 /* Not for g77. */
16350 /* if it's '#include filename', add the missing .h */
16351 if (index (fname, '.') == NULL)
16352 strcat (fname, ".h");
16356 f = open_include_file (fname, searchptr);
16358 if (f == NULL && errno == EACCES)
16360 print_containing_files (FFEBAD_severityWARNING);
16361 ffebad_start_msg ("At %0, INCLUDE file %A exists, but is not readable",
16362 FFEBAD_severityWARNING);
16363 ffebad_string (fname);
16364 ffebad_here (0, l, c);
16375 /* A file that was not found. */
16377 strncpy (fname, (char *) fbeg, flen);
16379 print_containing_files (ffebad_severity (FFEBAD_OPEN_INCLUDE));
16380 ffebad_start (FFEBAD_OPEN_INCLUDE);
16381 ffebad_here (0, l, c);
16382 ffebad_string (fname);
16386 if (dsp[0].fname != NULL)
16387 free (dsp[0].fname);
16392 if (indepth >= (INPUT_STACK_MAX - 1))
16394 print_containing_files (FFEBAD_severityFATAL);
16395 ffebad_start_msg ("At %0, INCLUDE nesting too deep",
16396 FFEBAD_severityFATAL);
16397 ffebad_string (fname);
16398 ffebad_here (0, l, c);
16403 instack[indepth].line = ffewhere_line_use (l);
16404 instack[indepth].column = ffewhere_column_use (c);
16406 fp = &instack[indepth + 1];
16407 memset ((char *) fp, 0, sizeof (FILE_BUF));
16408 fp->nominal_fname = fp->fname = fname;
16409 fp->dir = searchptr;
16412 input_file_stack_tick++;
16416 #endif /* FFECOM_GCC_INCLUDE */
16418 /**INDENT* (Do not reformat this comment even with -fca option.)
16419 Data-gathering files: Given the source file listed below, compiled with
16420 f2c I obtained the output file listed after that, and from the output
16421 file I derived the above code.
16423 -------- (begin input file to f2c)
16429 double precision D1,D2
16431 call getem(A1,A2,C1,C2,I1,I2,R1,R2,D1,D2)
16458 c FFEINTRIN_impACOS
16459 call fooR(ACOS(R1))
16460 c FFEINTRIN_impAIMAG
16461 call fooR(AIMAG(C1))
16462 c FFEINTRIN_impAINT
16463 call fooR(AINT(R1))
16464 c FFEINTRIN_impALOG
16465 call fooR(ALOG(R1))
16466 c FFEINTRIN_impALOG10
16467 call fooR(ALOG10(R1))
16468 c FFEINTRIN_impAMAX0
16469 call fooR(AMAX0(I1,I2))
16470 c FFEINTRIN_impAMAX1
16471 call fooR(AMAX1(R1,R2))
16472 c FFEINTRIN_impAMIN0
16473 call fooR(AMIN0(I1,I2))
16474 c FFEINTRIN_impAMIN1
16475 call fooR(AMIN1(R1,R2))
16476 c FFEINTRIN_impAMOD
16477 call fooR(AMOD(R1,R2))
16478 c FFEINTRIN_impANINT
16479 call fooR(ANINT(R1))
16480 c FFEINTRIN_impASIN
16481 call fooR(ASIN(R1))
16482 c FFEINTRIN_impATAN
16483 call fooR(ATAN(R1))
16484 c FFEINTRIN_impATAN2
16485 call fooR(ATAN2(R1,R2))
16486 c FFEINTRIN_impCABS
16487 call fooR(CABS(C1))
16488 c FFEINTRIN_impCCOS
16489 call fooC(CCOS(C1))
16490 c FFEINTRIN_impCEXP
16491 call fooC(CEXP(C1))
16492 c FFEINTRIN_impCHAR
16493 call fooA(CHAR(I1))
16494 c FFEINTRIN_impCLOG
16495 call fooC(CLOG(C1))
16496 c FFEINTRIN_impCONJG
16497 call fooC(CONJG(C1))
16500 c FFEINTRIN_impCOSH
16501 call fooR(COSH(R1))
16502 c FFEINTRIN_impCSIN
16503 call fooC(CSIN(C1))
16504 c FFEINTRIN_impCSQRT
16505 call fooC(CSQRT(C1))
16506 c FFEINTRIN_impDABS
16507 call fooD(DABS(D1))
16508 c FFEINTRIN_impDACOS
16509 call fooD(DACOS(D1))
16510 c FFEINTRIN_impDASIN
16511 call fooD(DASIN(D1))
16512 c FFEINTRIN_impDATAN
16513 call fooD(DATAN(D1))
16514 c FFEINTRIN_impDATAN2
16515 call fooD(DATAN2(D1,D2))
16516 c FFEINTRIN_impDCOS
16517 call fooD(DCOS(D1))
16518 c FFEINTRIN_impDCOSH
16519 call fooD(DCOSH(D1))
16520 c FFEINTRIN_impDDIM
16521 call fooD(DDIM(D1,D2))
16522 c FFEINTRIN_impDEXP
16523 call fooD(DEXP(D1))
16525 call fooR(DIM(R1,R2))
16526 c FFEINTRIN_impDINT
16527 call fooD(DINT(D1))
16528 c FFEINTRIN_impDLOG
16529 call fooD(DLOG(D1))
16530 c FFEINTRIN_impDLOG10
16531 call fooD(DLOG10(D1))
16532 c FFEINTRIN_impDMAX1
16533 call fooD(DMAX1(D1,D2))
16534 c FFEINTRIN_impDMIN1
16535 call fooD(DMIN1(D1,D2))
16536 c FFEINTRIN_impDMOD
16537 call fooD(DMOD(D1,D2))
16538 c FFEINTRIN_impDNINT
16539 call fooD(DNINT(D1))
16540 c FFEINTRIN_impDPROD
16541 call fooD(DPROD(R1,R2))
16542 c FFEINTRIN_impDSIGN
16543 call fooD(DSIGN(D1,D2))
16544 c FFEINTRIN_impDSIN
16545 call fooD(DSIN(D1))
16546 c FFEINTRIN_impDSINH
16547 call fooD(DSINH(D1))
16548 c FFEINTRIN_impDSQRT
16549 call fooD(DSQRT(D1))
16550 c FFEINTRIN_impDTAN
16551 call fooD(DTAN(D1))
16552 c FFEINTRIN_impDTANH
16553 call fooD(DTANH(D1))
16556 c FFEINTRIN_impIABS
16557 call fooI(IABS(I1))
16558 c FFEINTRIN_impICHAR
16559 call fooI(ICHAR(A1))
16560 c FFEINTRIN_impIDIM
16561 call fooI(IDIM(I1,I2))
16562 c FFEINTRIN_impIDNINT
16563 call fooI(IDNINT(D1))
16564 c FFEINTRIN_impINDEX
16565 call fooI(INDEX(A1,A2))
16566 c FFEINTRIN_impISIGN
16567 call fooI(ISIGN(I1,I2))
16571 call fooL(LGE(A1,A2))
16573 call fooL(LGT(A1,A2))
16575 call fooL(LLE(A1,A2))
16577 call fooL(LLT(A1,A2))
16578 c FFEINTRIN_impMAX0
16579 call fooI(MAX0(I1,I2))
16580 c FFEINTRIN_impMAX1
16581 call fooI(MAX1(R1,R2))
16582 c FFEINTRIN_impMIN0
16583 call fooI(MIN0(I1,I2))
16584 c FFEINTRIN_impMIN1
16585 call fooI(MIN1(R1,R2))
16587 call fooI(MOD(I1,I2))
16588 c FFEINTRIN_impNINT
16589 call fooI(NINT(R1))
16590 c FFEINTRIN_impSIGN
16591 call fooR(SIGN(R1,R2))
16594 c FFEINTRIN_impSINH
16595 call fooR(SINH(R1))
16596 c FFEINTRIN_impSQRT
16597 call fooR(SQRT(R1))
16600 c FFEINTRIN_impTANH
16601 call fooR(TANH(R1))
16602 c FFEINTRIN_imp_CMPLX_C
16603 call fooC(cmplx(C1,C2))
16604 c FFEINTRIN_imp_CMPLX_D
16605 call fooZ(cmplx(D1,D2))
16606 c FFEINTRIN_imp_CMPLX_I
16607 call fooC(cmplx(I1,I2))
16608 c FFEINTRIN_imp_CMPLX_R
16609 call fooC(cmplx(R1,R2))
16610 c FFEINTRIN_imp_DBLE_C
16611 call fooD(dble(C1))
16612 c FFEINTRIN_imp_DBLE_D
16613 call fooD(dble(D1))
16614 c FFEINTRIN_imp_DBLE_I
16615 call fooD(dble(I1))
16616 c FFEINTRIN_imp_DBLE_R
16617 call fooD(dble(R1))
16618 c FFEINTRIN_imp_INT_C
16620 c FFEINTRIN_imp_INT_D
16622 c FFEINTRIN_imp_INT_I
16624 c FFEINTRIN_imp_INT_R
16626 c FFEINTRIN_imp_REAL_C
16627 call fooR(real(C1))
16628 c FFEINTRIN_imp_REAL_D
16629 call fooR(real(D1))
16630 c FFEINTRIN_imp_REAL_I
16631 call fooR(real(I1))
16632 c FFEINTRIN_imp_REAL_R
16633 call fooR(real(R1))
16635 c FFEINTRIN_imp_INT_D:
16637 c FFEINTRIN_specIDINT
16638 call fooI(IDINT(D1))
16640 c FFEINTRIN_imp_INT_R:
16642 c FFEINTRIN_specIFIX
16643 call fooI(IFIX(R1))
16644 c FFEINTRIN_specINT
16647 c FFEINTRIN_imp_REAL_D:
16649 c FFEINTRIN_specSNGL
16650 call fooR(SNGL(D1))
16652 c FFEINTRIN_imp_REAL_I:
16654 c FFEINTRIN_specFLOAT
16655 call fooR(FLOAT(I1))
16656 c FFEINTRIN_specREAL
16657 call fooR(REAL(I1))
16660 -------- (end input file to f2c)
16662 -------- (begin output from providing above input file as input to:
16663 -------- `f2c | gcc -E -C - | sed -e "s:/[*]*://:g" -e "s:[*]*[/]://:g" \
16664 -------- -e "s:^#.*$::g"')
16666 // -- translated by f2c (version 19950223).
16667 You must link the resulting object file with the libraries:
16668 -lf2c -lm (in that order)
16672 // f2c.h -- Standard Fortran to C header file //
16674 /// barf [ba:rf] 2. "He suggested using FORTRAN, and everybody barfed."
16676 - From The Shogakukan DICTIONARY OF NEW ENGLISH (Second edition) //
16681 // F2C_INTEGER will normally be `int' but would be `long' on 16-bit systems //
16682 // we assume short, float are OK //
16683 typedef long int // long int // integer;
16684 typedef char *address;
16685 typedef short int shortint;
16686 typedef float real;
16687 typedef double doublereal;
16688 typedef struct { real r, i; } complex;
16689 typedef struct { doublereal r, i; } doublecomplex;
16690 typedef long int // long int // logical;
16691 typedef short int shortlogical;
16692 typedef char logical1;
16693 typedef char integer1;
16694 // typedef long long longint; // // system-dependent //
16699 // Extern is for use with -E //
16713 typedef long int // int or long int // flag;
16714 typedef long int // int or long int // ftnlen;
16715 typedef long int // int or long int // ftnint;
16718 //external read, write//
16727 //internal read, write//
16757 //rewind, backspace, endfile//
16769 ftnint *inex; //parameters in standard's order//
16795 union Multitype { // for multiple entry points //
16806 typedef union Multitype Multitype;
16808 typedef long Long; // No longer used; formerly in Namelist //
16810 struct Vardesc { // for Namelist //
16816 typedef struct Vardesc Vardesc;
16823 typedef struct Namelist Namelist;
16832 // procedure parameter types for -A and -C++ //
16837 typedef int // Unknown procedure type // (*U_fp)();
16838 typedef shortint (*J_fp)();
16839 typedef integer (*I_fp)();
16840 typedef real (*R_fp)();
16841 typedef doublereal (*D_fp)(), (*E_fp)();
16842 typedef // Complex // void (*C_fp)();
16843 typedef // Double Complex // void (*Z_fp)();
16844 typedef logical (*L_fp)();
16845 typedef shortlogical (*K_fp)();
16846 typedef // Character // void (*H_fp)();
16847 typedef // Subroutine // int (*S_fp)();
16849 // E_fp is for real functions when -R is not specified //
16850 typedef void C_f; // complex function //
16851 typedef void H_f; // character function //
16852 typedef void Z_f; // double complex function //
16853 typedef doublereal E_f; // real function with -R not specified //
16855 // undef any lower-case symbols that your C compiler predefines, e.g.: //
16858 // (No such symbols should be defined in a strict ANSI C compiler.
16859 We can avoid trouble with f2c-translated code by using
16860 gcc -ansi [-traditional].) //
16884 // Main program // MAIN__()
16886 // System generated locals //
16889 doublereal d__1, d__2;
16891 doublecomplex z__1, z__2, z__3;
16895 // Builtin functions //
16898 double pow_ri(), pow_di();
16902 double acos(), r_imag(), r_int(), log(), r_lg10(), r_mod(), r_nint(),
16903 asin(), atan(), atan2(), c_abs();
16904 void c_cos(), c_exp(), c_log(), r_cnjg();
16905 double cos(), cosh();
16906 void c_sin(), c_sqrt();
16907 double d_dim(), exp(), r_dim(), d_int(), d_lg10(), d_mod(), d_nint(),
16908 d_sign(), sin(), sinh(), sqrt(), tan(), tanh();
16909 integer i_dim(), i_dnnt(), i_indx(), i_sign(), i_len();
16910 logical l_ge(), l_gt(), l_le(), l_lt();
16914 // Local variables //
16915 extern // Subroutine // int fooa_(), fooc_(), food_(), fooi_(), foor_(),
16916 fool_(), fooz_(), getem_();
16917 static char a1[10], a2[10];
16918 static complex c1, c2;
16919 static doublereal d1, d2;
16920 static integer i1, i2;
16921 static real r1, r2;
16924 getem_(a1, a2, &c1, &c2, &i1, &i2, &r1, &r2, &d1, &d2, 10L, 10L);
16932 d__1 = (doublereal) i1;
16933 q__1.r = c1.r / d__1, q__1.i = c1.i / d__1;
16943 c_div(&q__1, &c1, &c2);
16945 q__1.r = c1.r / r1, q__1.i = c1.i / r1;
16947 z__1.r = c1.r / d1, z__1.i = c1.i / d1;
16950 i__1 = pow_ii(&i1, &i2);
16952 r__1 = pow_ri(&r1, &i1);
16954 d__1 = pow_di(&d1, &i1);
16956 pow_ci(&q__1, &c1, &i1);
16958 d__1 = (doublereal) r1;
16959 d__2 = (doublereal) r2;
16960 r__1 = pow_dd(&d__1, &d__2);
16962 d__2 = (doublereal) r1;
16963 d__1 = pow_dd(&d__2, &d1);
16965 d__1 = pow_dd(&d1, &d2);
16967 d__2 = (doublereal) r1;
16968 d__1 = pow_dd(&d1, &d__2);
16970 z__2.r = c1.r, z__2.i = c1.i;
16971 z__3.r = c2.r, z__3.i = c2.i;
16972 pow_zz(&z__1, &z__2, &z__3);
16973 q__1.r = z__1.r, q__1.i = z__1.i;
16975 z__2.r = c1.r, z__2.i = c1.i;
16976 z__3.r = r1, z__3.i = 0.;
16977 pow_zz(&z__1, &z__2, &z__3);
16978 q__1.r = z__1.r, q__1.i = z__1.i;
16980 z__2.r = c1.r, z__2.i = c1.i;
16981 z__3.r = d1, z__3.i = 0.;
16982 pow_zz(&z__1, &z__2, &z__3);
16984 // FFEINTRIN_impABS //
16985 r__1 = (doublereal)(( r1 ) >= 0 ? ( r1 ) : -( r1 )) ;
16987 // FFEINTRIN_impACOS //
16990 // FFEINTRIN_impAIMAG //
16991 r__1 = r_imag(&c1);
16993 // FFEINTRIN_impAINT //
16996 // FFEINTRIN_impALOG //
16999 // FFEINTRIN_impALOG10 //
17000 r__1 = r_lg10(&r1);
17002 // FFEINTRIN_impAMAX0 //
17003 r__1 = (real) (( i1 ) >= ( i2 ) ? ( i1 ) : ( i2 )) ;
17005 // FFEINTRIN_impAMAX1 //
17006 r__1 = (doublereal)(( r1 ) >= ( r2 ) ? ( r1 ) : ( r2 )) ;
17008 // FFEINTRIN_impAMIN0 //
17009 r__1 = (real) (( i1 ) <= ( i2 ) ? ( i1 ) : ( i2 )) ;
17011 // FFEINTRIN_impAMIN1 //
17012 r__1 = (doublereal)(( r1 ) <= ( r2 ) ? ( r1 ) : ( r2 )) ;
17014 // FFEINTRIN_impAMOD //
17015 r__1 = r_mod(&r1, &r2);
17017 // FFEINTRIN_impANINT //
17018 r__1 = r_nint(&r1);
17020 // FFEINTRIN_impASIN //
17023 // FFEINTRIN_impATAN //
17026 // FFEINTRIN_impATAN2 //
17027 r__1 = atan2(r1, r2);
17029 // FFEINTRIN_impCABS //
17032 // FFEINTRIN_impCCOS //
17035 // FFEINTRIN_impCEXP //
17038 // FFEINTRIN_impCHAR //
17039 *(unsigned char *)&ch__1[0] = i1;
17041 // FFEINTRIN_impCLOG //
17044 // FFEINTRIN_impCONJG //
17045 r_cnjg(&q__1, &c1);
17047 // FFEINTRIN_impCOS //
17050 // FFEINTRIN_impCOSH //
17053 // FFEINTRIN_impCSIN //
17056 // FFEINTRIN_impCSQRT //
17057 c_sqrt(&q__1, &c1);
17059 // FFEINTRIN_impDABS //
17060 d__1 = (( d1 ) >= 0 ? ( d1 ) : -( d1 )) ;
17062 // FFEINTRIN_impDACOS //
17065 // FFEINTRIN_impDASIN //
17068 // FFEINTRIN_impDATAN //
17071 // FFEINTRIN_impDATAN2 //
17072 d__1 = atan2(d1, d2);
17074 // FFEINTRIN_impDCOS //
17077 // FFEINTRIN_impDCOSH //
17080 // FFEINTRIN_impDDIM //
17081 d__1 = d_dim(&d1, &d2);
17083 // FFEINTRIN_impDEXP //
17086 // FFEINTRIN_impDIM //
17087 r__1 = r_dim(&r1, &r2);
17089 // FFEINTRIN_impDINT //
17092 // FFEINTRIN_impDLOG //
17095 // FFEINTRIN_impDLOG10 //
17096 d__1 = d_lg10(&d1);
17098 // FFEINTRIN_impDMAX1 //
17099 d__1 = (( d1 ) >= ( d2 ) ? ( d1 ) : ( d2 )) ;
17101 // FFEINTRIN_impDMIN1 //
17102 d__1 = (( d1 ) <= ( d2 ) ? ( d1 ) : ( d2 )) ;
17104 // FFEINTRIN_impDMOD //
17105 d__1 = d_mod(&d1, &d2);
17107 // FFEINTRIN_impDNINT //
17108 d__1 = d_nint(&d1);
17110 // FFEINTRIN_impDPROD //
17111 d__1 = (doublereal) r1 * r2;
17113 // FFEINTRIN_impDSIGN //
17114 d__1 = d_sign(&d1, &d2);
17116 // FFEINTRIN_impDSIN //
17119 // FFEINTRIN_impDSINH //
17122 // FFEINTRIN_impDSQRT //
17125 // FFEINTRIN_impDTAN //
17128 // FFEINTRIN_impDTANH //
17131 // FFEINTRIN_impEXP //
17134 // FFEINTRIN_impIABS //
17135 i__1 = (( i1 ) >= 0 ? ( i1 ) : -( i1 )) ;
17137 // FFEINTRIN_impICHAR //
17138 i__1 = *(unsigned char *)a1;
17140 // FFEINTRIN_impIDIM //
17141 i__1 = i_dim(&i1, &i2);
17143 // FFEINTRIN_impIDNINT //
17144 i__1 = i_dnnt(&d1);
17146 // FFEINTRIN_impINDEX //
17147 i__1 = i_indx(a1, a2, 10L, 10L);
17149 // FFEINTRIN_impISIGN //
17150 i__1 = i_sign(&i1, &i2);
17152 // FFEINTRIN_impLEN //
17153 i__1 = i_len(a1, 10L);
17155 // FFEINTRIN_impLGE //
17156 L__1 = l_ge(a1, a2, 10L, 10L);
17158 // FFEINTRIN_impLGT //
17159 L__1 = l_gt(a1, a2, 10L, 10L);
17161 // FFEINTRIN_impLLE //
17162 L__1 = l_le(a1, a2, 10L, 10L);
17164 // FFEINTRIN_impLLT //
17165 L__1 = l_lt(a1, a2, 10L, 10L);
17167 // FFEINTRIN_impMAX0 //
17168 i__1 = (( i1 ) >= ( i2 ) ? ( i1 ) : ( i2 )) ;
17170 // FFEINTRIN_impMAX1 //
17171 i__1 = (integer) (doublereal)(( r1 ) >= ( r2 ) ? ( r1 ) : ( r2 )) ;
17173 // FFEINTRIN_impMIN0 //
17174 i__1 = (( i1 ) <= ( i2 ) ? ( i1 ) : ( i2 )) ;
17176 // FFEINTRIN_impMIN1 //
17177 i__1 = (integer) (doublereal)(( r1 ) <= ( r2 ) ? ( r1 ) : ( r2 )) ;
17179 // FFEINTRIN_impMOD //
17182 // FFEINTRIN_impNINT //
17183 i__1 = i_nint(&r1);
17185 // FFEINTRIN_impSIGN //
17186 r__1 = r_sign(&r1, &r2);
17188 // FFEINTRIN_impSIN //
17191 // FFEINTRIN_impSINH //
17194 // FFEINTRIN_impSQRT //
17197 // FFEINTRIN_impTAN //
17200 // FFEINTRIN_impTANH //
17203 // FFEINTRIN_imp_CMPLX_C //
17206 q__1.r = r__1, q__1.i = r__2;
17208 // FFEINTRIN_imp_CMPLX_D //
17209 z__1.r = d1, z__1.i = d2;
17211 // FFEINTRIN_imp_CMPLX_I //
17214 q__1.r = r__1, q__1.i = r__2;
17216 // FFEINTRIN_imp_CMPLX_R //
17217 q__1.r = r1, q__1.i = r2;
17219 // FFEINTRIN_imp_DBLE_C //
17220 d__1 = (doublereal) c1.r;
17222 // FFEINTRIN_imp_DBLE_D //
17225 // FFEINTRIN_imp_DBLE_I //
17226 d__1 = (doublereal) i1;
17228 // FFEINTRIN_imp_DBLE_R //
17229 d__1 = (doublereal) r1;
17231 // FFEINTRIN_imp_INT_C //
17232 i__1 = (integer) c1.r;
17234 // FFEINTRIN_imp_INT_D //
17235 i__1 = (integer) d1;
17237 // FFEINTRIN_imp_INT_I //
17240 // FFEINTRIN_imp_INT_R //
17241 i__1 = (integer) r1;
17243 // FFEINTRIN_imp_REAL_C //
17246 // FFEINTRIN_imp_REAL_D //
17249 // FFEINTRIN_imp_REAL_I //
17252 // FFEINTRIN_imp_REAL_R //
17256 // FFEINTRIN_imp_INT_D: //
17258 // FFEINTRIN_specIDINT //
17259 i__1 = (integer) d1;
17262 // FFEINTRIN_imp_INT_R: //
17264 // FFEINTRIN_specIFIX //
17265 i__1 = (integer) r1;
17267 // FFEINTRIN_specINT //
17268 i__1 = (integer) r1;
17271 // FFEINTRIN_imp_REAL_D: //
17273 // FFEINTRIN_specSNGL //
17277 // FFEINTRIN_imp_REAL_I: //
17279 // FFEINTRIN_specFLOAT //
17282 // FFEINTRIN_specREAL //
17288 -------- (end output file from f2c)