1 /* com.c -- Implementation File (module.c template V1.0)
2 Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000
3 Free Software Foundation, Inc.
4 Contributed by James Craig Burley.
6 This file is part of GNU Fortran.
8 GNU Fortran is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU Fortran is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Fortran; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
27 Contains compiler-specific functions.
32 /* Understanding this module means understanding the interface between
33 the g77 front end and the gcc back end (or, perhaps, some other
34 back end). In here are the functions called by the front end proper
35 to notify whatever back end is in place about certain things, and
36 also the back-end-specific functions. It's a bear to deal with, so
37 lately I've been trying to simplify things, especially with regard
38 to the gcc-back-end-specific stuff.
40 Building expressions generally seems quite easy, but building decls
41 has been challenging and is undergoing revision. gcc has several
44 TYPE_DECL -- a type (int, float, struct, function, etc.)
45 CONST_DECL -- a constant of some type other than function
46 LABEL_DECL -- a variable or a constant?
47 PARM_DECL -- an argument to a function (a variable that is a dummy)
48 RESULT_DECL -- the return value of a function (a variable)
49 VAR_DECL -- other variable (can hold a ptr-to-function, struct, int, etc.)
50 FUNCTION_DECL -- a function (either the actual function or an extern ref)
51 FIELD_DECL -- a field in a struct or union (goes into types)
53 g77 has a set of functions that somewhat parallels the gcc front end
54 when it comes to building decls:
56 Internal Function (one we define, not just declare as extern):
58 yes = suspend_momentary ();
59 if (is_nested) push_f_function_context ();
60 start_function (get_identifier ("function_name"), function_type,
61 is_nested, is_public);
62 // for each arg, build PARM_DECL and call push_parm_decl (decl) with it;
63 store_parm_decls (is_main_program);
64 ffecom_start_compstmt ();
65 // for stmts and decls inside function, do appropriate things;
66 ffecom_end_compstmt ();
67 finish_function (is_nested);
68 if (is_nested) pop_f_function_context ();
69 if (is_nested) resume_momentary (yes);
75 yes = suspend_momentary ();
76 // fill in external, public, static, &c for decl, and
77 // set DECL_INITIAL to error_mark_node if going to initialize
78 // set is_top_level TRUE only if not at top level and decl
79 // must go in top level (i.e. not within current function decl context)
80 d = start_decl (decl, is_top_level);
81 init = ...; // if have initializer
82 finish_decl (d, init, is_top_level);
83 resume_momentary (yes);
90 #if FFECOM_targetCURRENT == FFECOM_targetGCC
95 #include "output.j" /* Must follow tree.j so TREE_CODE is defined! */
98 #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
100 #define FFECOM_GCC_INCLUDE 1 /* Enable -I. */
102 /* BEGIN stuff from gcc/cccp.c. */
104 /* The following symbols should be autoconfigured:
111 In the mean time, we'll get by with approximations based
112 on existing GCC configuration symbols. */
115 # ifndef HAVE_STDLIB_H
116 # define HAVE_STDLIB_H 1
118 # ifndef HAVE_UNISTD_H
119 # define HAVE_UNISTD_H 1
121 # ifndef STDC_HEADERS
122 # define STDC_HEADERS 1
124 #endif /* defined (POSIX) */
126 #if defined (POSIX) || (defined (USG) && !defined (VMS))
127 # ifndef HAVE_FCNTL_H
128 # define HAVE_FCNTL_H 1
135 # if TIME_WITH_SYS_TIME
136 # include <sys/time.h>
140 # include <sys/time.h>
145 # include <sys/resource.h>
152 /* This defines "errno" properly for VMS, and gives us EACCES. */
165 /* VMS-specific definitions */
168 #define O_RDONLY 0 /* Open arg for Read/Only */
169 #define O_WRONLY 1 /* Open arg for Write/Only */
170 #define read(fd,buf,size) VMS_read (fd,buf,size)
171 #define write(fd,buf,size) VMS_write (fd,buf,size)
172 #define open(fname,mode,prot) VMS_open (fname,mode,prot)
173 #define fopen(fname,mode) VMS_fopen (fname,mode)
174 #define freopen(fname,mode,ofile) VMS_freopen (fname,mode,ofile)
175 #define strncat(dst,src,cnt) VMS_strncat (dst,src,cnt)
176 #define fstat(fd,stbuf) VMS_fstat (fd,stbuf)
177 static int VMS_fstat (), VMS_stat ();
178 static char * VMS_strncat ();
179 static int VMS_read ();
180 static int VMS_write ();
181 static int VMS_open ();
182 static FILE * VMS_fopen ();
183 static FILE * VMS_freopen ();
184 static void hack_vms_include_specification ();
185 typedef struct { unsigned :16, :16, :16; } vms_ino_t;
186 #define ino_t vms_ino_t
187 #define INCLUDE_LEN_FUDGE 10 /* leave room for VMS syntax conversion */
189 #define BSTRING /* VMS/GCC supplies the bstring routines */
190 #endif /* __GNUC__ */
197 /* END stuff from gcc/cccp.c. */
199 #define FFECOM_DETERMINE_TYPES 1 /* for com.h */
216 /* Externals defined here. */
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 current_function_decl;
226 /* ~~gcc/tree.h *should* declare this, because toplev.c and dwarfout.c
229 const char * const language_string = "GNU F77";
231 /* Stream for reading from the input file. */
234 /* These definitions parallel those in c-decl.c so that code from that
235 module can be used pretty much as is. Much of these defs aren't
236 otherwise used, i.e. by g77 code per se, except some of them are used
237 to build some of them that are. The ones that are global (i.e. not
238 "static") are those that ste.c and such might use (directly
239 or by using com macros that reference them in their definitions). */
241 tree string_type_node;
243 /* The rest of these are inventions for g77, though there might be
244 similar things in the C front end. As they are found, these
245 inventions should be renamed to be canonical. Note that only
246 the ones currently required to be global are so. */
248 static tree ffecom_tree_fun_type_void;
250 tree ffecom_integer_type_node; /* Abbrev for _tree_type[blah][blah]. */
251 tree ffecom_integer_zero_node; /* Like *_*_* with g77's integer type. */
252 tree ffecom_integer_one_node; /* " */
253 tree ffecom_tree_type[FFEINFO_basictype][FFEINFO_kindtype];
255 /* _fun_type things are the f2c-specific versions. For -fno-f2c,
256 just use build_function_type and build_pointer_type on the
257 appropriate _tree_type array element. */
259 static tree ffecom_tree_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
260 static tree ffecom_tree_ptr_to_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
261 static tree ffecom_tree_subr_type;
262 static tree ffecom_tree_ptr_to_subr_type;
263 static tree ffecom_tree_blockdata_type;
265 static tree ffecom_tree_xargc_;
267 ffecomSymbol ffecom_symbol_null_
276 ffeinfoKindtype ffecom_pointer_kind_ = FFEINFO_basictypeNONE;
277 ffeinfoKindtype ffecom_label_kind_ = FFEINFO_basictypeNONE;
279 int ffecom_f2c_typecode_[FFEINFO_basictype][FFEINFO_kindtype];
280 tree ffecom_f2c_integer_type_node;
281 tree ffecom_f2c_ptr_to_integer_type_node;
282 tree ffecom_f2c_address_type_node;
283 tree ffecom_f2c_real_type_node;
284 tree ffecom_f2c_ptr_to_real_type_node;
285 tree ffecom_f2c_doublereal_type_node;
286 tree ffecom_f2c_complex_type_node;
287 tree ffecom_f2c_doublecomplex_type_node;
288 tree ffecom_f2c_longint_type_node;
289 tree ffecom_f2c_logical_type_node;
290 tree ffecom_f2c_flag_type_node;
291 tree ffecom_f2c_ftnlen_type_node;
292 tree ffecom_f2c_ftnlen_zero_node;
293 tree ffecom_f2c_ftnlen_one_node;
294 tree ffecom_f2c_ftnlen_two_node;
295 tree ffecom_f2c_ptr_to_ftnlen_type_node;
296 tree ffecom_f2c_ftnint_type_node;
297 tree ffecom_f2c_ptr_to_ftnint_type_node;
298 #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
300 /* Simple definitions and enumerations. */
302 #ifndef FFECOM_sizeMAXSTACKITEM
303 #define FFECOM_sizeMAXSTACKITEM 32*1024 /* Keep user-declared things
304 larger than this # bytes
305 off stack if possible. */
308 /* For systems that have large enough stacks, they should define
309 this to 0, and here, for ease of use later on, we just undefine
312 #if FFECOM_sizeMAXSTACKITEM == 0
313 #undef FFECOM_sizeMAXSTACKITEM
319 FFECOM_rttypeVOIDSTAR_, /* C's `void *' type. */
320 FFECOM_rttypeFTNINT_, /* f2c's `ftnint' type. */
321 FFECOM_rttypeINTEGER_, /* f2c's `integer' type. */
322 FFECOM_rttypeLONGINT_, /* f2c's `longint' type. */
323 FFECOM_rttypeLOGICAL_, /* f2c's `logical' type. */
324 FFECOM_rttypeREAL_F2C_, /* f2c's `real' returned as `double'. */
325 FFECOM_rttypeREAL_GNU_, /* `real' returned as such. */
326 FFECOM_rttypeCOMPLEX_F2C_, /* f2c's `complex' returned via 1st arg. */
327 FFECOM_rttypeCOMPLEX_GNU_, /* f2c's `complex' returned directly. */
328 FFECOM_rttypeDOUBLE_, /* C's `double' type. */
329 FFECOM_rttypeDOUBLEREAL_, /* f2c's `doublereal' type. */
330 FFECOM_rttypeDBLCMPLX_F2C_, /* f2c's `doublecomplex' returned via 1st arg. */
331 FFECOM_rttypeDBLCMPLX_GNU_, /* f2c's `doublecomplex' returned directly. */
332 FFECOM_rttypeCHARACTER_, /* f2c `char *'/`ftnlen' pair. */
336 /* Internal typedefs. */
338 #if FFECOM_targetCURRENT == FFECOM_targetGCC
339 typedef struct _ffecom_concat_list_ ffecomConcatList_;
340 #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
342 /* Private include files. */
345 /* Internal structure definitions. */
347 #if FFECOM_targetCURRENT == FFECOM_targetGCC
348 struct _ffecom_concat_list_
353 ffetargetCharacterSize minlen;
354 ffetargetCharacterSize maxlen;
356 #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
358 /* Static functions (internal). */
360 #if FFECOM_targetCURRENT == FFECOM_targetGCC
361 static tree ffecom_arglist_expr_ (const char *argstring, ffebld args);
362 static tree ffecom_widest_expr_type_ (ffebld list);
363 static bool ffecom_overlap_ (tree dest_decl, tree dest_offset,
364 tree dest_size, tree source_tree,
365 ffebld source, bool scalar_arg);
366 static bool ffecom_args_overlapping_ (tree dest_tree, ffebld dest,
367 tree args, tree callee_commons,
369 static tree ffecom_build_f2c_string_ (int i, const char *s);
370 static tree ffecom_call_ (tree fn, ffeinfoKindtype kt,
371 bool is_f2c_complex, tree type,
372 tree args, tree dest_tree,
373 ffebld dest, bool *dest_used,
374 tree callee_commons, bool scalar_args, tree hook);
375 static tree ffecom_call_binop_ (tree fn, ffeinfoKindtype kt,
376 bool is_f2c_complex, tree type,
377 ffebld left, ffebld right,
378 tree dest_tree, ffebld dest,
379 bool *dest_used, tree callee_commons,
380 bool scalar_args, tree hook);
381 static void ffecom_char_args_x_ (tree *xitem, tree *length,
382 ffebld expr, bool with_null);
383 static tree ffecom_check_size_overflow_ (ffesymbol s, tree type, bool dummy);
384 static tree ffecom_char_enhance_arg_ (tree *xtype, ffesymbol s);
385 static ffecomConcatList_
386 ffecom_concat_list_gather_ (ffecomConcatList_ catlist,
388 ffetargetCharacterSize max);
389 static void ffecom_concat_list_kill_ (ffecomConcatList_ catlist);
390 static ffecomConcatList_ ffecom_concat_list_new_ (ffebld expr,
391 ffetargetCharacterSize max);
392 static void ffecom_debug_kludge_ (tree aggr, const char *aggr_type,
393 ffesymbol member, tree member_type,
394 ffetargetOffset offset);
395 static void ffecom_do_entry_ (ffesymbol fn, int entrynum);
396 static tree ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest,
397 bool *dest_used, bool assignp, bool widenp);
398 static tree ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree,
399 ffebld dest, bool *dest_used);
400 static tree ffecom_expr_power_integer_ (ffebld expr);
401 static void ffecom_expr_transform_ (ffebld expr);
402 static void ffecom_f2c_make_type_ (tree *type, int tcode, const char *name);
403 static void ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size,
405 static ffeglobal ffecom_finish_global_ (ffeglobal global);
406 static ffesymbol ffecom_finish_symbol_transform_ (ffesymbol s);
407 static tree ffecom_get_appended_identifier_ (char us, const char *text);
408 static tree ffecom_get_external_identifier_ (ffesymbol s);
409 static tree ffecom_get_identifier_ (const char *text);
410 static tree ffecom_gen_sfuncdef_ (ffesymbol s,
413 static const char *ffecom_gfrt_args_ (ffecomGfrt ix);
414 static tree ffecom_gfrt_tree_ (ffecomGfrt ix);
415 static tree ffecom_init_zero_ (tree decl);
416 static tree ffecom_intrinsic_ichar_ (tree tree_type, ffebld arg,
418 static tree ffecom_intrinsic_len_ (ffebld expr);
419 static void ffecom_let_char_ (tree dest_tree,
421 ffetargetCharacterSize dest_size,
423 static void ffecom_make_gfrt_ (ffecomGfrt ix);
424 static void ffecom_member_phase1_ (ffestorag mst, ffestorag st);
425 static void ffecom_member_phase2_ (ffestorag mst, ffestorag st);
426 static void ffecom_prepare_let_char_ (ffetargetCharacterSize dest_size,
428 static void ffecom_push_dummy_decls_ (ffebld dumlist,
430 static void ffecom_start_progunit_ (void);
431 static ffesymbol ffecom_sym_transform_ (ffesymbol s);
432 static ffesymbol ffecom_sym_transform_assign_ (ffesymbol s);
433 static void ffecom_transform_common_ (ffesymbol s);
434 static void ffecom_transform_equiv_ (ffestorag st);
435 static tree ffecom_transform_namelist_ (ffesymbol s);
436 static void ffecom_tree_canonize_ptr_ (tree *decl, tree *offset,
438 static void ffecom_tree_canonize_ref_ (tree *decl, tree *offset,
439 tree *size, tree tree);
440 static tree ffecom_tree_divide_ (tree tree_type, tree left, tree right,
441 tree dest_tree, ffebld dest,
442 bool *dest_used, tree hook);
443 static tree ffecom_type_localvar_ (ffesymbol s,
446 static tree ffecom_type_namelist_ (void);
447 static tree ffecom_type_vardesc_ (void);
448 static tree ffecom_vardesc_ (ffebld expr);
449 static tree ffecom_vardesc_array_ (ffesymbol s);
450 static tree ffecom_vardesc_dims_ (ffesymbol s);
451 static tree ffecom_convert_narrow_ (tree type, tree expr);
452 static tree ffecom_convert_widen_ (tree type, tree expr);
453 #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
455 /* These are static functions that parallel those found in the C front
456 end and thus have the same names. */
458 #if FFECOM_targetCURRENT == FFECOM_targetGCC
459 static tree bison_rule_compstmt_ (void);
460 static void bison_rule_pushlevel_ (void);
461 static void delete_block (tree block);
462 static int duplicate_decls (tree newdecl, tree olddecl);
463 static void finish_decl (tree decl, tree init, bool is_top_level);
464 static void finish_function (int nested);
465 static const char *lang_printable_name (tree decl, int v);
466 static tree lookup_name_current_level (tree name);
467 static struct binding_level *make_binding_level (void);
468 static void pop_f_function_context (void);
469 static void push_f_function_context (void);
470 static void push_parm_decl (tree parm);
471 static tree pushdecl_top_level (tree decl);
472 static int kept_level_p (void);
473 static tree storedecls (tree decls);
474 static void store_parm_decls (int is_main_program);
475 static tree start_decl (tree decl, bool is_top_level);
476 static void start_function (tree name, tree type, int nested, int public);
477 #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
478 #if FFECOM_GCC_INCLUDE
479 static void ffecom_file_ (const char *name);
480 static void ffecom_initialize_char_syntax_ (void);
481 static void ffecom_close_include_ (FILE *f);
482 static int ffecom_decode_include_option_ (char *spec);
483 static FILE *ffecom_open_include_ (char *name, ffewhereLine l,
485 #endif /* FFECOM_GCC_INCLUDE */
487 /* Static objects accessed by functions in this module. */
489 static ffesymbol ffecom_primary_entry_ = NULL;
490 static ffesymbol ffecom_nested_entry_ = NULL;
491 static ffeinfoKind ffecom_primary_entry_kind_;
492 static bool ffecom_primary_entry_is_proc_;
493 #if FFECOM_targetCURRENT == FFECOM_targetGCC
494 static tree ffecom_outer_function_decl_;
495 static tree ffecom_previous_function_decl_;
496 static tree ffecom_which_entrypoint_decl_;
497 static tree ffecom_float_zero_ = NULL_TREE;
498 static tree ffecom_float_half_ = NULL_TREE;
499 static tree ffecom_double_zero_ = NULL_TREE;
500 static tree ffecom_double_half_ = NULL_TREE;
501 static tree ffecom_func_result_;/* For functions. */
502 static tree ffecom_func_length_;/* For CHARACTER fns. */
503 static ffebld ffecom_list_blockdata_;
504 static ffebld ffecom_list_common_;
505 static ffebld ffecom_master_arglist_;
506 static ffeinfoBasictype ffecom_master_bt_;
507 static ffeinfoKindtype ffecom_master_kt_;
508 static ffetargetCharacterSize ffecom_master_size_;
509 static int ffecom_num_fns_ = 0;
510 static int ffecom_num_entrypoints_ = 0;
511 static bool ffecom_is_altreturning_ = FALSE;
512 static tree ffecom_multi_type_node_;
513 static tree ffecom_multi_retval_;
515 ffecom_multi_fields_[FFEINFO_basictype][FFEINFO_kindtype];
516 static bool ffecom_member_namelisted_; /* _member_phase1_ namelisted? */
517 static bool ffecom_doing_entry_ = FALSE;
518 static bool ffecom_transform_only_dummies_ = FALSE;
519 static int ffecom_typesize_pointer_;
520 static int ffecom_typesize_integer1_;
522 /* Holds pointer-to-function expressions. */
524 static tree ffecom_gfrt_[FFECOM_gfrt]
527 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) NULL_TREE,
528 #include "com-rt.def"
532 /* Holds the external names of the functions. */
534 static const char *ffecom_gfrt_name_[FFECOM_gfrt]
537 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) NAME,
538 #include "com-rt.def"
542 /* Whether the function returns. */
544 static bool ffecom_gfrt_volatile_[FFECOM_gfrt]
547 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) VOLATILE,
548 #include "com-rt.def"
552 /* Whether the function returns type complex. */
554 static bool ffecom_gfrt_complex_[FFECOM_gfrt]
557 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) COMPLEX,
558 #include "com-rt.def"
562 /* Type code for the function return value. */
564 static ffecomRttype_ ffecom_gfrt_type_[FFECOM_gfrt]
567 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) TYPE,
568 #include "com-rt.def"
572 /* String of codes for the function's arguments. */
574 static const char *ffecom_gfrt_argstring_[FFECOM_gfrt]
577 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) ARGS,
578 #include "com-rt.def"
581 #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
583 /* Internal macros. */
585 #if FFECOM_targetCURRENT == FFECOM_targetGCC
587 /* We let tm.h override the types used here, to handle trivial differences
588 such as the choice of unsigned int or long unsigned int for size_t.
589 When machines start needing nontrivial differences in the size type,
590 it would be best to do something here to figure out automatically
591 from other information what type to use. */
594 #define SIZE_TYPE "long unsigned int"
597 #define ffecom_concat_list_count_(catlist) ((catlist).count)
598 #define ffecom_concat_list_expr_(catlist,i) ((catlist).exprs[(i)])
599 #define ffecom_concat_list_maxlen_(catlist) ((catlist).maxlen)
600 #define ffecom_concat_list_minlen_(catlist) ((catlist).minlen)
602 #define ffecom_char_args_(i,l,e) ffecom_char_args_x_((i),(l),(e),FALSE)
603 #define ffecom_char_args_with_null_(i,l,e) ffecom_char_args_x_((i),(l),(e),TRUE)
605 /* For each binding contour we allocate a binding_level structure
606 * which records the names defined in that contour.
609 * 1) one for each function definition,
610 * where internal declarations of the parameters appear.
612 * The current meaning of a name can be found by searching the levels from
613 * the current one out to the global one.
616 /* Note that the information in the `names' component of the global contour
617 is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */
621 /* A chain of _DECL nodes for all variables, constants, functions,
622 and typedef types. These are in the reverse of the order supplied.
626 /* For each level (except not the global one),
627 a chain of BLOCK nodes for all the levels
628 that were entered and exited one level down. */
631 /* The BLOCK node for this level, if one has been preallocated.
632 If 0, the BLOCK is allocated (if needed) when the level is popped. */
635 /* The binding level which this one is contained in (inherits from). */
636 struct binding_level *level_chain;
638 /* 0: no ffecom_prepare_* functions called at this level yet;
639 1: ffecom_prepare* functions called, except not ffecom_prepare_end;
640 2: ffecom_prepare_end called. */
644 #define NULL_BINDING_LEVEL (struct binding_level *) NULL
646 /* The binding level currently in effect. */
648 static struct binding_level *current_binding_level;
650 /* A chain of binding_level structures awaiting reuse. */
652 static struct binding_level *free_binding_level;
654 /* The outermost binding level, for names of file scope.
655 This is created when the compiler is started and exists
656 through the entire run. */
658 static struct binding_level *global_binding_level;
660 /* Binding level structures are initialized by copying this one. */
662 static struct binding_level clear_binding_level
664 {NULL, NULL, NULL, NULL_BINDING_LEVEL, 0};
666 /* Language-dependent contents of an identifier. */
668 struct lang_identifier
670 struct tree_identifier ignore;
671 tree global_value, local_value, label_value;
675 /* Macros for access to language-specific slots in an identifier. */
676 /* Each of these slots contains a DECL node or null. */
678 /* This represents the value which the identifier has in the
679 file-scope namespace. */
680 #define IDENTIFIER_GLOBAL_VALUE(NODE) \
681 (((struct lang_identifier *)(NODE))->global_value)
682 /* This represents the value which the identifier has in the current
684 #define IDENTIFIER_LOCAL_VALUE(NODE) \
685 (((struct lang_identifier *)(NODE))->local_value)
686 /* This represents the value which the identifier has as a label in
687 the current label scope. */
688 #define IDENTIFIER_LABEL_VALUE(NODE) \
689 (((struct lang_identifier *)(NODE))->label_value)
690 /* This is nonzero if the identifier was "made up" by g77 code. */
691 #define IDENTIFIER_INVENTED(NODE) \
692 (((struct lang_identifier *)(NODE))->invented)
694 /* In identifiers, C uses the following fields in a special way:
695 TREE_PUBLIC to record that there was a previous local extern decl.
696 TREE_USED to record that such a decl was used.
697 TREE_ADDRESSABLE to record that the address of such a decl was used. */
699 /* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function
700 that have names. Here so we can clear out their names' definitions
701 at the end of the function. */
703 static tree named_labels;
705 /* A list of LABEL_DECLs from outer contexts that are currently shadowed. */
707 static tree shadowed_labels;
709 #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
711 /* Return the subscript expression, modified to do range-checking.
713 `array' is the array to be checked against.
714 `element' is the subscript expression to check.
715 `dim' is the dimension number (starting at 0).
716 `total_dims' is the total number of dimensions (0 for CHARACTER substring).
720 ffecom_subscript_check_ (tree array, tree element, int dim, int total_dims,
723 tree low = TYPE_MIN_VALUE (TYPE_DOMAIN (array));
724 tree high = TYPE_MAX_VALUE (TYPE_DOMAIN (array));
729 if (element == error_mark_node)
732 if (TREE_TYPE (low) != TREE_TYPE (element))
734 if (TYPE_PRECISION (TREE_TYPE (low))
735 > TYPE_PRECISION (TREE_TYPE (element)))
736 element = convert (TREE_TYPE (low), element);
739 low = convert (TREE_TYPE (element), low);
741 high = convert (TREE_TYPE (element), high);
745 element = ffecom_save_tree (element);
746 cond = ffecom_2 (LE_EXPR, integer_type_node,
751 cond = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
753 ffecom_2 (LE_EXPR, integer_type_node,
770 var = xmalloc (strlen (array_name) + 20);
771 sprintf (&var[0], "%s[%s-substring]",
773 dim ? "end" : "start");
774 len = strlen (var) + 1;
778 len = strlen (array_name) + 1;
783 var = xmalloc (strlen (array_name) + 40);
784 sprintf (&var[0], "%s[subscript-%d-of-%d]",
786 dim + 1, total_dims);
787 len = strlen (var) + 1;
791 arg1 = build_string (len, var);
797 = build_type_variant (build_array_type (char_type_node,
801 build_int_2 (len, 0))),
803 TREE_CONSTANT (arg1) = 1;
804 TREE_STATIC (arg1) = 1;
805 arg1 = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg1)),
808 /* s_rnge adds one to the element to print it, so bias against
809 that -- want to print a faithful *subscript* value. */
810 arg2 = convert (ffecom_f2c_ftnint_type_node,
811 ffecom_2 (MINUS_EXPR,
814 convert (TREE_TYPE (element),
817 proc = xmalloc ((len = strlen (input_filename)
818 + IDENTIFIER_LENGTH (DECL_NAME (current_function_decl))
821 sprintf (&proc[0], "%s/%s",
823 IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));
824 arg3 = build_string (len, proc);
829 = build_type_variant (build_array_type (char_type_node,
833 build_int_2 (len, 0))),
835 TREE_CONSTANT (arg3) = 1;
836 TREE_STATIC (arg3) = 1;
837 arg3 = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg3)),
840 arg4 = convert (ffecom_f2c_ftnint_type_node,
841 build_int_2 (lineno, 0));
843 arg1 = build_tree_list (NULL_TREE, arg1);
844 arg2 = build_tree_list (NULL_TREE, arg2);
845 arg3 = build_tree_list (NULL_TREE, arg3);
846 arg4 = build_tree_list (NULL_TREE, arg4);
847 TREE_CHAIN (arg3) = arg4;
848 TREE_CHAIN (arg2) = arg3;
849 TREE_CHAIN (arg1) = arg2;
853 die = ffecom_call_gfrt (FFECOM_gfrtRANGE,
855 TREE_SIDE_EFFECTS (die) = 1;
857 element = ffecom_3 (COND_EXPR,
866 /* Return the computed element of an array reference.
868 `item' is NULL_TREE, or the transformed pointer to the array.
869 `expr' is the original opARRAYREF expression, which is transformed
870 if `item' is NULL_TREE.
871 `want_ptr' is non-zero if a pointer to the element, instead of
872 the element itself, is to be returned. */
875 ffecom_arrayref_ (tree item, ffebld expr, int want_ptr)
877 ffebld dims[FFECOM_dimensionsMAX];
880 int flatten = ffe_is_flatten_arrays ();
890 if (ffebld_op (ffebld_left (expr)) == FFEBLD_opSYMTER)
891 array_name = ffesymbol_text (ffebld_symter (ffebld_left (expr)));
893 array_name = "[expr?]";
895 /* Build up ARRAY_REFs in reverse order (since we're column major
896 here in Fortran land). */
898 for (i = 0, list = ffebld_right (expr);
900 ++i, list = ffebld_trail (list))
902 dims[i] = ffebld_head (list);
903 type = ffeinfo_type (ffebld_basictype (dims[i]),
904 ffebld_kindtype (dims[i]));
906 && ffecom_typesize_pointer_ > ffecom_typesize_integer1_
907 && ffetype_size (type) > ffecom_typesize_integer1_)
908 /* E.g. ARRAY(INDEX), given INTEGER*8 INDEX, on a system with 64-bit
909 pointers and 32-bit integers. Do the full 64-bit pointer
910 arithmetic, for codes using arrays for nonstandard heap-like
917 need_ptr = want_ptr || flatten;
922 item = ffecom_ptr_to_expr (ffebld_left (expr));
924 item = ffecom_expr (ffebld_left (expr));
926 if (item == error_mark_node)
929 if (ffeinfo_where (ffebld_info (expr)) == FFEINFO_whereFLEETING
930 && ! mark_addressable (item))
931 return error_mark_node;
934 if (item == error_mark_node)
941 for (--i, array = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item)));
943 --i, array = TYPE_MAIN_VARIANT (TREE_TYPE (array)))
945 min = TYPE_MIN_VALUE (TYPE_DOMAIN (array));
946 element = ffecom_expr_ (dims[i], NULL, NULL, NULL, FALSE, TRUE);
947 if (flag_bounds_check)
948 element = ffecom_subscript_check_ (array, element, i, total_dims,
950 if (element == error_mark_node)
953 /* Widen integral arithmetic as desired while preserving
955 tree_type = TREE_TYPE (element);
956 tree_type_x = tree_type;
958 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
959 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
960 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
962 if (TREE_TYPE (min) != tree_type_x)
963 min = convert (tree_type_x, min);
964 if (TREE_TYPE (element) != tree_type_x)
965 element = convert (tree_type_x, element);
967 item = ffecom_2 (PLUS_EXPR,
968 build_pointer_type (TREE_TYPE (array)),
970 size_binop (MULT_EXPR,
971 size_in_bytes (TREE_TYPE (array)),
973 fold (build (MINUS_EXPR,
979 item = ffecom_1 (INDIRECT_REF,
980 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item))),
990 array = TYPE_MAIN_VARIANT (TREE_TYPE (item));
992 element = ffecom_expr_ (dims[i], NULL, NULL, NULL, FALSE, TRUE);
993 if (flag_bounds_check)
994 element = ffecom_subscript_check_ (array, element, i, total_dims,
996 if (element == error_mark_node)
999 /* Widen integral arithmetic as desired while preserving
1001 tree_type = TREE_TYPE (element);
1002 tree_type_x = tree_type;
1004 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
1005 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
1006 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
1008 element = convert (tree_type_x, element);
1010 item = ffecom_2 (ARRAY_REF,
1011 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item))),
1020 /* This is like gcc's stabilize_reference -- in fact, most of the code
1021 comes from that -- but it handles the situation where the reference
1022 is going to have its subparts picked at, and it shouldn't change
1023 (or trigger extra invocations of functions in the subtrees) due to
1024 this. save_expr is a bit overzealous, because we don't need the
1025 entire thing calculated and saved like a temp. So, for DECLs, no
1026 change is needed, because these are stable aggregates, and ARRAY_REF
1027 and such might well be stable too, but for things like calculations,
1028 we do need to calculate a snapshot of a value before picking at it. */
1030 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1032 ffecom_stabilize_aggregate_ (tree ref)
1035 enum tree_code code = TREE_CODE (ref);
1042 /* No action is needed in this case. */
1048 case FIX_TRUNC_EXPR:
1049 case FIX_FLOOR_EXPR:
1050 case FIX_ROUND_EXPR:
1052 result = build_nt (code, stabilize_reference (TREE_OPERAND (ref, 0)));
1056 result = build_nt (INDIRECT_REF,
1057 stabilize_reference_1 (TREE_OPERAND (ref, 0)));
1061 result = build_nt (COMPONENT_REF,
1062 stabilize_reference (TREE_OPERAND (ref, 0)),
1063 TREE_OPERAND (ref, 1));
1067 result = build_nt (BIT_FIELD_REF,
1068 stabilize_reference (TREE_OPERAND (ref, 0)),
1069 stabilize_reference_1 (TREE_OPERAND (ref, 1)),
1070 stabilize_reference_1 (TREE_OPERAND (ref, 2)));
1074 result = build_nt (ARRAY_REF,
1075 stabilize_reference (TREE_OPERAND (ref, 0)),
1076 stabilize_reference_1 (TREE_OPERAND (ref, 1)));
1080 result = build_nt (COMPOUND_EXPR,
1081 stabilize_reference_1 (TREE_OPERAND (ref, 0)),
1082 stabilize_reference (TREE_OPERAND (ref, 1)));
1086 result = build1 (INDIRECT_REF, TREE_TYPE (ref),
1087 save_expr (build1 (ADDR_EXPR,
1088 build_pointer_type (TREE_TYPE (ref)),
1094 return save_expr (ref);
1097 return error_mark_node;
1100 TREE_TYPE (result) = TREE_TYPE (ref);
1101 TREE_READONLY (result) = TREE_READONLY (ref);
1102 TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (ref);
1103 TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (ref);
1104 TREE_RAISES (result) = TREE_RAISES (ref);
1110 /* A rip-off of gcc's convert.c convert_to_complex function,
1111 reworked to handle complex implemented as C structures
1112 (RECORD_TYPE with two fields, real and imaginary `r' and `i'). */
1114 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1116 ffecom_convert_to_complex_ (tree type, tree expr)
1118 register enum tree_code form = TREE_CODE (TREE_TYPE (expr));
1121 assert (TREE_CODE (type) == RECORD_TYPE);
1123 subtype = TREE_TYPE (TYPE_FIELDS (type));
1125 if (form == REAL_TYPE || form == INTEGER_TYPE || form == ENUMERAL_TYPE)
1127 expr = convert (subtype, expr);
1128 return ffecom_2 (COMPLEX_EXPR, type, expr,
1129 convert (subtype, integer_zero_node));
1132 if (form == RECORD_TYPE)
1134 tree elt_type = TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr)));
1135 if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype))
1139 expr = save_expr (expr);
1140 return ffecom_2 (COMPLEX_EXPR,
1143 ffecom_1 (REALPART_EXPR,
1144 TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))),
1147 ffecom_1 (IMAGPART_EXPR,
1148 TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))),
1153 if (form == POINTER_TYPE || form == REFERENCE_TYPE)
1154 error ("pointer value used where a complex was expected");
1156 error ("aggregate value used where a complex was expected");
1158 return ffecom_2 (COMPLEX_EXPR, type,
1159 convert (subtype, integer_zero_node),
1160 convert (subtype, integer_zero_node));
1164 /* Like gcc's convert(), but crashes if widening might happen. */
1166 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1168 ffecom_convert_narrow_ (type, expr)
1171 register tree e = expr;
1172 register enum tree_code code = TREE_CODE (type);
1174 if (type == TREE_TYPE (e)
1175 || TREE_CODE (e) == ERROR_MARK)
1177 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
1178 return fold (build1 (NOP_EXPR, type, e));
1179 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
1180 || code == ERROR_MARK)
1181 return error_mark_node;
1182 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
1184 assert ("void value not ignored as it ought to be" == NULL);
1185 return error_mark_node;
1187 assert (code != VOID_TYPE);
1188 if ((code != RECORD_TYPE)
1189 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
1190 assert ("converting COMPLEX to REAL" == NULL);
1191 assert (code != ENUMERAL_TYPE);
1192 if (code == INTEGER_TYPE)
1194 assert ((TREE_CODE (TREE_TYPE (e)) == INTEGER_TYPE
1195 && TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (e)))
1196 || (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE
1197 && (TYPE_PRECISION (type)
1198 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e))))));
1199 return fold (convert_to_integer (type, e));
1201 if (code == POINTER_TYPE)
1203 assert (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE);
1204 return fold (convert_to_pointer (type, e));
1206 if (code == REAL_TYPE)
1208 assert (TREE_CODE (TREE_TYPE (e)) == REAL_TYPE);
1209 assert (TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (e)));
1210 return fold (convert_to_real (type, e));
1212 if (code == COMPLEX_TYPE)
1214 assert (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE);
1215 assert (TYPE_PRECISION (TREE_TYPE (type)) <= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e))));
1216 return fold (convert_to_complex (type, e));
1218 if (code == RECORD_TYPE)
1220 assert (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE);
1221 /* Check that at least the first field name agrees. */
1222 assert (DECL_NAME (TYPE_FIELDS (type))
1223 == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e))));
1224 assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1225 <= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))));
1226 if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1227 == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))))
1229 return fold (ffecom_convert_to_complex_ (type, e));
1232 assert ("conversion to non-scalar type requested" == NULL);
1233 return error_mark_node;
1237 /* Like gcc's convert(), but crashes if narrowing might happen. */
1239 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1241 ffecom_convert_widen_ (type, expr)
1244 register tree e = expr;
1245 register enum tree_code code = TREE_CODE (type);
1247 if (type == TREE_TYPE (e)
1248 || TREE_CODE (e) == ERROR_MARK)
1250 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
1251 return fold (build1 (NOP_EXPR, type, e));
1252 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
1253 || code == ERROR_MARK)
1254 return error_mark_node;
1255 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
1257 assert ("void value not ignored as it ought to be" == NULL);
1258 return error_mark_node;
1260 assert (code != VOID_TYPE);
1261 if ((code != RECORD_TYPE)
1262 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
1263 assert ("narrowing COMPLEX to REAL" == NULL);
1264 assert (code != ENUMERAL_TYPE);
1265 if (code == INTEGER_TYPE)
1267 assert ((TREE_CODE (TREE_TYPE (e)) == INTEGER_TYPE
1268 && TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (e)))
1269 || (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE
1270 && (TYPE_PRECISION (type)
1271 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e))))));
1272 return fold (convert_to_integer (type, e));
1274 if (code == POINTER_TYPE)
1276 assert (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE);
1277 return fold (convert_to_pointer (type, e));
1279 if (code == REAL_TYPE)
1281 assert (TREE_CODE (TREE_TYPE (e)) == REAL_TYPE);
1282 assert (TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (e)));
1283 return fold (convert_to_real (type, e));
1285 if (code == COMPLEX_TYPE)
1287 assert (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE);
1288 assert (TYPE_PRECISION (TREE_TYPE (type)) >= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e))));
1289 return fold (convert_to_complex (type, e));
1291 if (code == RECORD_TYPE)
1293 assert (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE);
1294 /* Check that at least the first field name agrees. */
1295 assert (DECL_NAME (TYPE_FIELDS (type))
1296 == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e))));
1297 assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1298 >= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))));
1299 if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1300 == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))))
1302 return fold (ffecom_convert_to_complex_ (type, e));
1305 assert ("conversion to non-scalar type requested" == NULL);
1306 return error_mark_node;
1310 /* Handles making a COMPLEX type, either the standard
1311 (but buggy?) gbe way, or the safer (but less elegant?)
1314 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1316 ffecom_make_complex_type_ (tree subtype)
1322 if (ffe_is_emulate_complex ())
1324 type = make_node (RECORD_TYPE);
1325 realfield = ffecom_decl_field (type, NULL_TREE, "r", subtype);
1326 imagfield = ffecom_decl_field (type, realfield, "i", subtype);
1327 TYPE_FIELDS (type) = realfield;
1332 type = make_node (COMPLEX_TYPE);
1333 TREE_TYPE (type) = subtype;
1341 /* Chooses either the gbe or the f2c way to build a
1342 complex constant. */
1344 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1346 ffecom_build_complex_constant_ (tree type, tree realpart, tree imagpart)
1350 if (ffe_is_emulate_complex ())
1352 bothparts = build_tree_list (TYPE_FIELDS (type), realpart);
1353 TREE_CHAIN (bothparts) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), imagpart);
1354 bothparts = build (CONSTRUCTOR, type, NULL_TREE, bothparts);
1358 bothparts = build_complex (type, realpart, imagpart);
1365 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1367 ffecom_arglist_expr_ (const char *c, ffebld expr)
1370 tree *plist = &list;
1371 tree trail = NULL_TREE; /* Append char length args here. */
1372 tree *ptrail = &trail;
1377 tree wanted = NULL_TREE;
1378 static char zed[] = "0";
1383 while (expr != NULL)
1406 wanted = ffecom_f2c_complex_type_node;
1410 wanted = ffecom_f2c_doublereal_type_node;
1414 wanted = ffecom_f2c_doublecomplex_type_node;
1418 wanted = ffecom_f2c_real_type_node;
1422 wanted = ffecom_f2c_integer_type_node;
1426 wanted = ffecom_f2c_longint_type_node;
1430 assert ("bad argstring code" == NULL);
1436 exprh = ffebld_head (expr);
1440 if ((wanted == NULL_TREE)
1443 (ffecom_tree_type[ffeinfo_basictype (ffebld_info (exprh))]
1444 [ffeinfo_kindtype (ffebld_info (exprh))])
1445 == TYPE_MODE (wanted))))
1447 = build_tree_list (NULL_TREE,
1448 ffecom_arg_ptr_to_expr (exprh,
1452 item = ffecom_arg_expr (exprh, &length);
1453 item = ffecom_convert_widen_ (wanted, item);
1456 item = ffecom_1 (ADDR_EXPR,
1457 build_pointer_type (TREE_TYPE (item)),
1461 = build_tree_list (NULL_TREE,
1465 plist = &TREE_CHAIN (*plist);
1466 expr = ffebld_trail (expr);
1467 if (length != NULL_TREE)
1469 *ptrail = build_tree_list (NULL_TREE, length);
1470 ptrail = &TREE_CHAIN (*ptrail);
1474 /* We've run out of args in the call; if the implementation expects
1475 more, supply null pointers for them, which the implementation can
1476 check to see if an arg was omitted. */
1478 while (*c != '\0' && *c != '0')
1483 assert ("missing arg to run-time routine!" == NULL);
1498 assert ("bad arg string code" == NULL);
1502 = build_tree_list (NULL_TREE,
1504 plist = &TREE_CHAIN (*plist);
1513 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1515 ffecom_widest_expr_type_ (ffebld list)
1518 ffebld widest = NULL;
1520 ffetype widest_type = NULL;
1523 for (; list != NULL; list = ffebld_trail (list))
1525 item = ffebld_head (list);
1528 if ((widest != NULL)
1529 && (ffeinfo_basictype (ffebld_info (item))
1530 != ffeinfo_basictype (ffebld_info (widest))))
1532 type = ffeinfo_type (ffeinfo_basictype (ffebld_info (item)),
1533 ffeinfo_kindtype (ffebld_info (item)));
1534 if ((widest == FFEINFO_kindtypeNONE)
1535 || (ffetype_size (type)
1536 > ffetype_size (widest_type)))
1543 assert (widest != NULL);
1544 t = ffecom_tree_type[ffeinfo_basictype (ffebld_info (widest))]
1545 [ffeinfo_kindtype (ffebld_info (widest))];
1546 assert (t != NULL_TREE);
1551 /* Check whether a partial overlap between two expressions is possible.
1553 Can *starting* to write a portion of expr1 change the value
1554 computed (perhaps already, *partially*) by expr2?
1556 Currently, this is a concern only for a COMPLEX expr1. But if it
1557 isn't in COMMON or local EQUIVALENCE, since we don't support
1558 aliasing of arguments, it isn't a concern. */
1561 ffecom_possible_partial_overlap_ (ffebld expr1, ffebld expr2 ATTRIBUTE_UNUSED)
1566 switch (ffebld_op (expr1))
1568 case FFEBLD_opSYMTER:
1569 sym = ffebld_symter (expr1);
1572 case FFEBLD_opARRAYREF:
1573 if (ffebld_op (ffebld_left (expr1)) != FFEBLD_opSYMTER)
1575 sym = ffebld_symter (ffebld_left (expr1));
1582 if (ffesymbol_where (sym) != FFEINFO_whereCOMMON
1583 && (ffesymbol_where (sym) != FFEINFO_whereLOCAL
1584 || ! (st = ffesymbol_storage (sym))
1585 || ! ffestorag_parent (st)))
1588 /* It's in COMMON or local EQUIVALENCE. */
1593 /* Check whether dest and source might overlap. ffebld versions of these
1594 might or might not be passed, will be NULL if not.
1596 The test is really whether source_tree is modifiable and, if modified,
1597 might overlap destination such that the value(s) in the destination might
1598 change before it is finally modified. dest_* are the canonized
1599 destination itself. */
1601 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1603 ffecom_overlap_ (tree dest_decl, tree dest_offset, tree dest_size,
1604 tree source_tree, ffebld source UNUSED,
1612 if (source_tree == NULL_TREE)
1615 switch (TREE_CODE (source_tree))
1618 case IDENTIFIER_NODE:
1629 case TRUNC_DIV_EXPR:
1631 case FLOOR_DIV_EXPR:
1632 case ROUND_DIV_EXPR:
1633 case TRUNC_MOD_EXPR:
1635 case FLOOR_MOD_EXPR:
1636 case ROUND_MOD_EXPR:
1638 case EXACT_DIV_EXPR:
1639 case FIX_TRUNC_EXPR:
1641 case FIX_FLOOR_EXPR:
1642 case FIX_ROUND_EXPR:
1657 case BIT_ANDTC_EXPR:
1659 case TRUTH_ANDIF_EXPR:
1660 case TRUTH_ORIF_EXPR:
1661 case TRUTH_AND_EXPR:
1663 case TRUTH_XOR_EXPR:
1664 case TRUTH_NOT_EXPR:
1680 return ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1681 TREE_OPERAND (source_tree, 1), NULL,
1685 return ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1686 TREE_OPERAND (source_tree, 0), NULL,
1691 case NON_LVALUE_EXPR:
1693 if (TREE_CODE (TREE_TYPE (source_tree)) != POINTER_TYPE)
1696 ffecom_tree_canonize_ptr_ (&source_decl, &source_offset,
1698 source_size = TYPE_SIZE (TREE_TYPE (TREE_TYPE (source_tree)));
1703 ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1704 TREE_OPERAND (source_tree, 1), NULL,
1706 || ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1707 TREE_OPERAND (source_tree, 2), NULL,
1712 ffecom_tree_canonize_ref_ (&source_decl, &source_offset,
1714 TREE_OPERAND (source_tree, 0));
1718 if (TREE_CODE (TREE_TYPE (source_tree)) != POINTER_TYPE)
1721 source_decl = source_tree;
1722 source_offset = size_zero_node;
1723 source_size = TYPE_SIZE (TREE_TYPE (TREE_TYPE (source_tree)));
1727 case REFERENCE_EXPR:
1728 case PREDECREMENT_EXPR:
1729 case PREINCREMENT_EXPR:
1730 case POSTDECREMENT_EXPR:
1731 case POSTINCREMENT_EXPR:
1739 /* Come here when source_decl, source_offset, and source_size filled
1740 in appropriately. */
1742 if (source_decl == NULL_TREE)
1743 return FALSE; /* No decl involved, so no overlap. */
1745 if (source_decl != dest_decl)
1746 return FALSE; /* Different decl, no overlap. */
1748 if (TREE_CODE (dest_size) == ERROR_MARK)
1749 return TRUE; /* Assignment into entire assumed-size
1750 array? Shouldn't happen.... */
1752 t = ffecom_2 (LE_EXPR, integer_type_node,
1753 ffecom_2 (PLUS_EXPR, TREE_TYPE (dest_offset),
1755 convert (TREE_TYPE (dest_offset),
1757 convert (TREE_TYPE (dest_offset),
1760 if (integer_onep (t))
1761 return FALSE; /* Destination precedes source. */
1764 || (source_size == NULL_TREE)
1765 || (TREE_CODE (source_size) == ERROR_MARK)
1766 || integer_zerop (source_size))
1767 return TRUE; /* No way to tell if dest follows source. */
1769 t = ffecom_2 (LE_EXPR, integer_type_node,
1770 ffecom_2 (PLUS_EXPR, TREE_TYPE (source_offset),
1772 convert (TREE_TYPE (source_offset),
1774 convert (TREE_TYPE (source_offset),
1777 if (integer_onep (t))
1778 return FALSE; /* Destination follows source. */
1780 return TRUE; /* Destination and source overlap. */
1784 /* Check whether dest might overlap any of a list of arguments or is
1785 in a COMMON area the callee might know about (and thus modify). */
1787 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1789 ffecom_args_overlapping_ (tree dest_tree, ffebld dest UNUSED,
1790 tree args, tree callee_commons,
1798 ffecom_tree_canonize_ref_ (&dest_decl, &dest_offset, &dest_size,
1801 if (dest_decl == NULL_TREE)
1802 return FALSE; /* Seems unlikely! */
1804 /* If the decl cannot be determined reliably, or if its in COMMON
1805 and the callee isn't known to not futz with COMMON via other
1806 means, overlap might happen. */
1808 if ((TREE_CODE (dest_decl) == ERROR_MARK)
1809 || ((callee_commons != NULL_TREE)
1810 && TREE_PUBLIC (dest_decl)))
1813 for (; args != NULL_TREE; args = TREE_CHAIN (args))
1815 if (((arg = TREE_VALUE (args)) != NULL_TREE)
1816 && ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1817 arg, NULL, scalar_args))
1825 /* Build a string for a variable name as used by NAMELIST. This means that
1826 if we're using the f2c library, we build an uppercase string, since
1829 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1831 ffecom_build_f2c_string_ (int i, const char *s)
1833 if (!ffe_is_f2c_library ())
1834 return build_string (i, s);
1843 if (((size_t) i) > ARRAY_SIZE (space))
1844 tmp = malloc_new_ks (malloc_pool_image (), "f2c_string", i);
1848 for (p = s, q = tmp; *p != '\0'; ++p, ++q)
1849 *q = ffesrc_toupper (*p);
1852 t = build_string (i, tmp);
1854 if (((size_t) i) > ARRAY_SIZE (space))
1855 malloc_kill_ks (malloc_pool_image (), tmp, i);
1862 /* Returns CALL_EXPR or equivalent with given type (pass NULL_TREE for
1863 type to just get whatever the function returns), handling the
1864 f2c value-returning convention, if required, by prepending
1865 to the arglist a pointer to a temporary to receive the return value. */
1867 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1869 ffecom_call_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex,
1870 tree type, tree args, tree dest_tree,
1871 ffebld dest, bool *dest_used, tree callee_commons,
1872 bool scalar_args, tree hook)
1877 if (dest_used != NULL)
1882 if ((dest_used == NULL)
1884 || (ffeinfo_basictype (ffebld_info (dest))
1885 != FFEINFO_basictypeCOMPLEX)
1886 || (ffeinfo_kindtype (ffebld_info (dest)) != kt)
1887 || ((type != NULL_TREE) && (TREE_TYPE (dest_tree) != type))
1888 || ffecom_args_overlapping_ (dest_tree, dest, args,
1893 tempvar = ffecom_make_tempvar (ffecom_tree_type
1894 [FFEINFO_basictypeCOMPLEX][kt],
1895 FFETARGET_charactersizeNONE,
1905 tempvar = dest_tree;
1910 = build_tree_list (NULL_TREE,
1911 ffecom_1 (ADDR_EXPR,
1912 build_pointer_type (TREE_TYPE (tempvar)),
1914 TREE_CHAIN (item) = args;
1916 item = ffecom_3s (CALL_EXPR, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), fn,
1919 if (tempvar != dest_tree)
1920 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), item, tempvar);
1923 item = ffecom_3s (CALL_EXPR, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), fn,
1926 if ((type != NULL_TREE) && (TREE_TYPE (item) != type))
1927 item = ffecom_convert_narrow_ (type, item);
1933 /* Given two arguments, transform them and make a call to the given
1934 function via ffecom_call_. */
1936 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1938 ffecom_call_binop_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex,
1939 tree type, ffebld left, ffebld right,
1940 tree dest_tree, ffebld dest, bool *dest_used,
1941 tree callee_commons, bool scalar_args, tree hook)
1948 left_tree = ffecom_arg_ptr_to_expr (left, &left_length);
1949 right_tree = ffecom_arg_ptr_to_expr (right, &right_length);
1951 left_tree = build_tree_list (NULL_TREE, left_tree);
1952 right_tree = build_tree_list (NULL_TREE, right_tree);
1953 TREE_CHAIN (left_tree) = right_tree;
1955 if (left_length != NULL_TREE)
1957 left_length = build_tree_list (NULL_TREE, left_length);
1958 TREE_CHAIN (right_tree) = left_length;
1961 if (right_length != NULL_TREE)
1963 right_length = build_tree_list (NULL_TREE, right_length);
1964 if (left_length != NULL_TREE)
1965 TREE_CHAIN (left_length) = right_length;
1967 TREE_CHAIN (right_tree) = right_length;
1970 return ffecom_call_ (fn, kt, is_f2c_complex, type, left_tree,
1971 dest_tree, dest, dest_used, callee_commons,
1976 /* Return ptr/length args for char subexpression
1978 Handles CHARACTER-type CONTER, SYMTER, SUBSTR, ARRAYREF, and FUNCREF
1979 subexpressions by constructing the appropriate trees for the ptr-to-
1980 character-text and length-of-character-text arguments in a calling
1983 Note that if with_null is TRUE, and the expression is an opCONTER,
1984 a null byte is appended to the string. */
1986 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1988 ffecom_char_args_x_ (tree *xitem, tree *length, ffebld expr, bool with_null)
1992 ffetargetCharacter1 val;
1993 ffetargetCharacterSize newlen;
1995 switch (ffebld_op (expr))
1997 case FFEBLD_opCONTER:
1998 val = ffebld_constant_character1 (ffebld_conter (expr));
1999 newlen = ffetarget_length_character1 (val);
2002 /* Begin FFETARGET-NULL-KLUDGE. */
2006 *length = build_int_2 (newlen, 0);
2007 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
2008 high = build_int_2 (newlen, 0);
2009 TREE_TYPE (high) = ffecom_f2c_ftnlen_type_node;
2010 item = build_string (newlen,
2011 ffetarget_text_character1 (val));
2012 /* End FFETARGET-NULL-KLUDGE. */
2014 = build_type_variant
2018 (ffecom_f2c_ftnlen_type_node,
2019 ffecom_f2c_ftnlen_one_node,
2022 TREE_CONSTANT (item) = 1;
2023 TREE_STATIC (item) = 1;
2024 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
2028 case FFEBLD_opSYMTER:
2030 ffesymbol s = ffebld_symter (expr);
2032 item = ffesymbol_hook (s).decl_tree;
2033 if (item == NULL_TREE)
2035 s = ffecom_sym_transform_ (s);
2036 item = ffesymbol_hook (s).decl_tree;
2038 if (ffesymbol_kind (s) == FFEINFO_kindENTITY)
2040 if (ffesymbol_size (s) == FFETARGET_charactersizeNONE)
2041 *length = ffesymbol_hook (s).length_tree;
2044 *length = build_int_2 (ffesymbol_size (s), 0);
2045 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
2048 else if (item == error_mark_node)
2049 *length = error_mark_node;
2051 /* FFEINFO_kindFUNCTION. */
2052 *length = NULL_TREE;
2053 if (!ffesymbol_hook (s).addr
2054 && (item != error_mark_node))
2055 item = ffecom_1 (ADDR_EXPR,
2056 build_pointer_type (TREE_TYPE (item)),
2061 case FFEBLD_opARRAYREF:
2063 ffecom_char_args_ (&item, length, ffebld_left (expr));
2065 if (item == error_mark_node || *length == error_mark_node)
2067 item = *length = error_mark_node;
2071 item = ffecom_arrayref_ (item, expr, 1);
2075 case FFEBLD_opSUBSTR:
2079 ffebld thing = ffebld_right (expr);
2086 assert (ffebld_op (thing) == FFEBLD_opITEM);
2087 start = ffebld_head (thing);
2088 thing = ffebld_trail (thing);
2089 assert (ffebld_trail (thing) == NULL);
2090 end = ffebld_head (thing);
2092 /* Determine name for pretty-printing range-check errors. */
2093 for (left_symter = ffebld_left (expr);
2094 left_symter && ffebld_op (left_symter) == FFEBLD_opARRAYREF;
2095 left_symter = ffebld_left (left_symter))
2097 if (ffebld_op (left_symter) == FFEBLD_opSYMTER)
2098 char_name = ffesymbol_text (ffebld_symter (left_symter));
2100 char_name = "[expr?]";
2102 ffecom_char_args_ (&item, length, ffebld_left (expr));
2104 if (item == error_mark_node || *length == error_mark_node)
2106 item = *length = error_mark_node;
2110 array = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item)));
2112 /* ~~~~Handle INTEGER*8 start/end, a la FFEBLD_opARRAYREF. */
2120 end_tree = ffecom_expr (end);
2121 if (flag_bounds_check)
2122 end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0,
2124 end_tree = convert (ffecom_f2c_ftnlen_type_node,
2127 if (end_tree == error_mark_node)
2129 item = *length = error_mark_node;
2138 start_tree = ffecom_expr (start);
2139 if (flag_bounds_check)
2140 start_tree = ffecom_subscript_check_ (array, start_tree, 0, 0,
2142 start_tree = convert (ffecom_f2c_ftnlen_type_node,
2145 if (start_tree == error_mark_node)
2147 item = *length = error_mark_node;
2151 start_tree = ffecom_save_tree (start_tree);
2153 item = ffecom_2 (PLUS_EXPR, TREE_TYPE (item),
2155 ffecom_2 (MINUS_EXPR,
2156 TREE_TYPE (start_tree),
2158 ffecom_f2c_ftnlen_one_node));
2162 *length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
2163 ffecom_f2c_ftnlen_one_node,
2164 ffecom_2 (MINUS_EXPR,
2165 ffecom_f2c_ftnlen_type_node,
2171 end_tree = ffecom_expr (end);
2172 if (flag_bounds_check)
2173 end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0,
2175 end_tree = convert (ffecom_f2c_ftnlen_type_node,
2178 if (end_tree == error_mark_node)
2180 item = *length = error_mark_node;
2184 *length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
2185 ffecom_f2c_ftnlen_one_node,
2186 ffecom_2 (MINUS_EXPR,
2187 ffecom_f2c_ftnlen_type_node,
2188 end_tree, start_tree));
2194 case FFEBLD_opFUNCREF:
2196 ffesymbol s = ffebld_symter (ffebld_left (expr));
2199 ffetargetCharacterSize size = ffeinfo_size (ffebld_info (expr));
2202 if (size == FFETARGET_charactersizeNONE)
2203 /* ~~Kludge alert! This should someday be fixed. */
2206 *length = build_int_2 (size, 0);
2207 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
2209 if (ffeinfo_where (ffebld_info (ffebld_left (expr)))
2210 == FFEINFO_whereINTRINSIC)
2214 /* Invocation of an intrinsic returning CHARACTER*1. */
2215 item = ffecom_expr_intrinsic_ (expr, NULL_TREE,
2219 ix = ffeintrin_gfrt_direct (ffebld_symter_implementation (ffebld_left (expr)));
2220 assert (ix != FFECOM_gfrt);
2221 item = ffecom_gfrt_tree_ (ix);
2226 item = ffesymbol_hook (s).decl_tree;
2227 if (item == NULL_TREE)
2229 s = ffecom_sym_transform_ (s);
2230 item = ffesymbol_hook (s).decl_tree;
2232 if (item == error_mark_node)
2234 item = *length = error_mark_node;
2238 if (!ffesymbol_hook (s).addr)
2239 item = ffecom_1_fn (item);
2243 tempvar = ffecom_push_tempvar (char_type_node, size, -1, TRUE);
2245 tempvar = ffebld_nonter_hook (expr);
2248 tempvar = ffecom_1 (ADDR_EXPR,
2249 build_pointer_type (TREE_TYPE (tempvar)),
2252 args = build_tree_list (NULL_TREE, tempvar);
2254 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT) /* Sfunc args by value. */
2255 TREE_CHAIN (args) = ffecom_list_expr (ffebld_right (expr));
2258 TREE_CHAIN (args) = build_tree_list (NULL_TREE, *length);
2259 if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC)
2261 TREE_CHAIN (TREE_CHAIN (args))
2262 = ffecom_arglist_expr_ (ffecom_gfrt_args_ (ix),
2263 ffebld_right (expr));
2267 TREE_CHAIN (TREE_CHAIN (args))
2268 = ffecom_list_ptr_to_expr (ffebld_right (expr));
2272 item = ffecom_3s (CALL_EXPR,
2273 TREE_TYPE (TREE_TYPE (TREE_TYPE (item))),
2274 item, args, NULL_TREE);
2275 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), item,
2280 case FFEBLD_opCONVERT:
2282 ffecom_char_args_ (&item, length, ffebld_left (expr));
2284 if (item == error_mark_node || *length == error_mark_node)
2286 item = *length = error_mark_node;
2290 if ((ffebld_size_known (ffebld_left (expr))
2291 == FFETARGET_charactersizeNONE)
2292 || (ffebld_size_known (ffebld_left (expr)) < (ffebld_size (expr))))
2293 { /* Possible blank-padding needed, copy into
2300 tempvar = ffecom_make_tempvar (char_type_node,
2301 ffebld_size (expr), -1);
2303 tempvar = ffebld_nonter_hook (expr);
2306 tempvar = ffecom_1 (ADDR_EXPR,
2307 build_pointer_type (TREE_TYPE (tempvar)),
2310 newlen = build_int_2 (ffebld_size (expr), 0);
2311 TREE_TYPE (newlen) = ffecom_f2c_ftnlen_type_node;
2313 args = build_tree_list (NULL_TREE, tempvar);
2314 TREE_CHAIN (args) = build_tree_list (NULL_TREE, item);
2315 TREE_CHAIN (TREE_CHAIN (args)) = build_tree_list (NULL_TREE, newlen);
2316 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (args)))
2317 = build_tree_list (NULL_TREE, *length);
2319 item = ffecom_call_gfrt (FFECOM_gfrtCOPY, args, NULL_TREE);
2320 TREE_SIDE_EFFECTS (item) = 1;
2321 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), fold (item),
2326 { /* Just truncate the length. */
2327 *length = build_int_2 (ffebld_size (expr), 0);
2328 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
2333 assert ("bad op for single char arg expr" == NULL);
2342 /* Check the size of the type to be sure it doesn't overflow the
2343 "portable" capacities of the compiler back end. `dummy' types
2344 can generally overflow the normal sizes as long as the computations
2345 themselves don't overflow. A particular target of the back end
2346 must still enforce its size requirements, though, and the back
2347 end takes care of this in stor-layout.c. */
2349 #if FFECOM_targetCURRENT == FFECOM_targetGCC
2351 ffecom_check_size_overflow_ (ffesymbol s, tree type, bool dummy)
2353 if (TREE_CODE (type) == ERROR_MARK)
2356 if (TYPE_SIZE (type) == NULL_TREE)
2359 if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
2362 if ((tree_int_cst_sgn (TYPE_SIZE (type)) < 0)
2363 || (!dummy && (((TREE_INT_CST_HIGH (TYPE_SIZE (type)) != 0))
2364 || TREE_OVERFLOW (TYPE_SIZE (type)))))
2366 ffebad_start (FFEBAD_ARRAY_LARGE);
2367 ffebad_string (ffesymbol_text (s));
2368 ffebad_here (0, ffesymbol_where_line (s), ffesymbol_where_column (s));
2371 return error_mark_node;
2378 /* Builds a length argument (PARM_DECL). Also wraps type in an array type
2379 where the dimension info is (1:size) where <size> is ffesymbol_size(s) if
2380 known, length_arg if not known (FFETARGET_charactersizeNONE). */
2382 #if FFECOM_targetCURRENT == FFECOM_targetGCC
2384 ffecom_char_enhance_arg_ (tree *xtype, ffesymbol s)
2386 ffetargetCharacterSize sz = ffesymbol_size (s);
2391 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT)
2392 tlen = NULL_TREE; /* A statement function, no length passed. */
2395 if (ffesymbol_where (s) == FFEINFO_whereDUMMY)
2396 tlen = ffecom_get_invented_identifier ("__g77_length_%s",
2397 ffesymbol_text (s));
2399 tlen = ffecom_get_invented_identifier ("__g77_%s", "length");
2400 tlen = build_decl (PARM_DECL, tlen, ffecom_f2c_ftnlen_type_node);
2402 DECL_ARTIFICIAL (tlen) = 1;
2406 if (sz == FFETARGET_charactersizeNONE)
2408 assert (tlen != NULL_TREE);
2409 highval = variable_size (tlen);
2413 highval = build_int_2 (sz, 0);
2414 TREE_TYPE (highval) = ffecom_f2c_ftnlen_type_node;
2417 type = build_array_type (type,
2418 build_range_type (ffecom_f2c_ftnlen_type_node,
2419 ffecom_f2c_ftnlen_one_node,
2427 /* ffecom_concat_list_gather_ -- Gather list of concatenated string exprs
2429 ffecomConcatList_ catlist;
2430 ffebld expr; // expr of CHARACTER basictype.
2431 ffetargetCharacterSize max; // max chars to gather or _...NONE if no max
2432 catlist = ffecom_concat_list_gather_(catlist,expr,max);
2434 Scans expr for character subexpressions, updates and returns catlist
2437 #if FFECOM_targetCURRENT == FFECOM_targetGCC
2438 static ffecomConcatList_
2439 ffecom_concat_list_gather_ (ffecomConcatList_ catlist, ffebld expr,
2440 ffetargetCharacterSize max)
2442 ffetargetCharacterSize sz;
2444 recurse: /* :::::::::::::::::::: */
2449 if ((max != FFETARGET_charactersizeNONE) && (catlist.minlen >= max))
2450 return catlist; /* Don't append any more items. */
2452 switch (ffebld_op (expr))
2454 case FFEBLD_opCONTER:
2455 case FFEBLD_opSYMTER:
2456 case FFEBLD_opARRAYREF:
2457 case FFEBLD_opFUNCREF:
2458 case FFEBLD_opSUBSTR:
2459 case FFEBLD_opCONVERT: /* Callers should strip this off beforehand
2460 if they don't need to preserve it. */
2461 if (catlist.count == catlist.max)
2462 { /* Make a (larger) list. */
2466 newmax = (catlist.max == 0) ? 8 : catlist.max * 2;
2467 newx = malloc_new_ks (malloc_pool_image (), "catlist",
2468 newmax * sizeof (newx[0]));
2469 if (catlist.max != 0)
2471 memcpy (newx, catlist.exprs, catlist.max * sizeof (newx[0]));
2472 malloc_kill_ks (malloc_pool_image (), catlist.exprs,
2473 catlist.max * sizeof (newx[0]));
2475 catlist.max = newmax;
2476 catlist.exprs = newx;
2478 if ((sz = ffebld_size_known (expr)) != FFETARGET_charactersizeNONE)
2479 catlist.minlen += sz;
2481 ++catlist.minlen; /* Not true for F90; can be 0 length. */
2482 if ((sz = ffebld_size_max (expr)) == FFETARGET_charactersizeNONE)
2483 catlist.maxlen = sz;
2485 catlist.maxlen += sz;
2486 if ((max != FFETARGET_charactersizeNONE) && (catlist.minlen > max))
2487 { /* This item overlaps (or is beyond) the end
2488 of the destination. */
2489 switch (ffebld_op (expr))
2491 case FFEBLD_opCONTER:
2492 case FFEBLD_opSYMTER:
2493 case FFEBLD_opARRAYREF:
2494 case FFEBLD_opFUNCREF:
2495 case FFEBLD_opSUBSTR:
2496 /* ~~Do useful truncations here. */
2500 assert ("op changed or inconsistent switches!" == NULL);
2504 catlist.exprs[catlist.count++] = expr;
2507 case FFEBLD_opPAREN:
2508 expr = ffebld_left (expr);
2509 goto recurse; /* :::::::::::::::::::: */
2511 case FFEBLD_opCONCATENATE:
2512 catlist = ffecom_concat_list_gather_ (catlist, ffebld_left (expr), max);
2513 expr = ffebld_right (expr);
2514 goto recurse; /* :::::::::::::::::::: */
2516 #if 0 /* Breaks passing small actual arg to larger
2517 dummy arg of sfunc */
2518 case FFEBLD_opCONVERT:
2519 expr = ffebld_left (expr);
2521 ffetargetCharacterSize cmax;
2523 cmax = catlist.len + ffebld_size_known (expr);
2525 if ((max == FFETARGET_charactersizeNONE) || (max > cmax))
2528 goto recurse; /* :::::::::::::::::::: */
2535 assert ("bad op in _gather_" == NULL);
2541 /* ffecom_concat_list_kill_ -- Kill list of concatenated string exprs
2543 ffecomConcatList_ catlist;
2544 ffecom_concat_list_kill_(catlist);
2546 Anything allocated within the list info is deallocated. */
2548 #if FFECOM_targetCURRENT == FFECOM_targetGCC
2550 ffecom_concat_list_kill_ (ffecomConcatList_ catlist)
2552 if (catlist.max != 0)
2553 malloc_kill_ks (malloc_pool_image (), catlist.exprs,
2554 catlist.max * sizeof (catlist.exprs[0]));
2558 /* Make list of concatenated string exprs.
2560 Returns a flattened list of concatenated subexpressions given a
2561 tree of such expressions. */
2563 #if FFECOM_targetCURRENT == FFECOM_targetGCC
2564 static ffecomConcatList_
2565 ffecom_concat_list_new_ (ffebld expr, ffetargetCharacterSize max)
2567 ffecomConcatList_ catlist;
2569 catlist.maxlen = catlist.minlen = catlist.max = catlist.count = 0;
2570 return ffecom_concat_list_gather_ (catlist, expr, max);
2575 /* Provide some kind of useful info on member of aggregate area,
2576 since current g77/gcc technology does not provide debug info
2577 on these members. */
2579 #if FFECOM_targetCURRENT == FFECOM_targetGCC
2581 ffecom_debug_kludge_ (tree aggr, const char *aggr_type, ffesymbol member,
2582 tree member_type UNUSED, ffetargetOffset offset)
2592 for (type_id = member_type;
2593 TREE_CODE (type_id) != IDENTIFIER_NODE;
2596 switch (TREE_CODE (type_id))
2600 type_id = TYPE_NAME (type_id);
2605 type_id = TREE_TYPE (type_id);
2609 assert ("no IDENTIFIER_NODE for type!" == NULL);
2610 type_id = error_mark_node;
2616 if (ffecom_transform_only_dummies_
2617 || !ffe_is_debug_kludge ())
2618 return; /* Can't do this yet, maybe later. */
2621 + strlen (aggr_type)
2622 + IDENTIFIER_LENGTH (DECL_NAME (aggr));
2624 + IDENTIFIER_LENGTH (type_id);
2627 if (((size_t) len) >= ARRAY_SIZE (space))
2628 buff = malloc_new_ks (malloc_pool_image (), "debug_kludge", len + 1);
2632 sprintf (&buff[0], "At (%s) `%s' plus %ld bytes",
2634 IDENTIFIER_POINTER (DECL_NAME (aggr)),
2637 value = build_string (len, buff);
2639 = build_type_variant (build_array_type (char_type_node,
2643 build_int_2 (strlen (buff), 0))),
2645 decl = build_decl (VAR_DECL,
2646 ffecom_get_identifier_ (ffesymbol_text (member)),
2648 TREE_CONSTANT (decl) = 1;
2649 TREE_STATIC (decl) = 1;
2650 DECL_INITIAL (decl) = error_mark_node;
2651 DECL_IN_SYSTEM_HEADER (decl) = 1; /* Don't let -Wunused complain. */
2652 decl = start_decl (decl, FALSE);
2653 finish_decl (decl, value, FALSE);
2655 if (buff != &space[0])
2656 malloc_kill_ks (malloc_pool_image (), buff, len + 1);
2660 /* ffecom_do_entry_ -- Do compilation of a particular entrypoint
2662 ffesymbol fn; // the SUBROUTINE, FUNCTION, or ENTRY symbol itself
2663 int i; // entry# for this entrypoint (used by master fn)
2664 ffecom_do_entrypoint_(s,i);
2666 Makes a public entry point that calls our private master fn (already
2669 #if FFECOM_targetCURRENT == FFECOM_targetGCC
2671 ffecom_do_entry_ (ffesymbol fn, int entrynum)
2674 tree type; /* Type of function. */
2675 tree multi_retval; /* Var holding return value (union). */
2676 tree result; /* Var holding result. */
2677 ffeinfoBasictype bt;
2681 bool charfunc; /* All entry points return same type
2683 bool cmplxfunc; /* Use f2c way of returning COMPLEX. */
2684 bool multi; /* Master fn has multiple return types. */
2685 bool altreturning = FALSE; /* This entry point has alternate returns. */
2687 int old_lineno = lineno;
2688 char *old_input_filename = input_filename;
2690 input_filename = ffesymbol_where_filename (fn);
2691 lineno = ffesymbol_where_filelinenum (fn);
2693 /* c-parse.y indeed does call suspend_momentary and not only ignores the
2694 return value, but also never calls resume_momentary, when starting an
2695 outer function (see "fndef:", "setspecs:", and so on). So g77 does the
2696 same thing. It shouldn't be a problem since start_function calls
2697 temporary_allocation, but it might be necessary. If it causes a problem
2698 here, then maybe there's a bug lurking in gcc. NOTE: This identical
2699 comment appears twice in thist file. */
2701 suspend_momentary ();
2703 ffecom_doing_entry_ = TRUE; /* Don't bother with array dimensions. */
2705 switch (ffecom_primary_entry_kind_)
2707 case FFEINFO_kindFUNCTION:
2709 /* Determine actual return type for function. */
2711 gt = FFEGLOBAL_typeFUNC;
2712 bt = ffesymbol_basictype (fn);
2713 kt = ffesymbol_kindtype (fn);
2714 if (bt == FFEINFO_basictypeNONE)
2716 ffeimplic_establish_symbol (fn);
2717 if (ffesymbol_funcresult (fn) != NULL)
2718 ffeimplic_establish_symbol (ffesymbol_funcresult (fn));
2719 bt = ffesymbol_basictype (fn);
2720 kt = ffesymbol_kindtype (fn);
2723 if (bt == FFEINFO_basictypeCHARACTER)
2724 charfunc = TRUE, cmplxfunc = FALSE;
2725 else if ((bt == FFEINFO_basictypeCOMPLEX)
2726 && ffesymbol_is_f2c (fn))
2727 charfunc = FALSE, cmplxfunc = TRUE;
2729 charfunc = cmplxfunc = FALSE;
2732 type = ffecom_tree_fun_type_void;
2733 else if (ffesymbol_is_f2c (fn))
2734 type = ffecom_tree_fun_type[bt][kt];
2736 type = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
2738 if ((type == NULL_TREE)
2739 || (TREE_TYPE (type) == NULL_TREE))
2740 type = ffecom_tree_fun_type_void; /* _sym_exec_transition. */
2742 multi = (ffecom_master_bt_ == FFEINFO_basictypeNONE);
2745 case FFEINFO_kindSUBROUTINE:
2746 gt = FFEGLOBAL_typeSUBR;
2747 bt = FFEINFO_basictypeNONE;
2748 kt = FFEINFO_kindtypeNONE;
2749 if (ffecom_is_altreturning_)
2750 { /* Am _I_ altreturning? */
2751 for (item = ffesymbol_dummyargs (fn);
2753 item = ffebld_trail (item))
2755 if (ffebld_op (ffebld_head (item)) == FFEBLD_opSTAR)
2757 altreturning = TRUE;
2762 type = ffecom_tree_subr_type;
2764 type = ffecom_tree_fun_type_void;
2767 type = ffecom_tree_fun_type_void;
2774 assert ("say what??" == NULL);
2776 case FFEINFO_kindANY:
2777 gt = FFEGLOBAL_typeANY;
2778 bt = FFEINFO_basictypeNONE;
2779 kt = FFEINFO_kindtypeNONE;
2780 type = error_mark_node;
2787 /* build_decl uses the current lineno and input_filename to set the decl
2788 source info. So, I've putzed with ffestd and ffeste code to update that
2789 source info to point to the appropriate statement just before calling
2790 ffecom_do_entrypoint (which calls this fn). */
2792 start_function (ffecom_get_external_identifier_ (fn),
2794 0, /* nested/inline */
2795 1); /* TREE_PUBLIC */
2797 if (((g = ffesymbol_global (fn)) != NULL)
2798 && ((ffeglobal_type (g) == gt)
2799 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
2801 ffeglobal_set_hook (g, current_function_decl);
2804 /* Reset args in master arg list so they get retransitioned. */
2806 for (item = ffecom_master_arglist_;
2808 item = ffebld_trail (item))
2813 arg = ffebld_head (item);
2814 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2815 continue; /* Alternate return or some such thing. */
2816 s = ffebld_symter (arg);
2817 ffesymbol_hook (s).decl_tree = NULL_TREE;
2818 ffesymbol_hook (s).length_tree = NULL_TREE;
2821 /* Build dummy arg list for this entry point. */
2823 yes = suspend_momentary ();
2825 if (charfunc || cmplxfunc)
2826 { /* Prepend arg for where result goes. */
2831 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
2833 type = ffecom_tree_type[FFEINFO_basictypeCOMPLEX][kt];
2835 result = ffecom_get_invented_identifier ("__g77_%s", "result");
2837 /* Make length arg _and_ enhance type info for CHAR arg itself. */
2840 length = ffecom_char_enhance_arg_ (&type, fn);
2842 length = NULL_TREE; /* Not ref'd if !charfunc. */
2844 type = build_pointer_type (type);
2845 result = build_decl (PARM_DECL, result, type);
2847 push_parm_decl (result);
2848 ffecom_func_result_ = result;
2852 push_parm_decl (length);
2853 ffecom_func_length_ = length;
2857 result = DECL_RESULT (current_function_decl);
2859 ffecom_push_dummy_decls_ (ffesymbol_dummyargs (fn), FALSE);
2861 resume_momentary (yes);
2863 store_parm_decls (0);
2865 ffecom_start_compstmt ();
2866 /* Disallow temp vars at this level. */
2867 current_binding_level->prep_state = 2;
2869 /* Make local var to hold return type for multi-type master fn. */
2873 yes = suspend_momentary ();
2875 multi_retval = ffecom_get_invented_identifier ("__g77_%s",
2877 multi_retval = build_decl (VAR_DECL, multi_retval,
2878 ffecom_multi_type_node_);
2879 multi_retval = start_decl (multi_retval, FALSE);
2880 finish_decl (multi_retval, NULL_TREE, FALSE);
2882 resume_momentary (yes);
2885 multi_retval = NULL_TREE; /* Not actually ref'd if !multi. */
2887 /* Here we emit the actual code for the entry point. */
2893 tree arglist = NULL_TREE;
2894 tree *plist = &arglist;
2900 /* Prepare actual arg list based on master arg list. */
2902 for (list = ffecom_master_arglist_;
2904 list = ffebld_trail (list))
2906 arg = ffebld_head (list);
2907 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2909 s = ffebld_symter (arg);
2910 if (ffesymbol_hook (s).decl_tree == NULL_TREE
2911 || ffesymbol_hook (s).decl_tree == error_mark_node)
2912 actarg = null_pointer_node; /* We don't have this arg. */
2914 actarg = ffesymbol_hook (s).decl_tree;
2915 *plist = build_tree_list (NULL_TREE, actarg);
2916 plist = &TREE_CHAIN (*plist);
2919 /* This code appends the length arguments for character
2920 variables/arrays. */
2922 for (list = ffecom_master_arglist_;
2924 list = ffebld_trail (list))
2926 arg = ffebld_head (list);
2927 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2929 s = ffebld_symter (arg);
2930 if (ffesymbol_basictype (s) != FFEINFO_basictypeCHARACTER)
2931 continue; /* Only looking for CHARACTER arguments. */
2932 if (ffesymbol_kind (s) != FFEINFO_kindENTITY)
2933 continue; /* Only looking for variables and arrays. */
2934 if (ffesymbol_hook (s).length_tree == NULL_TREE
2935 || ffesymbol_hook (s).length_tree == error_mark_node)
2936 actarg = ffecom_f2c_ftnlen_zero_node; /* We don't have this arg. */
2938 actarg = ffesymbol_hook (s).length_tree;
2939 *plist = build_tree_list (NULL_TREE, actarg);
2940 plist = &TREE_CHAIN (*plist);
2943 /* Prepend character-value return info to actual arg list. */
2947 prepend = build_tree_list (NULL_TREE, ffecom_func_result_);
2948 TREE_CHAIN (prepend)
2949 = build_tree_list (NULL_TREE, ffecom_func_length_);
2950 TREE_CHAIN (TREE_CHAIN (prepend)) = arglist;
2954 /* Prepend multi-type return value to actual arg list. */
2959 = build_tree_list (NULL_TREE,
2960 ffecom_1 (ADDR_EXPR,
2961 build_pointer_type (TREE_TYPE (multi_retval)),
2963 TREE_CHAIN (prepend) = arglist;
2967 /* Prepend my entry-point number to the actual arg list. */
2969 prepend = build_tree_list (NULL_TREE, build_int_2 (entrynum, 0));
2970 TREE_CHAIN (prepend) = arglist;
2973 /* Build the call to the master function. */
2975 master_fn = ffecom_1_fn (ffecom_previous_function_decl_);
2976 call = ffecom_3s (CALL_EXPR,
2977 TREE_TYPE (TREE_TYPE (TREE_TYPE (master_fn))),
2978 master_fn, arglist, NULL_TREE);
2980 /* Decide whether the master function is a function or subroutine, and
2981 handle the return value for my entry point. */
2983 if (charfunc || ((ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE)
2986 expand_expr_stmt (call);
2987 expand_null_return ();
2989 else if (multi && cmplxfunc)
2991 expand_expr_stmt (call);
2993 = ffecom_1 (INDIRECT_REF,
2994 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result))),
2996 result = ffecom_modify (NULL_TREE, result,
2997 ffecom_2 (COMPONENT_REF, TREE_TYPE (result),
2999 ffecom_multi_fields_[bt][kt]));
3000 expand_expr_stmt (result);
3001 expand_null_return ();
3005 expand_expr_stmt (call);
3007 = ffecom_modify (NULL_TREE, result,
3008 convert (TREE_TYPE (result),
3009 ffecom_2 (COMPONENT_REF,
3010 ffecom_tree_type[bt][kt],
3012 ffecom_multi_fields_[bt][kt])));
3013 expand_return (result);
3018 = ffecom_1 (INDIRECT_REF,
3019 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result))),
3021 result = ffecom_modify (NULL_TREE, result, call);
3022 expand_expr_stmt (result);
3023 expand_null_return ();
3027 result = ffecom_modify (NULL_TREE,
3029 convert (TREE_TYPE (result),
3031 expand_return (result);
3037 ffecom_end_compstmt ();
3039 finish_function (0);
3041 lineno = old_lineno;
3042 input_filename = old_input_filename;
3044 ffecom_doing_entry_ = FALSE;
3048 /* Transform expr into gcc tree with possible destination
3050 Recursive descent on expr while making corresponding tree nodes and
3051 attaching type info and such. If destination supplied and compatible
3052 with temporary that would be made in certain cases, temporary isn't
3053 made, destination used instead, and dest_used flag set TRUE. */
3055 #if FFECOM_targetCURRENT == FFECOM_targetGCC
3057 ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest,
3058 bool *dest_used, bool assignp, bool widenp)
3063 ffeinfoBasictype bt;
3066 tree dt; /* decl_tree for an ffesymbol. */
3067 tree tree_type, tree_type_x;
3070 enum tree_code code;
3072 assert (expr != NULL);
3074 if (dest_used != NULL)
3077 bt = ffeinfo_basictype (ffebld_info (expr));
3078 kt = ffeinfo_kindtype (ffebld_info (expr));
3079 tree_type = ffecom_tree_type[bt][kt];
3081 /* Widen integral arithmetic as desired while preserving signedness. */
3082 tree_type_x = NULL_TREE;
3083 if (widenp && tree_type
3084 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
3085 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
3086 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
3088 switch (ffebld_op (expr))
3090 case FFEBLD_opACCTER:
3093 ffebit bits = ffebld_accter_bits (expr);
3094 ffetargetOffset source_offset = 0;
3095 ffetargetOffset dest_offset = ffebld_accter_pad (expr);
3098 assert (dest_offset == 0
3099 || (bt == FFEINFO_basictypeCHARACTER
3100 && kt == FFEINFO_kindtypeCHARACTER1));
3105 ffebldConstantUnion cu;
3108 ffebldConstantArray ca = ffebld_accter (expr);
3110 ffebit_test (bits, source_offset, &value, &length);
3116 for (i = 0; i < length; ++i)
3118 cu = ffebld_constantarray_get (ca, bt, kt,
3121 t = ffecom_constantunion (&cu, bt, kt, tree_type);
3124 && dest_offset != 0)
3125 purpose = build_int_2 (dest_offset, 0);
3127 purpose = NULL_TREE;
3129 if (list == NULL_TREE)
3130 list = item = build_tree_list (purpose, t);
3133 TREE_CHAIN (item) = build_tree_list (purpose, t);
3134 item = TREE_CHAIN (item);
3138 source_offset += length;
3139 dest_offset += length;
3143 item = build_int_2 ((ffebld_accter_size (expr)
3144 + ffebld_accter_pad (expr)) - 1, 0);
3145 ffebit_kill (ffebld_accter_bits (expr));
3146 TREE_TYPE (item) = ffecom_integer_type_node;
3150 build_range_type (ffecom_integer_type_node,
3151 ffecom_integer_zero_node,
3153 list = build (CONSTRUCTOR, item, NULL_TREE, list);
3154 TREE_CONSTANT (list) = 1;
3155 TREE_STATIC (list) = 1;
3158 case FFEBLD_opARRTER:
3163 if (ffebld_arrter_pad (expr) == 0)
3167 assert (bt == FFEINFO_basictypeCHARACTER
3168 && kt == FFEINFO_kindtypeCHARACTER1);
3170 /* Becomes PURPOSE first time through loop. */
3171 item = build_int_2 (ffebld_arrter_pad (expr), 0);
3174 for (i = 0; i < ffebld_arrter_size (expr); ++i)
3176 ffebldConstantUnion cu
3177 = ffebld_constantarray_get (ffebld_arrter (expr), bt, kt, i);
3179 t = ffecom_constantunion (&cu, bt, kt, tree_type);
3181 if (list == NULL_TREE)
3182 /* Assume item is PURPOSE first time through loop. */
3183 list = item = build_tree_list (item, t);
3186 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
3187 item = TREE_CHAIN (item);
3192 item = build_int_2 ((ffebld_arrter_size (expr)
3193 + ffebld_arrter_pad (expr)) - 1, 0);
3194 TREE_TYPE (item) = ffecom_integer_type_node;
3198 build_range_type (ffecom_integer_type_node,
3199 ffecom_integer_zero_node,
3201 list = build (CONSTRUCTOR, item, NULL_TREE, list);
3202 TREE_CONSTANT (list) = 1;
3203 TREE_STATIC (list) = 1;
3206 case FFEBLD_opCONTER:
3207 assert (ffebld_conter_pad (expr) == 0);
3209 = ffecom_constantunion (&ffebld_constant_union (ffebld_conter (expr)),
3213 case FFEBLD_opSYMTER:
3214 if ((ffebld_symter_generic (expr) != FFEINTRIN_genNONE)
3215 || (ffebld_symter_specific (expr) != FFEINTRIN_specNONE))
3216 return ffecom_ptr_to_expr (expr); /* Same as %REF(intrinsic). */
3217 s = ffebld_symter (expr);
3218 t = ffesymbol_hook (s).decl_tree;
3221 { /* ASSIGN'ed-label expr. */
3222 if (ffe_is_ugly_assign ())
3224 /* User explicitly wants ASSIGN'ed variables to be at the same
3225 memory address as the variables when used in non-ASSIGN
3226 contexts. That can make old, arcane, non-standard code
3227 work, but don't try to do it when a pointer wouldn't fit
3228 in the normal variable (take other approach, and warn,
3233 s = ffecom_sym_transform_ (s);
3234 t = ffesymbol_hook (s).decl_tree;
3235 assert (t != NULL_TREE);
3238 if (t == error_mark_node)
3241 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (t)))
3242 >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
3244 if (ffesymbol_hook (s).addr)
3245 t = ffecom_1 (INDIRECT_REF,
3246 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), t);
3250 if (ffesymbol_hook (s).assign_tree == NULL_TREE)
3252 ffebad_start_msg ("ASSIGN'ed label cannot fit into `%A' at %0 -- using wider sibling",
3253 FFEBAD_severityWARNING);
3254 ffebad_string (ffesymbol_text (s));
3255 ffebad_here (0, ffesymbol_where_line (s),
3256 ffesymbol_where_column (s));
3261 /* Don't use the normal variable's tree for ASSIGN, though mark
3262 it as in the system header (housekeeping). Use an explicit,
3263 specially created sibling that is known to be wide enough
3264 to hold pointers to labels. */
3267 && TREE_CODE (t) == VAR_DECL)
3268 DECL_IN_SYSTEM_HEADER (t) = 1; /* Don't let -Wunused complain. */
3270 t = ffesymbol_hook (s).assign_tree;
3273 s = ffecom_sym_transform_assign_ (s);
3274 t = ffesymbol_hook (s).assign_tree;
3275 assert (t != NULL_TREE);
3282 s = ffecom_sym_transform_ (s);
3283 t = ffesymbol_hook (s).decl_tree;
3284 assert (t != NULL_TREE);
3286 if (ffesymbol_hook (s).addr)
3287 t = ffecom_1 (INDIRECT_REF,
3288 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), t);
3292 case FFEBLD_opARRAYREF:
3293 return ffecom_arrayref_ (NULL_TREE, expr, 0);
3295 case FFEBLD_opUPLUS:
3296 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3297 return ffecom_1 (NOP_EXPR, tree_type, left);
3299 case FFEBLD_opPAREN:
3300 /* ~~~Make sure Fortran rules respected here */
3301 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3302 return ffecom_1 (NOP_EXPR, tree_type, left);
3304 case FFEBLD_opUMINUS:
3305 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3308 tree_type = tree_type_x;
3309 left = convert (tree_type, left);
3311 return ffecom_1 (NEGATE_EXPR, tree_type, left);
3314 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3315 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
3318 tree_type = tree_type_x;
3319 left = convert (tree_type, left);
3320 right = convert (tree_type, right);
3322 return ffecom_2 (PLUS_EXPR, tree_type, left, right);
3324 case FFEBLD_opSUBTRACT:
3325 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3326 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
3329 tree_type = tree_type_x;
3330 left = convert (tree_type, left);
3331 right = convert (tree_type, right);
3333 return ffecom_2 (MINUS_EXPR, tree_type, left, right);
3335 case FFEBLD_opMULTIPLY:
3336 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3337 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
3340 tree_type = tree_type_x;
3341 left = convert (tree_type, left);
3342 right = convert (tree_type, right);
3344 return ffecom_2 (MULT_EXPR, tree_type, left, right);
3346 case FFEBLD_opDIVIDE:
3347 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3348 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
3351 tree_type = tree_type_x;
3352 left = convert (tree_type, left);
3353 right = convert (tree_type, right);
3355 return ffecom_tree_divide_ (tree_type, left, right,
3356 dest_tree, dest, dest_used,
3357 ffebld_nonter_hook (expr));
3359 case FFEBLD_opPOWER:
3361 ffebld left = ffebld_left (expr);
3362 ffebld right = ffebld_right (expr);
3364 ffeinfoKindtype rtkt;
3365 ffeinfoKindtype ltkt;
3367 switch (ffeinfo_basictype (ffebld_info (right)))
3369 case FFEINFO_basictypeINTEGER:
3372 item = ffecom_expr_power_integer_ (expr);
3373 if (item != NULL_TREE)
3377 rtkt = FFEINFO_kindtypeINTEGER1;
3378 switch (ffeinfo_basictype (ffebld_info (left)))
3380 case FFEINFO_basictypeINTEGER:
3381 if ((ffeinfo_kindtype (ffebld_info (left))
3382 == FFEINFO_kindtypeINTEGER4)
3383 || (ffeinfo_kindtype (ffebld_info (right))
3384 == FFEINFO_kindtypeINTEGER4))
3386 code = FFECOM_gfrtPOW_QQ;
3387 ltkt = FFEINFO_kindtypeINTEGER4;
3388 rtkt = FFEINFO_kindtypeINTEGER4;
3392 code = FFECOM_gfrtPOW_II;
3393 ltkt = FFEINFO_kindtypeINTEGER1;
3397 case FFEINFO_basictypeREAL:
3398 if (ffeinfo_kindtype (ffebld_info (left))
3399 == FFEINFO_kindtypeREAL1)
3401 code = FFECOM_gfrtPOW_RI;
3402 ltkt = FFEINFO_kindtypeREAL1;
3406 code = FFECOM_gfrtPOW_DI;
3407 ltkt = FFEINFO_kindtypeREAL2;
3411 case FFEINFO_basictypeCOMPLEX:
3412 if (ffeinfo_kindtype (ffebld_info (left))
3413 == FFEINFO_kindtypeREAL1)
3415 code = FFECOM_gfrtPOW_CI; /* Overlapping result okay. */
3416 ltkt = FFEINFO_kindtypeREAL1;
3420 code = FFECOM_gfrtPOW_ZI; /* Overlapping result okay. */
3421 ltkt = FFEINFO_kindtypeREAL2;
3426 assert ("bad pow_*i" == NULL);
3427 code = FFECOM_gfrtPOW_CI; /* Overlapping result okay. */
3428 ltkt = FFEINFO_kindtypeREAL1;
3431 if (ffeinfo_kindtype (ffebld_info (left)) != ltkt)
3432 left = ffeexpr_convert (left, NULL, NULL,
3433 ffeinfo_basictype (ffebld_info (left)),
3435 FFETARGET_charactersizeNONE,
3436 FFEEXPR_contextLET);
3437 if (ffeinfo_kindtype (ffebld_info (right)) != rtkt)
3438 right = ffeexpr_convert (right, NULL, NULL,
3439 FFEINFO_basictypeINTEGER,
3441 FFETARGET_charactersizeNONE,
3442 FFEEXPR_contextLET);
3445 case FFEINFO_basictypeREAL:
3446 if (ffeinfo_kindtype (ffebld_info (left)) == FFEINFO_kindtypeREAL1)
3447 left = ffeexpr_convert (left, NULL, NULL, FFEINFO_basictypeREAL,
3448 FFEINFO_kindtypeREALDOUBLE, 0,
3449 FFETARGET_charactersizeNONE,
3450 FFEEXPR_contextLET);
3451 if (ffeinfo_kindtype (ffebld_info (right))
3452 == FFEINFO_kindtypeREAL1)
3453 right = ffeexpr_convert (right, NULL, NULL,
3454 FFEINFO_basictypeREAL,
3455 FFEINFO_kindtypeREALDOUBLE, 0,
3456 FFETARGET_charactersizeNONE,
3457 FFEEXPR_contextLET);
3458 code = FFECOM_gfrtPOW_DD;
3461 case FFEINFO_basictypeCOMPLEX:
3462 if (ffeinfo_kindtype (ffebld_info (left)) == FFEINFO_kindtypeREAL1)
3463 left = ffeexpr_convert (left, NULL, NULL,
3464 FFEINFO_basictypeCOMPLEX,
3465 FFEINFO_kindtypeREALDOUBLE, 0,
3466 FFETARGET_charactersizeNONE,
3467 FFEEXPR_contextLET);
3468 if (ffeinfo_kindtype (ffebld_info (right))
3469 == FFEINFO_kindtypeREAL1)
3470 right = ffeexpr_convert (right, NULL, NULL,
3471 FFEINFO_basictypeCOMPLEX,
3472 FFEINFO_kindtypeREALDOUBLE, 0,
3473 FFETARGET_charactersizeNONE,
3474 FFEEXPR_contextLET);
3475 code = FFECOM_gfrtPOW_ZZ; /* Overlapping result okay. */
3479 assert ("bad pow_x*" == NULL);
3480 code = FFECOM_gfrtPOW_II;
3483 return ffecom_call_binop_ (ffecom_gfrt_tree_ (code),
3484 ffecom_gfrt_kindtype (code),
3485 (ffe_is_f2c_library ()
3486 && ffecom_gfrt_complex_[code]),
3487 tree_type, left, right,
3488 dest_tree, dest, dest_used,
3490 ffebld_nonter_hook (expr));
3496 case FFEINFO_basictypeLOGICAL:
3497 item = ffecom_truth_value_invert (ffecom_expr (ffebld_left (expr)));
3498 return convert (tree_type, item);
3500 case FFEINFO_basictypeINTEGER:
3501 return ffecom_1 (BIT_NOT_EXPR, tree_type,
3502 ffecom_expr (ffebld_left (expr)));
3505 assert ("NOT bad basictype" == NULL);
3507 case FFEINFO_basictypeANY:
3508 return error_mark_node;
3512 case FFEBLD_opFUNCREF:
3513 assert (ffeinfo_basictype (ffebld_info (expr))
3514 != FFEINFO_basictypeCHARACTER);
3516 case FFEBLD_opSUBRREF:
3517 if (ffeinfo_where (ffebld_info (ffebld_left (expr)))
3518 == FFEINFO_whereINTRINSIC)
3519 { /* Invocation of an intrinsic. */
3520 item = ffecom_expr_intrinsic_ (expr, dest_tree, dest,
3524 s = ffebld_symter (ffebld_left (expr));
3525 dt = ffesymbol_hook (s).decl_tree;
3526 if (dt == NULL_TREE)
3528 s = ffecom_sym_transform_ (s);
3529 dt = ffesymbol_hook (s).decl_tree;
3531 if (dt == error_mark_node)
3534 if (ffesymbol_hook (s).addr)
3537 item = ffecom_1_fn (dt);
3539 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT)
3540 args = ffecom_list_expr (ffebld_right (expr));
3542 args = ffecom_list_ptr_to_expr (ffebld_right (expr));
3544 if (args == error_mark_node)
3545 return error_mark_node;
3547 item = ffecom_call_ (item, kt,
3548 ffesymbol_is_f2c (s)
3549 && (bt == FFEINFO_basictypeCOMPLEX)
3550 && (ffesymbol_where (s)
3551 != FFEINFO_whereCONSTANT),
3554 dest_tree, dest, dest_used,
3555 error_mark_node, FALSE,
3556 ffebld_nonter_hook (expr));
3557 TREE_SIDE_EFFECTS (item) = 1;
3563 case FFEINFO_basictypeLOGICAL:
3565 = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
3566 ffecom_truth_value (ffecom_expr (ffebld_left (expr))),
3567 ffecom_truth_value (ffecom_expr (ffebld_right (expr))));
3568 return convert (tree_type, item);
3570 case FFEINFO_basictypeINTEGER:
3571 return ffecom_2 (BIT_AND_EXPR, tree_type,
3572 ffecom_expr (ffebld_left (expr)),
3573 ffecom_expr (ffebld_right (expr)));
3576 assert ("AND bad basictype" == NULL);
3578 case FFEINFO_basictypeANY:
3579 return error_mark_node;
3586 case FFEINFO_basictypeLOGICAL:
3588 = ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
3589 ffecom_truth_value (ffecom_expr (ffebld_left (expr))),
3590 ffecom_truth_value (ffecom_expr (ffebld_right (expr))));
3591 return convert (tree_type, item);
3593 case FFEINFO_basictypeINTEGER:
3594 return ffecom_2 (BIT_IOR_EXPR, tree_type,
3595 ffecom_expr (ffebld_left (expr)),
3596 ffecom_expr (ffebld_right (expr)));
3599 assert ("OR bad basictype" == NULL);
3601 case FFEINFO_basictypeANY:
3602 return error_mark_node;
3610 case FFEINFO_basictypeLOGICAL:
3612 = ffecom_2 (NE_EXPR, integer_type_node,
3613 ffecom_expr (ffebld_left (expr)),
3614 ffecom_expr (ffebld_right (expr)));
3615 return convert (tree_type, ffecom_truth_value (item));
3617 case FFEINFO_basictypeINTEGER:
3618 return ffecom_2 (BIT_XOR_EXPR, tree_type,
3619 ffecom_expr (ffebld_left (expr)),
3620 ffecom_expr (ffebld_right (expr)));
3623 assert ("XOR/NEQV bad basictype" == NULL);
3625 case FFEINFO_basictypeANY:
3626 return error_mark_node;
3633 case FFEINFO_basictypeLOGICAL:
3635 = ffecom_2 (EQ_EXPR, integer_type_node,
3636 ffecom_expr (ffebld_left (expr)),
3637 ffecom_expr (ffebld_right (expr)));
3638 return convert (tree_type, ffecom_truth_value (item));
3640 case FFEINFO_basictypeINTEGER:
3642 ffecom_1 (BIT_NOT_EXPR, tree_type,
3643 ffecom_2 (BIT_XOR_EXPR, tree_type,
3644 ffecom_expr (ffebld_left (expr)),
3645 ffecom_expr (ffebld_right (expr))));
3648 assert ("EQV bad basictype" == NULL);
3650 case FFEINFO_basictypeANY:
3651 return error_mark_node;
3655 case FFEBLD_opCONVERT:
3656 if (ffebld_op (ffebld_left (expr)) == FFEBLD_opANY)
3657 return error_mark_node;
3661 case FFEINFO_basictypeLOGICAL:
3662 case FFEINFO_basictypeINTEGER:
3663 case FFEINFO_basictypeREAL:
3664 return convert (tree_type, ffecom_expr (ffebld_left (expr)));
3666 case FFEINFO_basictypeCOMPLEX:
3667 switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr))))
3669 case FFEINFO_basictypeINTEGER:
3670 case FFEINFO_basictypeLOGICAL:
3671 case FFEINFO_basictypeREAL:
3672 item = ffecom_expr (ffebld_left (expr));
3673 if (item == error_mark_node)
3674 return error_mark_node;
3675 /* convert() takes care of converting to the subtype first,
3676 at least in gcc-2.7.2. */
3677 item = convert (tree_type, item);
3680 case FFEINFO_basictypeCOMPLEX:
3681 return convert (tree_type, ffecom_expr (ffebld_left (expr)));
3684 assert ("CONVERT COMPLEX bad basictype" == NULL);
3686 case FFEINFO_basictypeANY:
3687 return error_mark_node;
3692 assert ("CONVERT bad basictype" == NULL);
3694 case FFEINFO_basictypeANY:
3695 return error_mark_node;
3701 goto relational; /* :::::::::::::::::::: */
3705 goto relational; /* :::::::::::::::::::: */
3709 goto relational; /* :::::::::::::::::::: */
3713 goto relational; /* :::::::::::::::::::: */
3717 goto relational; /* :::::::::::::::::::: */
3722 relational: /* :::::::::::::::::::: */
3723 switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr))))
3725 case FFEINFO_basictypeLOGICAL:
3726 case FFEINFO_basictypeINTEGER:
3727 case FFEINFO_basictypeREAL:
3728 item = ffecom_2 (code, integer_type_node,
3729 ffecom_expr (ffebld_left (expr)),
3730 ffecom_expr (ffebld_right (expr)));
3731 return convert (tree_type, item);
3733 case FFEINFO_basictypeCOMPLEX:
3734 assert (code == EQ_EXPR || code == NE_EXPR);
3737 tree arg1 = ffecom_expr (ffebld_left (expr));
3738 tree arg2 = ffecom_expr (ffebld_right (expr));
3740 if (arg1 == error_mark_node || arg2 == error_mark_node)
3741 return error_mark_node;
3743 arg1 = ffecom_save_tree (arg1);
3744 arg2 = ffecom_save_tree (arg2);
3746 if (TREE_CODE (TREE_TYPE (arg1)) == COMPLEX_TYPE)
3748 real_type = TREE_TYPE (TREE_TYPE (arg1));
3749 assert (real_type == TREE_TYPE (TREE_TYPE (arg2)));
3753 real_type = TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg1)));
3754 assert (real_type == TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg2))));
3758 = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
3759 ffecom_2 (EQ_EXPR, integer_type_node,
3760 ffecom_1 (REALPART_EXPR, real_type, arg1),
3761 ffecom_1 (REALPART_EXPR, real_type, arg2)),
3762 ffecom_2 (EQ_EXPR, integer_type_node,
3763 ffecom_1 (IMAGPART_EXPR, real_type, arg1),
3764 ffecom_1 (IMAGPART_EXPR, real_type,
3766 if (code == EQ_EXPR)
3767 item = ffecom_truth_value (item);
3769 item = ffecom_truth_value_invert (item);
3770 return convert (tree_type, item);
3773 case FFEINFO_basictypeCHARACTER:
3775 ffebld left = ffebld_left (expr);
3776 ffebld right = ffebld_right (expr);
3782 /* f2c run-time functions do the implicit blank-padding for us,
3783 so we don't usually have to implement blank-padding ourselves.
3784 (The exception is when we pass an argument to a separately
3785 compiled statement function -- if we know the arg is not the
3786 same length as the dummy, we must truncate or extend it. If
3787 we "inline" statement functions, that necessity goes away as
3790 Strip off the CONVERT operators that blank-pad. (Truncation by
3791 CONVERT shouldn't happen here, but it can happen in
3794 while (ffebld_op (left) == FFEBLD_opCONVERT)
3795 left = ffebld_left (left);
3796 while (ffebld_op (right) == FFEBLD_opCONVERT)
3797 right = ffebld_left (right);
3799 left_tree = ffecom_arg_ptr_to_expr (left, &left_length);
3800 right_tree = ffecom_arg_ptr_to_expr (right, &right_length);
3802 if (left_tree == error_mark_node || left_length == error_mark_node
3803 || right_tree == error_mark_node
3804 || right_length == error_mark_node)
3805 return error_mark_node;
3807 if ((ffebld_size_known (left) == 1)
3808 && (ffebld_size_known (right) == 1))
3811 = ffecom_1 (INDIRECT_REF,
3812 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree))),
3815 = ffecom_1 (INDIRECT_REF,
3816 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree))),
3820 = ffecom_2 (code, integer_type_node,
3821 ffecom_2 (ARRAY_REF,
3822 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree))),
3825 ffecom_2 (ARRAY_REF,
3826 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree))),
3832 item = build_tree_list (NULL_TREE, left_tree);
3833 TREE_CHAIN (item) = build_tree_list (NULL_TREE, right_tree);
3834 TREE_CHAIN (TREE_CHAIN (item)) = build_tree_list (NULL_TREE,
3836 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item)))
3837 = build_tree_list (NULL_TREE, right_length);
3838 item = ffecom_call_gfrt (FFECOM_gfrtCMP, item, NULL_TREE);
3839 item = ffecom_2 (code, integer_type_node,
3841 convert (TREE_TYPE (item),
3842 integer_zero_node));
3844 item = convert (tree_type, item);
3850 assert ("relational bad basictype" == NULL);
3852 case FFEINFO_basictypeANY:
3853 return error_mark_node;
3857 case FFEBLD_opPERCENT_LOC:
3858 item = ffecom_arg_ptr_to_expr (ffebld_left (expr), &list);
3859 return convert (tree_type, item);
3863 case FFEBLD_opBOUNDS:
3864 case FFEBLD_opREPEAT:
3865 case FFEBLD_opLABTER:
3866 case FFEBLD_opLABTOK:
3867 case FFEBLD_opIMPDO:
3868 case FFEBLD_opCONCATENATE:
3869 case FFEBLD_opSUBSTR:
3871 assert ("bad op" == NULL);
3874 return error_mark_node;
3878 assert ("didn't think anything got here anymore!!" == NULL);
3880 switch (ffebld_arity (expr))
3883 TREE_OPERAND (item, 0) = ffecom_expr (ffebld_left (expr));
3884 TREE_OPERAND (item, 1) = ffecom_expr (ffebld_right (expr));
3885 if (TREE_OPERAND (item, 0) == error_mark_node
3886 || TREE_OPERAND (item, 1) == error_mark_node)
3887 return error_mark_node;
3891 TREE_OPERAND (item, 0) = ffecom_expr (ffebld_left (expr));
3892 if (TREE_OPERAND (item, 0) == error_mark_node)
3893 return error_mark_node;
3905 /* Returns the tree that does the intrinsic invocation.
3907 Note: this function applies only to intrinsics returning
3908 CHARACTER*1 or non-CHARACTER results, and to intrinsic
3911 #if FFECOM_targetCURRENT == FFECOM_targetGCC
3913 ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree,
3914 ffebld dest, bool *dest_used)
3917 tree saved_expr1; /* For those who need it. */
3918 tree saved_expr2; /* For those who need it. */
3919 ffeinfoBasictype bt;
3923 tree real_type; /* REAL type corresponding to COMPLEX. */
3925 ffebld list = ffebld_right (expr); /* List of (some) args. */
3926 ffebld arg1; /* For handy reference. */
3929 ffeintrinImp codegen_imp;
3932 assert (ffebld_op (ffebld_left (expr)) == FFEBLD_opSYMTER);
3934 if (dest_used != NULL)
3937 bt = ffeinfo_basictype (ffebld_info (expr));
3938 kt = ffeinfo_kindtype (ffebld_info (expr));
3939 tree_type = ffecom_tree_type[bt][kt];
3943 arg1 = ffebld_head (list);
3944 if (arg1 != NULL && ffebld_op (arg1) == FFEBLD_opANY)
3945 return error_mark_node;
3946 if ((list = ffebld_trail (list)) != NULL)
3948 arg2 = ffebld_head (list);
3949 if (arg2 != NULL && ffebld_op (arg2) == FFEBLD_opANY)
3950 return error_mark_node;
3951 if ((list = ffebld_trail (list)) != NULL)
3953 arg3 = ffebld_head (list);
3954 if (arg3 != NULL && ffebld_op (arg3) == FFEBLD_opANY)
3955 return error_mark_node;
3964 arg1 = arg2 = arg3 = NULL;
3966 /* <list> ends up at the opITEM of the 3rd arg, or NULL if there are < 3
3967 args. This is used by the MAX/MIN expansions. */
3970 arg1_type = ffecom_tree_type
3971 [ffeinfo_basictype (ffebld_info (arg1))]
3972 [ffeinfo_kindtype (ffebld_info (arg1))];
3974 arg1_type = NULL_TREE; /* Really not needed, but might catch bugs
3977 /* There are several ways for each of the cases in the following switch
3978 statements to exit (from simplest to use to most complicated):
3980 break; (when expr_tree == NULL)
3982 A standard call is made to the specific intrinsic just as if it had been
3983 passed in as a dummy procedure and called as any old procedure. This
3984 method can produce slower code but in some cases it's the easiest way for
3985 now. However, if a (presumably faster) direct call is available,
3986 that is used, so this is the easiest way in many more cases now.
3988 gfrt = FFECOM_gfrtWHATEVER;
3991 gfrt contains the gfrt index of a library function to call, passing the
3992 argument(s) by value rather than by reference. Used when a more
3993 careful choice of library function is needed than that provided
3994 by the vanilla `break;'.
3998 The expr_tree has been completely set up and is ready to be returned
3999 as is. No further actions are taken. Use this when the tree is not
4000 in the simple form for one of the arity_n labels. */
4002 /* For info on how the switch statement cases were written, see the files
4003 enclosed in comments below the switch statement. */
4005 codegen_imp = ffebld_symter_implementation (ffebld_left (expr));
4006 gfrt = ffeintrin_gfrt_direct (codegen_imp);
4007 if (gfrt == FFECOM_gfrt)
4008 gfrt = ffeintrin_gfrt_indirect (codegen_imp);
4010 switch (codegen_imp)
4012 case FFEINTRIN_impABS:
4013 case FFEINTRIN_impCABS:
4014 case FFEINTRIN_impCDABS:
4015 case FFEINTRIN_impDABS:
4016 case FFEINTRIN_impIABS:
4017 if (ffeinfo_basictype (ffebld_info (arg1))
4018 == FFEINFO_basictypeCOMPLEX)
4020 if (kt == FFEINFO_kindtypeREAL1)
4021 gfrt = FFECOM_gfrtCABS;
4022 else if (kt == FFEINFO_kindtypeREAL2)
4023 gfrt = FFECOM_gfrtCDABS;
4026 return ffecom_1 (ABS_EXPR, tree_type,
4027 convert (tree_type, ffecom_expr (arg1)));
4029 case FFEINTRIN_impACOS:
4030 case FFEINTRIN_impDACOS:
4033 case FFEINTRIN_impAIMAG:
4034 case FFEINTRIN_impDIMAG:
4035 case FFEINTRIN_impIMAGPART:
4036 if (TREE_CODE (arg1_type) == COMPLEX_TYPE)
4037 arg1_type = TREE_TYPE (arg1_type);
4039 arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type));
4043 ffecom_1 (IMAGPART_EXPR, arg1_type,
4044 ffecom_expr (arg1)));
4046 case FFEINTRIN_impAINT:
4047 case FFEINTRIN_impDINT:
4049 /* ~~Someday implement FIX_TRUNC_EXPR yielding same type as arg. */
4050 return ffecom_1 (FIX_TRUNC_EXPR, tree_type, ffecom_expr (arg1));
4051 #else /* in the meantime, must use floor to avoid range problems with ints */
4052 /* r__1 = r1 >= 0 ? floor(r1) : -floor(-r1); */
4053 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
4056 ffecom_3 (COND_EXPR, double_type_node,
4058 (ffecom_2 (GE_EXPR, integer_type_node,
4061 ffecom_float_zero_))),
4062 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
4063 build_tree_list (NULL_TREE,
4064 convert (double_type_node,
4067 ffecom_1 (NEGATE_EXPR, double_type_node,
4068 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
4069 build_tree_list (NULL_TREE,
4070 convert (double_type_node,
4071 ffecom_1 (NEGATE_EXPR,
4079 case FFEINTRIN_impANINT:
4080 case FFEINTRIN_impDNINT:
4081 #if 0 /* This way of doing it won't handle real
4082 numbers of large magnitudes. */
4083 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
4084 expr_tree = convert (tree_type,
4085 convert (integer_type_node,
4086 ffecom_3 (COND_EXPR, tree_type,
4091 ffecom_float_zero_)),
4092 ffecom_2 (PLUS_EXPR,
4095 ffecom_float_half_),
4096 ffecom_2 (MINUS_EXPR,
4099 ffecom_float_half_))));
4101 #else /* So we instead call floor. */
4102 /* r__1 = r1 >= 0 ? floor(r1 + .5) : -floor(.5 - r1) */
4103 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
4106 ffecom_3 (COND_EXPR, double_type_node,
4108 (ffecom_2 (GE_EXPR, integer_type_node,
4111 ffecom_float_zero_))),
4112 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
4113 build_tree_list (NULL_TREE,
4114 convert (double_type_node,
4115 ffecom_2 (PLUS_EXPR,
4119 ffecom_float_half_)))),
4121 ffecom_1 (NEGATE_EXPR, double_type_node,
4122 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
4123 build_tree_list (NULL_TREE,
4124 convert (double_type_node,
4125 ffecom_2 (MINUS_EXPR,
4128 ffecom_float_half_),
4135 case FFEINTRIN_impASIN:
4136 case FFEINTRIN_impDASIN:
4137 case FFEINTRIN_impATAN:
4138 case FFEINTRIN_impDATAN:
4139 case FFEINTRIN_impATAN2:
4140 case FFEINTRIN_impDATAN2:
4143 case FFEINTRIN_impCHAR:
4144 case FFEINTRIN_impACHAR:
4146 tempvar = ffecom_make_tempvar (char_type_node, 1, -1);
4148 tempvar = ffebld_nonter_hook (expr);
4152 tree tmv = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (tempvar)));
4154 expr_tree = ffecom_modify (tmv,
4155 ffecom_2 (ARRAY_REF, tmv, tempvar,
4157 convert (tmv, ffecom_expr (arg1)));
4159 expr_tree = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar),
4162 expr_tree = ffecom_1 (ADDR_EXPR,
4163 build_pointer_type (TREE_TYPE (expr_tree)),
4167 case FFEINTRIN_impCMPLX:
4168 case FFEINTRIN_impDCMPLX:
4171 convert (tree_type, ffecom_expr (arg1));
4173 real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
4175 ffecom_2 (COMPLEX_EXPR, tree_type,
4176 convert (real_type, ffecom_expr (arg1)),
4178 ffecom_expr (arg2)));
4180 case FFEINTRIN_impCOMPLEX:
4182 ffecom_2 (COMPLEX_EXPR, tree_type,
4184 ffecom_expr (arg2));
4186 case FFEINTRIN_impCONJG:
4187 case FFEINTRIN_impDCONJG:
4191 real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
4192 arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4194 ffecom_2 (COMPLEX_EXPR, tree_type,
4195 ffecom_1 (REALPART_EXPR, real_type, arg1_tree),
4196 ffecom_1 (NEGATE_EXPR, real_type,
4197 ffecom_1 (IMAGPART_EXPR, real_type, arg1_tree)));
4200 case FFEINTRIN_impCOS:
4201 case FFEINTRIN_impCCOS:
4202 case FFEINTRIN_impCDCOS:
4203 case FFEINTRIN_impDCOS:
4204 if (bt == FFEINFO_basictypeCOMPLEX)
4206 if (kt == FFEINFO_kindtypeREAL1)
4207 gfrt = FFECOM_gfrtCCOS; /* Overlapping result okay. */
4208 else if (kt == FFEINFO_kindtypeREAL2)
4209 gfrt = FFECOM_gfrtCDCOS; /* Overlapping result okay. */
4213 case FFEINTRIN_impCOSH:
4214 case FFEINTRIN_impDCOSH:
4217 case FFEINTRIN_impDBLE:
4218 case FFEINTRIN_impDFLOAT:
4219 case FFEINTRIN_impDREAL:
4220 case FFEINTRIN_impFLOAT:
4221 case FFEINTRIN_impIDINT:
4222 case FFEINTRIN_impIFIX:
4223 case FFEINTRIN_impINT2:
4224 case FFEINTRIN_impINT8:
4225 case FFEINTRIN_impINT:
4226 case FFEINTRIN_impLONG:
4227 case FFEINTRIN_impREAL:
4228 case FFEINTRIN_impSHORT:
4229 case FFEINTRIN_impSNGL:
4230 return convert (tree_type, ffecom_expr (arg1));
4232 case FFEINTRIN_impDIM:
4233 case FFEINTRIN_impDDIM:
4234 case FFEINTRIN_impIDIM:
4235 saved_expr1 = ffecom_save_tree (convert (tree_type,
4236 ffecom_expr (arg1)));
4237 saved_expr2 = ffecom_save_tree (convert (tree_type,
4238 ffecom_expr (arg2)));
4240 ffecom_3 (COND_EXPR, tree_type,
4242 (ffecom_2 (GT_EXPR, integer_type_node,
4245 ffecom_2 (MINUS_EXPR, tree_type,
4248 convert (tree_type, ffecom_float_zero_));
4250 case FFEINTRIN_impDPROD:
4252 ffecom_2 (MULT_EXPR, tree_type,
4253 convert (tree_type, ffecom_expr (arg1)),
4254 convert (tree_type, ffecom_expr (arg2)));
4256 case FFEINTRIN_impEXP:
4257 case FFEINTRIN_impCDEXP:
4258 case FFEINTRIN_impCEXP:
4259 case FFEINTRIN_impDEXP:
4260 if (bt == FFEINFO_basictypeCOMPLEX)
4262 if (kt == FFEINFO_kindtypeREAL1)
4263 gfrt = FFECOM_gfrtCEXP; /* Overlapping result okay. */
4264 else if (kt == FFEINFO_kindtypeREAL2)
4265 gfrt = FFECOM_gfrtCDEXP; /* Overlapping result okay. */
4269 case FFEINTRIN_impICHAR:
4270 case FFEINTRIN_impIACHAR:
4271 #if 0 /* The simple approach. */
4272 ffecom_char_args_ (&expr_tree, &saved_expr1 /* Ignored */ , arg1);
4274 = ffecom_1 (INDIRECT_REF,
4275 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
4278 = ffecom_2 (ARRAY_REF,
4279 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
4282 return convert (tree_type, expr_tree);
4283 #else /* The more interesting (and more optimal) approach. */
4284 expr_tree = ffecom_intrinsic_ichar_ (tree_type, arg1, &saved_expr1);
4285 expr_tree = ffecom_3 (COND_EXPR, tree_type,
4288 convert (tree_type, integer_zero_node));
4292 case FFEINTRIN_impINDEX:
4295 case FFEINTRIN_impLEN:
4297 break; /* The simple approach. */
4299 return ffecom_intrinsic_len_ (arg1); /* The more optimal approach. */
4302 case FFEINTRIN_impLGE:
4303 case FFEINTRIN_impLGT:
4304 case FFEINTRIN_impLLE:
4305 case FFEINTRIN_impLLT:
4308 case FFEINTRIN_impLOG:
4309 case FFEINTRIN_impALOG:
4310 case FFEINTRIN_impCDLOG:
4311 case FFEINTRIN_impCLOG:
4312 case FFEINTRIN_impDLOG:
4313 if (bt == FFEINFO_basictypeCOMPLEX)
4315 if (kt == FFEINFO_kindtypeREAL1)
4316 gfrt = FFECOM_gfrtCLOG; /* Overlapping result okay. */
4317 else if (kt == FFEINFO_kindtypeREAL2)
4318 gfrt = FFECOM_gfrtCDLOG; /* Overlapping result okay. */
4322 case FFEINTRIN_impLOG10:
4323 case FFEINTRIN_impALOG10:
4324 case FFEINTRIN_impDLOG10:
4325 if (gfrt != FFECOM_gfrt)
4326 break; /* Already picked one, stick with it. */
4328 if (kt == FFEINFO_kindtypeREAL1)
4329 gfrt = FFECOM_gfrtALOG10;
4330 else if (kt == FFEINFO_kindtypeREAL2)
4331 gfrt = FFECOM_gfrtDLOG10;
4334 case FFEINTRIN_impMAX:
4335 case FFEINTRIN_impAMAX0:
4336 case FFEINTRIN_impAMAX1:
4337 case FFEINTRIN_impDMAX1:
4338 case FFEINTRIN_impMAX0:
4339 case FFEINTRIN_impMAX1:
4340 if (bt != ffeinfo_basictype (ffebld_info (arg1)))
4341 arg1_type = ffecom_widest_expr_type_ (ffebld_right (expr));
4343 arg1_type = tree_type;
4344 expr_tree = ffecom_2 (MAX_EXPR, arg1_type,
4345 convert (arg1_type, ffecom_expr (arg1)),
4346 convert (arg1_type, ffecom_expr (arg2)));
4347 for (; list != NULL; list = ffebld_trail (list))
4349 if ((ffebld_head (list) == NULL)
4350 || (ffebld_op (ffebld_head (list)) == FFEBLD_opANY))
4352 expr_tree = ffecom_2 (MAX_EXPR, arg1_type,
4355 ffecom_expr (ffebld_head (list))));
4357 return convert (tree_type, expr_tree);
4359 case FFEINTRIN_impMIN:
4360 case FFEINTRIN_impAMIN0:
4361 case FFEINTRIN_impAMIN1:
4362 case FFEINTRIN_impDMIN1:
4363 case FFEINTRIN_impMIN0:
4364 case FFEINTRIN_impMIN1:
4365 if (bt != ffeinfo_basictype (ffebld_info (arg1)))
4366 arg1_type = ffecom_widest_expr_type_ (ffebld_right (expr));
4368 arg1_type = tree_type;
4369 expr_tree = ffecom_2 (MIN_EXPR, arg1_type,
4370 convert (arg1_type, ffecom_expr (arg1)),
4371 convert (arg1_type, ffecom_expr (arg2)));
4372 for (; list != NULL; list = ffebld_trail (list))
4374 if ((ffebld_head (list) == NULL)
4375 || (ffebld_op (ffebld_head (list)) == FFEBLD_opANY))
4377 expr_tree = ffecom_2 (MIN_EXPR, arg1_type,
4380 ffecom_expr (ffebld_head (list))));
4382 return convert (tree_type, expr_tree);
4384 case FFEINTRIN_impMOD:
4385 case FFEINTRIN_impAMOD:
4386 case FFEINTRIN_impDMOD:
4387 if (bt != FFEINFO_basictypeREAL)
4388 return ffecom_2 (TRUNC_MOD_EXPR, tree_type,
4389 convert (tree_type, ffecom_expr (arg1)),
4390 convert (tree_type, ffecom_expr (arg2)));
4392 if (kt == FFEINFO_kindtypeREAL1)
4393 gfrt = FFECOM_gfrtAMOD;
4394 else if (kt == FFEINFO_kindtypeREAL2)
4395 gfrt = FFECOM_gfrtDMOD;
4398 case FFEINTRIN_impNINT:
4399 case FFEINTRIN_impIDNINT:
4401 /* ~~Ideally FIX_ROUND_EXPR would be implemented, but it ain't yet. */
4402 return ffecom_1 (FIX_ROUND_EXPR, tree_type, ffecom_expr (arg1));
4404 /* i__1 = r1 >= 0 ? floor(r1 + .5) : -floor(.5 - r1); */
4405 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
4407 convert (ffecom_integer_type_node,
4408 ffecom_3 (COND_EXPR, arg1_type,
4410 (ffecom_2 (GE_EXPR, integer_type_node,
4413 ffecom_float_zero_))),
4414 ffecom_2 (PLUS_EXPR, arg1_type,
4417 ffecom_float_half_)),
4418 ffecom_2 (MINUS_EXPR, arg1_type,
4421 ffecom_float_half_))));
4424 case FFEINTRIN_impSIGN:
4425 case FFEINTRIN_impDSIGN:
4426 case FFEINTRIN_impISIGN:
4428 tree arg2_tree = ffecom_expr (arg2);
4432 (ffecom_1 (ABS_EXPR, tree_type,
4434 ffecom_expr (arg1))));
4436 = ffecom_3 (COND_EXPR, tree_type,
4438 (ffecom_2 (GE_EXPR, integer_type_node,
4440 convert (TREE_TYPE (arg2_tree),
4441 integer_zero_node))),
4443 ffecom_1 (NEGATE_EXPR, tree_type, saved_expr1));
4444 /* Make sure SAVE_EXPRs get referenced early enough. */
4446 = ffecom_2 (COMPOUND_EXPR, tree_type,
4447 convert (void_type_node, saved_expr1),
4452 case FFEINTRIN_impSIN:
4453 case FFEINTRIN_impCDSIN:
4454 case FFEINTRIN_impCSIN:
4455 case FFEINTRIN_impDSIN:
4456 if (bt == FFEINFO_basictypeCOMPLEX)
4458 if (kt == FFEINFO_kindtypeREAL1)
4459 gfrt = FFECOM_gfrtCSIN; /* Overlapping result okay. */
4460 else if (kt == FFEINFO_kindtypeREAL2)
4461 gfrt = FFECOM_gfrtCDSIN; /* Overlapping result okay. */
4465 case FFEINTRIN_impSINH:
4466 case FFEINTRIN_impDSINH:
4469 case FFEINTRIN_impSQRT:
4470 case FFEINTRIN_impCDSQRT:
4471 case FFEINTRIN_impCSQRT:
4472 case FFEINTRIN_impDSQRT:
4473 if (bt == FFEINFO_basictypeCOMPLEX)
4475 if (kt == FFEINFO_kindtypeREAL1)
4476 gfrt = FFECOM_gfrtCSQRT; /* Overlapping result okay. */
4477 else if (kt == FFEINFO_kindtypeREAL2)
4478 gfrt = FFECOM_gfrtCDSQRT; /* Overlapping result okay. */
4482 case FFEINTRIN_impTAN:
4483 case FFEINTRIN_impDTAN:
4484 case FFEINTRIN_impTANH:
4485 case FFEINTRIN_impDTANH:
4488 case FFEINTRIN_impREALPART:
4489 if (TREE_CODE (arg1_type) == COMPLEX_TYPE)
4490 arg1_type = TREE_TYPE (arg1_type);
4492 arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type));
4496 ffecom_1 (REALPART_EXPR, arg1_type,
4497 ffecom_expr (arg1)));
4499 case FFEINTRIN_impIAND:
4500 case FFEINTRIN_impAND:
4501 return ffecom_2 (BIT_AND_EXPR, tree_type,
4503 ffecom_expr (arg1)),
4505 ffecom_expr (arg2)));
4507 case FFEINTRIN_impIOR:
4508 case FFEINTRIN_impOR:
4509 return ffecom_2 (BIT_IOR_EXPR, tree_type,
4511 ffecom_expr (arg1)),
4513 ffecom_expr (arg2)));
4515 case FFEINTRIN_impIEOR:
4516 case FFEINTRIN_impXOR:
4517 return ffecom_2 (BIT_XOR_EXPR, tree_type,
4519 ffecom_expr (arg1)),
4521 ffecom_expr (arg2)));
4523 case FFEINTRIN_impLSHIFT:
4524 return ffecom_2 (LSHIFT_EXPR, tree_type,
4526 convert (integer_type_node,
4527 ffecom_expr (arg2)));
4529 case FFEINTRIN_impRSHIFT:
4530 return ffecom_2 (RSHIFT_EXPR, tree_type,
4532 convert (integer_type_node,
4533 ffecom_expr (arg2)));
4535 case FFEINTRIN_impNOT:
4536 return ffecom_1 (BIT_NOT_EXPR, tree_type, ffecom_expr (arg1));
4538 case FFEINTRIN_impBIT_SIZE:
4539 return convert (tree_type, TYPE_SIZE (arg1_type));
4541 case FFEINTRIN_impBTEST:
4543 ffetargetLogical1 true;
4544 ffetargetLogical1 false;
4548 ffetarget_logical1 (&true, TRUE);
4549 ffetarget_logical1 (&false, FALSE);
4551 true_tree = convert (tree_type, integer_one_node);
4553 true_tree = convert (tree_type, build_int_2 (true, 0));
4555 false_tree = convert (tree_type, integer_zero_node);
4557 false_tree = convert (tree_type, build_int_2 (false, 0));
4560 ffecom_3 (COND_EXPR, tree_type,
4562 (ffecom_2 (EQ_EXPR, integer_type_node,
4563 ffecom_2 (BIT_AND_EXPR, arg1_type,
4565 ffecom_2 (LSHIFT_EXPR, arg1_type,
4568 convert (integer_type_node,
4569 ffecom_expr (arg2)))),
4571 integer_zero_node))),
4576 case FFEINTRIN_impIBCLR:
4578 ffecom_2 (BIT_AND_EXPR, tree_type,
4580 ffecom_1 (BIT_NOT_EXPR, tree_type,
4581 ffecom_2 (LSHIFT_EXPR, tree_type,
4584 convert (integer_type_node,
4585 ffecom_expr (arg2)))));
4587 case FFEINTRIN_impIBITS:
4589 tree arg3_tree = ffecom_save_tree (convert (integer_type_node,
4590 ffecom_expr (arg3)));
4592 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4595 = ffecom_2 (BIT_AND_EXPR, tree_type,
4596 ffecom_2 (RSHIFT_EXPR, tree_type,
4598 convert (integer_type_node,
4599 ffecom_expr (arg2))),
4601 ffecom_2 (RSHIFT_EXPR, uns_type,
4602 ffecom_1 (BIT_NOT_EXPR,
4605 integer_zero_node)),
4606 ffecom_2 (MINUS_EXPR,
4608 TYPE_SIZE (uns_type),
4610 #if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4612 = ffecom_3 (COND_EXPR, tree_type,
4614 (ffecom_2 (NE_EXPR, integer_type_node,
4616 integer_zero_node)),
4618 convert (tree_type, integer_zero_node));
4623 case FFEINTRIN_impIBSET:
4625 ffecom_2 (BIT_IOR_EXPR, tree_type,
4627 ffecom_2 (LSHIFT_EXPR, tree_type,
4628 convert (tree_type, integer_one_node),
4629 convert (integer_type_node,
4630 ffecom_expr (arg2))));
4632 case FFEINTRIN_impISHFT:
4634 tree arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4635 tree arg2_tree = ffecom_save_tree (convert (integer_type_node,
4636 ffecom_expr (arg2)));
4638 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4641 = ffecom_3 (COND_EXPR, tree_type,
4643 (ffecom_2 (GE_EXPR, integer_type_node,
4645 integer_zero_node)),
4646 ffecom_2 (LSHIFT_EXPR, tree_type,
4650 ffecom_2 (RSHIFT_EXPR, uns_type,
4651 convert (uns_type, arg1_tree),
4652 ffecom_1 (NEGATE_EXPR,
4655 #if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4657 = ffecom_3 (COND_EXPR, tree_type,
4659 (ffecom_2 (NE_EXPR, integer_type_node,
4661 TYPE_SIZE (uns_type))),
4663 convert (tree_type, integer_zero_node));
4665 /* Make sure SAVE_EXPRs get referenced early enough. */
4667 = ffecom_2 (COMPOUND_EXPR, tree_type,
4668 convert (void_type_node, arg1_tree),
4669 ffecom_2 (COMPOUND_EXPR, tree_type,
4670 convert (void_type_node, arg2_tree),
4675 case FFEINTRIN_impISHFTC:
4677 tree arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4678 tree arg2_tree = ffecom_save_tree (convert (integer_type_node,
4679 ffecom_expr (arg2)));
4680 tree arg3_tree = (arg3 == NULL) ? TYPE_SIZE (tree_type)
4681 : ffecom_save_tree (convert (integer_type_node, ffecom_expr (arg3)));
4687 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4690 = ffecom_2 (LSHIFT_EXPR, tree_type,
4691 ffecom_1 (BIT_NOT_EXPR, tree_type,
4692 convert (tree_type, integer_zero_node)),
4694 #if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4696 = ffecom_3 (COND_EXPR, tree_type,
4698 (ffecom_2 (NE_EXPR, integer_type_node,
4700 TYPE_SIZE (uns_type))),
4702 convert (tree_type, integer_zero_node));
4704 mask_arg1 = ffecom_save_tree (mask_arg1);
4706 = ffecom_2 (BIT_AND_EXPR, tree_type,
4708 ffecom_1 (BIT_NOT_EXPR, tree_type,
4710 masked_arg1 = ffecom_save_tree (masked_arg1);
4712 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4714 ffecom_2 (RSHIFT_EXPR, uns_type,
4715 convert (uns_type, masked_arg1),
4716 ffecom_1 (NEGATE_EXPR,
4719 ffecom_2 (LSHIFT_EXPR, tree_type,
4721 ffecom_2 (PLUS_EXPR, integer_type_node,
4725 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4726 ffecom_2 (LSHIFT_EXPR, tree_type,
4730 ffecom_2 (RSHIFT_EXPR, uns_type,
4731 convert (uns_type, masked_arg1),
4732 ffecom_2 (MINUS_EXPR,
4737 = ffecom_3 (COND_EXPR, tree_type,
4739 (ffecom_2 (LT_EXPR, integer_type_node,
4741 integer_zero_node)),
4745 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4746 ffecom_2 (BIT_AND_EXPR, tree_type,
4749 ffecom_2 (BIT_AND_EXPR, tree_type,
4750 ffecom_1 (BIT_NOT_EXPR, tree_type,
4754 = ffecom_3 (COND_EXPR, tree_type,
4756 (ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
4757 ffecom_2 (EQ_EXPR, integer_type_node,
4762 ffecom_2 (EQ_EXPR, integer_type_node,
4764 integer_zero_node))),
4767 /* Make sure SAVE_EXPRs get referenced early enough. */
4769 = ffecom_2 (COMPOUND_EXPR, tree_type,
4770 convert (void_type_node, arg1_tree),
4771 ffecom_2 (COMPOUND_EXPR, tree_type,
4772 convert (void_type_node, arg2_tree),
4773 ffecom_2 (COMPOUND_EXPR, tree_type,
4774 convert (void_type_node,
4776 ffecom_2 (COMPOUND_EXPR, tree_type,
4777 convert (void_type_node,
4781 = ffecom_2 (COMPOUND_EXPR, tree_type,
4782 convert (void_type_node,
4788 case FFEINTRIN_impLOC:
4790 tree arg1_tree = ffecom_expr (arg1);
4793 = convert (tree_type,
4794 ffecom_1 (ADDR_EXPR,
4795 build_pointer_type (TREE_TYPE (arg1_tree)),
4800 case FFEINTRIN_impMVBITS:
4805 ffebld arg4 = ffebld_head (ffebld_trail (list));
4808 ffebld arg5 = ffebld_head (ffebld_trail (ffebld_trail (list)));
4812 tree arg5_plus_arg3;
4814 arg2_tree = convert (integer_type_node,
4815 ffecom_expr (arg2));
4816 arg3_tree = ffecom_save_tree (convert (integer_type_node,
4817 ffecom_expr (arg3)));
4818 arg4_tree = ffecom_expr_rw (NULL_TREE, arg4);
4819 arg4_type = TREE_TYPE (arg4_tree);
4821 arg1_tree = ffecom_save_tree (convert (arg4_type,
4822 ffecom_expr (arg1)));
4824 arg5_tree = ffecom_save_tree (convert (integer_type_node,
4825 ffecom_expr (arg5)));
4828 = ffecom_2 (LSHIFT_EXPR, arg4_type,
4829 ffecom_2 (BIT_AND_EXPR, arg4_type,
4830 ffecom_2 (RSHIFT_EXPR, arg4_type,
4833 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4834 ffecom_2 (LSHIFT_EXPR, arg4_type,
4835 ffecom_1 (BIT_NOT_EXPR,
4839 integer_zero_node)),
4843 = ffecom_save_tree (ffecom_2 (PLUS_EXPR, arg4_type,
4847 = ffecom_2 (LSHIFT_EXPR, arg4_type,
4848 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4850 integer_zero_node)),
4852 #if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4854 = ffecom_3 (COND_EXPR, arg4_type,
4856 (ffecom_2 (NE_EXPR, integer_type_node,
4858 convert (TREE_TYPE (arg5_plus_arg3),
4859 TYPE_SIZE (arg4_type)))),
4861 convert (arg4_type, integer_zero_node));
4864 = ffecom_2 (BIT_AND_EXPR, arg4_type,
4866 ffecom_2 (BIT_IOR_EXPR, arg4_type,
4868 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4869 ffecom_2 (LSHIFT_EXPR, arg4_type,
4870 ffecom_1 (BIT_NOT_EXPR,
4874 integer_zero_node)),
4877 = ffecom_2 (BIT_IOR_EXPR, arg4_type,
4880 #if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4882 = ffecom_3 (COND_EXPR, arg4_type,
4884 (ffecom_2 (NE_EXPR, integer_type_node,
4886 convert (TREE_TYPE (arg3_tree),
4887 integer_zero_node))),
4891 = ffecom_3 (COND_EXPR, arg4_type,
4893 (ffecom_2 (NE_EXPR, integer_type_node,
4895 convert (TREE_TYPE (arg3_tree),
4896 TYPE_SIZE (arg4_type)))),
4901 = ffecom_2s (MODIFY_EXPR, void_type_node,
4904 /* Make sure SAVE_EXPRs get referenced early enough. */
4906 = ffecom_2 (COMPOUND_EXPR, void_type_node,
4908 ffecom_2 (COMPOUND_EXPR, void_type_node,
4910 ffecom_2 (COMPOUND_EXPR, void_type_node,
4912 ffecom_2 (COMPOUND_EXPR, void_type_node,
4916 = ffecom_2 (COMPOUND_EXPR, void_type_node,
4923 case FFEINTRIN_impDERF:
4924 case FFEINTRIN_impERF:
4925 case FFEINTRIN_impDERFC:
4926 case FFEINTRIN_impERFC:
4929 case FFEINTRIN_impIARGC:
4930 /* extern int xargc; i__1 = xargc - 1; */
4931 expr_tree = ffecom_2 (MINUS_EXPR, TREE_TYPE (ffecom_tree_xargc_),
4933 convert (TREE_TYPE (ffecom_tree_xargc_),
4937 case FFEINTRIN_impSIGNAL_func:
4938 case FFEINTRIN_impSIGNAL_subr:
4944 arg1_tree = convert (ffecom_f2c_integer_type_node,
4945 ffecom_expr (arg1));
4946 arg1_tree = ffecom_1 (ADDR_EXPR,
4947 build_pointer_type (TREE_TYPE (arg1_tree)),
4950 /* Pass procedure as a pointer to it, anything else by value. */
4951 if (ffeinfo_kind (ffebld_info (arg2)) == FFEINFO_kindENTITY)
4952 arg2_tree = convert (integer_type_node, ffecom_expr (arg2));
4954 arg2_tree = ffecom_ptr_to_expr (arg2);
4955 arg2_tree = convert (TREE_TYPE (null_pointer_node),
4959 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
4961 arg3_tree = NULL_TREE;
4963 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4964 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
4965 TREE_CHAIN (arg1_tree) = arg2_tree;
4968 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4969 ffecom_gfrt_kindtype (gfrt),
4971 ((codegen_imp == FFEINTRIN_impSIGNAL_subr) ?
4975 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4976 ffebld_nonter_hook (expr));
4978 if (arg3_tree != NULL_TREE)
4980 = ffecom_modify (NULL_TREE, arg3_tree,
4981 convert (TREE_TYPE (arg3_tree),
4986 case FFEINTRIN_impALARM:
4992 arg1_tree = convert (ffecom_f2c_integer_type_node,
4993 ffecom_expr (arg1));
4994 arg1_tree = ffecom_1 (ADDR_EXPR,
4995 build_pointer_type (TREE_TYPE (arg1_tree)),
4998 /* Pass procedure as a pointer to it, anything else by value. */
4999 if (ffeinfo_kind (ffebld_info (arg2)) == FFEINFO_kindENTITY)
5000 arg2_tree = convert (integer_type_node, ffecom_expr (arg2));
5002 arg2_tree = ffecom_ptr_to_expr (arg2);
5003 arg2_tree = convert (TREE_TYPE (null_pointer_node),
5007 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5009 arg3_tree = NULL_TREE;
5011 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5012 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5013 TREE_CHAIN (arg1_tree) = arg2_tree;
5016 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5017 ffecom_gfrt_kindtype (gfrt),
5021 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5022 ffebld_nonter_hook (expr));
5024 if (arg3_tree != NULL_TREE)
5026 = ffecom_modify (NULL_TREE, arg3_tree,
5027 convert (TREE_TYPE (arg3_tree),
5032 case FFEINTRIN_impCHDIR_subr:
5033 case FFEINTRIN_impFDATE_subr:
5034 case FFEINTRIN_impFGET_subr:
5035 case FFEINTRIN_impFPUT_subr:
5036 case FFEINTRIN_impGETCWD_subr:
5037 case FFEINTRIN_impHOSTNM_subr:
5038 case FFEINTRIN_impSYSTEM_subr:
5039 case FFEINTRIN_impUNLINK_subr:
5041 tree arg1_len = integer_zero_node;
5045 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
5048 arg2_tree = ffecom_expr_w (NULL_TREE, arg2);
5050 arg2_tree = NULL_TREE;
5052 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5053 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5054 TREE_CHAIN (arg1_tree) = arg1_len;
5057 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5058 ffecom_gfrt_kindtype (gfrt),
5062 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5063 ffebld_nonter_hook (expr));
5065 if (arg2_tree != NULL_TREE)
5067 = ffecom_modify (NULL_TREE, arg2_tree,
5068 convert (TREE_TYPE (arg2_tree),
5073 case FFEINTRIN_impEXIT:
5077 expr_tree = build_tree_list (NULL_TREE,
5078 ffecom_1 (ADDR_EXPR,
5080 (ffecom_integer_type_node),
5081 integer_zero_node));
5084 ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5085 ffecom_gfrt_kindtype (gfrt),
5089 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5090 ffebld_nonter_hook (expr));
5092 case FFEINTRIN_impFLUSH:
5094 gfrt = FFECOM_gfrtFLUSH;
5096 gfrt = FFECOM_gfrtFLUSH1;
5099 case FFEINTRIN_impCHMOD_subr:
5100 case FFEINTRIN_impLINK_subr:
5101 case FFEINTRIN_impRENAME_subr:
5102 case FFEINTRIN_impSYMLNK_subr:
5104 tree arg1_len = integer_zero_node;
5106 tree arg2_len = integer_zero_node;
5110 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
5111 arg2_tree = ffecom_arg_ptr_to_expr (arg2, &arg2_len);
5113 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5115 arg3_tree = NULL_TREE;
5117 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5118 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5119 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5120 arg2_len = build_tree_list (NULL_TREE, arg2_len);
5121 TREE_CHAIN (arg1_tree) = arg2_tree;
5122 TREE_CHAIN (arg2_tree) = arg1_len;
5123 TREE_CHAIN (arg1_len) = arg2_len;
5124 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5125 ffecom_gfrt_kindtype (gfrt),
5129 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5130 ffebld_nonter_hook (expr));
5131 if (arg3_tree != NULL_TREE)
5132 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5133 convert (TREE_TYPE (arg3_tree),
5138 case FFEINTRIN_impLSTAT_subr:
5139 case FFEINTRIN_impSTAT_subr:
5141 tree arg1_len = integer_zero_node;
5146 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
5148 arg2_tree = ffecom_ptr_to_expr (arg2);
5151 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5153 arg3_tree = NULL_TREE;
5155 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5156 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5157 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5158 TREE_CHAIN (arg1_tree) = arg2_tree;
5159 TREE_CHAIN (arg2_tree) = arg1_len;
5160 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5161 ffecom_gfrt_kindtype (gfrt),
5165 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5166 ffebld_nonter_hook (expr));
5167 if (arg3_tree != NULL_TREE)
5168 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5169 convert (TREE_TYPE (arg3_tree),
5174 case FFEINTRIN_impFGETC_subr:
5175 case FFEINTRIN_impFPUTC_subr:
5179 tree arg2_len = integer_zero_node;
5182 arg1_tree = convert (ffecom_f2c_integer_type_node,
5183 ffecom_expr (arg1));
5184 arg1_tree = ffecom_1 (ADDR_EXPR,
5185 build_pointer_type (TREE_TYPE (arg1_tree)),
5188 arg2_tree = ffecom_arg_ptr_to_expr (arg2, &arg2_len);
5189 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5191 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5192 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5193 arg2_len = build_tree_list (NULL_TREE, arg2_len);
5194 TREE_CHAIN (arg1_tree) = arg2_tree;
5195 TREE_CHAIN (arg2_tree) = arg2_len;
5197 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5198 ffecom_gfrt_kindtype (gfrt),
5202 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5203 ffebld_nonter_hook (expr));
5204 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5205 convert (TREE_TYPE (arg3_tree),
5210 case FFEINTRIN_impFSTAT_subr:
5216 arg1_tree = convert (ffecom_f2c_integer_type_node,
5217 ffecom_expr (arg1));
5218 arg1_tree = ffecom_1 (ADDR_EXPR,
5219 build_pointer_type (TREE_TYPE (arg1_tree)),
5222 arg2_tree = convert (ffecom_f2c_ptr_to_integer_type_node,
5223 ffecom_ptr_to_expr (arg2));
5226 arg3_tree = NULL_TREE;
5228 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5230 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5231 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5232 TREE_CHAIN (arg1_tree) = arg2_tree;
5233 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5234 ffecom_gfrt_kindtype (gfrt),
5238 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5239 ffebld_nonter_hook (expr));
5240 if (arg3_tree != NULL_TREE) {
5241 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5242 convert (TREE_TYPE (arg3_tree),
5248 case FFEINTRIN_impKILL_subr:
5254 arg1_tree = convert (ffecom_f2c_integer_type_node,
5255 ffecom_expr (arg1));
5256 arg1_tree = ffecom_1 (ADDR_EXPR,
5257 build_pointer_type (TREE_TYPE (arg1_tree)),
5260 arg2_tree = convert (ffecom_f2c_integer_type_node,
5261 ffecom_expr (arg2));
5262 arg2_tree = ffecom_1 (ADDR_EXPR,
5263 build_pointer_type (TREE_TYPE (arg2_tree)),
5267 arg3_tree = NULL_TREE;
5269 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5271 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5272 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5273 TREE_CHAIN (arg1_tree) = arg2_tree;
5274 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5275 ffecom_gfrt_kindtype (gfrt),
5279 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5280 ffebld_nonter_hook (expr));
5281 if (arg3_tree != NULL_TREE) {
5282 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5283 convert (TREE_TYPE (arg3_tree),
5289 case FFEINTRIN_impCTIME_subr:
5290 case FFEINTRIN_impTTYNAM_subr:
5292 tree arg1_len = integer_zero_node;
5296 arg1_tree = ffecom_arg_ptr_to_expr (arg2, &arg1_len);
5298 arg2_tree = convert (((codegen_imp == FFEINTRIN_impCTIME_subr) ?
5299 ffecom_f2c_longint_type_node :
5300 ffecom_f2c_integer_type_node),
5301 ffecom_expr (arg1));
5302 arg2_tree = ffecom_1 (ADDR_EXPR,
5303 build_pointer_type (TREE_TYPE (arg2_tree)),
5306 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5307 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5308 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5309 TREE_CHAIN (arg1_len) = arg2_tree;
5310 TREE_CHAIN (arg1_tree) = arg1_len;
5313 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5314 ffecom_gfrt_kindtype (gfrt),
5318 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5319 ffebld_nonter_hook (expr));
5320 TREE_SIDE_EFFECTS (expr_tree) = 1;
5324 case FFEINTRIN_impIRAND:
5325 case FFEINTRIN_impRAND:
5326 /* Arg defaults to 0 (normal random case) */
5331 arg1_tree = ffecom_integer_zero_node;
5333 arg1_tree = ffecom_expr (arg1);
5334 arg1_tree = convert (ffecom_f2c_integer_type_node,
5336 arg1_tree = ffecom_1 (ADDR_EXPR,
5337 build_pointer_type (TREE_TYPE (arg1_tree)),
5339 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5341 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5342 ffecom_gfrt_kindtype (gfrt),
5344 ((codegen_imp == FFEINTRIN_impIRAND) ?
5345 ffecom_f2c_integer_type_node :
5346 ffecom_f2c_real_type_node),
5348 dest_tree, dest, dest_used,
5350 ffebld_nonter_hook (expr));
5354 case FFEINTRIN_impFTELL_subr:
5355 case FFEINTRIN_impUMASK_subr:
5360 arg1_tree = convert (ffecom_f2c_integer_type_node,
5361 ffecom_expr (arg1));
5362 arg1_tree = ffecom_1 (ADDR_EXPR,
5363 build_pointer_type (TREE_TYPE (arg1_tree)),
5367 arg2_tree = NULL_TREE;
5369 arg2_tree = ffecom_expr_w (NULL_TREE, arg2);
5371 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5372 ffecom_gfrt_kindtype (gfrt),
5375 build_tree_list (NULL_TREE, arg1_tree),
5376 NULL_TREE, NULL, NULL, NULL_TREE,
5378 ffebld_nonter_hook (expr));
5379 if (arg2_tree != NULL_TREE) {
5380 expr_tree = ffecom_modify (NULL_TREE, arg2_tree,
5381 convert (TREE_TYPE (arg2_tree),
5387 case FFEINTRIN_impCPU_TIME:
5388 case FFEINTRIN_impSECOND_subr:
5392 arg1_tree = ffecom_expr_w (NULL_TREE, arg1);
5395 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5396 ffecom_gfrt_kindtype (gfrt),
5400 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5401 ffebld_nonter_hook (expr));
5404 = ffecom_modify (NULL_TREE, arg1_tree,
5405 convert (TREE_TYPE (arg1_tree),
5410 case FFEINTRIN_impDTIME_subr:
5411 case FFEINTRIN_impETIME_subr:
5416 result_tree = ffecom_expr_w (NULL_TREE, arg2);
5418 arg1_tree = ffecom_ptr_to_expr (arg1);
5420 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5421 ffecom_gfrt_kindtype (gfrt),
5424 build_tree_list (NULL_TREE, arg1_tree),
5425 NULL_TREE, NULL, NULL, NULL_TREE,
5427 ffebld_nonter_hook (expr));
5428 expr_tree = ffecom_modify (NULL_TREE, result_tree,
5429 convert (TREE_TYPE (result_tree),
5434 /* Straightforward calls of libf2c routines: */
5435 case FFEINTRIN_impABORT:
5436 case FFEINTRIN_impACCESS:
5437 case FFEINTRIN_impBESJ0:
5438 case FFEINTRIN_impBESJ1:
5439 case FFEINTRIN_impBESJN:
5440 case FFEINTRIN_impBESY0:
5441 case FFEINTRIN_impBESY1:
5442 case FFEINTRIN_impBESYN:
5443 case FFEINTRIN_impCHDIR_func:
5444 case FFEINTRIN_impCHMOD_func:
5445 case FFEINTRIN_impDATE:
5446 case FFEINTRIN_impDATE_AND_TIME:
5447 case FFEINTRIN_impDBESJ0:
5448 case FFEINTRIN_impDBESJ1:
5449 case FFEINTRIN_impDBESJN:
5450 case FFEINTRIN_impDBESY0:
5451 case FFEINTRIN_impDBESY1:
5452 case FFEINTRIN_impDBESYN:
5453 case FFEINTRIN_impDTIME_func:
5454 case FFEINTRIN_impETIME_func:
5455 case FFEINTRIN_impFGETC_func:
5456 case FFEINTRIN_impFGET_func:
5457 case FFEINTRIN_impFNUM:
5458 case FFEINTRIN_impFPUTC_func:
5459 case FFEINTRIN_impFPUT_func:
5460 case FFEINTRIN_impFSEEK:
5461 case FFEINTRIN_impFSTAT_func:
5462 case FFEINTRIN_impFTELL_func:
5463 case FFEINTRIN_impGERROR:
5464 case FFEINTRIN_impGETARG:
5465 case FFEINTRIN_impGETCWD_func:
5466 case FFEINTRIN_impGETENV:
5467 case FFEINTRIN_impGETGID:
5468 case FFEINTRIN_impGETLOG:
5469 case FFEINTRIN_impGETPID:
5470 case FFEINTRIN_impGETUID:
5471 case FFEINTRIN_impGMTIME:
5472 case FFEINTRIN_impHOSTNM_func:
5473 case FFEINTRIN_impIDATE_unix:
5474 case FFEINTRIN_impIDATE_vxt:
5475 case FFEINTRIN_impIERRNO:
5476 case FFEINTRIN_impISATTY:
5477 case FFEINTRIN_impITIME:
5478 case FFEINTRIN_impKILL_func:
5479 case FFEINTRIN_impLINK_func:
5480 case FFEINTRIN_impLNBLNK:
5481 case FFEINTRIN_impLSTAT_func:
5482 case FFEINTRIN_impLTIME:
5483 case FFEINTRIN_impMCLOCK8:
5484 case FFEINTRIN_impMCLOCK:
5485 case FFEINTRIN_impPERROR:
5486 case FFEINTRIN_impRENAME_func:
5487 case FFEINTRIN_impSECNDS:
5488 case FFEINTRIN_impSECOND_func:
5489 case FFEINTRIN_impSLEEP:
5490 case FFEINTRIN_impSRAND:
5491 case FFEINTRIN_impSTAT_func:
5492 case FFEINTRIN_impSYMLNK_func:
5493 case FFEINTRIN_impSYSTEM_CLOCK:
5494 case FFEINTRIN_impSYSTEM_func:
5495 case FFEINTRIN_impTIME8:
5496 case FFEINTRIN_impTIME_unix:
5497 case FFEINTRIN_impTIME_vxt:
5498 case FFEINTRIN_impUMASK_func:
5499 case FFEINTRIN_impUNLINK_func:
5502 case FFEINTRIN_impCTIME_func: /* CHARACTER functions not handled here. */
5503 case FFEINTRIN_impFDATE_func: /* CHARACTER functions not handled here. */
5504 case FFEINTRIN_impTTYNAM_func: /* CHARACTER functions not handled here. */
5505 case FFEINTRIN_impNONE:
5506 case FFEINTRIN_imp: /* Hush up gcc warning. */
5507 fprintf (stderr, "No %s implementation.\n",
5508 ffeintrin_name_implementation (ffebld_symter_implementation (ffebld_left (expr))));
5509 assert ("unimplemented intrinsic" == NULL);
5510 return error_mark_node;
5513 assert (gfrt != FFECOM_gfrt); /* Must have an implementation! */
5515 expr_tree = ffecom_arglist_expr_ (ffecom_gfrt_args_ (gfrt),
5516 ffebld_right (expr));
5518 return ffecom_call_ (ffecom_gfrt_tree_ (gfrt), ffecom_gfrt_kindtype (gfrt),
5519 (ffe_is_f2c_library () && ffecom_gfrt_complex_[gfrt]),
5521 expr_tree, dest_tree, dest, dest_used,
5523 ffebld_nonter_hook (expr));
5525 /* See bottom of this file for f2c transforms used to determine
5526 many of the above implementations. The info seems to confuse
5527 Emacs's C mode indentation, which is why it's been moved to
5528 the bottom of this source file. */
5532 /* For power (exponentiation) where right-hand operand is type INTEGER,
5533 generate in-line code to do it the fast way (which, if the operand
5534 is a constant, might just mean a series of multiplies). */
5536 #if FFECOM_targetCURRENT == FFECOM_targetGCC
5538 ffecom_expr_power_integer_ (ffebld expr)
5540 tree l = ffecom_expr (ffebld_left (expr));
5541 tree r = ffecom_expr (ffebld_right (expr));
5542 tree ltype = TREE_TYPE (l);
5543 tree rtype = TREE_TYPE (r);
5544 tree result = NULL_TREE;
5546 if (l == error_mark_node
5547 || r == error_mark_node)
5548 return error_mark_node;
5550 if (TREE_CODE (r) == INTEGER_CST)
5552 int sgn = tree_int_cst_sgn (r);
5555 return convert (ltype, integer_one_node);
5557 if ((TREE_CODE (ltype) == INTEGER_TYPE)
5560 /* Reciprocal of integer is either 0, -1, or 1, so after
5561 calculating that (which we leave to the back end to do
5562 or not do optimally), don't bother with any multiplying. */
5564 result = ffecom_tree_divide_ (ltype,
5565 convert (ltype, integer_one_node),
5567 NULL_TREE, NULL, NULL, NULL_TREE);
5568 r = ffecom_1 (NEGATE_EXPR,
5571 if ((TREE_INT_CST_LOW (r) & 1) == 0)
5572 result = ffecom_1 (ABS_EXPR, rtype,
5576 /* Generate appropriate series of multiplies, preceded
5577 by divide if the exponent is negative. */
5583 l = ffecom_tree_divide_ (ltype,
5584 convert (ltype, integer_one_node),
5586 NULL_TREE, NULL, NULL,
5587 ffebld_nonter_hook (expr));
5588 r = ffecom_1 (NEGATE_EXPR, rtype, r);
5589 assert (TREE_CODE (r) == INTEGER_CST);
5591 if (tree_int_cst_sgn (r) < 0)
5592 { /* The "most negative" number. */
5593 r = ffecom_1 (NEGATE_EXPR, rtype,
5594 ffecom_2 (RSHIFT_EXPR, rtype,
5598 l = ffecom_2 (MULT_EXPR, ltype,
5606 if (TREE_INT_CST_LOW (r) & 1)
5608 if (result == NULL_TREE)
5611 result = ffecom_2 (MULT_EXPR, ltype,
5616 r = ffecom_2 (RSHIFT_EXPR, rtype,
5619 if (integer_zerop (r))
5621 assert (TREE_CODE (r) == INTEGER_CST);
5624 l = ffecom_2 (MULT_EXPR, ltype,
5631 /* Though rhs isn't a constant, in-line code cannot be expanded
5632 while transforming dummies
5633 because the back end cannot be easily convinced to generate
5634 stores (MODIFY_EXPR), handle temporaries, and so on before
5635 all the appropriate rtx's have been generated for things like
5636 dummy args referenced in rhs -- which doesn't happen until
5637 store_parm_decls() is called (expand_function_start, I believe,
5638 does the actual rtx-stuffing of PARM_DECLs).
5640 So, in this case, let the caller generate the call to the
5641 run-time-library function to evaluate the power for us. */
5643 if (ffecom_transform_only_dummies_)
5646 /* Right-hand operand not a constant, expand in-line code to figure
5647 out how to do the multiplies, &c.
5649 The returned expression is expressed this way in GNU C, where l and
5652 ({ typeof (r) rtmp = r;
5653 typeof (l) ltmp = l;
5660 if ((basetypeof (l) == basetypeof (int))
5663 result = ((typeof (l)) 1) / ltmp;
5664 if ((ltmp < 0) && (((-rtmp) & 1) == 0))
5670 if ((basetypeof (l) != basetypeof (int))
5673 ltmp = ((typeof (l)) 1) / ltmp;
5677 rtmp = -(rtmp >> 1);
5685 if ((rtmp >>= 1) == 0)
5694 Note that some of the above is compile-time collapsable, such as
5695 the first part of the if statements that checks the base type of
5696 l against int. The if statements are phrased that way to suggest
5697 an easy way to generate the if/else constructs here, knowing that
5698 the back end should (and probably does) eliminate the resulting
5699 dead code (either the int case or the non-int case), something
5700 it couldn't do without the redundant phrasing, requiring explicit
5701 dead-code elimination here, which would be kind of difficult to
5708 tree basetypeof_l_is_int;
5713 = build_int_2 ((TREE_CODE (ltype) == INTEGER_TYPE), 0);
5715 se = expand_start_stmt_expr ();
5717 ffecom_start_compstmt ();
5720 rtmp = ffecom_make_tempvar ("power_r", rtype,
5721 FFETARGET_charactersizeNONE, -1);
5722 ltmp = ffecom_make_tempvar ("power_l", ltype,
5723 FFETARGET_charactersizeNONE, -1);
5724 result = ffecom_make_tempvar ("power_res", ltype,
5725 FFETARGET_charactersizeNONE, -1);
5726 if (TREE_CODE (ltype) == COMPLEX_TYPE
5727 || TREE_CODE (ltype) == RECORD_TYPE)
5728 divide = ffecom_make_tempvar ("power_div", ltype,
5729 FFETARGET_charactersizeNONE, -1);
5736 hook = ffebld_nonter_hook (expr);
5738 assert (TREE_CODE (hook) == TREE_VEC);
5739 assert (TREE_VEC_LENGTH (hook) == 4);
5740 rtmp = TREE_VEC_ELT (hook, 0);
5741 ltmp = TREE_VEC_ELT (hook, 1);
5742 result = TREE_VEC_ELT (hook, 2);
5743 divide = TREE_VEC_ELT (hook, 3);
5744 if (TREE_CODE (ltype) == COMPLEX_TYPE
5745 || TREE_CODE (ltype) == RECORD_TYPE)
5752 expand_expr_stmt (ffecom_modify (void_type_node,
5755 expand_expr_stmt (ffecom_modify (void_type_node,
5758 expand_start_cond (ffecom_truth_value
5759 (ffecom_2 (EQ_EXPR, integer_type_node,
5761 convert (rtype, integer_zero_node))),
5763 expand_expr_stmt (ffecom_modify (void_type_node,
5765 convert (ltype, integer_one_node)));
5766 expand_start_else ();
5767 if (! integer_zerop (basetypeof_l_is_int))
5769 expand_start_cond (ffecom_2 (LT_EXPR, integer_type_node,
5772 integer_zero_node)),
5774 expand_expr_stmt (ffecom_modify (void_type_node,
5778 convert (ltype, integer_one_node),
5780 NULL_TREE, NULL, NULL,
5782 expand_start_cond (ffecom_truth_value
5783 (ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
5784 ffecom_2 (LT_EXPR, integer_type_node,
5787 integer_zero_node)),
5788 ffecom_2 (EQ_EXPR, integer_type_node,
5789 ffecom_2 (BIT_AND_EXPR,
5791 ffecom_1 (NEGATE_EXPR,
5797 integer_zero_node)))),
5799 expand_expr_stmt (ffecom_modify (void_type_node,
5801 ffecom_1 (NEGATE_EXPR,
5805 expand_start_else ();
5807 expand_expr_stmt (ffecom_modify (void_type_node,
5809 convert (ltype, integer_one_node)));
5810 expand_start_cond (ffecom_truth_value
5811 (ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
5812 ffecom_truth_value_invert
5813 (basetypeof_l_is_int),
5814 ffecom_2 (LT_EXPR, integer_type_node,
5817 integer_zero_node)))),
5819 expand_expr_stmt (ffecom_modify (void_type_node,
5823 convert (ltype, integer_one_node),
5825 NULL_TREE, NULL, NULL,
5827 expand_expr_stmt (ffecom_modify (void_type_node,
5829 ffecom_1 (NEGATE_EXPR, rtype,
5831 expand_start_cond (ffecom_truth_value
5832 (ffecom_2 (LT_EXPR, integer_type_node,
5834 convert (rtype, integer_zero_node))),
5836 expand_expr_stmt (ffecom_modify (void_type_node,
5838 ffecom_1 (NEGATE_EXPR, rtype,
5839 ffecom_2 (RSHIFT_EXPR,
5842 integer_one_node))));
5843 expand_expr_stmt (ffecom_modify (void_type_node,
5845 ffecom_2 (MULT_EXPR, ltype,
5850 expand_start_loop (1);
5851 expand_start_cond (ffecom_truth_value
5852 (ffecom_2 (BIT_AND_EXPR, rtype,
5854 convert (rtype, integer_one_node))),
5856 expand_expr_stmt (ffecom_modify (void_type_node,
5858 ffecom_2 (MULT_EXPR, ltype,
5862 expand_exit_loop_if_false (NULL,
5864 (ffecom_modify (rtype,
5866 ffecom_2 (RSHIFT_EXPR,
5869 integer_one_node))));
5870 expand_expr_stmt (ffecom_modify (void_type_node,
5872 ffecom_2 (MULT_EXPR, ltype,
5877 if (!integer_zerop (basetypeof_l_is_int))
5879 expand_expr_stmt (result);
5881 t = ffecom_end_compstmt ();
5883 result = expand_end_stmt_expr (se);
5885 /* This code comes from c-parse.in, after its expand_end_stmt_expr. */
5887 if (TREE_CODE (t) == BLOCK)
5889 /* Make a BIND_EXPR for the BLOCK already made. */
5890 result = build (BIND_EXPR, TREE_TYPE (result),
5891 NULL_TREE, result, t);
5892 /* Remove the block from the tree at this point.
5893 It gets put back at the proper place
5894 when the BIND_EXPR is expanded. */
5905 /* ffecom_expr_transform_ -- Transform symbols in expr
5907 ffebld expr; // FFE expression.
5908 ffecom_expr_transform_ (expr);
5910 Recursive descent on expr while transforming any untransformed SYMTERs. */
5912 #if FFECOM_targetCURRENT == FFECOM_targetGCC
5914 ffecom_expr_transform_ (ffebld expr)
5919 tail_recurse: /* :::::::::::::::::::: */
5924 switch (ffebld_op (expr))
5926 case FFEBLD_opSYMTER:
5927 s = ffebld_symter (expr);
5928 t = ffesymbol_hook (s).decl_tree;
5929 if ((t == NULL_TREE)
5930 && ((ffesymbol_kind (s) != FFEINFO_kindNONE)
5931 || ((ffesymbol_where (s) != FFEINFO_whereNONE)
5932 && (ffesymbol_where (s) != FFEINFO_whereINTRINSIC))))
5934 s = ffecom_sym_transform_ (s);
5935 t = ffesymbol_hook (s).decl_tree; /* Sfunc expr non-dummy,
5938 break; /* Ok if (t == NULL) here. */
5941 ffecom_expr_transform_ (ffebld_head (expr));
5942 expr = ffebld_trail (expr);
5943 goto tail_recurse; /* :::::::::::::::::::: */
5949 switch (ffebld_arity (expr))
5952 ffecom_expr_transform_ (ffebld_left (expr));
5953 expr = ffebld_right (expr);
5954 goto tail_recurse; /* :::::::::::::::::::: */
5957 expr = ffebld_left (expr);
5958 goto tail_recurse; /* :::::::::::::::::::: */
5968 /* Make a type based on info in live f2c.h file. */
5970 #if FFECOM_targetCURRENT == FFECOM_targetGCC
5972 ffecom_f2c_make_type_ (tree *type, int tcode, const char *name)
5976 case FFECOM_f2ccodeCHAR:
5977 *type = make_signed_type (CHAR_TYPE_SIZE);
5980 case FFECOM_f2ccodeSHORT:
5981 *type = make_signed_type (SHORT_TYPE_SIZE);
5984 case FFECOM_f2ccodeINT:
5985 *type = make_signed_type (INT_TYPE_SIZE);
5988 case FFECOM_f2ccodeLONG:
5989 *type = make_signed_type (LONG_TYPE_SIZE);
5992 case FFECOM_f2ccodeLONGLONG:
5993 *type = make_signed_type (LONG_LONG_TYPE_SIZE);
5996 case FFECOM_f2ccodeCHARPTR:
5997 *type = build_pointer_type (DEFAULT_SIGNED_CHAR
5998 ? signed_char_type_node
5999 : unsigned_char_type_node);
6002 case FFECOM_f2ccodeFLOAT:
6003 *type = make_node (REAL_TYPE);
6004 TYPE_PRECISION (*type) = FLOAT_TYPE_SIZE;
6005 layout_type (*type);
6008 case FFECOM_f2ccodeDOUBLE:
6009 *type = make_node (REAL_TYPE);
6010 TYPE_PRECISION (*type) = DOUBLE_TYPE_SIZE;
6011 layout_type (*type);
6014 case FFECOM_f2ccodeLONGDOUBLE:
6015 *type = make_node (REAL_TYPE);
6016 TYPE_PRECISION (*type) = LONG_DOUBLE_TYPE_SIZE;
6017 layout_type (*type);
6020 case FFECOM_f2ccodeTWOREALS:
6021 *type = ffecom_make_complex_type_ (ffecom_f2c_real_type_node);
6024 case FFECOM_f2ccodeTWODOUBLEREALS:
6025 *type = ffecom_make_complex_type_ (ffecom_f2c_doublereal_type_node);
6029 assert ("unexpected FFECOM_f2ccodeXYZZY!" == NULL);
6030 *type = error_mark_node;
6034 pushdecl (build_decl (TYPE_DECL,
6035 ffecom_get_invented_identifier ("__g77_f2c_%s", name),
6040 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6041 /* Set the f2c list-directed-I/O code for whatever (integral) type has the
6045 ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size,
6051 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
6052 if (((t = ffecom_tree_type[bt][j]) != NULL_TREE)
6053 && (TREE_INT_CST_LOW (TYPE_SIZE (t)) == size))
6055 assert (code != -1);
6056 ffecom_f2c_typecode_[bt][j] = code;
6062 /* Finish up globals after doing all program units in file
6064 Need to handle only uninitialized COMMON areas. */
6066 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6068 ffecom_finish_global_ (ffeglobal global)
6074 if (ffeglobal_type (global) != FFEGLOBAL_typeCOMMON)
6077 if (ffeglobal_common_init (global))
6080 cbt = ffeglobal_hook (global);
6081 if ((cbt == NULL_TREE)
6082 || !ffeglobal_common_have_size (global))
6083 return global; /* No need to make common, never ref'd. */
6085 suspend_momentary ();
6087 DECL_EXTERNAL (cbt) = 0;
6089 /* Give the array a size now. */
6091 size = build_int_2 ((ffeglobal_common_size (global)
6092 + ffeglobal_common_pad (global)) - 1,
6095 cbtype = TREE_TYPE (cbt);
6096 TYPE_DOMAIN (cbtype) = build_range_type (integer_type_node,
6099 if (!TREE_TYPE (size))
6100 TREE_TYPE (size) = TYPE_DOMAIN (cbtype);
6101 layout_type (cbtype);
6103 cbt = start_decl (cbt, FALSE);
6104 assert (cbt == ffeglobal_hook (global));
6106 finish_decl (cbt, NULL_TREE, FALSE);
6112 /* Finish up any untransformed symbols. */
6114 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6116 ffecom_finish_symbol_transform_ (ffesymbol s)
6118 if ((s == NULL) || (TREE_CODE (current_function_decl) == ERROR_MARK))
6121 /* It's easy to know to transform an untransformed symbol, to make sure
6122 we put out debugging info for it. But COMMON variables, unlike
6123 EQUIVALENCE ones, aren't given declarations in addition to the
6124 tree expressions that specify offsets, because COMMON variables
6125 can be referenced in the outer scope where only dummy arguments
6126 (PARM_DECLs) should really be seen. To be safe, just don't do any
6127 VAR_DECLs for COMMON variables when we transform them for real
6128 use, and therefore we do all the VAR_DECL creating here. */
6130 if (ffesymbol_hook (s).decl_tree == NULL_TREE)
6132 if (ffesymbol_kind (s) != FFEINFO_kindNONE
6133 || (ffesymbol_where (s) != FFEINFO_whereNONE
6134 && ffesymbol_where (s) != FFEINFO_whereINTRINSIC
6135 && ffesymbol_where (s) != FFEINFO_whereDUMMY))
6136 /* Not transformed, and not CHARACTER*(*), and not a dummy
6137 argument, which can happen only if the entry point names
6138 it "rides in on" are all invalidated for other reasons. */
6139 s = ffecom_sym_transform_ (s);
6142 if ((ffesymbol_where (s) == FFEINFO_whereCOMMON)
6143 && (ffesymbol_hook (s).decl_tree != error_mark_node))
6145 int yes = suspend_momentary ();
6147 /* This isn't working, at least for dbxout. The .s file looks
6148 okay to me (burley), but in gdb 4.9 at least, the variables
6149 appear to reside somewhere outside of the common area, so
6150 it doesn't make sense to mislead anyone by generating the info
6151 on those variables until this is fixed. NOTE: Same problem
6152 with EQUIVALENCE, sadly...see similar #if later. */
6153 ffecom_member_phase2_ (ffesymbol_storage (ffesymbol_common (s)),
6154 ffesymbol_storage (s));
6156 resume_momentary (yes);
6163 /* Append underscore(s) to name before calling get_identifier. "us"
6164 is nonzero if the name already contains an underscore and thus
6165 needs two underscores appended. */
6167 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6169 ffecom_get_appended_identifier_ (char us, const char *name)
6175 newname = xmalloc ((i = strlen (name)) + 1
6176 + ffe_is_underscoring ()
6178 memcpy (newname, name, i);
6180 newname[i + us] = '_';
6181 newname[i + 1 + us] = '\0';
6182 id = get_identifier (newname);
6190 /* Decide whether to append underscore to name before calling
6193 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6195 ffecom_get_external_identifier_ (ffesymbol s)
6198 const char *name = ffesymbol_text (s);
6200 /* If name is a built-in name, just return it as is. */
6202 if (!ffe_is_underscoring ()
6203 || (strcmp (name, FFETARGET_nameBLANK_COMMON) == 0)
6204 #if FFETARGET_isENFORCED_MAIN_NAME
6205 || (strcmp (name, FFETARGET_nameENFORCED_NAME) == 0)
6207 || (strcmp (name, FFETARGET_nameUNNAMED_MAIN) == 0)
6209 || (strcmp (name, FFETARGET_nameUNNAMED_BLOCK_DATA) == 0))
6210 return get_identifier (name);
6212 us = ffe_is_second_underscore ()
6213 ? (strchr (name, '_') != NULL)
6216 return ffecom_get_appended_identifier_ (us, name);
6220 /* Decide whether to append underscore to internal name before calling
6223 This is for non-external, top-function-context names only. Transform
6224 identifier so it doesn't conflict with the transformed result
6225 of using a _different_ external name. E.g. if "CALL FOO" is
6226 transformed into "FOO_();", then the variable in "FOO_ = 3"
6227 must be transformed into something that does not conflict, since
6228 these two things should be independent.
6230 The transformation is as follows. If the name does not contain
6231 an underscore, there is no possible conflict, so just return.
6232 If the name does contain an underscore, then transform it just
6233 like we transform an external identifier. */
6235 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6237 ffecom_get_identifier_ (const char *name)
6239 /* If name does not contain an underscore, just return it as is. */
6241 if (!ffe_is_underscoring ()
6242 || (strchr (name, '_') == NULL))
6243 return get_identifier (name);
6245 return ffecom_get_appended_identifier_ (ffe_is_second_underscore (),
6250 /* ffecom_gen_sfuncdef_ -- Generate definition of statement function
6253 ffesymbol s; // kindFUNCTION, whereIMMEDIATE.
6254 t = ffecom_gen_sfuncdef_(s,ffesymbol_basictype(s),
6255 ffesymbol_kindtype(s));
6257 Call after setting up containing function and getting trees for all
6260 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6262 ffecom_gen_sfuncdef_ (ffesymbol s, ffeinfoBasictype bt, ffeinfoKindtype kt)
6264 ffebld expr = ffesymbol_sfexpr (s);
6268 bool charfunc = (bt == FFEINFO_basictypeCHARACTER);
6269 static bool recurse = FALSE;
6271 int old_lineno = lineno;
6272 char *old_input_filename = input_filename;
6274 ffecom_nested_entry_ = s;
6276 /* For now, we don't have a handy pointer to where the sfunc is actually
6277 defined, though that should be easy to add to an ffesymbol. (The
6278 token/where info available might well point to the place where the type
6279 of the sfunc is declared, especially if that precedes the place where
6280 the sfunc itself is defined, which is typically the case.) We should
6281 put out a null pointer rather than point somewhere wrong, but I want to
6282 see how it works at this point. */
6284 input_filename = ffesymbol_where_filename (s);
6285 lineno = ffesymbol_where_filelinenum (s);
6287 /* Pretransform the expression so any newly discovered things belong to the
6288 outer program unit, not to the statement function. */
6290 ffecom_expr_transform_ (expr);
6292 /* Make sure no recursive invocation of this fn (a specific case of failing
6293 to pretransform an sfunc's expression, i.e. where its expression
6294 references another untransformed sfunc) happens. */
6299 yes = suspend_momentary ();
6301 push_f_function_context ();
6304 type = void_type_node;
6307 type = ffecom_tree_type[bt][kt];
6308 if (type == NULL_TREE)
6309 type = integer_type_node; /* _sym_exec_transition reports
6313 start_function (ffecom_get_identifier_ (ffesymbol_text (s)),
6314 build_function_type (type, NULL_TREE),
6315 1, /* nested/inline */
6316 0); /* TREE_PUBLIC */
6318 /* We don't worry about COMPLEX return values here, because this is
6319 entirely internal to our code, and gcc has the ability to return COMPLEX
6320 directly as a value. */
6322 yes = suspend_momentary ();
6325 { /* Prepend arg for where result goes. */
6328 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
6330 result = ffecom_get_invented_identifier ("__g77_%s", "result");
6332 ffecom_char_enhance_arg_ (&type, s); /* Ignore returned length. */
6334 type = build_pointer_type (type);
6335 result = build_decl (PARM_DECL, result, type);
6337 push_parm_decl (result);
6340 result = NULL_TREE; /* Not ref'd if !charfunc. */
6342 ffecom_push_dummy_decls_ (ffesymbol_dummyargs (s), TRUE);
6344 resume_momentary (yes);
6346 store_parm_decls (0);
6348 ffecom_start_compstmt ();
6354 ffetargetCharacterSize sz = ffesymbol_size (s);
6357 result_length = build_int_2 (sz, 0);
6358 TREE_TYPE (result_length) = ffecom_f2c_ftnlen_type_node;
6360 ffecom_prepare_let_char_ (sz, expr);
6362 ffecom_prepare_end ();
6364 ffecom_let_char_ (result, result_length, sz, expr);
6365 expand_null_return ();
6369 ffecom_prepare_expr (expr);
6371 ffecom_prepare_end ();
6373 expand_return (ffecom_modify (NULL_TREE,
6374 DECL_RESULT (current_function_decl),
6375 ffecom_expr (expr)));
6381 ffecom_end_compstmt ();
6383 func = current_function_decl;
6384 finish_function (1);
6386 pop_f_function_context ();
6388 resume_momentary (yes);
6392 lineno = old_lineno;
6393 input_filename = old_input_filename;
6395 ffecom_nested_entry_ = NULL;
6402 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6404 ffecom_gfrt_args_ (ffecomGfrt ix)
6406 return ffecom_gfrt_argstring_[ix];
6410 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6412 ffecom_gfrt_tree_ (ffecomGfrt ix)
6414 if (ffecom_gfrt_[ix] == NULL_TREE)
6415 ffecom_make_gfrt_ (ix);
6417 return ffecom_1 (ADDR_EXPR,
6418 build_pointer_type (TREE_TYPE (ffecom_gfrt_[ix])),
6423 /* Return initialize-to-zero expression for this VAR_DECL. */
6425 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6426 /* A somewhat evil way to prevent the garbage collector
6427 from collecting 'tree' structures. */
6428 #define NUM_TRACKED_CHUNK 63
6429 static struct tree_ggc_tracker
6431 struct tree_ggc_tracker *next;
6432 tree trees[NUM_TRACKED_CHUNK];
6433 } *tracker_head = NULL;
6436 mark_tracker_head (void *arg)
6438 struct tree_ggc_tracker *head;
6441 for (head = * (struct tree_ggc_tracker **) arg;
6446 for (i = 0; i < NUM_TRACKED_CHUNK; i++)
6447 ggc_mark_tree (head->trees[i]);
6452 ffecom_save_tree_forever (tree t)
6455 if (tracker_head != NULL)
6456 for (i = 0; i < NUM_TRACKED_CHUNK; i++)
6457 if (tracker_head->trees[i] == NULL)
6459 tracker_head->trees[i] = t;
6464 /* Need to allocate a new block. */
6465 struct tree_ggc_tracker *old_head = tracker_head;
6467 tracker_head = ggc_alloc (sizeof (*tracker_head));
6468 tracker_head->next = old_head;
6469 tracker_head->trees[0] = t;
6470 for (i = 1; i < NUM_TRACKED_CHUNK; i++)
6471 tracker_head->trees[i] = NULL;
6476 ffecom_init_zero_ (tree decl)
6479 int incremental = TREE_STATIC (decl);
6480 tree type = TREE_TYPE (decl);
6484 make_decl_rtl (decl, NULL, TREE_PUBLIC (decl) ? 1 : 0);
6485 assemble_variable (decl, TREE_PUBLIC (decl) ? 1 : 0, 0, 1);
6490 if ((TREE_CODE (type) != ARRAY_TYPE)
6491 && (TREE_CODE (type) != RECORD_TYPE)
6492 && (TREE_CODE (type) != UNION_TYPE)
6494 init = convert (type, integer_zero_node);
6495 else if (!incremental)
6497 int momentary = suspend_momentary ();
6499 init = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
6500 TREE_CONSTANT (init) = 1;
6501 TREE_STATIC (init) = 1;
6503 resume_momentary (momentary);
6507 int momentary = suspend_momentary ();
6509 assemble_zeros (int_size_in_bytes (type));
6510 init = error_mark_node;
6512 resume_momentary (momentary);
6515 pop_momentary_nofree ();
6521 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6523 ffecom_intrinsic_ichar_ (tree tree_type, ffebld arg,
6529 switch (ffebld_op (arg))
6531 case FFEBLD_opCONTER: /* For F90, check 0-length. */
6532 if (ffetarget_length_character1
6533 (ffebld_constant_character1
6534 (ffebld_conter (arg))) == 0)
6536 *maybe_tree = integer_zero_node;
6537 return convert (tree_type, integer_zero_node);
6540 *maybe_tree = integer_one_node;
6541 expr_tree = build_int_2 (*ffetarget_text_character1
6542 (ffebld_constant_character1
6543 (ffebld_conter (arg))),
6545 TREE_TYPE (expr_tree) = tree_type;
6548 case FFEBLD_opSYMTER:
6549 case FFEBLD_opARRAYREF:
6550 case FFEBLD_opFUNCREF:
6551 case FFEBLD_opSUBSTR:
6552 ffecom_char_args_ (&expr_tree, &length_tree, arg);
6554 if ((expr_tree == error_mark_node)
6555 || (length_tree == error_mark_node))
6557 *maybe_tree = error_mark_node;
6558 return error_mark_node;
6561 if (integer_zerop (length_tree))
6563 *maybe_tree = integer_zero_node;
6564 return convert (tree_type, integer_zero_node);
6568 = ffecom_1 (INDIRECT_REF,
6569 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
6572 = ffecom_2 (ARRAY_REF,
6573 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
6576 expr_tree = convert (tree_type, expr_tree);
6578 if (TREE_CODE (length_tree) == INTEGER_CST)
6579 *maybe_tree = integer_one_node;
6580 else /* Must check length at run time. */
6582 = ffecom_truth_value
6583 (ffecom_2 (GT_EXPR, integer_type_node,
6585 ffecom_f2c_ftnlen_zero_node));
6588 case FFEBLD_opPAREN:
6589 case FFEBLD_opCONVERT:
6590 if (ffeinfo_size (ffebld_info (arg)) == 0)
6592 *maybe_tree = integer_zero_node;
6593 return convert (tree_type, integer_zero_node);
6595 return ffecom_intrinsic_ichar_ (tree_type, ffebld_left (arg),
6598 case FFEBLD_opCONCATENATE:
6605 expr_left = ffecom_intrinsic_ichar_ (tree_type, ffebld_left (arg),
6607 expr_right = ffecom_intrinsic_ichar_ (tree_type, ffebld_right (arg),
6609 *maybe_tree = ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
6612 expr_tree = ffecom_3 (COND_EXPR, tree_type,
6620 assert ("bad op in ICHAR" == NULL);
6621 return error_mark_node;
6626 /* ffecom_intrinsic_len_ -- Return length info for char arg (LEN())
6630 length_arg = ffecom_intrinsic_len_ (expr);
6632 Handles CHARACTER-type CONTER, SYMTER, SUBSTR, ARRAYREF, and FUNCREF
6633 subexpressions by constructing the appropriate tree for the
6634 length-of-character-text argument in a calling sequence. */
6636 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6638 ffecom_intrinsic_len_ (ffebld expr)
6640 ffetargetCharacter1 val;
6643 switch (ffebld_op (expr))
6645 case FFEBLD_opCONTER:
6646 val = ffebld_constant_character1 (ffebld_conter (expr));
6647 length = build_int_2 (ffetarget_length_character1 (val), 0);
6648 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6651 case FFEBLD_opSYMTER:
6653 ffesymbol s = ffebld_symter (expr);
6656 item = ffesymbol_hook (s).decl_tree;
6657 if (item == NULL_TREE)
6659 s = ffecom_sym_transform_ (s);
6660 item = ffesymbol_hook (s).decl_tree;
6662 if (ffesymbol_kind (s) == FFEINFO_kindENTITY)
6664 if (ffesymbol_size (s) == FFETARGET_charactersizeNONE)
6665 length = ffesymbol_hook (s).length_tree;
6668 length = build_int_2 (ffesymbol_size (s), 0);
6669 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6672 else if (item == error_mark_node)
6673 length = error_mark_node;
6674 else /* FFEINFO_kindFUNCTION: */
6679 case FFEBLD_opARRAYREF:
6680 length = ffecom_intrinsic_len_ (ffebld_left (expr));
6683 case FFEBLD_opSUBSTR:
6687 ffebld thing = ffebld_right (expr);
6691 assert (ffebld_op (thing) == FFEBLD_opITEM);
6692 start = ffebld_head (thing);
6693 thing = ffebld_trail (thing);
6694 assert (ffebld_trail (thing) == NULL);
6695 end = ffebld_head (thing);
6697 length = ffecom_intrinsic_len_ (ffebld_left (expr));
6699 if (length == error_mark_node)
6708 length = convert (ffecom_f2c_ftnlen_type_node,
6714 start_tree = convert (ffecom_f2c_ftnlen_type_node,
6715 ffecom_expr (start));
6717 if (start_tree == error_mark_node)
6719 length = error_mark_node;
6725 length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6726 ffecom_f2c_ftnlen_one_node,
6727 ffecom_2 (MINUS_EXPR,
6728 ffecom_f2c_ftnlen_type_node,
6734 end_tree = convert (ffecom_f2c_ftnlen_type_node,
6737 if (end_tree == error_mark_node)
6739 length = error_mark_node;
6743 length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6744 ffecom_f2c_ftnlen_one_node,
6745 ffecom_2 (MINUS_EXPR,
6746 ffecom_f2c_ftnlen_type_node,
6747 end_tree, start_tree));
6753 case FFEBLD_opCONCATENATE:
6755 = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6756 ffecom_intrinsic_len_ (ffebld_left (expr)),
6757 ffecom_intrinsic_len_ (ffebld_right (expr)));
6760 case FFEBLD_opFUNCREF:
6761 case FFEBLD_opCONVERT:
6762 length = build_int_2 (ffebld_size (expr), 0);
6763 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6767 assert ("bad op for single char arg expr" == NULL);
6768 length = ffecom_f2c_ftnlen_zero_node;
6772 assert (length != NULL_TREE);
6778 /* Handle CHARACTER assignments.
6780 Generates code to do the assignment. Used by ordinary assignment
6781 statement handler ffecom_let_stmt and by statement-function
6782 handler to generate code for a statement function. */
6784 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6786 ffecom_let_char_ (tree dest_tree, tree dest_length,
6787 ffetargetCharacterSize dest_size, ffebld source)
6789 ffecomConcatList_ catlist;
6794 if ((dest_tree == error_mark_node)
6795 || (dest_length == error_mark_node))
6798 assert (dest_tree != NULL_TREE);
6799 assert (dest_length != NULL_TREE);
6801 /* Source might be an opCONVERT, which just means it is a different size
6802 than the destination. Since the underlying implementation here handles
6803 that (directly or via the s_copy or s_cat run-time-library functions),
6804 we don't need the "convenience" of an opCONVERT that tells us to
6805 truncate or blank-pad, particularly since the resulting implementation
6806 would probably be slower than otherwise. */
6808 while (ffebld_op (source) == FFEBLD_opCONVERT)
6809 source = ffebld_left (source);
6811 catlist = ffecom_concat_list_new_ (source, dest_size);
6812 switch (ffecom_concat_list_count_ (catlist))
6814 case 0: /* Shouldn't happen, but in case it does... */
6815 ffecom_concat_list_kill_ (catlist);
6816 source_tree = null_pointer_node;
6817 source_length = ffecom_f2c_ftnlen_zero_node;
6818 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6819 TREE_CHAIN (expr_tree) = build_tree_list (NULL_TREE, source_tree);
6820 TREE_CHAIN (TREE_CHAIN (expr_tree))
6821 = build_tree_list (NULL_TREE, dest_length);
6822 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6823 = build_tree_list (NULL_TREE, source_length);
6825 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCOPY, expr_tree, NULL_TREE);
6826 TREE_SIDE_EFFECTS (expr_tree) = 1;
6828 expand_expr_stmt (expr_tree);
6832 case 1: /* The (fairly) easy case. */
6833 ffecom_char_args_ (&source_tree, &source_length,
6834 ffecom_concat_list_expr_ (catlist, 0));
6835 ffecom_concat_list_kill_ (catlist);
6836 assert (source_tree != NULL_TREE);
6837 assert (source_length != NULL_TREE);
6839 if ((source_tree == error_mark_node)
6840 || (source_length == error_mark_node))
6846 = ffecom_1 (INDIRECT_REF,
6847 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6851 = ffecom_2 (ARRAY_REF,
6852 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6857 = ffecom_1 (INDIRECT_REF,
6858 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6862 = ffecom_2 (ARRAY_REF,
6863 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6868 expr_tree = ffecom_modify (void_type_node, dest_tree, source_tree);
6870 expand_expr_stmt (expr_tree);
6875 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6876 TREE_CHAIN (expr_tree) = build_tree_list (NULL_TREE, source_tree);
6877 TREE_CHAIN (TREE_CHAIN (expr_tree))
6878 = build_tree_list (NULL_TREE, dest_length);
6879 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6880 = build_tree_list (NULL_TREE, source_length);
6882 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCOPY, expr_tree, NULL_TREE);
6883 TREE_SIDE_EFFECTS (expr_tree) = 1;
6885 expand_expr_stmt (expr_tree);
6889 default: /* Must actually concatenate things. */
6893 /* Heavy-duty concatenation. */
6896 int count = ffecom_concat_list_count_ (catlist);
6908 = ffecom_push_tempvar (ffecom_f2c_ftnlen_type_node,
6909 FFETARGET_charactersizeNONE, count, TRUE);
6910 item_array = items = ffecom_push_tempvar (ffecom_f2c_address_type_node,
6911 FFETARGET_charactersizeNONE,
6917 hook = ffebld_nonter_hook (source);
6919 assert (TREE_CODE (hook) == TREE_VEC);
6920 assert (TREE_VEC_LENGTH (hook) == 2);
6921 length_array = lengths = TREE_VEC_ELT (hook, 0);
6922 item_array = items = TREE_VEC_ELT (hook, 1);
6926 for (i = 0; i < count; ++i)
6928 ffecom_char_args_ (&citem, &clength,
6929 ffecom_concat_list_expr_ (catlist, i));
6930 if ((citem == error_mark_node)
6931 || (clength == error_mark_node))
6933 ffecom_concat_list_kill_ (catlist);
6938 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (items),
6939 ffecom_modify (void_type_node,
6940 ffecom_2 (ARRAY_REF,
6941 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array))),
6943 build_int_2 (i, 0)),
6947 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (lengths),
6948 ffecom_modify (void_type_node,
6949 ffecom_2 (ARRAY_REF,
6950 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array))),
6952 build_int_2 (i, 0)),
6957 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6958 TREE_CHAIN (expr_tree)
6959 = build_tree_list (NULL_TREE,
6960 ffecom_1 (ADDR_EXPR,
6961 build_pointer_type (TREE_TYPE (items)),
6963 TREE_CHAIN (TREE_CHAIN (expr_tree))
6964 = build_tree_list (NULL_TREE,
6965 ffecom_1 (ADDR_EXPR,
6966 build_pointer_type (TREE_TYPE (lengths)),
6968 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6971 ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
6972 convert (ffecom_f2c_ftnlen_type_node,
6973 build_int_2 (count, 0))));
6974 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree))))
6975 = build_tree_list (NULL_TREE, dest_length);
6977 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCAT, expr_tree, NULL_TREE);
6978 TREE_SIDE_EFFECTS (expr_tree) = 1;
6980 expand_expr_stmt (expr_tree);
6983 ffecom_concat_list_kill_ (catlist);
6987 /* ffecom_make_gfrt_ -- Make initial info for run-time routine
6990 ffecom_make_gfrt_(ix);
6992 Assumes gfrt_[ix] is NULL_TREE, and replaces it with the FUNCTION_DECL
6993 for the indicated run-time routine (ix). */
6995 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6997 ffecom_make_gfrt_ (ffecomGfrt ix)
7002 switch (ffecom_gfrt_type_[ix])
7004 case FFECOM_rttypeVOID_:
7005 ttype = void_type_node;
7008 case FFECOM_rttypeVOIDSTAR_:
7009 ttype = TREE_TYPE (null_pointer_node); /* `void *'. */
7012 case FFECOM_rttypeFTNINT_:
7013 ttype = ffecom_f2c_ftnint_type_node;
7016 case FFECOM_rttypeINTEGER_:
7017 ttype = ffecom_f2c_integer_type_node;
7020 case FFECOM_rttypeLONGINT_:
7021 ttype = ffecom_f2c_longint_type_node;
7024 case FFECOM_rttypeLOGICAL_:
7025 ttype = ffecom_f2c_logical_type_node;
7028 case FFECOM_rttypeREAL_F2C_:
7029 ttype = double_type_node;
7032 case FFECOM_rttypeREAL_GNU_:
7033 ttype = float_type_node;
7036 case FFECOM_rttypeCOMPLEX_F2C_:
7037 ttype = void_type_node;
7040 case FFECOM_rttypeCOMPLEX_GNU_:
7041 ttype = ffecom_f2c_complex_type_node;
7044 case FFECOM_rttypeDOUBLE_:
7045 ttype = double_type_node;
7048 case FFECOM_rttypeDOUBLEREAL_:
7049 ttype = ffecom_f2c_doublereal_type_node;
7052 case FFECOM_rttypeDBLCMPLX_F2C_:
7053 ttype = void_type_node;
7056 case FFECOM_rttypeDBLCMPLX_GNU_:
7057 ttype = ffecom_f2c_doublecomplex_type_node;
7060 case FFECOM_rttypeCHARACTER_:
7061 ttype = void_type_node;
7066 assert ("bad rttype" == NULL);
7070 ttype = build_function_type (ttype, NULL_TREE);
7071 t = build_decl (FUNCTION_DECL,
7072 get_identifier (ffecom_gfrt_name_[ix]),
7074 DECL_EXTERNAL (t) = 1;
7075 TREE_PUBLIC (t) = 1;
7076 TREE_THIS_VOLATILE (t) = ffecom_gfrt_volatile_[ix] ? 1 : 0;
7078 t = start_decl (t, TRUE);
7080 finish_decl (t, NULL_TREE, TRUE);
7082 ffecom_gfrt_[ix] = t;
7086 /* Phase 1 pass over each member of a COMMON/EQUIVALENCE group. */
7088 #if FFECOM_targetCURRENT == FFECOM_targetGCC
7090 ffecom_member_phase1_ (ffestorag mst UNUSED, ffestorag st)
7092 ffesymbol s = ffestorag_symbol (st);
7094 if (ffesymbol_namelisted (s))
7095 ffecom_member_namelisted_ = TRUE;
7099 /* Phase 2 pass over each member of a COMMON/EQUIVALENCE group. Declare
7100 the member so debugger will see it. Otherwise nobody should be
7101 referencing the member. */
7103 #if FFECOM_targetCURRENT == FFECOM_targetGCC
7105 ffecom_member_phase2_ (ffestorag mst, ffestorag st)
7113 || ((mt = ffestorag_hook (mst)) == NULL)
7114 || (mt == error_mark_node))
7118 || ((s = ffestorag_symbol (st)) == NULL))
7121 type = ffecom_type_localvar_ (s,
7122 ffesymbol_basictype (s),
7123 ffesymbol_kindtype (s));
7124 if (type == error_mark_node)
7127 t = build_decl (VAR_DECL,
7128 ffecom_get_identifier_ (ffesymbol_text (s)),
7131 TREE_STATIC (t) = TREE_STATIC (mt);
7132 DECL_INITIAL (t) = NULL_TREE;
7133 TREE_ASM_WRITTEN (t) = 1;
7136 = gen_rtx (MEM, TYPE_MODE (type),
7137 plus_constant (XEXP (DECL_RTL (mt), 0),
7138 ffestorag_modulo (mst)
7139 + ffestorag_offset (st)
7140 - ffestorag_offset (mst)));
7142 t = start_decl (t, FALSE);
7144 finish_decl (t, NULL_TREE, FALSE);
7148 /* Prepare source expression for assignment into a destination perhaps known
7149 to be of a specific size. */
7152 ffecom_prepare_let_char_ (ffetargetCharacterSize dest_size, ffebld source)
7154 ffecomConcatList_ catlist;
7159 tree tempvar = NULL_TREE;
7161 while (ffebld_op (source) == FFEBLD_opCONVERT)
7162 source = ffebld_left (source);
7164 catlist = ffecom_concat_list_new_ (source, dest_size);
7165 count = ffecom_concat_list_count_ (catlist);
7170 = ffecom_make_tempvar ("let_char_len", ffecom_f2c_ftnlen_type_node,
7171 FFETARGET_charactersizeNONE, count);
7173 = ffecom_make_tempvar ("let_char_item", ffecom_f2c_address_type_node,
7174 FFETARGET_charactersizeNONE, count);
7176 tempvar = make_tree_vec (2);
7177 TREE_VEC_ELT (tempvar, 0) = ltmp;
7178 TREE_VEC_ELT (tempvar, 1) = itmp;
7181 for (i = 0; i < count; ++i)
7182 ffecom_prepare_arg_ptr_to_expr (ffecom_concat_list_expr_ (catlist, i));
7184 ffecom_concat_list_kill_ (catlist);
7188 ffebld_nonter_set_hook (source, tempvar);
7189 current_binding_level->prep_state = 1;
7193 /* ffecom_push_dummy_decls_ -- Transform dummy args, push parm decls in order
7195 Ignores STAR (alternate-return) dummies. All other get exec-transitioned
7196 (which generates their trees) and then their trees get push_parm_decl'd.
7198 The second arg is TRUE if the dummies are for a statement function, in
7199 which case lengths are not pushed for character arguments (since they are
7200 always known by both the caller and the callee, though the code allows
7201 for someday permitting CHAR*(*) stmtfunc dummies). */
7203 #if FFECOM_targetCURRENT == FFECOM_targetGCC
7205 ffecom_push_dummy_decls_ (ffebld dummy_list, bool stmtfunc)
7212 ffecom_transform_only_dummies_ = TRUE;
7214 /* First push the parms corresponding to actual dummy "contents". */
7216 for (dumlist = dummy_list; dumlist != NULL; dumlist = ffebld_trail (dumlist))
7218 dummy = ffebld_head (dumlist);
7219 switch (ffebld_op (dummy))
7223 continue; /* Forget alternate returns. */
7228 assert (ffebld_op (dummy) == FFEBLD_opSYMTER);
7229 s = ffebld_symter (dummy);
7230 parm = ffesymbol_hook (s).decl_tree;
7231 if (parm == NULL_TREE)
7233 s = ffecom_sym_transform_ (s);
7234 parm = ffesymbol_hook (s).decl_tree;
7235 assert (parm != NULL_TREE);
7237 if (parm != error_mark_node)
7238 push_parm_decl (parm);
7241 /* Then, for CHARACTER dummies, push the parms giving their lengths. */
7243 for (dumlist = dummy_list; dumlist != NULL; dumlist = ffebld_trail (dumlist))
7245 dummy = ffebld_head (dumlist);
7246 switch (ffebld_op (dummy))
7250 continue; /* Forget alternate returns, they mean
7256 s = ffebld_symter (dummy);
7257 if (ffesymbol_basictype (s) != FFEINFO_basictypeCHARACTER)
7258 continue; /* Only looking for CHARACTER arguments. */
7259 if (stmtfunc && (ffesymbol_size (s) != FFETARGET_charactersizeNONE))
7260 continue; /* Stmtfunc arg with known size needs no
7262 if (ffesymbol_kind (s) != FFEINFO_kindENTITY)
7263 continue; /* Only looking for variables and arrays. */
7264 parm = ffesymbol_hook (s).length_tree;
7265 assert (parm != NULL_TREE);
7266 if (parm != error_mark_node)
7267 push_parm_decl (parm);
7270 ffecom_transform_only_dummies_ = FALSE;
7274 /* ffecom_start_progunit_ -- Beginning of program unit
7276 Does GNU back end stuff necessary to teach it about the start of its
7277 equivalent of a Fortran program unit. */
7279 #if FFECOM_targetCURRENT == FFECOM_targetGCC
7281 ffecom_start_progunit_ ()
7283 ffesymbol fn = ffecom_primary_entry_;
7285 tree id; /* Identifier (name) of function. */
7286 tree type; /* Type of function. */
7287 tree result; /* Result of function. */
7288 ffeinfoBasictype bt;
7292 ffeglobalType egt = FFEGLOBAL_type;
7295 bool altentries = (ffecom_num_entrypoints_ != 0);
7298 && (ffecom_primary_entry_kind_ == FFEINFO_kindFUNCTION)
7299 && (ffecom_master_bt_ == FFEINFO_basictypeNONE);
7300 bool main_program = FALSE;
7301 int old_lineno = lineno;
7302 char *old_input_filename = input_filename;
7305 assert (fn != NULL);
7306 assert (ffesymbol_hook (fn).decl_tree == NULL_TREE);
7308 input_filename = ffesymbol_where_filename (fn);
7309 lineno = ffesymbol_where_filelinenum (fn);
7311 /* c-parse.y indeed does call suspend_momentary and not only ignores the
7312 return value, but also never calls resume_momentary, when starting an
7313 outer function (see "fndef:", "setspecs:", and so on). So g77 does the
7314 same thing. It shouldn't be a problem since start_function calls
7315 temporary_allocation, but it might be necessary. If it causes a problem
7316 here, then maybe there's a bug lurking in gcc. NOTE: This identical
7317 comment appears twice in thist file. */
7319 suspend_momentary ();
7321 switch (ffecom_primary_entry_kind_)
7323 case FFEINFO_kindPROGRAM:
7324 main_program = TRUE;
7325 gt = FFEGLOBAL_typeMAIN;
7326 bt = FFEINFO_basictypeNONE;
7327 kt = FFEINFO_kindtypeNONE;
7328 type = ffecom_tree_fun_type_void;
7333 case FFEINFO_kindBLOCKDATA:
7334 gt = FFEGLOBAL_typeBDATA;
7335 bt = FFEINFO_basictypeNONE;
7336 kt = FFEINFO_kindtypeNONE;
7337 type = ffecom_tree_fun_type_void;
7342 case FFEINFO_kindFUNCTION:
7343 gt = FFEGLOBAL_typeFUNC;
7344 egt = FFEGLOBAL_typeEXT;
7345 bt = ffesymbol_basictype (fn);
7346 kt = ffesymbol_kindtype (fn);
7347 if (bt == FFEINFO_basictypeNONE)
7349 ffeimplic_establish_symbol (fn);
7350 if (ffesymbol_funcresult (fn) != NULL)
7351 ffeimplic_establish_symbol (ffesymbol_funcresult (fn));
7352 bt = ffesymbol_basictype (fn);
7353 kt = ffesymbol_kindtype (fn);
7357 charfunc = cmplxfunc = FALSE;
7358 else if (bt == FFEINFO_basictypeCHARACTER)
7359 charfunc = TRUE, cmplxfunc = FALSE;
7360 else if ((bt == FFEINFO_basictypeCOMPLEX)
7361 && ffesymbol_is_f2c (fn)
7363 charfunc = FALSE, cmplxfunc = TRUE;
7365 charfunc = cmplxfunc = FALSE;
7367 if (multi || charfunc)
7368 type = ffecom_tree_fun_type_void;
7369 else if (ffesymbol_is_f2c (fn) && !altentries)
7370 type = ffecom_tree_fun_type[bt][kt];
7372 type = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
7374 if ((type == NULL_TREE)
7375 || (TREE_TYPE (type) == NULL_TREE))
7376 type = ffecom_tree_fun_type_void; /* _sym_exec_transition. */
7379 case FFEINFO_kindSUBROUTINE:
7380 gt = FFEGLOBAL_typeSUBR;
7381 egt = FFEGLOBAL_typeEXT;
7382 bt = FFEINFO_basictypeNONE;
7383 kt = FFEINFO_kindtypeNONE;
7384 if (ffecom_is_altreturning_)
7385 type = ffecom_tree_subr_type;
7387 type = ffecom_tree_fun_type_void;
7393 assert ("say what??" == NULL);
7395 case FFEINFO_kindANY:
7396 gt = FFEGLOBAL_typeANY;
7397 bt = FFEINFO_basictypeNONE;
7398 kt = FFEINFO_kindtypeNONE;
7399 type = error_mark_node;
7407 id = ffecom_get_invented_identifier ("__g77_masterfun_%s",
7408 ffesymbol_text (fn));
7410 #if FFETARGET_isENFORCED_MAIN
7411 else if (main_program)
7412 id = get_identifier (FFETARGET_nameENFORCED_MAIN_NAME);
7415 id = ffecom_get_external_identifier_ (fn);
7419 0, /* nested/inline */
7420 !altentries); /* TREE_PUBLIC */
7422 TREE_USED (current_function_decl) = 1; /* Avoid spurious warning if altentries. */
7425 && ((g = ffesymbol_global (fn)) != NULL)
7426 && ((ffeglobal_type (g) == gt)
7427 || (ffeglobal_type (g) == egt)))
7429 ffeglobal_set_hook (g, current_function_decl);
7432 yes = suspend_momentary ();
7434 /* Arg handling needs exec-transitioned ffesymbols to work with. But
7435 exec-transitioning needs current_function_decl to be filled in. So we
7436 do these things in two phases. */
7439 { /* 1st arg identifies which entrypoint. */
7440 ffecom_which_entrypoint_decl_
7441 = build_decl (PARM_DECL,
7442 ffecom_get_invented_identifier ("__g77_%s",
7443 "which_entrypoint"),
7445 push_parm_decl (ffecom_which_entrypoint_decl_);
7451 { /* Arg for result (return value). */
7456 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
7458 type = ffecom_tree_type[FFEINFO_basictypeCOMPLEX][kt];
7460 type = ffecom_multi_type_node_;
7462 result = ffecom_get_invented_identifier ("__g77_%s", "result");
7464 /* Make length arg _and_ enhance type info for CHAR arg itself. */
7467 length = ffecom_char_enhance_arg_ (&type, fn);
7469 length = NULL_TREE; /* Not ref'd if !charfunc. */
7471 type = build_pointer_type (type);
7472 result = build_decl (PARM_DECL, result, type);
7474 push_parm_decl (result);
7476 ffecom_multi_retval_ = result;
7478 ffecom_func_result_ = result;
7482 push_parm_decl (length);
7483 ffecom_func_length_ = length;
7487 if (ffecom_primary_entry_is_proc_)
7490 arglist = ffecom_master_arglist_;
7492 arglist = ffesymbol_dummyargs (fn);
7493 ffecom_push_dummy_decls_ (arglist, FALSE);
7496 resume_momentary (yes);
7498 if (TREE_CODE (current_function_decl) != ERROR_MARK)
7499 store_parm_decls (main_program ? 1 : 0);
7501 ffecom_start_compstmt ();
7502 /* Disallow temp vars at this level. */
7503 current_binding_level->prep_state = 2;
7505 lineno = old_lineno;
7506 input_filename = old_input_filename;
7508 /* This handles any symbols still untransformed, in case -g specified.
7509 This used to be done in ffecom_finish_progunit, but it turns out to
7510 be necessary to do it here so that statement functions are
7511 expanded before code. But don't bother for BLOCK DATA. */
7513 if (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA)
7514 ffesymbol_drive (ffecom_finish_symbol_transform_);
7518 /* ffecom_sym_transform_ -- Transform FFE sym into backend sym
7521 ffecom_sym_transform_(s);
7523 The ffesymbol_hook info for s is updated with appropriate backend info
7526 #if FFECOM_targetCURRENT == FFECOM_targetGCC
7528 ffecom_sym_transform_ (ffesymbol s)
7530 tree t; /* Transformed thingy. */
7531 tree tlen; /* Length if CHAR*(*). */
7532 bool addr; /* Is t the address of the thingy? */
7533 ffeinfoBasictype bt;
7537 int old_lineno = lineno;
7538 char *old_input_filename = input_filename;
7540 /* Must ensure special ASSIGN variables are declared at top of outermost
7541 block, else they'll end up in the innermost block when their first
7542 ASSIGN is seen, which leaves them out of scope when they're the
7543 subject of a GOTO or I/O statement.
7545 We make this variable even if -fugly-assign. Just let it go unused,
7546 in case it turns out there are cases where we really want to use this
7547 variable anyway (e.g. ASSIGN to INTEGER*2 variable). */
7549 if (! ffecom_transform_only_dummies_
7550 && ffesymbol_assigned (s)
7551 && ! ffesymbol_hook (s).assign_tree)
7552 s = ffecom_sym_transform_assign_ (s);
7554 if (ffesymbol_sfdummyparent (s) == NULL)
7556 input_filename = ffesymbol_where_filename (s);
7557 lineno = ffesymbol_where_filelinenum (s);
7561 ffesymbol sf = ffesymbol_sfdummyparent (s);
7563 input_filename = ffesymbol_where_filename (sf);
7564 lineno = ffesymbol_where_filelinenum (sf);
7567 bt = ffeinfo_basictype (ffebld_info (s));
7568 kt = ffeinfo_kindtype (ffebld_info (s));
7574 switch (ffesymbol_kind (s))
7576 case FFEINFO_kindNONE:
7577 switch (ffesymbol_where (s))
7579 case FFEINFO_whereDUMMY: /* Subroutine or function. */
7580 assert (ffecom_transform_only_dummies_);
7582 /* Before 0.4, this could be ENTITY/DUMMY, but see
7583 ffestu_sym_end_transition -- no longer true (in particular, if
7584 it could be an ENTITY, it _will_ be made one, so that
7585 possibility won't come through here). So we never make length
7586 arg for CHARACTER type. */
7588 t = build_decl (PARM_DECL,
7589 ffecom_get_identifier_ (ffesymbol_text (s)),
7590 ffecom_tree_ptr_to_subr_type);
7592 DECL_ARTIFICIAL (t) = 1;
7597 case FFEINFO_whereGLOBAL: /* Subroutine or function. */
7598 assert (!ffecom_transform_only_dummies_);
7600 if (((g = ffesymbol_global (s)) != NULL)
7601 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
7602 || (ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
7603 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
7604 && (ffeglobal_hook (g) != NULL_TREE)
7605 && ffe_is_globals ())
7607 t = ffeglobal_hook (g);
7611 t = build_decl (FUNCTION_DECL,
7612 ffecom_get_external_identifier_ (s),
7613 ffecom_tree_subr_type); /* Assume subr. */
7614 DECL_EXTERNAL (t) = 1;
7615 TREE_PUBLIC (t) = 1;
7617 t = start_decl (t, FALSE);
7618 finish_decl (t, NULL_TREE, FALSE);
7621 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
7622 || (ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
7623 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
7624 ffeglobal_set_hook (g, t);
7626 ffecom_save_tree_forever (t);
7631 assert ("NONE where unexpected" == NULL);
7633 case FFEINFO_whereANY:
7638 case FFEINFO_kindENTITY:
7639 switch (ffeinfo_where (ffesymbol_info (s)))
7642 case FFEINFO_whereCONSTANT:
7643 /* ~~Debugging info needed? */
7644 assert (!ffecom_transform_only_dummies_);
7645 t = error_mark_node; /* Shouldn't ever see this in expr. */
7648 case FFEINFO_whereLOCAL:
7649 assert (!ffecom_transform_only_dummies_);
7652 ffestorag st = ffesymbol_storage (s);
7656 && (ffestorag_size (st) == 0))
7658 t = error_mark_node;
7662 yes = suspend_momentary ();
7663 type = ffecom_type_localvar_ (s, bt, kt);
7664 resume_momentary (yes);
7666 if (type == error_mark_node)
7668 t = error_mark_node;
7673 && (ffestorag_parent (st) != NULL))
7674 { /* Child of EQUIVALENCE parent. */
7678 ffetargetOffset offset;
7680 est = ffestorag_parent (st);
7681 ffecom_transform_equiv_ (est);
7683 et = ffestorag_hook (est);
7684 assert (et != NULL_TREE);
7686 if (! TREE_STATIC (et))
7687 put_var_into_stack (et);
7689 yes = suspend_momentary ();
7691 offset = ffestorag_modulo (est)
7692 + ffestorag_offset (ffesymbol_storage (s))
7693 - ffestorag_offset (est);
7695 ffecom_debug_kludge_ (et, "EQUIVALENCE", s, type, offset);
7697 /* (t_type *) (((char *) &et) + offset) */
7699 t = convert (string_type_node, /* (char *) */
7700 ffecom_1 (ADDR_EXPR,
7701 build_pointer_type (TREE_TYPE (et)),
7703 t = ffecom_2 (PLUS_EXPR, TREE_TYPE (t),
7705 build_int_2 (offset, 0));
7706 t = convert (build_pointer_type (type),
7708 TREE_CONSTANT (t) = staticp (et);
7712 resume_momentary (yes);
7717 bool init = ffesymbol_is_init (s);
7719 yes = suspend_momentary ();
7721 t = build_decl (VAR_DECL,
7722 ffecom_get_identifier_ (ffesymbol_text (s)),
7726 || ffesymbol_namelisted (s)
7727 #ifdef FFECOM_sizeMAXSTACKITEM
7729 && (ffestorag_size (st) > FFECOM_sizeMAXSTACKITEM))
7731 || ((ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
7732 && (ffecom_primary_entry_kind_
7733 != FFEINFO_kindBLOCKDATA)
7734 && (ffesymbol_is_save (s) || ffe_is_saveall ())))
7735 TREE_STATIC (t) = !ffesymbol_attr (s, FFESYMBOL_attrADJUSTABLE);
7737 TREE_STATIC (t) = 0; /* No need to make static. */
7739 if (init || ffe_is_init_local_zero ())
7740 DECL_INITIAL (t) = error_mark_node;
7742 /* Keep -Wunused from complaining about var if it
7743 is used as sfunc arg or DATA implied-DO. */
7744 if (ffesymbol_attrs (s) & FFESYMBOL_attrsSFARG)
7745 DECL_IN_SYSTEM_HEADER (t) = 1;
7747 t = start_decl (t, FALSE);
7751 if (ffesymbol_init (s) != NULL)
7752 initexpr = ffecom_expr (ffesymbol_init (s));
7754 initexpr = ffecom_init_zero_ (t);
7756 else if (ffe_is_init_local_zero ())
7757 initexpr = ffecom_init_zero_ (t);
7759 initexpr = NULL_TREE; /* Not ref'd if !init. */
7761 finish_decl (t, initexpr, FALSE);
7763 if (st != NULL && DECL_SIZE (t) != error_mark_node)
7765 assert (TREE_CODE (DECL_SIZE_UNIT (t)) == INTEGER_CST);
7766 assert (TREE_INT_CST_HIGH (DECL_SIZE_UNIT (t)) == 0);
7767 assert (TREE_INT_CST_LOW (DECL_SIZE_UNIT (t))
7768 == ffestorag_size (st));
7771 resume_momentary (yes);
7776 case FFEINFO_whereRESULT:
7777 assert (!ffecom_transform_only_dummies_);
7779 if (bt == FFEINFO_basictypeCHARACTER)
7780 { /* Result is already in list of dummies, use
7782 t = ffecom_func_result_;
7783 tlen = ffecom_func_length_;
7787 if ((ffecom_num_entrypoints_ == 0)
7788 && (bt == FFEINFO_basictypeCOMPLEX)
7789 && (ffesymbol_is_f2c (ffecom_primary_entry_)))
7790 { /* Result is already in list of dummies, use
7792 t = ffecom_func_result_;
7796 if (ffecom_func_result_ != NULL_TREE)
7798 t = ffecom_func_result_;
7801 if ((ffecom_num_entrypoints_ != 0)
7802 && (ffecom_master_bt_ == FFEINFO_basictypeNONE))
7804 yes = suspend_momentary ();
7806 assert (ffecom_multi_retval_ != NULL_TREE);
7807 t = ffecom_1 (INDIRECT_REF, ffecom_multi_type_node_,
7808 ffecom_multi_retval_);
7809 t = ffecom_2 (COMPONENT_REF, ffecom_tree_type[bt][kt],
7810 t, ffecom_multi_fields_[bt][kt]);
7812 resume_momentary (yes);
7816 yes = suspend_momentary ();
7818 t = build_decl (VAR_DECL,
7819 ffecom_get_identifier_ (ffesymbol_text (s)),
7820 ffecom_tree_type[bt][kt]);
7821 TREE_STATIC (t) = 0; /* Put result on stack. */
7822 t = start_decl (t, FALSE);
7823 finish_decl (t, NULL_TREE, FALSE);
7825 ffecom_func_result_ = t;
7827 resume_momentary (yes);
7830 case FFEINFO_whereDUMMY:
7838 bool adjustable = FALSE; /* Conditionally adjustable? */
7840 type = ffecom_tree_type[bt][kt];
7841 if (ffesymbol_sfdummyparent (s) != NULL)
7843 if (current_function_decl == ffecom_outer_function_decl_)
7844 { /* Exec transition before sfunc
7845 context; get it later. */
7848 t = ffecom_get_identifier_ (ffesymbol_text
7849 (ffesymbol_sfdummyparent (s)));
7852 t = ffecom_get_identifier_ (ffesymbol_text (s));
7854 assert (ffecom_transform_only_dummies_);
7856 old_sizes = get_pending_sizes ();
7857 put_pending_sizes (old_sizes);
7859 if (bt == FFEINFO_basictypeCHARACTER)
7860 tlen = ffecom_char_enhance_arg_ (&type, s);
7861 type = ffecom_check_size_overflow_ (s, type, TRUE);
7863 for (dl = ffesymbol_dims (s); dl != NULL; dl = ffebld_trail (dl))
7865 if (type == error_mark_node)
7868 dim = ffebld_head (dl);
7869 assert (ffebld_op (dim) == FFEBLD_opBOUNDS);
7870 if ((ffebld_left (dim) == NULL) || ffecom_doing_entry_)
7871 low = ffecom_integer_one_node;
7873 low = ffecom_expr (ffebld_left (dim));
7874 assert (ffebld_right (dim) != NULL);
7875 if ((ffebld_op (ffebld_right (dim)) == FFEBLD_opSTAR)
7876 || ffecom_doing_entry_)
7878 /* Used to just do high=low. But for ffecom_tree_
7879 canonize_ref_, it probably is important to correctly
7880 assess the size. E.g. given COMPLEX C(*),CFUNC and
7881 C(2)=CFUNC(C), overlap can happen, while it can't
7882 for, say, C(1)=CFUNC(C(2)). */
7883 /* Even more recently used to set to INT_MAX, but that
7884 broke when some overflow checking went into the back
7885 end. Now we just leave the upper bound unspecified. */
7889 high = ffecom_expr (ffebld_right (dim));
7891 /* Determine whether array is conditionally adjustable,
7892 to decide whether back-end magic is needed.
7894 Normally the front end uses the back-end function
7895 variable_size to wrap SAVE_EXPR's around expressions
7896 affecting the size/shape of an array so that the
7897 size/shape info doesn't change during execution
7898 of the compiled code even though variables and
7899 functions referenced in those expressions might.
7901 variable_size also makes sure those saved expressions
7902 get evaluated immediately upon entry to the
7903 compiled procedure -- the front end normally doesn't
7904 have to worry about that.
7906 However, there is a problem with this that affects
7907 g77's implementation of entry points, and that is
7908 that it is _not_ true that each invocation of the
7909 compiled procedure is permitted to evaluate
7910 array size/shape info -- because it is possible
7911 that, for some invocations, that info is invalid (in
7912 which case it is "promised" -- i.e. a violation of
7913 the Fortran standard -- that the compiled code
7914 won't reference the array or its size/shape
7915 during that particular invocation).
7917 To phrase this in C terms, consider this gcc function:
7919 void foo (int *n, float (*a)[*n])
7921 // a is "pointer to array ...", fyi.
7924 Suppose that, for some invocations, it is permitted
7925 for a caller of foo to do this:
7929 Now the _written_ code for foo can take such a call
7930 into account by either testing explicitly for whether
7931 (a == NULL) || (n == NULL) -- presumably it is
7932 not permitted to reference *a in various fashions
7933 if (n == NULL) I suppose -- or it can avoid it by
7934 looking at other info (other arguments, static/global
7937 However, this won't work in gcc 2.5.8 because it'll
7938 automatically emit the code to save the "*n"
7939 expression, which'll yield a NULL dereference for
7940 the "foo (NULL, NULL)" call, something the code
7941 for foo cannot prevent.
7943 g77 definitely needs to avoid executing such
7944 code anytime the pointer to the adjustable array
7945 is NULL, because even if its bounds expressions
7946 don't have any references to possible "absent"
7947 variables like "*n" -- say all variable references
7948 are to COMMON variables, i.e. global (though in C,
7949 local static could actually make sense) -- the
7950 expressions could yield other run-time problems
7951 for allowably "dead" values in those variables.
7953 For example, let's consider a more complicated
7959 void foo (float (*a)[i/j])
7964 The above is (essentially) quite valid for Fortran
7965 but, again, for a call like "foo (NULL);", it is
7966 permitted for i and j to be undefined when the
7967 call is made. If j happened to be zero, for
7968 example, emitting the code to evaluate "i/j"
7969 could result in a run-time error.
7971 Offhand, though I don't have my F77 or F90
7972 standards handy, it might even be valid for a
7973 bounds expression to contain a function reference,
7974 in which case I doubt it is permitted for an
7975 implementation to invoke that function in the
7976 Fortran case involved here (invocation of an
7977 alternate ENTRY point that doesn't have the adjustable
7978 array as one of its arguments).
7980 So, the code that the compiler would normally emit
7981 to preevaluate the size/shape info for an
7982 adjustable array _must not_ be executed at run time
7983 in certain cases. Specifically, for Fortran,
7984 the case is when the pointer to the adjustable
7985 array == NULL. (For gnu-ish C, it might be nice
7986 for the source code itself to specify an expression
7987 that, if TRUE, inhibits execution of the code. Or
7988 reverse the sense for elegance.)
7990 (Note that g77 could use a different test than NULL,
7991 actually, since it happens to always pass an
7992 integer to the called function that specifies which
7993 entry point is being invoked. Hmm, this might
7994 solve the next problem.)
7996 One way a user could, I suppose, write "foo" so
7997 it works is to insert COND_EXPR's for the
7998 size/shape info so the dangerous stuff isn't
7999 actually done, as in:
8001 void foo (int *n, float (*a)[(a == NULL) ? 0 : *n])
8006 The next problem is that the front end needs to
8007 be able to tell the back end about the array's
8008 decl _before_ it tells it about the conditional
8009 expression to inhibit evaluation of size/shape info,
8012 To solve this, the front end needs to be able
8013 to give the back end the expression to inhibit
8014 generation of the preevaluation code _after_
8015 it makes the decl for the adjustable array.
8017 Until then, the above example using the COND_EXPR
8018 doesn't pass muster with gcc because the "(a == NULL)"
8019 part has a reference to "a", which is still
8020 undefined at that point.
8022 g77 will therefore use a different mechanism in the
8026 && ((TREE_CODE (low) != INTEGER_CST)
8027 || (high && TREE_CODE (high) != INTEGER_CST)))
8030 #if 0 /* Old approach -- see below. */
8031 if (TREE_CODE (low) != INTEGER_CST)
8032 low = ffecom_3 (COND_EXPR, integer_type_node,
8033 ffecom_adjarray_passed_ (s),
8035 ffecom_integer_zero_node);
8037 if (high && TREE_CODE (high) != INTEGER_CST)
8038 high = ffecom_3 (COND_EXPR, integer_type_node,
8039 ffecom_adjarray_passed_ (s),
8041 ffecom_integer_zero_node);
8044 /* ~~~gcc/stor-layout.c (layout_type) should do this,
8045 probably. Fixes 950302-1.f. */
8047 if (TREE_CODE (low) != INTEGER_CST)
8048 low = variable_size (low);
8050 /* ~~~Similarly, this fixes dumb0.f. The C front end
8051 does this, which is why dumb0.c would work. */
8053 if (high && TREE_CODE (high) != INTEGER_CST)
8054 high = variable_size (high);
8059 build_range_type (ffecom_integer_type_node,
8061 type = ffecom_check_size_overflow_ (s, type, TRUE);
8064 if (type == error_mark_node)
8066 t = error_mark_node;
8070 if ((ffesymbol_sfdummyparent (s) == NULL)
8071 || (ffesymbol_basictype (s) == FFEINFO_basictypeCHARACTER))
8073 type = build_pointer_type (type);
8077 t = build_decl (PARM_DECL, t, type);
8079 DECL_ARTIFICIAL (t) = 1;
8082 /* If this arg is present in every entry point's list of
8083 dummy args, then we're done. */
8085 if (ffesymbol_numentries (s)
8086 == (ffecom_num_entrypoints_ + 1))
8091 /* If variable_size in stor-layout has been called during
8092 the above, then get_pending_sizes should have the
8093 yet-to-be-evaluated saved expressions pending.
8094 Make the whole lot of them get emitted, conditionally
8095 on whether the array decl ("t" above) is not NULL. */
8098 tree sizes = get_pending_sizes ();
8103 tem = TREE_CHAIN (tem))
8105 tree temv = TREE_VALUE (tem);
8111 = ffecom_2 (COMPOUND_EXPR,
8120 = ffecom_3 (COND_EXPR,
8127 convert (TREE_TYPE (sizes),
8128 integer_zero_node));
8129 sizes = ffecom_save_tree (sizes);
8132 = tree_cons (NULL_TREE, sizes, tem);
8136 put_pending_sizes (sizes);
8142 && (ffesymbol_numentries (s)
8143 != ffecom_num_entrypoints_ + 1))
8145 = ffecom_2 (NE_EXPR, integer_type_node,
8151 && (ffesymbol_numentries (s)
8152 != ffecom_num_entrypoints_ + 1))
8154 ffebad_start (FFEBAD_MISSING_ADJARRAY_UNSUPPORTED);
8155 ffebad_here (0, ffesymbol_where_line (s),
8156 ffesymbol_where_column (s));
8157 ffebad_string (ffesymbol_text (s));
8166 case FFEINFO_whereCOMMON:
8171 ffestorag st = ffesymbol_storage (s);
8175 cs = ffesymbol_common (s); /* The COMMON area itself. */
8176 if (st != NULL) /* Else not laid out. */
8178 ffecom_transform_common_ (cs);
8179 st = ffesymbol_storage (s);
8182 yes = suspend_momentary ();
8184 type = ffecom_type_localvar_ (s, bt, kt);
8186 cg = ffesymbol_global (cs); /* The global COMMON info. */
8188 || (ffeglobal_type (cg) != FFEGLOBAL_typeCOMMON))
8191 ct = ffeglobal_hook (cg); /* The common area's tree. */
8193 if ((ct == NULL_TREE)
8195 || (type == error_mark_node))
8196 t = error_mark_node;
8199 ffetargetOffset offset;
8202 cst = ffestorag_parent (st);
8203 assert (cst == ffesymbol_storage (cs));
8205 offset = ffestorag_modulo (cst)
8206 + ffestorag_offset (st)
8207 - ffestorag_offset (cst);
8209 ffecom_debug_kludge_ (ct, "COMMON", s, type, offset);
8211 /* (t_type *) (((char *) &ct) + offset) */
8213 t = convert (string_type_node, /* (char *) */
8214 ffecom_1 (ADDR_EXPR,
8215 build_pointer_type (TREE_TYPE (ct)),
8217 t = ffecom_2 (PLUS_EXPR, TREE_TYPE (t),
8219 build_int_2 (offset, 0));
8220 t = convert (build_pointer_type (type),
8222 TREE_CONSTANT (t) = 1;
8227 resume_momentary (yes);
8231 case FFEINFO_whereIMMEDIATE:
8232 case FFEINFO_whereGLOBAL:
8233 case FFEINFO_whereFLEETING:
8234 case FFEINFO_whereFLEETING_CADDR:
8235 case FFEINFO_whereFLEETING_IADDR:
8236 case FFEINFO_whereINTRINSIC:
8237 case FFEINFO_whereCONSTANT_SUBOBJECT:
8239 assert ("ENTITY where unheard of" == NULL);
8241 case FFEINFO_whereANY:
8242 t = error_mark_node;
8247 case FFEINFO_kindFUNCTION:
8248 switch (ffeinfo_where (ffesymbol_info (s)))
8250 case FFEINFO_whereLOCAL: /* Me. */
8251 assert (!ffecom_transform_only_dummies_);
8252 t = current_function_decl;
8255 case FFEINFO_whereGLOBAL:
8256 assert (!ffecom_transform_only_dummies_);
8258 if (((g = ffesymbol_global (s)) != NULL)
8259 && ((ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
8260 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
8261 && (ffeglobal_hook (g) != NULL_TREE)
8262 && ffe_is_globals ())
8264 t = ffeglobal_hook (g);
8268 if (ffesymbol_is_f2c (s)
8269 && (ffesymbol_where (s) != FFEINFO_whereCONSTANT))
8270 t = ffecom_tree_fun_type[bt][kt];
8272 t = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
8274 t = build_decl (FUNCTION_DECL,
8275 ffecom_get_external_identifier_ (s),
8277 DECL_EXTERNAL (t) = 1;
8278 TREE_PUBLIC (t) = 1;
8280 t = start_decl (t, FALSE);
8281 finish_decl (t, NULL_TREE, FALSE);
8284 && ((ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
8285 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
8286 ffeglobal_set_hook (g, t);
8288 ffecom_save_tree_forever (t);
8292 case FFEINFO_whereDUMMY:
8293 assert (ffecom_transform_only_dummies_);
8295 if (ffesymbol_is_f2c (s)
8296 && (ffesymbol_where (s) != FFEINFO_whereCONSTANT))
8297 t = ffecom_tree_ptr_to_fun_type[bt][kt];
8299 t = build_pointer_type
8300 (build_function_type (ffecom_tree_type[bt][kt], NULL_TREE));
8302 t = build_decl (PARM_DECL,
8303 ffecom_get_identifier_ (ffesymbol_text (s)),
8306 DECL_ARTIFICIAL (t) = 1;
8311 case FFEINFO_whereCONSTANT: /* Statement function. */
8312 assert (!ffecom_transform_only_dummies_);
8313 t = ffecom_gen_sfuncdef_ (s, bt, kt);
8316 case FFEINFO_whereINTRINSIC:
8317 assert (!ffecom_transform_only_dummies_);
8318 break; /* Let actual references generate their
8322 assert ("FUNCTION where unheard of" == NULL);
8324 case FFEINFO_whereANY:
8325 t = error_mark_node;
8330 case FFEINFO_kindSUBROUTINE:
8331 switch (ffeinfo_where (ffesymbol_info (s)))
8333 case FFEINFO_whereLOCAL: /* Me. */
8334 assert (!ffecom_transform_only_dummies_);
8335 t = current_function_decl;
8338 case FFEINFO_whereGLOBAL:
8339 assert (!ffecom_transform_only_dummies_);
8341 if (((g = ffesymbol_global (s)) != NULL)
8342 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
8343 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
8344 && (ffeglobal_hook (g) != NULL_TREE)
8345 && ffe_is_globals ())
8347 t = ffeglobal_hook (g);
8351 t = build_decl (FUNCTION_DECL,
8352 ffecom_get_external_identifier_ (s),
8353 ffecom_tree_subr_type);
8354 DECL_EXTERNAL (t) = 1;
8355 TREE_PUBLIC (t) = 1;
8357 t = start_decl (t, FALSE);
8358 finish_decl (t, NULL_TREE, FALSE);
8361 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
8362 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
8363 ffeglobal_set_hook (g, t);
8365 ffecom_save_tree_forever (t);
8369 case FFEINFO_whereDUMMY:
8370 assert (ffecom_transform_only_dummies_);
8372 t = build_decl (PARM_DECL,
8373 ffecom_get_identifier_ (ffesymbol_text (s)),
8374 ffecom_tree_ptr_to_subr_type);
8376 DECL_ARTIFICIAL (t) = 1;
8381 case FFEINFO_whereINTRINSIC:
8382 assert (!ffecom_transform_only_dummies_);
8383 break; /* Let actual references generate their
8387 assert ("SUBROUTINE where unheard of" == NULL);
8389 case FFEINFO_whereANY:
8390 t = error_mark_node;
8395 case FFEINFO_kindPROGRAM:
8396 switch (ffeinfo_where (ffesymbol_info (s)))
8398 case FFEINFO_whereLOCAL: /* Me. */
8399 assert (!ffecom_transform_only_dummies_);
8400 t = current_function_decl;
8403 case FFEINFO_whereCOMMON:
8404 case FFEINFO_whereDUMMY:
8405 case FFEINFO_whereGLOBAL:
8406 case FFEINFO_whereRESULT:
8407 case FFEINFO_whereFLEETING:
8408 case FFEINFO_whereFLEETING_CADDR:
8409 case FFEINFO_whereFLEETING_IADDR:
8410 case FFEINFO_whereIMMEDIATE:
8411 case FFEINFO_whereINTRINSIC:
8412 case FFEINFO_whereCONSTANT:
8413 case FFEINFO_whereCONSTANT_SUBOBJECT:
8415 assert ("PROGRAM where unheard of" == NULL);
8417 case FFEINFO_whereANY:
8418 t = error_mark_node;
8423 case FFEINFO_kindBLOCKDATA:
8424 switch (ffeinfo_where (ffesymbol_info (s)))
8426 case FFEINFO_whereLOCAL: /* Me. */
8427 assert (!ffecom_transform_only_dummies_);
8428 t = current_function_decl;
8431 case FFEINFO_whereGLOBAL:
8432 assert (!ffecom_transform_only_dummies_);
8434 t = build_decl (FUNCTION_DECL,
8435 ffecom_get_external_identifier_ (s),
8436 ffecom_tree_blockdata_type);
8437 DECL_EXTERNAL (t) = 1;
8438 TREE_PUBLIC (t) = 1;
8440 t = start_decl (t, FALSE);
8441 finish_decl (t, NULL_TREE, FALSE);
8443 ffecom_save_tree_forever (t);
8447 case FFEINFO_whereCOMMON:
8448 case FFEINFO_whereDUMMY:
8449 case FFEINFO_whereRESULT:
8450 case FFEINFO_whereFLEETING:
8451 case FFEINFO_whereFLEETING_CADDR:
8452 case FFEINFO_whereFLEETING_IADDR:
8453 case FFEINFO_whereIMMEDIATE:
8454 case FFEINFO_whereINTRINSIC:
8455 case FFEINFO_whereCONSTANT:
8456 case FFEINFO_whereCONSTANT_SUBOBJECT:
8458 assert ("BLOCKDATA where unheard of" == NULL);
8460 case FFEINFO_whereANY:
8461 t = error_mark_node;
8466 case FFEINFO_kindCOMMON:
8467 switch (ffeinfo_where (ffesymbol_info (s)))
8469 case FFEINFO_whereLOCAL:
8470 assert (!ffecom_transform_only_dummies_);
8471 ffecom_transform_common_ (s);
8474 case FFEINFO_whereNONE:
8475 case FFEINFO_whereCOMMON:
8476 case FFEINFO_whereDUMMY:
8477 case FFEINFO_whereGLOBAL:
8478 case FFEINFO_whereRESULT:
8479 case FFEINFO_whereFLEETING:
8480 case FFEINFO_whereFLEETING_CADDR:
8481 case FFEINFO_whereFLEETING_IADDR:
8482 case FFEINFO_whereIMMEDIATE:
8483 case FFEINFO_whereINTRINSIC:
8484 case FFEINFO_whereCONSTANT:
8485 case FFEINFO_whereCONSTANT_SUBOBJECT:
8487 assert ("COMMON where unheard of" == NULL);
8489 case FFEINFO_whereANY:
8490 t = error_mark_node;
8495 case FFEINFO_kindCONSTRUCT:
8496 switch (ffeinfo_where (ffesymbol_info (s)))
8498 case FFEINFO_whereLOCAL:
8499 assert (!ffecom_transform_only_dummies_);
8502 case FFEINFO_whereNONE:
8503 case FFEINFO_whereCOMMON:
8504 case FFEINFO_whereDUMMY:
8505 case FFEINFO_whereGLOBAL:
8506 case FFEINFO_whereRESULT:
8507 case FFEINFO_whereFLEETING:
8508 case FFEINFO_whereFLEETING_CADDR:
8509 case FFEINFO_whereFLEETING_IADDR:
8510 case FFEINFO_whereIMMEDIATE:
8511 case FFEINFO_whereINTRINSIC:
8512 case FFEINFO_whereCONSTANT:
8513 case FFEINFO_whereCONSTANT_SUBOBJECT:
8515 assert ("CONSTRUCT where unheard of" == NULL);
8517 case FFEINFO_whereANY:
8518 t = error_mark_node;
8523 case FFEINFO_kindNAMELIST:
8524 switch (ffeinfo_where (ffesymbol_info (s)))
8526 case FFEINFO_whereLOCAL:
8527 assert (!ffecom_transform_only_dummies_);
8528 t = ffecom_transform_namelist_ (s);
8531 case FFEINFO_whereNONE:
8532 case FFEINFO_whereCOMMON:
8533 case FFEINFO_whereDUMMY:
8534 case FFEINFO_whereGLOBAL:
8535 case FFEINFO_whereRESULT:
8536 case FFEINFO_whereFLEETING:
8537 case FFEINFO_whereFLEETING_CADDR:
8538 case FFEINFO_whereFLEETING_IADDR:
8539 case FFEINFO_whereIMMEDIATE:
8540 case FFEINFO_whereINTRINSIC:
8541 case FFEINFO_whereCONSTANT:
8542 case FFEINFO_whereCONSTANT_SUBOBJECT:
8544 assert ("NAMELIST where unheard of" == NULL);
8546 case FFEINFO_whereANY:
8547 t = error_mark_node;
8553 assert ("kind unheard of" == NULL);
8555 case FFEINFO_kindANY:
8556 t = error_mark_node;
8560 ffesymbol_hook (s).decl_tree = t;
8561 ffesymbol_hook (s).length_tree = tlen;
8562 ffesymbol_hook (s).addr = addr;
8564 lineno = old_lineno;
8565 input_filename = old_input_filename;
8571 /* Transform into ASSIGNable symbol.
8573 Symbol has already been transformed, but for whatever reason, the
8574 resulting decl_tree has been deemed not usable for an ASSIGN target.
8575 (E.g. it isn't wide enough to hold a pointer.) So, here we invent
8576 another local symbol of type void * and stuff that in the assign_tree
8577 argument. The F77/F90 standards allow this implementation. */
8579 #if FFECOM_targetCURRENT == FFECOM_targetGCC
8581 ffecom_sym_transform_assign_ (ffesymbol s)
8583 tree t; /* Transformed thingy. */
8585 int old_lineno = lineno;
8586 char *old_input_filename = input_filename;
8588 if (ffesymbol_sfdummyparent (s) == NULL)
8590 input_filename = ffesymbol_where_filename (s);
8591 lineno = ffesymbol_where_filelinenum (s);
8595 ffesymbol sf = ffesymbol_sfdummyparent (s);
8597 input_filename = ffesymbol_where_filename (sf);
8598 lineno = ffesymbol_where_filelinenum (sf);
8601 assert (!ffecom_transform_only_dummies_);
8603 yes = suspend_momentary ();
8605 t = build_decl (VAR_DECL,
8606 ffecom_get_invented_identifier ("__g77_ASSIGN_%s",
8607 ffesymbol_text (s)),
8608 TREE_TYPE (null_pointer_node));
8610 switch (ffesymbol_where (s))
8612 case FFEINFO_whereLOCAL:
8613 /* Unlike for regular vars, SAVE status is easy to determine for
8614 ASSIGNed vars, since there's no initialization, there's no
8615 effective storage association (so "SAVE J" does not apply to
8616 K even given "EQUIVALENCE (J,K)"), there's no size issue
8617 to worry about, etc. */
8618 if ((ffesymbol_is_save (s) || ffe_is_saveall ())
8619 && (ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
8620 && (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA))
8621 TREE_STATIC (t) = 1; /* SAVEd in proc, make static. */
8623 TREE_STATIC (t) = 0; /* No need to make static. */
8626 case FFEINFO_whereCOMMON:
8627 TREE_STATIC (t) = 1; /* Assume COMMONs always SAVEd. */
8630 case FFEINFO_whereDUMMY:
8631 /* Note that twinning a DUMMY means the caller won't see
8632 the ASSIGNed value. But both F77 and F90 allow implementations
8633 to do this, i.e. disallow Fortran code that would try and
8634 take advantage of actually putting a label into a variable
8635 via a dummy argument (or any other storage association, for
8637 TREE_STATIC (t) = 0;
8641 TREE_STATIC (t) = 0;
8645 t = start_decl (t, FALSE);
8646 finish_decl (t, NULL_TREE, FALSE);
8648 resume_momentary (yes);
8650 ffesymbol_hook (s).assign_tree = t;
8652 lineno = old_lineno;
8653 input_filename = old_input_filename;
8659 /* Implement COMMON area in back end.
8661 Because COMMON-based variables can be referenced in the dimension
8662 expressions of dummy (adjustable) arrays, and because dummies
8663 (in the gcc back end) need to be put in the outer binding level
8664 of a function (which has two binding levels, the outer holding
8665 the dummies and the inner holding the other vars), special care
8666 must be taken to handle COMMON areas.
8668 The current strategy is basically to always tell the back end about
8669 the COMMON area as a top-level external reference to just a block
8670 of storage of the master type of that area (e.g. integer, real,
8671 character, whatever -- not a structure). As a distinct action,
8672 if initial values are provided, tell the back end about the area
8673 as a top-level non-external (initialized) area and remember not to
8674 allow further initialization or expansion of the area. Meanwhile,
8675 if no initialization happens at all, tell the back end about
8676 the largest size we've seen declared so the space does get reserved.
8677 (This function doesn't handle all that stuff, but it does some
8678 of the important things.)
8680 Meanwhile, for COMMON variables themselves, just keep creating
8681 references like *((float *) (&common_area + offset)) each time
8682 we reference the variable. In other words, don't make a VAR_DECL
8683 or any kind of component reference (like we used to do before 0.4),
8684 though we might do that as well just for debugging purposes (and
8685 stuff the rtl with the appropriate offset expression). */
8687 #if FFECOM_targetCURRENT == FFECOM_targetGCC
8689 ffecom_transform_common_ (ffesymbol s)
8691 ffestorag st = ffesymbol_storage (s);
8692 ffeglobal g = ffesymbol_global (s);
8697 bool is_init = ffestorag_is_init (st);
8699 assert (st != NULL);
8702 || (ffeglobal_type (g) != FFEGLOBAL_typeCOMMON))
8705 /* First update the size of the area in global terms. */
8707 ffeglobal_size_common (s, ffestorag_size (st));
8709 if (!ffeglobal_common_init (g))
8710 is_init = FALSE; /* No explicit init, don't let erroneous joins init. */
8712 cbt = ffeglobal_hook (g);
8714 /* If we already have declared this common block for a previous program
8715 unit, and either we already initialized it or we don't have new
8716 initialization for it, just return what we have without changing it. */
8718 if ((cbt != NULL_TREE)
8720 || !DECL_EXTERNAL (cbt)))
8722 if (st->hook == NULL) ffestorag_set_hook (st, cbt);
8726 /* Process inits. */
8730 if (ffestorag_init (st) != NULL)
8734 /* Set the padding for the expression, so ffecom_expr
8735 knows to insert that many zeros. */
8736 switch (ffebld_op (sexp = ffestorag_init (st)))
8738 case FFEBLD_opCONTER:
8739 ffebld_conter_set_pad (sexp, ffestorag_modulo (st));
8742 case FFEBLD_opARRTER:
8743 ffebld_arrter_set_pad (sexp, ffestorag_modulo (st));
8746 case FFEBLD_opACCTER:
8747 ffebld_accter_set_pad (sexp, ffestorag_modulo (st));
8751 assert ("bad op for cmn init (pad)" == NULL);
8755 init = ffecom_expr (sexp);
8756 if (init == error_mark_node)
8757 { /* Hopefully the back end complained! */
8759 if (cbt != NULL_TREE)
8764 init = error_mark_node;
8769 /* cbtype must be permanently allocated! */
8771 /* Allocate the MAX of the areas so far, seen filewide. */
8772 high = build_int_2 ((ffeglobal_common_size (g)
8773 + ffeglobal_common_pad (g)) - 1, 0);
8774 TREE_TYPE (high) = ffecom_integer_type_node;
8777 cbtype = build_array_type (char_type_node,
8778 build_range_type (integer_type_node,
8782 cbtype = build_array_type (char_type_node, NULL_TREE);
8784 if (cbt == NULL_TREE)
8787 = build_decl (VAR_DECL,
8788 ffecom_get_external_identifier_ (s),
8790 TREE_STATIC (cbt) = 1;
8791 TREE_PUBLIC (cbt) = 1;
8796 TREE_TYPE (cbt) = cbtype;
8798 DECL_EXTERNAL (cbt) = init ? 0 : 1;
8799 DECL_INITIAL (cbt) = init ? error_mark_node : NULL_TREE;
8801 cbt = start_decl (cbt, TRUE);
8802 if (ffeglobal_hook (g) != NULL)
8803 assert (cbt == ffeglobal_hook (g));
8805 assert (!init || !DECL_EXTERNAL (cbt));
8807 /* Make sure that any type can live in COMMON and be referenced
8808 without getting a bus error. We could pick the most restrictive
8809 alignment of all entities actually placed in the COMMON, but
8810 this seems easy enough. */
8812 DECL_ALIGN (cbt) = BIGGEST_ALIGNMENT;
8814 if (is_init && (ffestorag_init (st) == NULL))
8815 init = ffecom_init_zero_ (cbt);
8817 finish_decl (cbt, init, TRUE);
8820 ffestorag_set_init (st, ffebld_new_any ());
8824 assert (DECL_SIZE_UNIT (cbt) != NULL_TREE);
8825 assert (TREE_CODE (DECL_SIZE_UNIT (cbt)) == INTEGER_CST);
8826 assert (TREE_INT_CST_HIGH (DECL_SIZE_UNIT (cbt)) == 0);
8827 assert (TREE_INT_CST_LOW (DECL_SIZE_UNIT (cbt))
8828 == ffeglobal_common_size (g) + ffeglobal_common_pad (g));
8831 ffeglobal_set_hook (g, cbt);
8833 ffestorag_set_hook (st, cbt);
8835 ffecom_save_tree_forever (cbt);
8839 /* Make master area for local EQUIVALENCE. */
8841 #if FFECOM_targetCURRENT == FFECOM_targetGCC
8843 ffecom_transform_equiv_ (ffestorag eqst)
8849 bool is_init = ffestorag_is_init (eqst);
8852 assert (eqst != NULL);
8854 eqt = ffestorag_hook (eqst);
8856 if (eqt != NULL_TREE)
8859 /* Process inits. */
8863 if (ffestorag_init (eqst) != NULL)
8867 /* Set the padding for the expression, so ffecom_expr
8868 knows to insert that many zeros. */
8869 switch (ffebld_op (sexp = ffestorag_init (eqst)))
8871 case FFEBLD_opCONTER:
8872 ffebld_conter_set_pad (sexp, ffestorag_modulo (eqst));
8875 case FFEBLD_opARRTER:
8876 ffebld_arrter_set_pad (sexp, ffestorag_modulo (eqst));
8879 case FFEBLD_opACCTER:
8880 ffebld_accter_set_pad (sexp, ffestorag_modulo (eqst));
8884 assert ("bad op for eqv init (pad)" == NULL);
8888 init = ffecom_expr (sexp);
8889 if (init == error_mark_node)
8890 init = NULL_TREE; /* Hopefully the back end complained! */
8893 init = error_mark_node;
8895 else if (ffe_is_init_local_zero ())
8896 init = error_mark_node;
8900 ffecom_member_namelisted_ = FALSE;
8901 ffestorag_drive (ffestorag_list_equivs (eqst),
8902 &ffecom_member_phase1_,
8905 yes = suspend_momentary ();
8907 high = build_int_2 ((ffestorag_size (eqst)
8908 + ffestorag_modulo (eqst)) - 1, 0);
8909 TREE_TYPE (high) = ffecom_integer_type_node;
8911 eqtype = build_array_type (char_type_node,
8912 build_range_type (ffecom_integer_type_node,
8913 ffecom_integer_zero_node,
8916 eqt = build_decl (VAR_DECL,
8917 ffecom_get_invented_identifier ("__g77_equiv_%s",
8919 (ffestorag_symbol (eqst))),
8921 DECL_EXTERNAL (eqt) = 0;
8923 || ffecom_member_namelisted_
8924 #ifdef FFECOM_sizeMAXSTACKITEM
8925 || (ffestorag_size (eqst) > FFECOM_sizeMAXSTACKITEM)
8927 || ((ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
8928 && (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA)
8929 && (ffestorag_is_save (eqst) || ffe_is_saveall ())))
8930 TREE_STATIC (eqt) = 1;
8932 TREE_STATIC (eqt) = 0;
8933 TREE_PUBLIC (eqt) = 0;
8934 DECL_CONTEXT (eqt) = current_function_decl;
8936 DECL_INITIAL (eqt) = error_mark_node;
8938 DECL_INITIAL (eqt) = NULL_TREE;
8940 eqt = start_decl (eqt, FALSE);
8942 /* Make sure that any type can live in EQUIVALENCE and be referenced
8943 without getting a bus error. We could pick the most restrictive
8944 alignment of all entities actually placed in the EQUIVALENCE, but
8945 this seems easy enough. */
8947 DECL_ALIGN (eqt) = BIGGEST_ALIGNMENT;
8949 if ((!is_init && ffe_is_init_local_zero ())
8950 || (is_init && (ffestorag_init (eqst) == NULL)))
8951 init = ffecom_init_zero_ (eqt);
8953 finish_decl (eqt, init, FALSE);
8956 ffestorag_set_init (eqst, ffebld_new_any ());
8959 assert (TREE_CODE (DECL_SIZE_UNIT (eqt)) == INTEGER_CST);
8960 assert (TREE_INT_CST_HIGH (DECL_SIZE_UNIT (eqt)) == 0);
8961 assert (TREE_INT_CST_LOW (DECL_SIZE_UNIT (eqt))
8962 == ffestorag_size (eqst) + ffestorag_modulo (eqst));
8965 ffestorag_set_hook (eqst, eqt);
8967 #ifdef SOMEONE_GETS_DEBUG_SUPPORT_WORKING
8968 ffestorag_drive (ffestorag_list_equivs (eqst),
8969 &ffecom_member_phase2_,
8973 resume_momentary (yes);
8977 /* Implement NAMELIST in back end. See f2c/format.c for more info. */
8979 #if FFECOM_targetCURRENT == FFECOM_targetGCC
8981 ffecom_transform_namelist_ (ffesymbol s)
8984 tree nmltype = ffecom_type_namelist_ ();
8993 static int mynumber = 0;
8995 yes = suspend_momentary ();
8997 nmlt = build_decl (VAR_DECL,
8998 ffecom_get_invented_identifier ("__g77_namelist_%d",
9001 TREE_STATIC (nmlt) = 1;
9002 DECL_INITIAL (nmlt) = error_mark_node;
9004 nmlt = start_decl (nmlt, FALSE);
9006 /* Process inits. */
9008 i = strlen (ffesymbol_text (s));
9010 high = build_int_2 (i, 0);
9011 TREE_TYPE (high) = ffecom_f2c_ftnlen_type_node;
9013 nameinit = ffecom_build_f2c_string_ (i + 1,
9014 ffesymbol_text (s));
9015 TREE_TYPE (nameinit)
9016 = build_type_variant
9019 build_range_type (ffecom_f2c_ftnlen_type_node,
9020 ffecom_f2c_ftnlen_one_node,
9023 TREE_CONSTANT (nameinit) = 1;
9024 TREE_STATIC (nameinit) = 1;
9025 nameinit = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (nameinit)),
9028 varsinit = ffecom_vardesc_array_ (s);
9029 varsinit = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (varsinit)),
9031 TREE_CONSTANT (varsinit) = 1;
9032 TREE_STATIC (varsinit) = 1;
9037 for (i = 0, b = ffesymbol_namelist (s); b != NULL; b = ffebld_trail (b))
9040 nvarsinit = build_int_2 (i, 0);
9041 TREE_TYPE (nvarsinit) = integer_type_node;
9042 TREE_CONSTANT (nvarsinit) = 1;
9043 TREE_STATIC (nvarsinit) = 1;
9045 nmlinits = build_tree_list ((field = TYPE_FIELDS (nmltype)), nameinit);
9046 TREE_CHAIN (nmlinits) = build_tree_list ((field = TREE_CHAIN (field)),
9048 TREE_CHAIN (TREE_CHAIN (nmlinits))
9049 = build_tree_list ((field = TREE_CHAIN (field)), nvarsinit);
9051 nmlinits = build (CONSTRUCTOR, nmltype, NULL_TREE, nmlinits);
9052 TREE_CONSTANT (nmlinits) = 1;
9053 TREE_STATIC (nmlinits) = 1;
9055 finish_decl (nmlt, nmlinits, FALSE);
9057 nmlt = ffecom_1 (ADDR_EXPR, build_pointer_type (nmltype), nmlt);
9059 resume_momentary (yes);
9066 /* A subroutine of ffecom_tree_canonize_ref_. The incoming tree is
9067 analyzed on the assumption it is calculating a pointer to be
9068 indirected through. It must return the proper decl and offset,
9069 taking into account different units of measurements for offsets. */
9071 #if FFECOM_targetCURRENT == FFECOM_targetGCC
9073 ffecom_tree_canonize_ptr_ (tree *decl, tree *offset,
9076 switch (TREE_CODE (t))
9080 case NON_LVALUE_EXPR:
9081 ffecom_tree_canonize_ptr_ (decl, offset, TREE_OPERAND (t, 0));
9085 ffecom_tree_canonize_ptr_ (decl, offset, TREE_OPERAND (t, 0));
9086 if ((*decl == NULL_TREE)
9087 || (*decl == error_mark_node))
9090 if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST)
9092 /* An offset into COMMON. */
9093 *offset = fold (build (PLUS_EXPR, TREE_TYPE (*offset),
9094 *offset, TREE_OPERAND (t, 1)));
9095 /* Convert offset (presumably in bytes) into canonical units
9096 (presumably bits). */
9097 *offset = fold (build (MULT_EXPR, TREE_TYPE (*offset),
9098 TYPE_SIZE (TREE_TYPE (TREE_TYPE (t))),
9102 /* Not a COMMON reference, so an unrecognized pattern. */
9103 *decl = error_mark_node;
9108 *offset = bitsize_int (0);
9112 if (TREE_CODE (TREE_OPERAND (t, 0)) == VAR_DECL)
9114 /* A reference to COMMON. */
9115 *decl = TREE_OPERAND (t, 0);
9116 *offset = bitsize_int (0);
9121 /* Not a COMMON reference, so an unrecognized pattern. */
9122 *decl = error_mark_node;
9128 /* Given a tree that is possibly intended for use as an lvalue, return
9129 information representing a canonical view of that tree as a decl, an
9130 offset into that decl, and a size for the lvalue.
9132 If there's no applicable decl, NULL_TREE is returned for the decl,
9133 and the other fields are left undefined.
9135 If the tree doesn't fit the recognizable forms, an ERROR_MARK node
9136 is returned for the decl, and the other fields are left undefined.
9138 Otherwise, the decl returned currently is either a VAR_DECL or a
9141 The offset returned is always valid, but of course not necessarily
9142 a constant, and not necessarily converted into the appropriate
9143 type, leaving that up to the caller (so as to avoid that overhead
9144 if the decls being looked at are different anyway).
9146 If the size cannot be determined (e.g. an adjustable array),
9147 an ERROR_MARK node is returned for the size. Otherwise, the
9148 size returned is valid, not necessarily a constant, and not
9149 necessarily converted into the appropriate type as with the
9152 Note that the offset and size expressions are expressed in the
9153 base storage units (usually bits) rather than in the units of
9154 the type of the decl, because two decls with different types
9155 might overlap but with apparently non-overlapping array offsets,
9156 whereas converting the array offsets to consistant offsets will
9157 reveal the overlap. */
9159 #if FFECOM_targetCURRENT == FFECOM_targetGCC
9161 ffecom_tree_canonize_ref_ (tree *decl, tree *offset,
9164 /* The default path is to report a nonexistant decl. */
9170 switch (TREE_CODE (t))
9173 case IDENTIFIER_NODE:
9182 case TRUNC_DIV_EXPR:
9184 case FLOOR_DIV_EXPR:
9185 case ROUND_DIV_EXPR:
9186 case TRUNC_MOD_EXPR:
9188 case FLOOR_MOD_EXPR:
9189 case ROUND_MOD_EXPR:
9191 case EXACT_DIV_EXPR:
9192 case FIX_TRUNC_EXPR:
9194 case FIX_FLOOR_EXPR:
9195 case FIX_ROUND_EXPR:
9210 case BIT_ANDTC_EXPR:
9212 case TRUTH_ANDIF_EXPR:
9213 case TRUTH_ORIF_EXPR:
9214 case TRUTH_AND_EXPR:
9216 case TRUTH_XOR_EXPR:
9217 case TRUTH_NOT_EXPR:
9237 *offset = bitsize_int (0);
9238 *size = TYPE_SIZE (TREE_TYPE (t));
9243 tree array = TREE_OPERAND (t, 0);
9244 tree element = TREE_OPERAND (t, 1);
9247 if ((array == NULL_TREE)
9248 || (element == NULL_TREE))
9250 *decl = error_mark_node;
9254 ffecom_tree_canonize_ref_ (decl, &init_offset, size,
9256 if ((*decl == NULL_TREE)
9257 || (*decl == error_mark_node))
9261 = size_binop (MULT_EXPR,
9262 TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))),
9264 fold (build (MINUS_EXPR, TREE_TYPE (element),
9268 (TREE_TYPE (array)))))));;
9270 *offset = size_binop (PLUS_EXPR, convert (sizetype, init_offset),
9273 *size = TYPE_SIZE (TREE_TYPE (t));
9279 /* Most of this code is to handle references to COMMON. And so
9280 far that is useful only for calling library functions, since
9281 external (user) functions might reference common areas. But
9282 even calling an external function, it's worthwhile to decode
9283 COMMON references because if not storing into COMMON, we don't
9284 want COMMON-based arguments to gratuitously force use of a
9287 *size = TYPE_SIZE (TREE_TYPE (t));
9289 ffecom_tree_canonize_ptr_ (decl, offset,
9290 TREE_OPERAND (t, 0));
9297 case NON_LVALUE_EXPR:
9300 case COND_EXPR: /* More cases than we can handle. */
9302 case REFERENCE_EXPR:
9303 case PREDECREMENT_EXPR:
9304 case PREINCREMENT_EXPR:
9305 case POSTDECREMENT_EXPR:
9306 case POSTINCREMENT_EXPR:
9309 *decl = error_mark_node;
9315 /* Do divide operation appropriate to type of operands. */
9317 #if FFECOM_targetCURRENT == FFECOM_targetGCC
9319 ffecom_tree_divide_ (tree tree_type, tree left, tree right,
9320 tree dest_tree, ffebld dest, bool *dest_used,
9323 if ((left == error_mark_node)
9324 || (right == error_mark_node))
9325 return error_mark_node;
9327 switch (TREE_CODE (tree_type))
9330 return ffecom_2 (TRUNC_DIV_EXPR, tree_type,
9335 if (! optimize_size)
9336 return ffecom_2 (RDIV_EXPR, tree_type,
9342 if (TREE_TYPE (tree_type)
9343 == ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1])
9344 ix = FFECOM_gfrtDIV_CC; /* Overlapping result okay. */
9346 ix = FFECOM_gfrtDIV_ZZ; /* Overlapping result okay. */
9348 left = ffecom_1 (ADDR_EXPR,
9349 build_pointer_type (TREE_TYPE (left)),
9351 left = build_tree_list (NULL_TREE, left);
9352 right = ffecom_1 (ADDR_EXPR,
9353 build_pointer_type (TREE_TYPE (right)),
9355 right = build_tree_list (NULL_TREE, right);
9356 TREE_CHAIN (left) = right;
9358 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
9359 ffecom_gfrt_kindtype (ix),
9360 ffe_is_f2c_library (),
9363 dest_tree, dest, dest_used,
9364 NULL_TREE, TRUE, hook);
9372 if (TREE_TYPE (TYPE_FIELDS (tree_type))
9373 == ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1])
9374 ix = FFECOM_gfrtDIV_CC; /* Overlapping result okay. */
9376 ix = FFECOM_gfrtDIV_ZZ; /* Overlapping result okay. */
9378 left = ffecom_1 (ADDR_EXPR,
9379 build_pointer_type (TREE_TYPE (left)),
9381 left = build_tree_list (NULL_TREE, left);
9382 right = ffecom_1 (ADDR_EXPR,
9383 build_pointer_type (TREE_TYPE (right)),
9385 right = build_tree_list (NULL_TREE, right);
9386 TREE_CHAIN (left) = right;
9388 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
9389 ffecom_gfrt_kindtype (ix),
9390 ffe_is_f2c_library (),
9393 dest_tree, dest, dest_used,
9394 NULL_TREE, TRUE, hook);
9399 return ffecom_2 (RDIV_EXPR, tree_type,
9406 /* Build type info for non-dummy variable. */
9408 #if FFECOM_targetCURRENT == FFECOM_targetGCC
9410 ffecom_type_localvar_ (ffesymbol s, ffeinfoBasictype bt,
9419 type = ffecom_tree_type[bt][kt];
9420 if (bt == FFEINFO_basictypeCHARACTER)
9422 hight = build_int_2 (ffesymbol_size (s), 0);
9423 TREE_TYPE (hight) = ffecom_f2c_ftnlen_type_node;
9428 build_range_type (ffecom_f2c_ftnlen_type_node,
9429 ffecom_f2c_ftnlen_one_node,
9431 type = ffecom_check_size_overflow_ (s, type, FALSE);
9434 for (dl = ffesymbol_dims (s); dl != NULL; dl = ffebld_trail (dl))
9436 if (type == error_mark_node)
9439 dim = ffebld_head (dl);
9440 assert (ffebld_op (dim) == FFEBLD_opBOUNDS);
9442 if (ffebld_left (dim) == NULL)
9443 lowt = integer_one_node;
9445 lowt = ffecom_expr (ffebld_left (dim));
9447 if (TREE_CODE (lowt) != INTEGER_CST)
9448 lowt = variable_size (lowt);
9450 assert (ffebld_right (dim) != NULL);
9451 hight = ffecom_expr (ffebld_right (dim));
9453 if (TREE_CODE (hight) != INTEGER_CST)
9454 hight = variable_size (hight);
9456 type = build_array_type (type,
9457 build_range_type (ffecom_integer_type_node,
9459 type = ffecom_check_size_overflow_ (s, type, FALSE);
9466 /* Build Namelist type. */
9468 #if FFECOM_targetCURRENT == FFECOM_targetGCC
9470 ffecom_type_namelist_ ()
9472 static tree type = NULL_TREE;
9474 if (type == NULL_TREE)
9476 static tree namefield, varsfield, nvarsfield;
9479 vardesctype = ffecom_type_vardesc_ ();
9481 type = make_node (RECORD_TYPE);
9483 vardesctype = build_pointer_type (build_pointer_type (vardesctype));
9485 namefield = ffecom_decl_field (type, NULL_TREE, "name",
9487 varsfield = ffecom_decl_field (type, namefield, "vars", vardesctype);
9488 nvarsfield = ffecom_decl_field (type, varsfield, "nvars",
9491 TYPE_FIELDS (type) = namefield;
9494 ggc_add_tree_root (&type, 1);
9502 /* Build Vardesc type. */
9504 #if FFECOM_targetCURRENT == FFECOM_targetGCC
9506 ffecom_type_vardesc_ ()
9508 static tree type = NULL_TREE;
9509 static tree namefield, addrfield, dimsfield, typefield;
9511 if (type == NULL_TREE)
9513 type = make_node (RECORD_TYPE);
9515 namefield = ffecom_decl_field (type, NULL_TREE, "name",
9517 addrfield = ffecom_decl_field (type, namefield, "addr",
9519 dimsfield = ffecom_decl_field (type, addrfield, "dims",
9520 ffecom_f2c_ptr_to_ftnlen_type_node);
9521 typefield = ffecom_decl_field (type, dimsfield, "type",
9524 TYPE_FIELDS (type) = namefield;
9527 ggc_add_tree_root (&type, 1);
9535 #if FFECOM_targetCURRENT == FFECOM_targetGCC
9537 ffecom_vardesc_ (ffebld expr)
9541 assert (ffebld_op (expr) == FFEBLD_opSYMTER);
9542 s = ffebld_symter (expr);
9544 if (ffesymbol_hook (s).vardesc_tree == NULL_TREE)
9547 tree vardesctype = ffecom_type_vardesc_ ();
9556 static int mynumber = 0;
9558 yes = suspend_momentary ();
9560 var = build_decl (VAR_DECL,
9561 ffecom_get_invented_identifier ("__g77_vardesc_%d",
9564 TREE_STATIC (var) = 1;
9565 DECL_INITIAL (var) = error_mark_node;
9567 var = start_decl (var, FALSE);
9569 /* Process inits. */
9571 nameinit = ffecom_build_f2c_string_ ((i = strlen (ffesymbol_text (s)))
9573 ffesymbol_text (s));
9574 TREE_TYPE (nameinit)
9575 = build_type_variant
9578 build_range_type (integer_type_node,
9580 build_int_2 (i, 0))),
9582 TREE_CONSTANT (nameinit) = 1;
9583 TREE_STATIC (nameinit) = 1;
9584 nameinit = ffecom_1 (ADDR_EXPR,
9585 build_pointer_type (TREE_TYPE (nameinit)),
9588 addrinit = ffecom_arg_ptr_to_expr (expr, &typeinit);
9590 dimsinit = ffecom_vardesc_dims_ (s);
9592 if (typeinit == NULL_TREE)
9594 ffeinfoBasictype bt = ffesymbol_basictype (s);
9595 ffeinfoKindtype kt = ffesymbol_kindtype (s);
9596 int tc = ffecom_f2c_typecode (bt, kt);
9599 typeinit = build_int_2 (tc, (tc < 0) ? -1 : 0);
9602 typeinit = ffecom_1 (NEGATE_EXPR, TREE_TYPE (typeinit), typeinit);
9604 varinits = build_tree_list ((field = TYPE_FIELDS (vardesctype)),
9606 TREE_CHAIN (varinits) = build_tree_list ((field = TREE_CHAIN (field)),
9608 TREE_CHAIN (TREE_CHAIN (varinits))
9609 = build_tree_list ((field = TREE_CHAIN (field)), dimsinit);
9610 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (varinits)))
9611 = build_tree_list ((field = TREE_CHAIN (field)), typeinit);
9613 varinits = build (CONSTRUCTOR, vardesctype, NULL_TREE, varinits);
9614 TREE_CONSTANT (varinits) = 1;
9615 TREE_STATIC (varinits) = 1;
9617 finish_decl (var, varinits, FALSE);
9619 var = ffecom_1 (ADDR_EXPR, build_pointer_type (vardesctype), var);
9621 resume_momentary (yes);
9623 ffesymbol_hook (s).vardesc_tree = var;
9626 return ffesymbol_hook (s).vardesc_tree;
9630 #if FFECOM_targetCURRENT == FFECOM_targetGCC
9632 ffecom_vardesc_array_ (ffesymbol s)
9636 tree item = NULL_TREE;
9640 static int mynumber = 0;
9642 for (i = 0, list = NULL_TREE, b = ffesymbol_namelist (s);
9644 b = ffebld_trail (b), ++i)
9648 t = ffecom_vardesc_ (ffebld_head (b));
9650 if (list == NULL_TREE)
9651 list = item = build_tree_list (NULL_TREE, t);
9654 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
9655 item = TREE_CHAIN (item);
9659 yes = suspend_momentary ();
9661 item = build_array_type (build_pointer_type (ffecom_type_vardesc_ ()),
9662 build_range_type (integer_type_node,
9664 build_int_2 (i, 0)));
9665 list = build (CONSTRUCTOR, item, NULL_TREE, list);
9666 TREE_CONSTANT (list) = 1;
9667 TREE_STATIC (list) = 1;
9669 var = ffecom_get_invented_identifier ("__g77_vardesc_array_%d", mynumber++);
9670 var = build_decl (VAR_DECL, var, item);
9671 TREE_STATIC (var) = 1;
9672 DECL_INITIAL (var) = error_mark_node;
9673 var = start_decl (var, FALSE);
9674 finish_decl (var, list, FALSE);
9676 resume_momentary (yes);
9682 #if FFECOM_targetCURRENT == FFECOM_targetGCC
9684 ffecom_vardesc_dims_ (ffesymbol s)
9686 if (ffesymbol_dims (s) == NULL)
9687 return convert (ffecom_f2c_ptr_to_ftnlen_type_node,
9695 tree item = NULL_TREE;
9700 tree baseoff = NULL_TREE;
9701 static int mynumber = 0;
9703 numdim = build_int_2 ((int) ffesymbol_rank (s), 0);
9704 TREE_TYPE (numdim) = ffecom_f2c_ftnlen_type_node;
9706 numelem = ffecom_expr (ffesymbol_arraysize (s));
9707 TREE_TYPE (numelem) = ffecom_f2c_ftnlen_type_node;
9710 backlist = NULL_TREE;
9711 for (b = ffesymbol_dims (s), e = ffesymbol_extents (s);
9713 b = ffebld_trail (b), e = ffebld_trail (e))
9719 if (ffebld_trail (b) == NULL)
9723 t = convert (ffecom_f2c_ftnlen_type_node,
9724 ffecom_expr (ffebld_head (e)));
9726 if (list == NULL_TREE)
9727 list = item = build_tree_list (NULL_TREE, t);
9730 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
9731 item = TREE_CHAIN (item);
9735 if (ffebld_left (ffebld_head (b)) == NULL)
9736 low = ffecom_integer_one_node;
9738 low = ffecom_expr (ffebld_left (ffebld_head (b)));
9739 low = convert (ffecom_f2c_ftnlen_type_node, low);
9741 back = build_tree_list (low, t);
9742 TREE_CHAIN (back) = backlist;
9746 for (item = backlist; item != NULL_TREE; item = TREE_CHAIN (item))
9748 if (TREE_VALUE (item) == NULL_TREE)
9749 baseoff = TREE_PURPOSE (item);
9751 baseoff = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
9752 TREE_PURPOSE (item),
9753 ffecom_2 (MULT_EXPR,
9754 ffecom_f2c_ftnlen_type_node,
9759 /* backlist now dead, along with all TREE_PURPOSEs on it. */
9761 baseoff = build_tree_list (NULL_TREE, baseoff);
9762 TREE_CHAIN (baseoff) = list;
9764 numelem = build_tree_list (NULL_TREE, numelem);
9765 TREE_CHAIN (numelem) = baseoff;
9767 numdim = build_tree_list (NULL_TREE, numdim);
9768 TREE_CHAIN (numdim) = numelem;
9770 yes = suspend_momentary ();
9772 item = build_array_type (ffecom_f2c_ftnlen_type_node,
9773 build_range_type (integer_type_node,
9776 ((int) ffesymbol_rank (s)
9778 list = build (CONSTRUCTOR, item, NULL_TREE, numdim);
9779 TREE_CONSTANT (list) = 1;
9780 TREE_STATIC (list) = 1;
9782 var = ffecom_get_invented_identifier ("__g77_dims_%d", mynumber++);
9783 var = build_decl (VAR_DECL, var, item);
9784 TREE_STATIC (var) = 1;
9785 DECL_INITIAL (var) = error_mark_node;
9786 var = start_decl (var, FALSE);
9787 finish_decl (var, list, FALSE);
9789 var = ffecom_1 (ADDR_EXPR, build_pointer_type (item), var);
9791 resume_momentary (yes);
9798 /* Essentially does a "fold (build1 (code, type, node))" while checking
9799 for certain housekeeping things.
9801 NOTE: for building an ADDR_EXPR around a FUNCTION_DECL, use
9802 ffecom_1_fn instead. */
9804 #if FFECOM_targetCURRENT == FFECOM_targetGCC
9806 ffecom_1 (enum tree_code code, tree type, tree node)
9810 if ((node == error_mark_node)
9811 || (type == error_mark_node))
9812 return error_mark_node;
9814 if (code == ADDR_EXPR)
9816 if (!mark_addressable (node))
9817 assert ("can't mark_addressable this node!" == NULL);
9820 switch (ffe_is_emulate_complex () ? code : NOP_EXPR)
9825 item = build (COMPONENT_REF, type, node, TYPE_FIELDS (TREE_TYPE (node)));
9829 item = build (COMPONENT_REF, type, node, TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (node))));
9834 if (TREE_CODE (type) != RECORD_TYPE)
9836 item = build1 (code, type, node);
9839 node = ffecom_stabilize_aggregate_ (node);
9840 realtype = TREE_TYPE (TYPE_FIELDS (type));
9842 ffecom_2 (COMPLEX_EXPR, type,
9843 ffecom_1 (NEGATE_EXPR, realtype,
9844 ffecom_1 (REALPART_EXPR, realtype,
9846 ffecom_1 (NEGATE_EXPR, realtype,
9847 ffecom_1 (IMAGPART_EXPR, realtype,
9852 item = build1 (code, type, node);
9856 if (TREE_SIDE_EFFECTS (node))
9857 TREE_SIDE_EFFECTS (item) = 1;
9858 if ((code == ADDR_EXPR) && staticp (node))
9859 TREE_CONSTANT (item) = 1;
9864 /* Like ffecom_1 (ADDR_EXPR, TREE_TYPE (node), node), except
9865 handles TREE_CODE (node) == FUNCTION_DECL. In particular,
9866 does not set TREE_ADDRESSABLE (because calling an inline
9867 function does not mean the function needs to be separately
9870 #if FFECOM_targetCURRENT == FFECOM_targetGCC
9872 ffecom_1_fn (tree node)
9877 if (node == error_mark_node)
9878 return error_mark_node;
9880 type = build_type_variant (TREE_TYPE (node),
9881 TREE_READONLY (node),
9882 TREE_THIS_VOLATILE (node));
9883 item = build1 (ADDR_EXPR,
9884 build_pointer_type (type), node);
9885 if (TREE_SIDE_EFFECTS (node))
9886 TREE_SIDE_EFFECTS (item) = 1;
9888 TREE_CONSTANT (item) = 1;
9893 /* Essentially does a "fold (build (code, type, node1, node2))" while
9894 checking for certain housekeeping things. */
9896 #if FFECOM_targetCURRENT == FFECOM_targetGCC
9898 ffecom_2 (enum tree_code code, tree type, tree node1,
9903 if ((node1 == error_mark_node)
9904 || (node2 == error_mark_node)
9905 || (type == error_mark_node))
9906 return error_mark_node;
9908 switch (ffe_is_emulate_complex () ? code : NOP_EXPR)
9910 tree a, b, c, d, realtype;
9913 assert ("no CONJ_EXPR support yet" == NULL);
9914 return error_mark_node;
9917 item = build_tree_list (TYPE_FIELDS (type), node1);
9918 TREE_CHAIN (item) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), node2);
9919 item = build (CONSTRUCTOR, type, NULL_TREE, item);
9923 if (TREE_CODE (type) != RECORD_TYPE)
9925 item = build (code, type, node1, node2);
9928 node1 = ffecom_stabilize_aggregate_ (node1);
9929 node2 = ffecom_stabilize_aggregate_ (node2);
9930 realtype = TREE_TYPE (TYPE_FIELDS (type));
9932 ffecom_2 (COMPLEX_EXPR, type,
9933 ffecom_2 (PLUS_EXPR, realtype,
9934 ffecom_1 (REALPART_EXPR, realtype,
9936 ffecom_1 (REALPART_EXPR, realtype,
9938 ffecom_2 (PLUS_EXPR, realtype,
9939 ffecom_1 (IMAGPART_EXPR, realtype,
9941 ffecom_1 (IMAGPART_EXPR, realtype,
9946 if (TREE_CODE (type) != RECORD_TYPE)
9948 item = build (code, type, node1, node2);
9951 node1 = ffecom_stabilize_aggregate_ (node1);
9952 node2 = ffecom_stabilize_aggregate_ (node2);
9953 realtype = TREE_TYPE (TYPE_FIELDS (type));
9955 ffecom_2 (COMPLEX_EXPR, type,
9956 ffecom_2 (MINUS_EXPR, realtype,
9957 ffecom_1 (REALPART_EXPR, realtype,
9959 ffecom_1 (REALPART_EXPR, realtype,
9961 ffecom_2 (MINUS_EXPR, realtype,
9962 ffecom_1 (IMAGPART_EXPR, realtype,
9964 ffecom_1 (IMAGPART_EXPR, realtype,
9969 if (TREE_CODE (type) != RECORD_TYPE)
9971 item = build (code, type, node1, node2);
9974 node1 = ffecom_stabilize_aggregate_ (node1);
9975 node2 = ffecom_stabilize_aggregate_ (node2);
9976 realtype = TREE_TYPE (TYPE_FIELDS (type));
9977 a = save_expr (ffecom_1 (REALPART_EXPR, realtype,
9979 b = save_expr (ffecom_1 (IMAGPART_EXPR, realtype,
9981 c = save_expr (ffecom_1 (REALPART_EXPR, realtype,
9983 d = save_expr (ffecom_1 (IMAGPART_EXPR, realtype,
9986 ffecom_2 (COMPLEX_EXPR, type,
9987 ffecom_2 (MINUS_EXPR, realtype,
9988 ffecom_2 (MULT_EXPR, realtype,
9991 ffecom_2 (MULT_EXPR, realtype,
9994 ffecom_2 (PLUS_EXPR, realtype,
9995 ffecom_2 (MULT_EXPR, realtype,
9998 ffecom_2 (MULT_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_ANDIF_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 if ((TREE_CODE (node1) != RECORD_TYPE)
10031 && (TREE_CODE (node2) != RECORD_TYPE))
10033 item = build (code, type, node1, node2);
10036 assert (TREE_CODE (node1) == RECORD_TYPE);
10037 assert (TREE_CODE (node2) == RECORD_TYPE);
10038 node1 = ffecom_stabilize_aggregate_ (node1);
10039 node2 = ffecom_stabilize_aggregate_ (node2);
10040 realtype = TREE_TYPE (TYPE_FIELDS (type));
10042 ffecom_2 (TRUTH_ORIF_EXPR, type,
10043 ffecom_2 (code, type,
10044 ffecom_1 (REALPART_EXPR, realtype,
10046 ffecom_1 (REALPART_EXPR, realtype,
10048 ffecom_2 (code, type,
10049 ffecom_1 (IMAGPART_EXPR, realtype,
10051 ffecom_1 (IMAGPART_EXPR, realtype,
10056 item = build (code, type, node1, node2);
10060 if (TREE_SIDE_EFFECTS (node1) || TREE_SIDE_EFFECTS (node2))
10061 TREE_SIDE_EFFECTS (item) = 1;
10062 return fold (item);
10066 /* ffecom_2pass_advise_entrypoint -- Advise that there's this entrypoint
10068 ffesymbol s; // the ENTRY point itself
10069 if (ffecom_2pass_advise_entrypoint(s))
10070 // the ENTRY point has been accepted
10072 Does whatever compiler needs to do when it learns about the entrypoint,
10073 like determine the return type of the master function, count the
10074 number of entrypoints, etc. Returns FALSE if the return type is
10075 not compatible with the return type(s) of other entrypoint(s).
10077 NOTE: for every call to this fn that returns TRUE, _do_entrypoint must
10078 later (after _finish_progunit) be called with the same entrypoint(s)
10079 as passed to this fn for which TRUE was returned.
10082 Return FALSE if the return type conflicts with previous entrypoints. */
10084 #if FFECOM_targetCURRENT == FFECOM_targetGCC
10086 ffecom_2pass_advise_entrypoint (ffesymbol entry)
10088 ffebld list; /* opITEM. */
10089 ffebld mlist; /* opITEM. */
10090 ffebld plist; /* opITEM. */
10091 ffebld arg; /* ffebld_head(opITEM). */
10092 ffebld item; /* opITEM. */
10093 ffesymbol s; /* ffebld_symter(arg). */
10094 ffeinfoBasictype bt = ffesymbol_basictype (entry);
10095 ffeinfoKindtype kt = ffesymbol_kindtype (entry);
10096 ffetargetCharacterSize size = ffesymbol_size (entry);
10099 if (ffecom_num_entrypoints_ == 0)
10100 { /* First entrypoint, make list of main
10101 arglist's dummies. */
10102 assert (ffecom_primary_entry_ != NULL);
10104 ffecom_master_bt_ = ffesymbol_basictype (ffecom_primary_entry_);
10105 ffecom_master_kt_ = ffesymbol_kindtype (ffecom_primary_entry_);
10106 ffecom_master_size_ = ffesymbol_size (ffecom_primary_entry_);
10108 for (plist = NULL, list = ffesymbol_dummyargs (ffecom_primary_entry_);
10110 list = ffebld_trail (list))
10112 arg = ffebld_head (list);
10113 if (ffebld_op (arg) != FFEBLD_opSYMTER)
10114 continue; /* Alternate return or some such thing. */
10115 item = ffebld_new_item (arg, NULL);
10117 ffecom_master_arglist_ = item;
10119 ffebld_set_trail (plist, item);
10124 /* If necessary, scan entry arglist for alternate returns. Do this scan
10125 apparently redundantly (it's done below to UNIONize the arglists) so
10126 that we don't complain about RETURN 1 if an offending ENTRY is the only
10127 one with an alternate return. */
10129 if (!ffecom_is_altreturning_)
10131 for (list = ffesymbol_dummyargs (entry);
10133 list = ffebld_trail (list))
10135 arg = ffebld_head (list);
10136 if (ffebld_op (arg) == FFEBLD_opSTAR)
10138 ffecom_is_altreturning_ = TRUE;
10144 /* Now check type compatibility. */
10146 switch (ffecom_master_bt_)
10148 case FFEINFO_basictypeNONE:
10149 ok = (bt != FFEINFO_basictypeCHARACTER);
10152 case FFEINFO_basictypeCHARACTER:
10154 = (bt == FFEINFO_basictypeCHARACTER)
10155 && (kt == ffecom_master_kt_)
10156 && (size == ffecom_master_size_);
10159 case FFEINFO_basictypeANY:
10160 return FALSE; /* Just don't bother. */
10163 if (bt == FFEINFO_basictypeCHARACTER)
10169 if ((bt != ffecom_master_bt_) || (kt != ffecom_master_kt_))
10171 ffecom_master_bt_ = FFEINFO_basictypeNONE;
10172 ffecom_master_kt_ = FFEINFO_kindtypeNONE;
10179 ffebad_start (FFEBAD_ENTRY_CONFLICTS);
10180 ffest_ffebad_here_current_stmt (0);
10182 return FALSE; /* Can't handle entrypoint. */
10185 /* Entrypoint type compatible with previous types. */
10187 ++ffecom_num_entrypoints_;
10189 /* Master-arg-list = UNION(Master-arg-list,entry-arg-list). */
10191 for (list = ffesymbol_dummyargs (entry);
10193 list = ffebld_trail (list))
10195 arg = ffebld_head (list);
10196 if (ffebld_op (arg) != FFEBLD_opSYMTER)
10197 continue; /* Alternate return or some such thing. */
10198 s = ffebld_symter (arg);
10199 for (plist = NULL, mlist = ffecom_master_arglist_;
10201 plist = mlist, mlist = ffebld_trail (mlist))
10202 { /* plist points to previous item for easy
10203 appending of arg. */
10204 if (ffebld_symter (ffebld_head (mlist)) == s)
10205 break; /* Already have this arg in the master list. */
10208 continue; /* Already have this arg in the master list. */
10210 /* Append this arg to the master list. */
10212 item = ffebld_new_item (arg, NULL);
10214 ffecom_master_arglist_ = item;
10216 ffebld_set_trail (plist, item);
10223 /* ffecom_2pass_do_entrypoint -- Do compilation of entrypoint
10225 ffesymbol s; // the ENTRY point itself
10226 ffecom_2pass_do_entrypoint(s);
10228 Does whatever compiler needs to do to make the entrypoint actually
10229 happen. Must be called for each entrypoint after
10230 ffecom_finish_progunit is called. */
10232 #if FFECOM_targetCURRENT == FFECOM_targetGCC
10234 ffecom_2pass_do_entrypoint (ffesymbol entry)
10236 static int mfn_num = 0;
10237 static int ent_num;
10239 if (mfn_num != ffecom_num_fns_)
10240 { /* First entrypoint for this program unit. */
10242 mfn_num = ffecom_num_fns_;
10243 ffecom_do_entry_ (ffecom_primary_entry_, 0);
10248 --ffecom_num_entrypoints_;
10250 ffecom_do_entry_ (entry, ent_num);
10255 /* Essentially does a "fold (build (code, type, node1, node2))" while
10256 checking for certain housekeeping things. Always sets
10257 TREE_SIDE_EFFECTS. */
10259 #if FFECOM_targetCURRENT == FFECOM_targetGCC
10261 ffecom_2s (enum tree_code code, tree type, tree node1,
10266 if ((node1 == error_mark_node)
10267 || (node2 == error_mark_node)
10268 || (type == error_mark_node))
10269 return error_mark_node;
10271 item = build (code, type, node1, node2);
10272 TREE_SIDE_EFFECTS (item) = 1;
10273 return fold (item);
10277 /* Essentially does a "fold (build (code, type, node1, node2, node3))" while
10278 checking for certain housekeeping things. */
10280 #if FFECOM_targetCURRENT == FFECOM_targetGCC
10282 ffecom_3 (enum tree_code code, tree type, tree node1,
10283 tree node2, tree node3)
10287 if ((node1 == error_mark_node)
10288 || (node2 == error_mark_node)
10289 || (node3 == error_mark_node)
10290 || (type == error_mark_node))
10291 return error_mark_node;
10293 item = build (code, type, node1, node2, node3);
10294 if (TREE_SIDE_EFFECTS (node1) || TREE_SIDE_EFFECTS (node2)
10295 || (node3 != NULL_TREE && TREE_SIDE_EFFECTS (node3)))
10296 TREE_SIDE_EFFECTS (item) = 1;
10297 return fold (item);
10301 /* Essentially does a "fold (build (code, type, node1, node2, node3))" while
10302 checking for certain housekeeping things. Always sets
10303 TREE_SIDE_EFFECTS. */
10305 #if FFECOM_targetCURRENT == FFECOM_targetGCC
10307 ffecom_3s (enum tree_code code, tree type, tree node1,
10308 tree node2, tree node3)
10312 if ((node1 == error_mark_node)
10313 || (node2 == error_mark_node)
10314 || (node3 == error_mark_node)
10315 || (type == error_mark_node))
10316 return error_mark_node;
10318 item = build (code, type, node1, node2, node3);
10319 TREE_SIDE_EFFECTS (item) = 1;
10320 return fold (item);
10325 /* ffecom_arg_expr -- Transform argument expr into gcc tree
10327 See use by ffecom_list_expr.
10329 If expression is NULL, returns an integer zero tree. If it is not
10330 a CHARACTER expression, returns whatever ffecom_expr
10331 returns and sets the length return value to NULL_TREE. Otherwise
10332 generates code to evaluate the character expression, returns the proper
10333 pointer to the result, but does NOT set the length return value to a tree
10334 that specifies the length of the result. (In other words, the length
10335 variable is always set to NULL_TREE, because a length is never passed.)
10338 Don't set returned length, since nobody needs it (yet; someday if
10339 we allow CHARACTER*(*) dummies to statement functions, we'll need
10342 #if FFECOM_targetCURRENT == FFECOM_targetGCC
10344 ffecom_arg_expr (ffebld expr, tree *length)
10348 *length = NULL_TREE;
10351 return integer_zero_node;
10353 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10354 return ffecom_expr (expr);
10356 return ffecom_arg_ptr_to_expr (expr, &ign);
10360 /* Transform expression into constant argument-pointer-to-expression tree.
10362 If the expression can be transformed into a argument-pointer-to-expression
10363 tree that is constant, that is done, and the tree returned. Else
10364 NULL_TREE is returned.
10366 That way, a caller can attempt to provide compile-time initialization
10367 of a variable and, if that fails, *then* choose to start a new block
10368 and resort to using temporaries, as appropriate. */
10371 ffecom_arg_ptr_to_const_expr (ffebld expr, tree *length)
10374 return integer_zero_node;
10376 if (ffebld_op (expr) == FFEBLD_opANY)
10379 *length = error_mark_node;
10380 return error_mark_node;
10383 if (ffebld_arity (expr) == 0
10384 && (ffebld_op (expr) != FFEBLD_opSYMTER
10385 || ffebld_where (expr) == FFEINFO_whereCOMMON
10386 || ffebld_where (expr) == FFEINFO_whereGLOBAL
10387 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
10391 t = ffecom_arg_ptr_to_expr (expr, length);
10392 assert (TREE_CONSTANT (t));
10393 assert (! length || TREE_CONSTANT (*length));
10398 && ffebld_size (expr) != FFETARGET_charactersizeNONE)
10399 *length = build_int_2 (ffebld_size (expr), 0);
10401 *length = NULL_TREE;
10405 /* ffecom_arg_ptr_to_expr -- Transform argument expr into gcc tree
10407 See use by ffecom_list_ptr_to_expr.
10409 If expression is NULL, returns an integer zero tree. If it is not
10410 a CHARACTER expression, returns whatever ffecom_ptr_to_expr
10411 returns and sets the length return value to NULL_TREE. Otherwise
10412 generates code to evaluate the character expression, returns the proper
10413 pointer to the result, AND sets the length return value to a tree that
10414 specifies the length of the result.
10416 If the length argument is NULL, this is a slightly special
10417 case of building a FORMAT expression, that is, an expression that
10418 will be used at run time without regard to length. For the current
10419 implementation, which uses the libf2c library, this means it is nice
10420 to append a null byte to the end of the expression, where feasible,
10421 to make sure any diagnostic about the FORMAT string terminates at
10424 For now, treat %REF(char-expr) as the same as char-expr with a NULL
10425 length argument. This might even be seen as a feature, if a null
10426 byte can always be appended. */
10428 #if FFECOM_targetCURRENT == FFECOM_targetGCC
10430 ffecom_arg_ptr_to_expr (ffebld expr, tree *length)
10434 ffecomConcatList_ catlist;
10436 if (length != NULL)
10437 *length = NULL_TREE;
10440 return integer_zero_node;
10442 switch (ffebld_op (expr))
10444 case FFEBLD_opPERCENT_VAL:
10445 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10446 return ffecom_expr (ffebld_left (expr));
10451 temp_exp = ffecom_arg_ptr_to_expr (ffebld_left (expr), &temp_length);
10452 if (temp_exp == error_mark_node)
10453 return error_mark_node;
10455 return ffecom_1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (temp_exp)),
10459 case FFEBLD_opPERCENT_REF:
10460 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10461 return ffecom_ptr_to_expr (ffebld_left (expr));
10462 if (length != NULL)
10464 ign_length = NULL_TREE;
10465 length = &ign_length;
10467 expr = ffebld_left (expr);
10470 case FFEBLD_opPERCENT_DESCR:
10471 switch (ffeinfo_basictype (ffebld_info (expr)))
10473 #ifdef PASS_HOLLERITH_BY_DESCRIPTOR
10474 case FFEINFO_basictypeHOLLERITH:
10476 case FFEINFO_basictypeCHARACTER:
10477 break; /* Passed by descriptor anyway. */
10480 item = ffecom_ptr_to_expr (expr);
10481 if (item != error_mark_node)
10482 *length = TYPE_SIZE (TREE_TYPE (TREE_TYPE (item)));
10491 #ifdef PASS_HOLLERITH_BY_DESCRIPTOR
10492 if ((ffeinfo_basictype (ffebld_info (expr)) == FFEINFO_basictypeHOLLERITH)
10493 && (length != NULL))
10494 { /* Pass Hollerith by descriptor. */
10495 ffetargetHollerith h;
10497 assert (ffebld_op (expr) == FFEBLD_opCONTER);
10498 h = ffebld_cu_val_hollerith (ffebld_constant_union
10499 (ffebld_conter (expr)));
10501 = build_int_2 (h.length, 0);
10502 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
10506 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10507 return ffecom_ptr_to_expr (expr);
10509 assert (ffeinfo_kindtype (ffebld_info (expr))
10510 == FFEINFO_kindtypeCHARACTER1);
10512 while (ffebld_op (expr) == FFEBLD_opPAREN)
10513 expr = ffebld_left (expr);
10515 catlist = ffecom_concat_list_new_ (expr, FFETARGET_charactersizeNONE);
10516 switch (ffecom_concat_list_count_ (catlist))
10518 case 0: /* Shouldn't happen, but in case it does... */
10519 if (length != NULL)
10521 *length = ffecom_f2c_ftnlen_zero_node;
10522 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
10524 ffecom_concat_list_kill_ (catlist);
10525 return null_pointer_node;
10527 case 1: /* The (fairly) easy case. */
10528 if (length == NULL)
10529 ffecom_char_args_with_null_ (&item, &ign_length,
10530 ffecom_concat_list_expr_ (catlist, 0));
10532 ffecom_char_args_ (&item, length,
10533 ffecom_concat_list_expr_ (catlist, 0));
10534 ffecom_concat_list_kill_ (catlist);
10535 assert (item != NULL_TREE);
10538 default: /* Must actually concatenate things. */
10543 int count = ffecom_concat_list_count_ (catlist);
10554 ffetargetCharacterSize sz;
10556 sz = ffecom_concat_list_maxlen_ (catlist);
10558 assert (sz != FFETARGET_charactersizeNONE);
10563 = ffecom_push_tempvar (ffecom_f2c_ftnlen_type_node,
10564 FFETARGET_charactersizeNONE, count, TRUE);
10567 = ffecom_push_tempvar (ffecom_f2c_address_type_node,
10568 FFETARGET_charactersizeNONE, count, TRUE);
10569 temporary = ffecom_push_tempvar (char_type_node,
10575 hook = ffebld_nonter_hook (expr);
10577 assert (TREE_CODE (hook) == TREE_VEC);
10578 assert (TREE_VEC_LENGTH (hook) == 3);
10579 length_array = lengths = TREE_VEC_ELT (hook, 0);
10580 item_array = items = TREE_VEC_ELT (hook, 1);
10581 temporary = TREE_VEC_ELT (hook, 2);
10585 known_length = ffecom_f2c_ftnlen_zero_node;
10587 for (i = 0; i < count; ++i)
10590 && (length == NULL))
10591 ffecom_char_args_with_null_ (&citem, &clength,
10592 ffecom_concat_list_expr_ (catlist, i));
10594 ffecom_char_args_ (&citem, &clength,
10595 ffecom_concat_list_expr_ (catlist, i));
10596 if ((citem == error_mark_node)
10597 || (clength == error_mark_node))
10599 ffecom_concat_list_kill_ (catlist);
10600 *length = error_mark_node;
10601 return error_mark_node;
10605 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (items),
10606 ffecom_modify (void_type_node,
10607 ffecom_2 (ARRAY_REF,
10608 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array))),
10610 build_int_2 (i, 0)),
10613 clength = ffecom_save_tree (clength);
10614 if (length != NULL)
10616 = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
10620 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (lengths),
10621 ffecom_modify (void_type_node,
10622 ffecom_2 (ARRAY_REF,
10623 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array))),
10625 build_int_2 (i, 0)),
10630 temporary = ffecom_1 (ADDR_EXPR,
10631 build_pointer_type (TREE_TYPE (temporary)),
10634 item = build_tree_list (NULL_TREE, temporary);
10636 = build_tree_list (NULL_TREE,
10637 ffecom_1 (ADDR_EXPR,
10638 build_pointer_type (TREE_TYPE (items)),
10640 TREE_CHAIN (TREE_CHAIN (item))
10641 = build_tree_list (NULL_TREE,
10642 ffecom_1 (ADDR_EXPR,
10643 build_pointer_type (TREE_TYPE (lengths)),
10645 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item)))
10648 ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
10649 convert (ffecom_f2c_ftnlen_type_node,
10650 build_int_2 (count, 0))));
10651 num = build_int_2 (sz, 0);
10652 TREE_TYPE (num) = ffecom_f2c_ftnlen_type_node;
10653 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item))))
10654 = build_tree_list (NULL_TREE, num);
10656 item = ffecom_call_gfrt (FFECOM_gfrtCAT, item, NULL_TREE);
10657 TREE_SIDE_EFFECTS (item) = 1;
10658 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (temporary),
10662 if (length != NULL)
10663 *length = known_length;
10666 ffecom_concat_list_kill_ (catlist);
10667 assert (item != NULL_TREE);
10672 /* Generate call to run-time function.
10674 The first arg is the GNU Fortran Run-Time function index, the second
10675 arg is the list of arguments to pass to it. Returned is the expression
10676 (WITHOUT TREE_SIDE_EFFECTS set!) that makes the call and returns the
10677 result (which may be void). */
10679 #if FFECOM_targetCURRENT == FFECOM_targetGCC
10681 ffecom_call_gfrt (ffecomGfrt ix, tree args, tree hook)
10683 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
10684 ffecom_gfrt_kindtype (ix),
10685 ffe_is_f2c_library () && ffecom_gfrt_complex_[ix],
10686 NULL_TREE, args, NULL_TREE, NULL,
10687 NULL, NULL_TREE, TRUE, hook);
10691 /* Transform constant-union to tree. */
10693 #if FFECOM_targetCURRENT == FFECOM_targetGCC
10695 ffecom_constantunion (ffebldConstantUnion *cu, ffeinfoBasictype bt,
10696 ffeinfoKindtype kt, tree tree_type)
10702 case FFEINFO_basictypeINTEGER:
10708 #if FFETARGET_okINTEGER1
10709 case FFEINFO_kindtypeINTEGER1:
10710 val = ffebld_cu_val_integer1 (*cu);
10714 #if FFETARGET_okINTEGER2
10715 case FFEINFO_kindtypeINTEGER2:
10716 val = ffebld_cu_val_integer2 (*cu);
10720 #if FFETARGET_okINTEGER3
10721 case FFEINFO_kindtypeINTEGER3:
10722 val = ffebld_cu_val_integer3 (*cu);
10726 #if FFETARGET_okINTEGER4
10727 case FFEINFO_kindtypeINTEGER4:
10728 val = ffebld_cu_val_integer4 (*cu);
10733 assert ("bad INTEGER constant kind type" == NULL);
10734 /* Fall through. */
10735 case FFEINFO_kindtypeANY:
10736 return error_mark_node;
10738 item = build_int_2 (val, (val < 0) ? -1 : 0);
10739 TREE_TYPE (item) = tree_type;
10743 case FFEINFO_basictypeLOGICAL:
10749 #if FFETARGET_okLOGICAL1
10750 case FFEINFO_kindtypeLOGICAL1:
10751 val = ffebld_cu_val_logical1 (*cu);
10755 #if FFETARGET_okLOGICAL2
10756 case FFEINFO_kindtypeLOGICAL2:
10757 val = ffebld_cu_val_logical2 (*cu);
10761 #if FFETARGET_okLOGICAL3
10762 case FFEINFO_kindtypeLOGICAL3:
10763 val = ffebld_cu_val_logical3 (*cu);
10767 #if FFETARGET_okLOGICAL4
10768 case FFEINFO_kindtypeLOGICAL4:
10769 val = ffebld_cu_val_logical4 (*cu);
10774 assert ("bad LOGICAL constant kind type" == NULL);
10775 /* Fall through. */
10776 case FFEINFO_kindtypeANY:
10777 return error_mark_node;
10779 item = build_int_2 (val, (val < 0) ? -1 : 0);
10780 TREE_TYPE (item) = tree_type;
10784 case FFEINFO_basictypeREAL:
10786 REAL_VALUE_TYPE val;
10790 #if FFETARGET_okREAL1
10791 case FFEINFO_kindtypeREAL1:
10792 val = ffetarget_value_real1 (ffebld_cu_val_real1 (*cu));
10796 #if FFETARGET_okREAL2
10797 case FFEINFO_kindtypeREAL2:
10798 val = ffetarget_value_real2 (ffebld_cu_val_real2 (*cu));
10802 #if FFETARGET_okREAL3
10803 case FFEINFO_kindtypeREAL3:
10804 val = ffetarget_value_real3 (ffebld_cu_val_real3 (*cu));
10808 #if FFETARGET_okREAL4
10809 case FFEINFO_kindtypeREAL4:
10810 val = ffetarget_value_real4 (ffebld_cu_val_real4 (*cu));
10815 assert ("bad REAL constant kind type" == NULL);
10816 /* Fall through. */
10817 case FFEINFO_kindtypeANY:
10818 return error_mark_node;
10820 item = build_real (tree_type, val);
10824 case FFEINFO_basictypeCOMPLEX:
10826 REAL_VALUE_TYPE real;
10827 REAL_VALUE_TYPE imag;
10828 tree el_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
10832 #if FFETARGET_okCOMPLEX1
10833 case FFEINFO_kindtypeREAL1:
10834 real = ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu).real);
10835 imag = ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu).imaginary);
10839 #if FFETARGET_okCOMPLEX2
10840 case FFEINFO_kindtypeREAL2:
10841 real = ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu).real);
10842 imag = ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu).imaginary);
10846 #if FFETARGET_okCOMPLEX3
10847 case FFEINFO_kindtypeREAL3:
10848 real = ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu).real);
10849 imag = ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu).imaginary);
10853 #if FFETARGET_okCOMPLEX4
10854 case FFEINFO_kindtypeREAL4:
10855 real = ffetarget_value_real4 (ffebld_cu_val_complex4 (*cu).real);
10856 imag = ffetarget_value_real4 (ffebld_cu_val_complex4 (*cu).imaginary);
10861 assert ("bad REAL constant kind type" == NULL);
10862 /* Fall through. */
10863 case FFEINFO_kindtypeANY:
10864 return error_mark_node;
10866 item = ffecom_build_complex_constant_ (tree_type,
10867 build_real (el_type, real),
10868 build_real (el_type, imag));
10872 case FFEINFO_basictypeCHARACTER:
10873 { /* Happens only in DATA and similar contexts. */
10874 ffetargetCharacter1 val;
10878 #if FFETARGET_okCHARACTER1
10879 case FFEINFO_kindtypeLOGICAL1:
10880 val = ffebld_cu_val_character1 (*cu);
10885 assert ("bad CHARACTER constant kind type" == NULL);
10886 /* Fall through. */
10887 case FFEINFO_kindtypeANY:
10888 return error_mark_node;
10890 item = build_string (ffetarget_length_character1 (val),
10891 ffetarget_text_character1 (val));
10893 = build_type_variant (build_array_type (char_type_node,
10895 (integer_type_node,
10898 (ffetarget_length_character1
10904 case FFEINFO_basictypeHOLLERITH:
10906 ffetargetHollerith h;
10908 h = ffebld_cu_val_hollerith (*cu);
10910 /* If not at least as wide as default INTEGER, widen it. */
10911 if (h.length >= FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE)
10912 item = build_string (h.length, h.text);
10915 char str[FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE];
10917 memcpy (str, h.text, h.length);
10918 memset (&str[h.length], ' ',
10919 FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE
10921 item = build_string (FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE,
10925 = build_type_variant (build_array_type (char_type_node,
10927 (integer_type_node,
10935 case FFEINFO_basictypeTYPELESS:
10937 ffetargetInteger1 ival;
10938 ffetargetTypeless tless;
10941 tless = ffebld_cu_val_typeless (*cu);
10942 error = ffetarget_convert_integer1_typeless (&ival, tless);
10943 assert (error == FFEBAD);
10945 item = build_int_2 ((int) ival, 0);
10950 assert ("not yet on constant type" == NULL);
10951 /* Fall through. */
10952 case FFEINFO_basictypeANY:
10953 return error_mark_node;
10956 TREE_CONSTANT (item) = 1;
10963 /* Transform expression into constant tree.
10965 If the expression can be transformed into a tree that is constant,
10966 that is done, and the tree returned. Else NULL_TREE is returned.
10968 That way, a caller can attempt to provide compile-time initialization
10969 of a variable and, if that fails, *then* choose to start a new block
10970 and resort to using temporaries, as appropriate. */
10973 ffecom_const_expr (ffebld expr)
10976 return integer_zero_node;
10978 if (ffebld_op (expr) == FFEBLD_opANY)
10979 return error_mark_node;
10981 if (ffebld_arity (expr) == 0
10982 && (ffebld_op (expr) != FFEBLD_opSYMTER
10984 /* ~~Enable once common/equivalence is handled properly? */
10985 || ffebld_where (expr) == FFEINFO_whereCOMMON
10987 || ffebld_where (expr) == FFEINFO_whereGLOBAL
10988 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
10992 t = ffecom_expr (expr);
10993 assert (TREE_CONSTANT (t));
11000 /* Handy way to make a field in a struct/union. */
11002 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11004 ffecom_decl_field (tree context, tree prevfield,
11005 const char *name, tree type)
11009 field = build_decl (FIELD_DECL, get_identifier (name), type);
11010 DECL_CONTEXT (field) = context;
11011 DECL_FRAME_SIZE (field) = 0;
11012 if (prevfield != NULL_TREE)
11013 TREE_CHAIN (prevfield) = field;
11021 ffecom_close_include (FILE *f)
11023 #if FFECOM_GCC_INCLUDE
11024 ffecom_close_include_ (f);
11029 ffecom_decode_include_option (char *spec)
11031 #if FFECOM_GCC_INCLUDE
11032 return ffecom_decode_include_option_ (spec);
11038 /* End a compound statement (block). */
11040 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11042 ffecom_end_compstmt (void)
11044 return bison_rule_compstmt_ ();
11046 #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
11048 /* ffecom_end_transition -- Perform end transition on all symbols
11050 ffecom_end_transition();
11052 Calls ffecom_sym_end_transition for each global and local symbol. */
11055 ffecom_end_transition ()
11057 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11061 if (ffe_is_ffedebug ())
11062 fprintf (dmpout, "; end_stmt_transition\n");
11064 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11065 ffecom_list_blockdata_ = NULL;
11066 ffecom_list_common_ = NULL;
11069 ffesymbol_drive (ffecom_sym_end_transition);
11070 if (ffe_is_ffedebug ())
11072 ffestorag_report ();
11073 #if FFECOM_targetCURRENT == FFECOM_targetFFE
11074 ffesymbol_report_all ();
11078 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11079 ffecom_start_progunit_ ();
11081 for (item = ffecom_list_blockdata_;
11083 item = ffebld_trail (item))
11091 static int number = 0;
11093 callee = ffebld_head (item);
11094 s = ffebld_symter (callee);
11095 t = ffesymbol_hook (s).decl_tree;
11096 if (t == NULL_TREE)
11098 s = ffecom_sym_transform_ (s);
11099 t = ffesymbol_hook (s).decl_tree;
11102 yes = suspend_momentary ();
11104 dt = build_pointer_type (TREE_TYPE (t));
11106 var = build_decl (VAR_DECL,
11107 ffecom_get_invented_identifier ("__g77_forceload_%d",
11110 DECL_EXTERNAL (var) = 0;
11111 TREE_STATIC (var) = 1;
11112 TREE_PUBLIC (var) = 0;
11113 DECL_INITIAL (var) = error_mark_node;
11114 TREE_USED (var) = 1;
11116 var = start_decl (var, FALSE);
11118 t = ffecom_1 (ADDR_EXPR, dt, t);
11120 finish_decl (var, t, FALSE);
11122 resume_momentary (yes);
11125 /* This handles any COMMON areas that weren't referenced but have, for
11126 example, important initial data. */
11128 for (item = ffecom_list_common_;
11130 item = ffebld_trail (item))
11131 ffecom_transform_common_ (ffebld_symter (ffebld_head (item)));
11133 ffecom_list_common_ = NULL;
11137 /* ffecom_exec_transition -- Perform exec transition on all symbols
11139 ffecom_exec_transition();
11141 Calls ffecom_sym_exec_transition for each global and local symbol.
11142 Make sure error updating not inhibited. */
11145 ffecom_exec_transition ()
11149 if (ffe_is_ffedebug ())
11150 fprintf (dmpout, "; exec_stmt_transition\n");
11152 inhibited = ffebad_inhibit ();
11153 ffebad_set_inhibit (FALSE);
11155 ffesymbol_drive (ffecom_sym_exec_transition); /* Don't retract! */
11156 ffeequiv_exec_transition (); /* Handle all pending EQUIVALENCEs. */
11157 if (ffe_is_ffedebug ())
11159 ffestorag_report ();
11160 #if FFECOM_targetCURRENT == FFECOM_targetFFE
11161 ffesymbol_report_all ();
11166 ffebad_set_inhibit (TRUE);
11169 /* Handle assignment statement.
11171 Convert dest and source using ffecom_expr, then join them
11172 with an ASSIGN op and pass the whole thing to expand_expr_stmt. */
11174 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11176 ffecom_expand_let_stmt (ffebld dest, ffebld source)
11183 if (ffeinfo_basictype (ffebld_info (dest)) != FFEINFO_basictypeCHARACTER)
11188 /* This attempts to replicate the test below, but must not be
11189 true when the test below is false. (Always err on the side
11190 of creating unused temporaries, to avoid ICEs.) */
11191 if (ffebld_op (dest) != FFEBLD_opSYMTER
11192 || ((dest_tree = ffesymbol_hook (ffebld_symter (dest)).decl_tree)
11193 && (TREE_CODE (dest_tree) != VAR_DECL
11194 || TREE_ADDRESSABLE (dest_tree))))
11196 ffecom_prepare_expr_ (source, dest);
11201 ffecom_prepare_expr_ (source, NULL);
11205 ffecom_prepare_expr_w (NULL_TREE, dest);
11207 /* For COMPLEX assignment like C1=C2, if partial overlap is possible,
11208 create a temporary through which the assignment is to take place,
11209 since MODIFY_EXPR doesn't handle partial overlap properly. */
11210 if (ffebld_basictype (dest) == FFEINFO_basictypeCOMPLEX
11211 && ffecom_possible_partial_overlap_ (dest, source))
11213 assign_temp = ffecom_make_tempvar ("complex_let",
11215 [ffebld_basictype (dest)]
11216 [ffebld_kindtype (dest)],
11217 FFETARGET_charactersizeNONE,
11221 assign_temp = NULL_TREE;
11223 ffecom_prepare_end ();
11225 dest_tree = ffecom_expr_w (NULL_TREE, dest);
11226 if (dest_tree == error_mark_node)
11229 if ((TREE_CODE (dest_tree) != VAR_DECL)
11230 || TREE_ADDRESSABLE (dest_tree))
11231 source_tree = ffecom_expr_ (source, dest_tree, dest, &dest_used,
11235 assert (! dest_used);
11237 source_tree = ffecom_expr (source);
11239 if (source_tree == error_mark_node)
11243 expr_tree = source_tree;
11244 else if (assign_temp)
11247 /* The back end understands a conceptual move (evaluate source;
11248 store into dest), so use that, in case it can determine
11249 that it is going to use, say, two registers as temporaries
11250 anyway. So don't use the temp (and someday avoid generating
11251 it, once this code starts triggering regularly). */
11252 expr_tree = ffecom_2s (MOVE_EXPR, void_type_node,
11256 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
11259 expand_expr_stmt (expr_tree);
11260 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
11266 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
11270 expand_expr_stmt (expr_tree);
11274 ffecom_prepare_let_char_ (ffebld_size_known (dest), source);
11275 ffecom_prepare_expr_w (NULL_TREE, dest);
11277 ffecom_prepare_end ();
11279 ffecom_char_args_ (&dest_tree, &dest_length, dest);
11280 ffecom_let_char_ (dest_tree, dest_length, ffebld_size_known (dest),
11285 /* ffecom_expr -- Transform expr into gcc tree
11288 ffebld expr; // FFE expression.
11289 tree = ffecom_expr(expr);
11291 Recursive descent on expr while making corresponding tree nodes and
11292 attaching type info and such. */
11294 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11296 ffecom_expr (ffebld expr)
11298 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, FALSE, FALSE);
11302 /* Like ffecom_expr, but return tree usable for assigned GOTO or FORMAT. */
11304 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11306 ffecom_expr_assign (ffebld expr)
11308 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, TRUE, FALSE);
11312 /* Like ffecom_expr_rw, but return tree usable for ASSIGN. */
11314 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11316 ffecom_expr_assign_w (ffebld expr)
11318 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, TRUE, FALSE);
11322 /* Transform expr for use as into read/write tree and stabilize the
11323 reference. Not for use on CHARACTER expressions.
11325 Recursive descent on expr while making corresponding tree nodes and
11326 attaching type info and such. */
11328 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11330 ffecom_expr_rw (tree type, ffebld expr)
11332 assert (expr != NULL);
11333 /* Different target types not yet supported. */
11334 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
11336 return stabilize_reference (ffecom_expr (expr));
11340 /* Transform expr for use as into write tree and stabilize the
11341 reference. Not for use on CHARACTER expressions.
11343 Recursive descent on expr while making corresponding tree nodes and
11344 attaching type info and such. */
11346 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11348 ffecom_expr_w (tree type, ffebld expr)
11350 assert (expr != NULL);
11351 /* Different target types not yet supported. */
11352 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
11354 return stabilize_reference (ffecom_expr (expr));
11358 /* Do global stuff. */
11360 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11362 ffecom_finish_compile ()
11364 assert (ffecom_outer_function_decl_ == NULL_TREE);
11365 assert (current_function_decl == NULL_TREE);
11367 ffeglobal_drive (ffecom_finish_global_);
11371 /* Public entry point for front end to access finish_decl. */
11373 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11375 ffecom_finish_decl (tree decl, tree init, bool is_top_level)
11377 assert (!is_top_level);
11378 finish_decl (decl, init, FALSE);
11382 /* Finish a program unit. */
11384 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11386 ffecom_finish_progunit ()
11388 ffecom_end_compstmt ();
11390 ffecom_previous_function_decl_ = current_function_decl;
11391 ffecom_which_entrypoint_decl_ = NULL_TREE;
11393 finish_function (0);
11398 /* Wrapper for get_identifier. pattern is sprintf-like. */
11400 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11402 ffecom_get_invented_identifier (const char *pattern, ...)
11408 va_start (ap, pattern);
11409 if (vasprintf (&nam, pattern, ap) == 0)
11412 decl = get_identifier (nam);
11414 IDENTIFIER_INVENTED (decl) = 1;
11419 ffecom_gfrt_basictype (ffecomGfrt gfrt)
11421 assert (gfrt < FFECOM_gfrt);
11423 switch (ffecom_gfrt_type_[gfrt])
11425 case FFECOM_rttypeVOID_:
11426 case FFECOM_rttypeVOIDSTAR_:
11427 return FFEINFO_basictypeNONE;
11429 case FFECOM_rttypeFTNINT_:
11430 return FFEINFO_basictypeINTEGER;
11432 case FFECOM_rttypeINTEGER_:
11433 return FFEINFO_basictypeINTEGER;
11435 case FFECOM_rttypeLONGINT_:
11436 return FFEINFO_basictypeINTEGER;
11438 case FFECOM_rttypeLOGICAL_:
11439 return FFEINFO_basictypeLOGICAL;
11441 case FFECOM_rttypeREAL_F2C_:
11442 case FFECOM_rttypeREAL_GNU_:
11443 return FFEINFO_basictypeREAL;
11445 case FFECOM_rttypeCOMPLEX_F2C_:
11446 case FFECOM_rttypeCOMPLEX_GNU_:
11447 return FFEINFO_basictypeCOMPLEX;
11449 case FFECOM_rttypeDOUBLE_:
11450 case FFECOM_rttypeDOUBLEREAL_:
11451 return FFEINFO_basictypeREAL;
11453 case FFECOM_rttypeDBLCMPLX_F2C_:
11454 case FFECOM_rttypeDBLCMPLX_GNU_:
11455 return FFEINFO_basictypeCOMPLEX;
11457 case FFECOM_rttypeCHARACTER_:
11458 return FFEINFO_basictypeCHARACTER;
11461 return FFEINFO_basictypeANY;
11466 ffecom_gfrt_kindtype (ffecomGfrt gfrt)
11468 assert (gfrt < FFECOM_gfrt);
11470 switch (ffecom_gfrt_type_[gfrt])
11472 case FFECOM_rttypeVOID_:
11473 case FFECOM_rttypeVOIDSTAR_:
11474 return FFEINFO_kindtypeNONE;
11476 case FFECOM_rttypeFTNINT_:
11477 return FFEINFO_kindtypeINTEGER1;
11479 case FFECOM_rttypeINTEGER_:
11480 return FFEINFO_kindtypeINTEGER1;
11482 case FFECOM_rttypeLONGINT_:
11483 return FFEINFO_kindtypeINTEGER4;
11485 case FFECOM_rttypeLOGICAL_:
11486 return FFEINFO_kindtypeLOGICAL1;
11488 case FFECOM_rttypeREAL_F2C_:
11489 case FFECOM_rttypeREAL_GNU_:
11490 return FFEINFO_kindtypeREAL1;
11492 case FFECOM_rttypeCOMPLEX_F2C_:
11493 case FFECOM_rttypeCOMPLEX_GNU_:
11494 return FFEINFO_kindtypeREAL1;
11496 case FFECOM_rttypeDOUBLE_:
11497 case FFECOM_rttypeDOUBLEREAL_:
11498 return FFEINFO_kindtypeREAL2;
11500 case FFECOM_rttypeDBLCMPLX_F2C_:
11501 case FFECOM_rttypeDBLCMPLX_GNU_:
11502 return FFEINFO_kindtypeREAL2;
11504 case FFECOM_rttypeCHARACTER_:
11505 return FFEINFO_kindtypeCHARACTER1;
11508 return FFEINFO_kindtypeANY;
11522 tree double_ftype_double;
11523 tree float_ftype_float;
11524 tree ldouble_ftype_ldouble;
11525 tree ffecom_tree_ptr_to_fun_type_void;
11527 /* This block of code comes from the now-obsolete cktyps.c. It checks
11528 whether the compiler environment is buggy in known ways, some of which
11529 would, if not explicitly checked here, result in subtle bugs in g77. */
11531 if (ffe_is_do_internal_checks ())
11533 static char names[][12]
11535 {"bar", "bletch", "foo", "foobar"};
11540 name = bsearch ("foo", &names[0], ARRAY_SIZE (names), sizeof (names[0]),
11541 (int (*)(const void *, const void *)) strcmp);
11542 if (name != (char *) &names[2])
11544 assert ("bsearch doesn't work, #define FFEPROJ_BSEARCH 0 in proj.h"
11549 ul = strtoul ("123456789", NULL, 10);
11550 if (ul != 123456789L)
11552 assert ("strtoul doesn't have enough range, #define FFEPROJ_STRTOUL 0\
11553 in proj.h" == NULL);
11557 fl = atof ("56.789");
11558 if ((fl < 56.788) || (fl > 56.79))
11560 assert ("atof not type double, fix your #include <stdio.h>"
11566 #if FFECOM_GCC_INCLUDE
11567 ffecom_initialize_char_syntax_ ();
11570 ffecom_outer_function_decl_ = NULL_TREE;
11571 current_function_decl = NULL_TREE;
11572 named_labels = NULL_TREE;
11573 current_binding_level = NULL_BINDING_LEVEL;
11574 free_binding_level = NULL_BINDING_LEVEL;
11575 /* Make the binding_level structure for global names. */
11577 global_binding_level = current_binding_level;
11578 current_binding_level->prep_state = 2;
11580 build_common_tree_nodes (1);
11582 /* Define `int' and `char' first so that dbx will output them first. */
11583 pushdecl (build_decl (TYPE_DECL, get_identifier ("int"),
11584 integer_type_node));
11585 pushdecl (build_decl (TYPE_DECL, get_identifier ("char"),
11587 pushdecl (build_decl (TYPE_DECL, get_identifier ("long int"),
11588 long_integer_type_node));
11589 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned int"),
11590 unsigned_type_node));
11591 pushdecl (build_decl (TYPE_DECL, get_identifier ("long unsigned int"),
11592 long_unsigned_type_node));
11593 pushdecl (build_decl (TYPE_DECL, get_identifier ("long long int"),
11594 long_long_integer_type_node));
11595 pushdecl (build_decl (TYPE_DECL, get_identifier ("long long unsigned int"),
11596 long_long_unsigned_type_node));
11597 pushdecl (build_decl (TYPE_DECL, get_identifier ("short int"),
11598 short_integer_type_node));
11599 pushdecl (build_decl (TYPE_DECL, get_identifier ("short unsigned int"),
11600 short_unsigned_type_node));
11602 /* Set the sizetype before we make other types. This *should* be the
11603 first type we create. */
11606 (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE))));
11607 ffecom_typesize_pointer_
11608 = TREE_INT_CST_LOW (TYPE_SIZE (sizetype)) / BITS_PER_UNIT;
11610 build_common_tree_nodes_2 (0);
11612 /* Define both `signed char' and `unsigned char'. */
11613 pushdecl (build_decl (TYPE_DECL, get_identifier ("signed char"),
11614 signed_char_type_node));
11616 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned char"),
11617 unsigned_char_type_node));
11619 pushdecl (build_decl (TYPE_DECL, get_identifier ("float"),
11621 pushdecl (build_decl (TYPE_DECL, get_identifier ("double"),
11622 double_type_node));
11623 pushdecl (build_decl (TYPE_DECL, get_identifier ("long double"),
11624 long_double_type_node));
11626 /* For now, override what build_common_tree_nodes has done. */
11627 complex_integer_type_node = ffecom_make_complex_type_ (integer_type_node);
11628 complex_float_type_node = ffecom_make_complex_type_ (float_type_node);
11629 complex_double_type_node = ffecom_make_complex_type_ (double_type_node);
11630 complex_long_double_type_node
11631 = ffecom_make_complex_type_ (long_double_type_node);
11633 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex int"),
11634 complex_integer_type_node));
11635 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex float"),
11636 complex_float_type_node));
11637 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex double"),
11638 complex_double_type_node));
11639 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex long double"),
11640 complex_long_double_type_node));
11642 pushdecl (build_decl (TYPE_DECL, get_identifier ("void"),
11644 /* We are not going to have real types in C with less than byte alignment,
11645 so we might as well not have any types that claim to have it. */
11646 TYPE_ALIGN (void_type_node) = BITS_PER_UNIT;
11648 string_type_node = build_pointer_type (char_type_node);
11650 ffecom_tree_fun_type_void
11651 = build_function_type (void_type_node, NULL_TREE);
11653 ffecom_tree_ptr_to_fun_type_void
11654 = build_pointer_type (ffecom_tree_fun_type_void);
11656 endlink = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
11659 = build_function_type (float_type_node,
11660 tree_cons (NULL_TREE, float_type_node, endlink));
11662 double_ftype_double
11663 = build_function_type (double_type_node,
11664 tree_cons (NULL_TREE, double_type_node, endlink));
11666 ldouble_ftype_ldouble
11667 = build_function_type (long_double_type_node,
11668 tree_cons (NULL_TREE, long_double_type_node,
11671 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11672 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11674 ffecom_tree_type[i][j] = NULL_TREE;
11675 ffecom_tree_fun_type[i][j] = NULL_TREE;
11676 ffecom_tree_ptr_to_fun_type[i][j] = NULL_TREE;
11677 ffecom_f2c_typecode_[i][j] = -1;
11680 /* Set up standard g77 types. Note that INTEGER and LOGICAL are set
11681 to size FLOAT_TYPE_SIZE because they have to be the same size as
11682 REAL, which also is FLOAT_TYPE_SIZE, according to the standard.
11683 Compiler options and other such stuff that change the ways these
11684 types are set should not affect this particular setup. */
11686 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER1]
11687 = t = make_signed_type (FLOAT_TYPE_SIZE);
11688 pushdecl (build_decl (TYPE_DECL, get_identifier ("integer"),
11690 type = ffetype_new ();
11692 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER1,
11694 ffetype_set_ams (type,
11695 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11696 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11697 ffetype_set_star (base_type,
11698 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11700 ffetype_set_kind (base_type, 1, type);
11701 ffecom_typesize_integer1_ = ffetype_size (type);
11702 assert (ffetype_size (type) == sizeof (ffetargetInteger1));
11704 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER1]
11705 = t = make_unsigned_type (FLOAT_TYPE_SIZE); /* HOLLERITH means unsigned. */
11706 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned"),
11709 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER2]
11710 = t = make_signed_type (CHAR_TYPE_SIZE);
11711 pushdecl (build_decl (TYPE_DECL, get_identifier ("byte"),
11713 type = ffetype_new ();
11714 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER2,
11716 ffetype_set_ams (type,
11717 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11718 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11719 ffetype_set_star (base_type,
11720 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11722 ffetype_set_kind (base_type, 3, type);
11723 assert (ffetype_size (type) == sizeof (ffetargetInteger2));
11725 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER2]
11726 = t = make_unsigned_type (CHAR_TYPE_SIZE);
11727 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned byte"),
11730 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER3]
11731 = t = make_signed_type (CHAR_TYPE_SIZE * 2);
11732 pushdecl (build_decl (TYPE_DECL, get_identifier ("word"),
11734 type = ffetype_new ();
11735 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER3,
11737 ffetype_set_ams (type,
11738 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11739 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11740 ffetype_set_star (base_type,
11741 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11743 ffetype_set_kind (base_type, 6, type);
11744 assert (ffetype_size (type) == sizeof (ffetargetInteger3));
11746 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER3]
11747 = t = make_unsigned_type (CHAR_TYPE_SIZE * 2);
11748 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned word"),
11751 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER4]
11752 = t = make_signed_type (FLOAT_TYPE_SIZE * 2);
11753 pushdecl (build_decl (TYPE_DECL, get_identifier ("integer4"),
11755 type = ffetype_new ();
11756 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER4,
11758 ffetype_set_ams (type,
11759 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11760 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11761 ffetype_set_star (base_type,
11762 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11764 ffetype_set_kind (base_type, 2, type);
11765 assert (ffetype_size (type) == sizeof (ffetargetInteger4));
11767 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER4]
11768 = t = make_unsigned_type (FLOAT_TYPE_SIZE * 2);
11769 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned4"),
11773 if (ffe_is_do_internal_checks ()
11774 && LONG_TYPE_SIZE != FLOAT_TYPE_SIZE
11775 && LONG_TYPE_SIZE != CHAR_TYPE_SIZE
11776 && LONG_TYPE_SIZE != SHORT_TYPE_SIZE
11777 && LONG_TYPE_SIZE != LONG_LONG_TYPE_SIZE)
11779 fprintf (stderr, "Sorry, no g77 support for LONG_TYPE_SIZE (%d bits) yet.\n",
11784 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL1]
11785 = t = make_signed_type (FLOAT_TYPE_SIZE);
11786 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical"),
11788 type = ffetype_new ();
11790 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL1,
11792 ffetype_set_ams (type,
11793 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11794 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11795 ffetype_set_star (base_type,
11796 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11798 ffetype_set_kind (base_type, 1, type);
11799 assert (ffetype_size (type) == sizeof (ffetargetLogical1));
11801 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL2]
11802 = t = make_signed_type (CHAR_TYPE_SIZE);
11803 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical2"),
11805 type = ffetype_new ();
11806 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL2,
11808 ffetype_set_ams (type,
11809 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11810 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11811 ffetype_set_star (base_type,
11812 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11814 ffetype_set_kind (base_type, 3, type);
11815 assert (ffetype_size (type) == sizeof (ffetargetLogical2));
11817 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL3]
11818 = t = make_signed_type (CHAR_TYPE_SIZE * 2);
11819 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical3"),
11821 type = ffetype_new ();
11822 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL3,
11824 ffetype_set_ams (type,
11825 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11826 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11827 ffetype_set_star (base_type,
11828 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11830 ffetype_set_kind (base_type, 6, type);
11831 assert (ffetype_size (type) == sizeof (ffetargetLogical3));
11833 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL4]
11834 = t = make_signed_type (FLOAT_TYPE_SIZE * 2);
11835 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical4"),
11837 type = ffetype_new ();
11838 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL4,
11840 ffetype_set_ams (type,
11841 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11842 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11843 ffetype_set_star (base_type,
11844 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11846 ffetype_set_kind (base_type, 2, type);
11847 assert (ffetype_size (type) == sizeof (ffetargetLogical4));
11849 ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]
11850 = t = make_node (REAL_TYPE);
11851 TYPE_PRECISION (t) = FLOAT_TYPE_SIZE;
11852 pushdecl (build_decl (TYPE_DECL, get_identifier ("real"),
11855 type = ffetype_new ();
11857 ffeinfo_set_type (FFEINFO_basictypeREAL, FFEINFO_kindtypeREAL1,
11859 ffetype_set_ams (type,
11860 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11861 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11862 ffetype_set_star (base_type,
11863 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11865 ffetype_set_kind (base_type, 1, type);
11866 ffecom_f2c_typecode_[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]
11867 = FFETARGET_f2cTYREAL;
11868 assert (ffetype_size (type) == sizeof (ffetargetReal1));
11870 ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREALDOUBLE]
11871 = t = make_node (REAL_TYPE);
11872 TYPE_PRECISION (t) = FLOAT_TYPE_SIZE * 2; /* Always twice REAL. */
11873 pushdecl (build_decl (TYPE_DECL, get_identifier ("double precision"),
11876 type = ffetype_new ();
11877 ffeinfo_set_type (FFEINFO_basictypeREAL, FFEINFO_kindtypeREALDOUBLE,
11879 ffetype_set_ams (type,
11880 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11881 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11882 ffetype_set_star (base_type,
11883 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11885 ffetype_set_kind (base_type, 2, type);
11886 ffecom_f2c_typecode_[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2]
11887 = FFETARGET_f2cTYDREAL;
11888 assert (ffetype_size (type) == sizeof (ffetargetReal2));
11890 ffecom_tree_type[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL1]
11891 = t = ffecom_make_complex_type_ (ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]);
11892 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex"),
11894 type = ffetype_new ();
11896 ffeinfo_set_type (FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREAL1,
11898 ffetype_set_ams (type,
11899 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11900 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11901 ffetype_set_star (base_type,
11902 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11904 ffetype_set_kind (base_type, 1, type);
11905 ffecom_f2c_typecode_[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL1]
11906 = FFETARGET_f2cTYCOMPLEX;
11907 assert (ffetype_size (type) == sizeof (ffetargetComplex1));
11909 ffecom_tree_type[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREALDOUBLE]
11910 = t = ffecom_make_complex_type_ (ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2]);
11911 pushdecl (build_decl (TYPE_DECL, get_identifier ("double complex"),
11913 type = ffetype_new ();
11914 ffeinfo_set_type (FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREALDOUBLE,
11916 ffetype_set_ams (type,
11917 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11918 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11919 ffetype_set_star (base_type,
11920 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11922 ffetype_set_kind (base_type, 2,
11924 ffecom_f2c_typecode_[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL2]
11925 = FFETARGET_f2cTYDCOMPLEX;
11926 assert (ffetype_size (type) == sizeof (ffetargetComplex2));
11928 /* Make function and ptr-to-function types for non-CHARACTER types. */
11930 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11931 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11933 if ((t = ffecom_tree_type[i][j]) != NULL_TREE)
11935 if (i == FFEINFO_basictypeINTEGER)
11937 /* Figure out the smallest INTEGER type that can hold
11938 a pointer on this machine. */
11939 if (GET_MODE_SIZE (TYPE_MODE (t))
11940 >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
11942 if ((ffecom_pointer_kind_ == FFEINFO_kindtypeNONE)
11943 || (GET_MODE_SIZE (TYPE_MODE (ffecom_tree_type[i][ffecom_pointer_kind_]))
11944 > GET_MODE_SIZE (TYPE_MODE (t))))
11945 ffecom_pointer_kind_ = j;
11948 else if (i == FFEINFO_basictypeCOMPLEX)
11949 t = void_type_node;
11950 /* For f2c compatibility, REAL functions are really
11951 implemented as DOUBLE PRECISION. */
11952 else if ((i == FFEINFO_basictypeREAL)
11953 && (j == FFEINFO_kindtypeREAL1))
11954 t = ffecom_tree_type
11955 [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2];
11957 t = ffecom_tree_fun_type[i][j] = build_function_type (t,
11959 ffecom_tree_ptr_to_fun_type[i][j] = build_pointer_type (t);
11963 /* Set up pointer types. */
11965 if (ffecom_pointer_kind_ == FFEINFO_basictypeNONE)
11966 fatal ("no INTEGER type can hold a pointer on this configuration");
11967 else if (0 && ffe_is_do_internal_checks ())
11968 fprintf (stderr, "Pointer type kt=%d\n", ffecom_pointer_kind_);
11969 ffetype_set_kind (ffeinfo_type (FFEINFO_basictypeINTEGER,
11970 FFEINFO_kindtypeINTEGERDEFAULT),
11972 ffeinfo_type (FFEINFO_basictypeINTEGER,
11973 ffecom_pointer_kind_));
11975 if (ffe_is_ugly_assign ())
11976 ffecom_label_kind_ = ffecom_pointer_kind_; /* Require ASSIGN etc to this. */
11978 ffecom_label_kind_ = FFEINFO_kindtypeINTEGERDEFAULT;
11979 if (0 && ffe_is_do_internal_checks ())
11980 fprintf (stderr, "Label type kt=%d\n", ffecom_label_kind_);
11982 ffecom_integer_type_node
11983 = ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER1];
11984 ffecom_integer_zero_node = convert (ffecom_integer_type_node,
11985 integer_zero_node);
11986 ffecom_integer_one_node = convert (ffecom_integer_type_node,
11989 /* Yes, the "FLOAT_TYPE_SIZE" references below are intentional.
11990 Turns out that by TYLONG, runtime/libI77/lio.h really means
11991 "whatever size an ftnint is". For consistency and sanity,
11992 com.h and runtime/f2c.h.in agree that flag, ftnint, and ftlen
11993 all are INTEGER, which we also make out of whatever back-end
11994 integer type is FLOAT_TYPE_SIZE bits wide. This change, from
11995 LONG_TYPE_SIZE, for TYLONG and TYLOGICAL, was necessary to
11996 accommodate machines like the Alpha. Note that this suggests
11997 f2c and libf2c are missing a distinction perhaps needed on
11998 some machines between "int" and "long int". -- burley 0.5.5 950215 */
12000 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, FLOAT_TYPE_SIZE,
12001 FFETARGET_f2cTYLONG);
12002 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, SHORT_TYPE_SIZE,
12003 FFETARGET_f2cTYSHORT);
12004 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, CHAR_TYPE_SIZE,
12005 FFETARGET_f2cTYINT1);
12006 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, LONG_LONG_TYPE_SIZE,
12007 FFETARGET_f2cTYQUAD);
12008 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, FLOAT_TYPE_SIZE,
12009 FFETARGET_f2cTYLOGICAL);
12010 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, SHORT_TYPE_SIZE,
12011 FFETARGET_f2cTYLOGICAL2);
12012 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, CHAR_TYPE_SIZE,
12013 FFETARGET_f2cTYLOGICAL1);
12014 /* ~~~Not really such a type in libf2c, e.g. I/O support? */
12015 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, LONG_LONG_TYPE_SIZE,
12016 FFETARGET_f2cTYQUAD);
12018 /* CHARACTER stuff is all special-cased, so it is not handled in the above
12019 loop. CHARACTER items are built as arrays of unsigned char. */
12021 ffecom_tree_type[FFEINFO_basictypeCHARACTER]
12022 [FFEINFO_kindtypeCHARACTER1] = t = char_type_node;
12023 type = ffetype_new ();
12025 ffeinfo_set_type (FFEINFO_basictypeCHARACTER,
12026 FFEINFO_kindtypeCHARACTER1,
12028 ffetype_set_ams (type,
12029 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
12030 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
12031 ffetype_set_kind (base_type, 1, type);
12032 assert (ffetype_size (type)
12033 == sizeof (((ffetargetCharacter1) { 0, NULL }).text[0]));
12035 ffecom_tree_fun_type[FFEINFO_basictypeCHARACTER]
12036 [FFEINFO_kindtypeCHARACTER1] = ffecom_tree_fun_type_void;
12037 ffecom_tree_ptr_to_fun_type[FFEINFO_basictypeCHARACTER]
12038 [FFEINFO_kindtypeCHARACTER1]
12039 = ffecom_tree_ptr_to_fun_type_void;
12040 ffecom_f2c_typecode_[FFEINFO_basictypeCHARACTER][FFEINFO_kindtypeCHARACTER1]
12041 = FFETARGET_f2cTYCHAR;
12043 ffecom_f2c_typecode_[FFEINFO_basictypeANY][FFEINFO_kindtypeANY]
12046 /* Make multi-return-value type and fields. */
12048 ffecom_multi_type_node_ = make_node (UNION_TYPE);
12052 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
12053 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
12057 if (ffecom_tree_type[i][j] == NULL_TREE)
12058 continue; /* Not supported. */
12059 sprintf (&name[0], "bt_%s_kt_%s",
12060 ffeinfo_basictype_string ((ffeinfoBasictype) i),
12061 ffeinfo_kindtype_string ((ffeinfoKindtype) j));
12062 ffecom_multi_fields_[i][j] = build_decl (FIELD_DECL,
12063 get_identifier (name),
12064 ffecom_tree_type[i][j]);
12065 DECL_CONTEXT (ffecom_multi_fields_[i][j])
12066 = ffecom_multi_type_node_;
12067 DECL_FRAME_SIZE (ffecom_multi_fields_[i][j]) = 0;
12068 TREE_CHAIN (ffecom_multi_fields_[i][j]) = field;
12069 field = ffecom_multi_fields_[i][j];
12072 TYPE_FIELDS (ffecom_multi_type_node_) = field;
12073 layout_type (ffecom_multi_type_node_);
12075 /* Subroutines usually return integer because they might have alternate
12078 ffecom_tree_subr_type
12079 = build_function_type (integer_type_node, NULL_TREE);
12080 ffecom_tree_ptr_to_subr_type
12081 = build_pointer_type (ffecom_tree_subr_type);
12082 ffecom_tree_blockdata_type
12083 = build_function_type (void_type_node, NULL_TREE);
12085 builtin_function ("__builtin_sqrtf", float_ftype_float,
12086 BUILT_IN_FSQRT, BUILT_IN_NORMAL, "sqrtf");
12087 builtin_function ("__builtin_fsqrt", double_ftype_double,
12088 BUILT_IN_FSQRT, BUILT_IN_NORMAL, "sqrt");
12089 builtin_function ("__builtin_sqrtl", ldouble_ftype_ldouble,
12090 BUILT_IN_FSQRT, BUILT_IN_NORMAL, "sqrtl");
12091 builtin_function ("__builtin_sinf", float_ftype_float,
12092 BUILT_IN_SIN, BUILT_IN_NORMAL, "sinf");
12093 builtin_function ("__builtin_sin", double_ftype_double,
12094 BUILT_IN_SIN, BUILT_IN_NORMAL, "sin");
12095 builtin_function ("__builtin_sinl", ldouble_ftype_ldouble,
12096 BUILT_IN_SIN, BUILT_IN_NORMAL, "sinl");
12097 builtin_function ("__builtin_cosf", float_ftype_float,
12098 BUILT_IN_COS, BUILT_IN_NORMAL, "cosf");
12099 builtin_function ("__builtin_cos", double_ftype_double,
12100 BUILT_IN_COS, BUILT_IN_NORMAL, "cos");
12101 builtin_function ("__builtin_cosl", ldouble_ftype_ldouble,
12102 BUILT_IN_COS, BUILT_IN_NORMAL, "cosl");
12105 pedantic_lvalues = FALSE;
12108 ffecom_f2c_make_type_ (&ffecom_f2c_integer_type_node,
12111 ffecom_f2c_make_type_ (&ffecom_f2c_address_type_node,
12114 ffecom_f2c_make_type_ (&ffecom_f2c_real_type_node,
12117 ffecom_f2c_make_type_ (&ffecom_f2c_doublereal_type_node,
12118 FFECOM_f2cDOUBLEREAL,
12120 ffecom_f2c_make_type_ (&ffecom_f2c_complex_type_node,
12123 ffecom_f2c_make_type_ (&ffecom_f2c_doublecomplex_type_node,
12124 FFECOM_f2cDOUBLECOMPLEX,
12126 ffecom_f2c_make_type_ (&ffecom_f2c_longint_type_node,
12129 ffecom_f2c_make_type_ (&ffecom_f2c_logical_type_node,
12132 ffecom_f2c_make_type_ (&ffecom_f2c_flag_type_node,
12135 ffecom_f2c_make_type_ (&ffecom_f2c_ftnlen_type_node,
12138 ffecom_f2c_make_type_ (&ffecom_f2c_ftnint_type_node,
12142 ffecom_f2c_ftnlen_zero_node
12143 = convert (ffecom_f2c_ftnlen_type_node, integer_zero_node);
12145 ffecom_f2c_ftnlen_one_node
12146 = convert (ffecom_f2c_ftnlen_type_node, integer_one_node);
12148 ffecom_f2c_ftnlen_two_node = build_int_2 (2, 0);
12149 TREE_TYPE (ffecom_f2c_ftnlen_two_node) = ffecom_integer_type_node;
12151 ffecom_f2c_ptr_to_ftnlen_type_node
12152 = build_pointer_type (ffecom_f2c_ftnlen_type_node);
12154 ffecom_f2c_ptr_to_ftnint_type_node
12155 = build_pointer_type (ffecom_f2c_ftnint_type_node);
12157 ffecom_f2c_ptr_to_integer_type_node
12158 = build_pointer_type (ffecom_f2c_integer_type_node);
12160 ffecom_f2c_ptr_to_real_type_node
12161 = build_pointer_type (ffecom_f2c_real_type_node);
12163 ffecom_float_zero_ = build_real (float_type_node, dconst0);
12164 ffecom_double_zero_ = build_real (double_type_node, dconst0);
12166 REAL_VALUE_TYPE point_5;
12168 #ifdef REAL_ARITHMETIC
12169 REAL_ARITHMETIC (point_5, RDIV_EXPR, dconst1, dconst2);
12173 ffecom_float_half_ = build_real (float_type_node, point_5);
12174 ffecom_double_half_ = build_real (double_type_node, point_5);
12177 /* Do "extern int xargc;". */
12179 ffecom_tree_xargc_ = build_decl (VAR_DECL,
12180 get_identifier ("f__xargc"),
12181 integer_type_node);
12182 DECL_EXTERNAL (ffecom_tree_xargc_) = 1;
12183 TREE_STATIC (ffecom_tree_xargc_) = 1;
12184 TREE_PUBLIC (ffecom_tree_xargc_) = 1;
12185 ffecom_tree_xargc_ = start_decl (ffecom_tree_xargc_, FALSE);
12186 finish_decl (ffecom_tree_xargc_, NULL_TREE, FALSE);
12188 #if 0 /* This is being fixed, and seems to be working now. */
12189 if ((FLOAT_TYPE_SIZE != 32)
12190 || (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node))) != 32))
12192 warning ("configuration: REAL, INTEGER, and LOGICAL are %d bits wide,",
12193 (int) FLOAT_TYPE_SIZE);
12194 warning ("and pointers are %d bits wide, but g77 doesn't yet work",
12195 (int) TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node))));
12196 warning ("properly unless they all are 32 bits wide.");
12197 warning ("Please keep this in mind before you report bugs. g77 should");
12198 warning ("support non-32-bit machines better as of version 0.6.");
12202 #if 0 /* Code in ste.c that would crash has been commented out. */
12203 if (TYPE_PRECISION (ffecom_f2c_ftnlen_type_node)
12204 < TYPE_PRECISION (string_type_node))
12205 /* I/O will probably crash. */
12206 warning ("configuration: char * holds %d bits, but ftnlen only %d",
12207 TYPE_PRECISION (string_type_node),
12208 TYPE_PRECISION (ffecom_f2c_ftnlen_type_node));
12211 #if 0 /* ASSIGN-related stuff has been changed to accommodate this. */
12212 if (TYPE_PRECISION (ffecom_integer_type_node)
12213 < TYPE_PRECISION (string_type_node))
12214 /* ASSIGN 10 TO I will crash. */
12215 warning ("configuration: char * holds %d bits, but INTEGER only %d --\n\
12216 ASSIGN statement might fail",
12217 TYPE_PRECISION (string_type_node),
12218 TYPE_PRECISION (ffecom_integer_type_node));
12223 /* ffecom_init_2 -- Initialize
12225 ffecom_init_2(); */
12227 #if FFECOM_targetCURRENT == FFECOM_targetGCC
12231 assert (ffecom_outer_function_decl_ == NULL_TREE);
12232 assert (current_function_decl == NULL_TREE);
12233 assert (ffecom_which_entrypoint_decl_ == NULL_TREE);
12235 ffecom_master_arglist_ = NULL;
12237 ffecom_primary_entry_ = NULL;
12238 ffecom_is_altreturning_ = FALSE;
12239 ffecom_func_result_ = NULL_TREE;
12240 ffecom_multi_retval_ = NULL_TREE;
12244 /* ffecom_list_expr -- Transform list of exprs into gcc tree
12247 ffebld expr; // FFE opITEM list.
12248 tree = ffecom_list_expr(expr);
12250 List of actual args is transformed into corresponding gcc backend list. */
12252 #if FFECOM_targetCURRENT == FFECOM_targetGCC
12254 ffecom_list_expr (ffebld expr)
12257 tree *plist = &list;
12258 tree trail = NULL_TREE; /* Append char length args here. */
12259 tree *ptrail = &trail;
12262 while (expr != NULL)
12264 tree texpr = ffecom_arg_expr (ffebld_head (expr), &length);
12266 if (texpr == error_mark_node)
12267 return error_mark_node;
12269 *plist = build_tree_list (NULL_TREE, texpr);
12270 plist = &TREE_CHAIN (*plist);
12271 expr = ffebld_trail (expr);
12272 if (length != NULL_TREE)
12274 *ptrail = build_tree_list (NULL_TREE, length);
12275 ptrail = &TREE_CHAIN (*ptrail);
12285 /* ffecom_list_ptr_to_expr -- Transform list of exprs into gcc tree
12288 ffebld expr; // FFE opITEM list.
12289 tree = ffecom_list_ptr_to_expr(expr);
12291 List of actual args is transformed into corresponding gcc backend list for
12292 use in calling an external procedure (vs. a statement function). */
12294 #if FFECOM_targetCURRENT == FFECOM_targetGCC
12296 ffecom_list_ptr_to_expr (ffebld expr)
12299 tree *plist = &list;
12300 tree trail = NULL_TREE; /* Append char length args here. */
12301 tree *ptrail = &trail;
12304 while (expr != NULL)
12306 tree texpr = ffecom_arg_ptr_to_expr (ffebld_head (expr), &length);
12308 if (texpr == error_mark_node)
12309 return error_mark_node;
12311 *plist = build_tree_list (NULL_TREE, texpr);
12312 plist = &TREE_CHAIN (*plist);
12313 expr = ffebld_trail (expr);
12314 if (length != NULL_TREE)
12316 *ptrail = build_tree_list (NULL_TREE, length);
12317 ptrail = &TREE_CHAIN (*ptrail);
12327 /* Obtain gcc's LABEL_DECL tree for label. */
12329 #if FFECOM_targetCURRENT == FFECOM_targetGCC
12331 ffecom_lookup_label (ffelab label)
12335 if (ffelab_hook (label) == NULL_TREE)
12337 char labelname[16];
12339 switch (ffelab_type (label))
12341 case FFELAB_typeLOOPEND:
12342 case FFELAB_typeNOTLOOP:
12343 case FFELAB_typeENDIF:
12344 sprintf (labelname, "%" ffelabValue_f "u", ffelab_value (label));
12345 glabel = build_decl (LABEL_DECL, get_identifier (labelname),
12347 DECL_CONTEXT (glabel) = current_function_decl;
12348 DECL_MODE (glabel) = VOIDmode;
12351 case FFELAB_typeFORMAT:
12352 glabel = build_decl (VAR_DECL,
12353 ffecom_get_invented_identifier
12354 ("__g77_format_%d", (int) ffelab_value (label)),
12355 build_type_variant (build_array_type
12359 TREE_CONSTANT (glabel) = 1;
12360 TREE_STATIC (glabel) = 1;
12361 DECL_CONTEXT (glabel) = 0;
12362 DECL_INITIAL (glabel) = NULL;
12363 make_decl_rtl (glabel, NULL, 0);
12364 expand_decl (glabel);
12366 ffecom_save_tree_forever (glabel);
12370 case FFELAB_typeANY:
12371 glabel = error_mark_node;
12375 assert ("bad label type" == NULL);
12379 ffelab_set_hook (label, glabel);
12383 glabel = ffelab_hook (label);
12390 /* Stabilizes the arguments. Don't use this if the lhs and rhs come from
12391 a single source specification (as in the fourth argument of MVBITS).
12392 If the type is NULL_TREE, the type of lhs is used to make the type of
12393 the MODIFY_EXPR. */
12395 #if FFECOM_targetCURRENT == FFECOM_targetGCC
12397 ffecom_modify (tree newtype, tree lhs,
12400 if (lhs == error_mark_node || rhs == error_mark_node)
12401 return error_mark_node;
12403 if (newtype == NULL_TREE)
12404 newtype = TREE_TYPE (lhs);
12406 if (TREE_SIDE_EFFECTS (lhs))
12407 lhs = stabilize_reference (lhs);
12409 return ffecom_2s (MODIFY_EXPR, newtype, lhs, rhs);
12414 /* Register source file name. */
12417 ffecom_file (const char *name)
12419 #if FFECOM_GCC_INCLUDE
12420 ffecom_file_ (name);
12424 /* ffecom_notify_init_storage -- An aggregate storage is now fully init'ed
12427 ffecom_notify_init_storage(st);
12429 Gets called when all possible units in an aggregate storage area (a LOCAL
12430 with equivalences or a COMMON) have been initialized. The initialization
12431 info either is in ffestorag_init or, if that is NULL,
12432 ffestorag_accretion:
12434 ffestorag_init may contain an opCONTER or opARRTER. opCONTER may occur
12435 even for an array if the array is one element in length!
12437 ffestorag_accretion will contain an opACCTER. It is much like an
12438 opARRTER except it has an ffebit object in it instead of just a size.
12439 The back end can use the info in the ffebit object, if it wants, to
12440 reduce the amount of actual initialization, but in any case it should
12441 kill the ffebit object when done. Also, set accretion to NULL but
12442 init to a non-NULL value.
12444 After performing initialization, DO NOT set init to NULL, because that'll
12445 tell the front end it is ok for more initialization to happen. Instead,
12446 set init to an opANY expression or some such thing that you can use to
12447 tell that you've already initialized the object.
12450 Support two-pass FFE. */
12453 ffecom_notify_init_storage (ffestorag st)
12455 ffebld init; /* The initialization expression. */
12456 #if 0 && FFECOM_targetCURRENT == FFECOM_targetGCC
12457 ffetargetOffset size; /* The size of the entity. */
12458 ffetargetAlign pad; /* Its initial padding. */
12461 if (ffestorag_init (st) == NULL)
12463 init = ffestorag_accretion (st);
12464 assert (init != NULL);
12465 ffestorag_set_accretion (st, NULL);
12466 ffestorag_set_accretes (st, 0);
12468 #if 0 && FFECOM_targetCURRENT == FFECOM_targetGCC
12469 /* For GNU backend, just turn ACCTER into ARRTER and proceed. */
12470 size = ffebld_accter_size (init);
12471 pad = ffebld_accter_pad (init);
12472 ffebit_kill (ffebld_accter_bits (init));
12473 ffebld_set_op (init, FFEBLD_opARRTER);
12474 ffebld_set_arrter (init, ffebld_accter (init));
12475 ffebld_arrter_set_size (init, size);
12476 ffebld_arrter_set_pad (init, size);
12480 ffestorag_set_init (st, init);
12485 init = ffestorag_init (st);
12488 #if FFECOM_ONEPASS /* Process the inits, wipe 'em out. */
12489 ffestorag_set_init (st, ffebld_new_any ());
12491 if (ffebld_op (init) == FFEBLD_opANY)
12492 return; /* Oh, we already did this! */
12494 #if FFECOM_targetCURRENT == FFECOM_targetFFE
12498 if (ffestorag_symbol (st) != NULL)
12499 s = ffestorag_symbol (st);
12501 s = ffestorag_typesymbol (st);
12503 fprintf (dmpout, "= initialize_storage \"%s\" ",
12504 (s != NULL) ? ffesymbol_text (s) : "(unnamed)");
12505 ffebld_dump (init);
12506 fputc ('\n', dmpout);
12510 #endif /* if FFECOM_ONEPASS */
12513 /* ffecom_notify_init_symbol -- A symbol is now fully init'ed
12516 ffecom_notify_init_symbol(s);
12518 Gets called when all possible units in a symbol (not placed in COMMON
12519 or involved in EQUIVALENCE, unless it as yet has no ffestorag object)
12520 have been initialized. The initialization info either is in
12521 ffesymbol_init or, if that is NULL, ffesymbol_accretion:
12523 ffesymbol_init may contain an opCONTER or opARRTER. opCONTER may occur
12524 even for an array if the array is one element in length!
12526 ffesymbol_accretion will contain an opACCTER. It is much like an
12527 opARRTER except it has an ffebit object in it instead of just a size.
12528 The back end can use the info in the ffebit object, if it wants, to
12529 reduce the amount of actual initialization, but in any case it should
12530 kill the ffebit object when done. Also, set accretion to NULL but
12531 init to a non-NULL value.
12533 After performing initialization, DO NOT set init to NULL, because that'll
12534 tell the front end it is ok for more initialization to happen. Instead,
12535 set init to an opANY expression or some such thing that you can use to
12536 tell that you've already initialized the object.
12539 Support two-pass FFE. */
12542 ffecom_notify_init_symbol (ffesymbol s)
12544 ffebld init; /* The initialization expression. */
12545 #if 0 && FFECOM_targetCURRENT == FFECOM_targetGCC
12546 ffetargetOffset size; /* The size of the entity. */
12547 ffetargetAlign pad; /* Its initial padding. */
12550 if (ffesymbol_storage (s) == NULL)
12551 return; /* Do nothing until COMMON/EQUIVALENCE
12552 possibilities checked. */
12554 if ((ffesymbol_init (s) == NULL)
12555 && ((init = ffesymbol_accretion (s)) != NULL))
12557 ffesymbol_set_accretion (s, NULL);
12558 ffesymbol_set_accretes (s, 0);
12560 #if 0 && FFECOM_targetCURRENT == FFECOM_targetGCC
12561 /* For GNU backend, just turn ACCTER into ARRTER and proceed. */
12562 size = ffebld_accter_size (init);
12563 pad = ffebld_accter_pad (init);
12564 ffebit_kill (ffebld_accter_bits (init));
12565 ffebld_set_op (init, FFEBLD_opARRTER);
12566 ffebld_set_arrter (init, ffebld_accter (init));
12567 ffebld_arrter_set_size (init, size);
12568 ffebld_arrter_set_pad (init, size);
12572 ffesymbol_set_init (s, init);
12577 init = ffesymbol_init (s);
12581 ffesymbol_set_init (s, ffebld_new_any ());
12583 if (ffebld_op (init) == FFEBLD_opANY)
12584 return; /* Oh, we already did this! */
12586 #if FFECOM_targetCURRENT == FFECOM_targetFFE
12587 fprintf (dmpout, "= initialize_symbol \"%s\" ", ffesymbol_text (s));
12588 ffebld_dump (init);
12589 fputc ('\n', dmpout);
12592 #endif /* if FFECOM_ONEPASS */
12595 /* ffecom_notify_primary_entry -- Learn which is the primary entry point
12598 ffecom_notify_primary_entry(s);
12600 Gets called when implicit or explicit PROGRAM statement seen or when
12601 FUNCTION, SUBROUTINE, or BLOCK DATA statement seen, with the primary
12602 global symbol that serves as the entry point. */
12605 ffecom_notify_primary_entry (ffesymbol s)
12607 ffecom_primary_entry_ = s;
12608 ffecom_primary_entry_kind_ = ffesymbol_kind (s);
12610 if ((ffecom_primary_entry_kind_ == FFEINFO_kindFUNCTION)
12611 || (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE))
12612 ffecom_primary_entry_is_proc_ = TRUE;
12614 ffecom_primary_entry_is_proc_ = FALSE;
12616 if (!ffe_is_silent ())
12618 if (ffecom_primary_entry_kind_ == FFEINFO_kindPROGRAM)
12619 fprintf (stderr, "%s:\n", ffesymbol_text (s));
12621 fprintf (stderr, " %s:\n", ffesymbol_text (s));
12624 #if FFECOM_targetCURRENT == FFECOM_targetGCC
12625 if (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE)
12630 for (list = ffesymbol_dummyargs (s);
12632 list = ffebld_trail (list))
12634 arg = ffebld_head (list);
12635 if (ffebld_op (arg) == FFEBLD_opSTAR)
12637 ffecom_is_altreturning_ = TRUE;
12646 ffecom_open_include (char *name, ffewhereLine l, ffewhereColumn c)
12648 #if FFECOM_GCC_INCLUDE
12649 return ffecom_open_include_ (name, l, c);
12651 return fopen (name, "r");
12655 /* ffecom_ptr_to_expr -- Transform expr into gcc tree with & in front
12658 ffebld expr; // FFE expression.
12659 tree = ffecom_ptr_to_expr(expr);
12661 Like ffecom_expr, but sticks address-of in front of most things. */
12663 #if FFECOM_targetCURRENT == FFECOM_targetGCC
12665 ffecom_ptr_to_expr (ffebld expr)
12668 ffeinfoBasictype bt;
12669 ffeinfoKindtype kt;
12672 assert (expr != NULL);
12674 switch (ffebld_op (expr))
12676 case FFEBLD_opSYMTER:
12677 s = ffebld_symter (expr);
12678 if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC)
12682 ix = ffeintrin_gfrt_indirect (ffebld_symter_implementation (expr));
12683 assert (ix != FFECOM_gfrt);
12684 if ((item = ffecom_gfrt_[ix]) == NULL_TREE)
12686 ffecom_make_gfrt_ (ix);
12687 item = ffecom_gfrt_[ix];
12692 item = ffesymbol_hook (s).decl_tree;
12693 if (item == NULL_TREE)
12695 s = ffecom_sym_transform_ (s);
12696 item = ffesymbol_hook (s).decl_tree;
12699 assert (item != NULL);
12700 if (item == error_mark_node)
12702 if (!ffesymbol_hook (s).addr)
12703 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12707 case FFEBLD_opARRAYREF:
12708 return ffecom_arrayref_ (NULL_TREE, expr, 1);
12710 case FFEBLD_opCONTER:
12712 bt = ffeinfo_basictype (ffebld_info (expr));
12713 kt = ffeinfo_kindtype (ffebld_info (expr));
12715 item = ffecom_constantunion (&ffebld_constant_union
12716 (ffebld_conter (expr)), bt, kt,
12717 ffecom_tree_type[bt][kt]);
12718 if (item == error_mark_node)
12719 return error_mark_node;
12720 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12725 return error_mark_node;
12728 bt = ffeinfo_basictype (ffebld_info (expr));
12729 kt = ffeinfo_kindtype (ffebld_info (expr));
12731 item = ffecom_expr (expr);
12732 if (item == error_mark_node)
12733 return error_mark_node;
12735 /* The back end currently optimizes a bit too zealously for us, in that
12736 we fail JCB001 if the following block of code is omitted. It checks
12737 to see if the transformed expression is a symbol or array reference,
12738 and encloses it in a SAVE_EXPR if that is the case. */
12741 if ((TREE_CODE (item) == VAR_DECL)
12742 || (TREE_CODE (item) == PARM_DECL)
12743 || (TREE_CODE (item) == RESULT_DECL)
12744 || (TREE_CODE (item) == INDIRECT_REF)
12745 || (TREE_CODE (item) == ARRAY_REF)
12746 || (TREE_CODE (item) == COMPONENT_REF)
12748 || (TREE_CODE (item) == OFFSET_REF)
12750 || (TREE_CODE (item) == BUFFER_REF)
12751 || (TREE_CODE (item) == REALPART_EXPR)
12752 || (TREE_CODE (item) == IMAGPART_EXPR))
12754 item = ffecom_save_tree (item);
12757 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12762 assert ("fall-through error" == NULL);
12763 return error_mark_node;
12767 /* Obtain a temp var with given data type.
12769 size is FFETARGET_charactersizeNONE for a non-CHARACTER type
12770 or >= 0 for a CHARACTER type.
12772 elements is -1 for a scalar or > 0 for an array of type. */
12774 #if FFECOM_targetCURRENT == FFECOM_targetGCC
12776 ffecom_make_tempvar (const char *commentary, tree type,
12777 ffetargetCharacterSize size, int elements)
12781 static int mynumber;
12783 assert (current_binding_level->prep_state < 2);
12785 if (type == error_mark_node)
12786 return error_mark_node;
12788 yes = suspend_momentary ();
12790 if (size != FFETARGET_charactersizeNONE)
12791 type = build_array_type (type,
12792 build_range_type (ffecom_f2c_ftnlen_type_node,
12793 ffecom_f2c_ftnlen_one_node,
12794 build_int_2 (size, 0)));
12795 if (elements != -1)
12796 type = build_array_type (type,
12797 build_range_type (integer_type_node,
12799 build_int_2 (elements - 1,
12801 t = build_decl (VAR_DECL,
12802 ffecom_get_invented_identifier ("__g77_%s_%d",
12807 t = start_decl (t, FALSE);
12808 finish_decl (t, NULL_TREE, FALSE);
12810 resume_momentary (yes);
12816 /* Prepare argument pointer to expression.
12818 Like ffecom_prepare_expr, except for expressions to be evaluated
12819 via ffecom_arg_ptr_to_expr. */
12822 ffecom_prepare_arg_ptr_to_expr (ffebld expr)
12824 /* ~~For now, it seems to be the same thing. */
12825 ffecom_prepare_expr (expr);
12829 /* End of preparations. */
12832 ffecom_prepare_end (void)
12834 int prep_state = current_binding_level->prep_state;
12836 assert (prep_state < 2);
12837 current_binding_level->prep_state = 2;
12839 return (prep_state == 1) ? TRUE : FALSE;
12842 /* Prepare expression.
12844 This is called before any code is generated for the current block.
12845 It scans the expression, declares any temporaries that might be needed
12846 during evaluation of the expression, and stores those temporaries in
12847 the appropriate "hook" fields of the expression. `dest', if not NULL,
12848 specifies the destination that ffecom_expr_ will see, in case that
12849 helps avoid generating unused temporaries.
12851 ~~Improve to avoid allocating unused temporaries by taking `dest'
12852 into account vis-a-vis aliasing requirements of complex/character
12856 ffecom_prepare_expr_ (ffebld expr, ffebld dest UNUSED)
12858 ffeinfoBasictype bt;
12859 ffeinfoKindtype kt;
12860 ffetargetCharacterSize sz;
12861 tree tempvar = NULL_TREE;
12863 assert (current_binding_level->prep_state < 2);
12868 bt = ffeinfo_basictype (ffebld_info (expr));
12869 kt = ffeinfo_kindtype (ffebld_info (expr));
12870 sz = ffeinfo_size (ffebld_info (expr));
12872 /* Generate whatever temporaries are needed to represent the result
12873 of the expression. */
12875 if (bt == FFEINFO_basictypeCHARACTER)
12877 while (ffebld_op (expr) == FFEBLD_opPAREN)
12878 expr = ffebld_left (expr);
12881 switch (ffebld_op (expr))
12884 /* Don't make temps for SYMTER, CONTER, etc. */
12885 if (ffebld_arity (expr) == 0)
12890 case FFEINFO_basictypeCOMPLEX:
12891 if (ffebld_op (expr) == FFEBLD_opFUNCREF)
12895 if (ffebld_op (ffebld_left (expr)) != FFEBLD_opSYMTER)
12898 s = ffebld_symter (ffebld_left (expr));
12899 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT
12900 || (ffesymbol_where (s) != FFEINFO_whereINTRINSIC
12901 && ! ffesymbol_is_f2c (s))
12902 || (ffesymbol_where (s) == FFEINFO_whereINTRINSIC
12903 && ! ffe_is_f2c_library ()))
12906 else if (ffebld_op (expr) == FFEBLD_opPOWER)
12908 /* Requires special treatment. There's no POW_CC function
12909 in libg2c, so POW_ZZ is used, which means we always
12910 need a double-complex temp, not a single-complex. */
12911 kt = FFEINFO_kindtypeREAL2;
12913 else if (ffebld_op (expr) != FFEBLD_opDIVIDE)
12914 /* The other ops don't need temps for complex operands. */
12917 /* ~~~Avoid making temps for some intrinsics, such as AIMAG(C),
12918 REAL(C). See 19990325-0.f, routine `check', for cases. */
12919 tempvar = ffecom_make_tempvar ("complex",
12921 [FFEINFO_basictypeCOMPLEX][kt],
12922 FFETARGET_charactersizeNONE,
12926 case FFEINFO_basictypeCHARACTER:
12927 if (ffebld_op (expr) != FFEBLD_opFUNCREF)
12930 if (sz == FFETARGET_charactersizeNONE)
12931 /* ~~Kludge alert! This should someday be fixed. */
12934 tempvar = ffecom_make_tempvar ("char", char_type_node, sz, -1);
12943 case FFEBLD_opPOWER:
12946 tree rtmp, ltmp, result;
12948 ltype = ffecom_type_expr (ffebld_left (expr));
12949 rtype = ffecom_type_expr (ffebld_right (expr));
12951 rtmp = ffecom_make_tempvar (rtype, FFETARGET_charactersizeNONE, -1);
12952 ltmp = ffecom_make_tempvar (ltype, FFETARGET_charactersizeNONE, -1);
12953 result = ffecom_make_tempvar (ltype, FFETARGET_charactersizeNONE, -1);
12955 tempvar = make_tree_vec (3);
12956 TREE_VEC_ELT (tempvar, 0) = rtmp;
12957 TREE_VEC_ELT (tempvar, 1) = ltmp;
12958 TREE_VEC_ELT (tempvar, 2) = result;
12963 case FFEBLD_opCONCATENATE:
12965 /* This gets special handling, because only one set of temps
12966 is needed for a tree of these -- the tree is treated as
12967 a flattened list of concatenations when generating code. */
12969 ffecomConcatList_ catlist;
12970 tree ltmp, itmp, result;
12974 catlist = ffecom_concat_list_new_ (expr, FFETARGET_charactersizeNONE);
12975 count = ffecom_concat_list_count_ (catlist);
12980 = ffecom_make_tempvar ("concat_len",
12981 ffecom_f2c_ftnlen_type_node,
12982 FFETARGET_charactersizeNONE, count);
12984 = ffecom_make_tempvar ("concat_item",
12985 ffecom_f2c_address_type_node,
12986 FFETARGET_charactersizeNONE, count);
12988 = ffecom_make_tempvar ("concat_res",
12990 ffecom_concat_list_maxlen_ (catlist),
12993 tempvar = make_tree_vec (3);
12994 TREE_VEC_ELT (tempvar, 0) = ltmp;
12995 TREE_VEC_ELT (tempvar, 1) = itmp;
12996 TREE_VEC_ELT (tempvar, 2) = result;
12999 for (i = 0; i < count; ++i)
13000 ffecom_prepare_arg_ptr_to_expr (ffecom_concat_list_expr_ (catlist,
13003 ffecom_concat_list_kill_ (catlist);
13007 ffebld_nonter_set_hook (expr, tempvar);
13008 current_binding_level->prep_state = 1;
13013 case FFEBLD_opCONVERT:
13014 if (bt == FFEINFO_basictypeCHARACTER
13015 && ((ffebld_size_known (ffebld_left (expr))
13016 == FFETARGET_charactersizeNONE)
13017 || (ffebld_size_known (ffebld_left (expr)) >= sz)))
13018 tempvar = ffecom_make_tempvar ("convert", char_type_node, sz, -1);
13024 ffebld_nonter_set_hook (expr, tempvar);
13025 current_binding_level->prep_state = 1;
13028 /* Prepare subexpressions for this expr. */
13030 switch (ffebld_op (expr))
13032 case FFEBLD_opPERCENT_LOC:
13033 ffecom_prepare_ptr_to_expr (ffebld_left (expr));
13036 case FFEBLD_opPERCENT_VAL:
13037 case FFEBLD_opPERCENT_REF:
13038 ffecom_prepare_expr (ffebld_left (expr));
13041 case FFEBLD_opPERCENT_DESCR:
13042 ffecom_prepare_arg_ptr_to_expr (ffebld_left (expr));
13045 case FFEBLD_opITEM:
13051 item = ffebld_trail (item))
13052 if (ffebld_head (item) != NULL)
13053 ffecom_prepare_expr (ffebld_head (item));
13058 /* Need to handle character conversion specially. */
13059 switch (ffebld_arity (expr))
13062 ffecom_prepare_expr (ffebld_left (expr));
13063 ffecom_prepare_expr (ffebld_right (expr));
13067 ffecom_prepare_expr (ffebld_left (expr));
13078 /* Prepare expression for reading and writing.
13080 Like ffecom_prepare_expr, except for expressions to be evaluated
13081 via ffecom_expr_rw. */
13084 ffecom_prepare_expr_rw (tree type, ffebld expr)
13086 /* This is all we support for now. */
13087 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
13089 /* ~~For now, it seems to be the same thing. */
13090 ffecom_prepare_expr (expr);
13094 /* Prepare expression for writing.
13096 Like ffecom_prepare_expr, except for expressions to be evaluated
13097 via ffecom_expr_w. */
13100 ffecom_prepare_expr_w (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 returning.
13112 Like ffecom_prepare_expr, except for expressions to be evaluated
13113 via ffecom_return_expr. */
13116 ffecom_prepare_return_expr (ffebld expr)
13118 assert (current_binding_level->prep_state < 2);
13120 if (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE
13121 && ffecom_is_altreturning_
13123 ffecom_prepare_expr (expr);
13126 /* Prepare pointer to expression.
13128 Like ffecom_prepare_expr, except for expressions to be evaluated
13129 via ffecom_ptr_to_expr. */
13132 ffecom_prepare_ptr_to_expr (ffebld expr)
13134 /* ~~For now, it seems to be the same thing. */
13135 ffecom_prepare_expr (expr);
13139 /* Transform expression into constant pointer-to-expression tree.
13141 If the expression can be transformed into a pointer-to-expression tree
13142 that is constant, that is done, and the tree returned. Else NULL_TREE
13145 That way, a caller can attempt to provide compile-time initialization
13146 of a variable and, if that fails, *then* choose to start a new block
13147 and resort to using temporaries, as appropriate. */
13150 ffecom_ptr_to_const_expr (ffebld expr)
13153 return integer_zero_node;
13155 if (ffebld_op (expr) == FFEBLD_opANY)
13156 return error_mark_node;
13158 if (ffebld_arity (expr) == 0
13159 && (ffebld_op (expr) != FFEBLD_opSYMTER
13160 || ffebld_where (expr) == FFEINFO_whereCOMMON
13161 || ffebld_where (expr) == FFEINFO_whereGLOBAL
13162 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
13166 t = ffecom_ptr_to_expr (expr);
13167 assert (TREE_CONSTANT (t));
13174 /* ffecom_return_expr -- Returns return-value expr given alt return expr
13176 tree rtn; // NULL_TREE means use expand_null_return()
13177 ffebld expr; // NULL if no alt return expr to RETURN stmt
13178 rtn = ffecom_return_expr(expr);
13180 Based on the program unit type and other info (like return function
13181 type, return master function type when alternate ENTRY points,
13182 whether subroutine has any alternate RETURN points, etc), returns the
13183 appropriate expression to be returned to the caller, or NULL_TREE
13184 meaning no return value or the caller expects it to be returned somewhere
13185 else (which is handled by other parts of this module). */
13187 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13189 ffecom_return_expr (ffebld expr)
13193 switch (ffecom_primary_entry_kind_)
13195 case FFEINFO_kindPROGRAM:
13196 case FFEINFO_kindBLOCKDATA:
13200 case FFEINFO_kindSUBROUTINE:
13201 if (!ffecom_is_altreturning_)
13202 rtn = NULL_TREE; /* No alt returns, never an expr. */
13203 else if (expr == NULL)
13204 rtn = integer_zero_node;
13206 rtn = ffecom_expr (expr);
13209 case FFEINFO_kindFUNCTION:
13210 if ((ffecom_multi_retval_ != NULL_TREE)
13211 || (ffesymbol_basictype (ffecom_primary_entry_)
13212 == FFEINFO_basictypeCHARACTER)
13213 || ((ffesymbol_basictype (ffecom_primary_entry_)
13214 == FFEINFO_basictypeCOMPLEX)
13215 && (ffecom_num_entrypoints_ == 0)
13216 && ffesymbol_is_f2c (ffecom_primary_entry_)))
13217 { /* Value is returned by direct assignment
13218 into (implicit) dummy. */
13222 rtn = ffecom_func_result_;
13224 /* Spurious error if RETURN happens before first reference! So elide
13225 this code. In particular, for debugging registry, rtn should always
13226 be non-null after all, but TREE_USED won't be set until we encounter
13227 a reference in the code. Perfectly okay (but weird) code that,
13228 e.g., has "GOTO 20;10 RETURN;20 RTN=0;GOTO 10", would result in
13229 this diagnostic for no reason. Have people use -O -Wuninitialized
13230 and leave it to the back end to find obviously weird cases. */
13232 /* Used to "assert(rtn != NULL_TREE);" here, but it's kind of a valid
13233 situation; if the return value has never been referenced, it won't
13234 have a tree under 2pass mode. */
13235 if ((rtn == NULL_TREE)
13236 || !TREE_USED (rtn))
13238 ffebad_start (FFEBAD_RETURN_VALUE_UNSET);
13239 ffebad_here (0, ffesymbol_where_line (ffecom_primary_entry_),
13240 ffesymbol_where_column (ffecom_primary_entry_));
13241 ffebad_string (ffesymbol_text (ffesymbol_funcresult
13242 (ffecom_primary_entry_)));
13249 assert ("bad unit kind" == NULL);
13250 case FFEINFO_kindANY:
13251 rtn = error_mark_node;
13259 /* Do save_expr only if tree is not error_mark_node. */
13261 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13263 ffecom_save_tree (tree t)
13265 return save_expr (t);
13269 /* Start a compound statement (block). */
13271 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13273 ffecom_start_compstmt (void)
13275 bison_rule_pushlevel_ ();
13277 #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
13279 /* Public entry point for front end to access start_decl. */
13281 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13283 ffecom_start_decl (tree decl, bool is_initialized)
13285 DECL_INITIAL (decl) = is_initialized ? error_mark_node : NULL_TREE;
13286 return start_decl (decl, FALSE);
13290 /* ffecom_sym_commit -- Symbol's state being committed to reality
13293 ffecom_sym_commit(s);
13295 Does whatever the backend needs when a symbol is committed after having
13296 been backtrackable for a period of time. */
13298 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13300 ffecom_sym_commit (ffesymbol s UNUSED)
13302 assert (!ffesymbol_retractable ());
13306 /* ffecom_sym_end_transition -- Perform end transition on all symbols
13308 ffecom_sym_end_transition();
13310 Does backend-specific stuff and also calls ffest_sym_end_transition
13311 to do the necessary FFE stuff.
13313 Backtracking is never enabled when this fn is called, so don't worry
13317 ffecom_sym_end_transition (ffesymbol s)
13321 assert (!ffesymbol_retractable ());
13323 s = ffest_sym_end_transition (s);
13325 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13326 if ((ffesymbol_kind (s) == FFEINFO_kindBLOCKDATA)
13327 && (ffesymbol_where (s) == FFEINFO_whereGLOBAL))
13329 ffecom_list_blockdata_
13330 = ffebld_new_item (ffebld_new_symter (s, FFEINTRIN_genNONE,
13331 FFEINTRIN_specNONE,
13332 FFEINTRIN_impNONE),
13333 ffecom_list_blockdata_);
13337 /* This is where we finally notice that a symbol has partial initialization
13338 and finalize it. */
13340 if (ffesymbol_accretion (s) != NULL)
13342 assert (ffesymbol_init (s) == NULL);
13343 ffecom_notify_init_symbol (s);
13345 else if (((st = ffesymbol_storage (s)) != NULL)
13346 && ((st = ffestorag_parent (st)) != NULL)
13347 && (ffestorag_accretion (st) != NULL))
13349 assert (ffestorag_init (st) == NULL);
13350 ffecom_notify_init_storage (st);
13353 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13354 if ((ffesymbol_kind (s) == FFEINFO_kindCOMMON)
13355 && (ffesymbol_where (s) == FFEINFO_whereLOCAL)
13356 && (ffesymbol_storage (s) != NULL))
13358 ffecom_list_common_
13359 = ffebld_new_item (ffebld_new_symter (s, FFEINTRIN_genNONE,
13360 FFEINTRIN_specNONE,
13361 FFEINTRIN_impNONE),
13362 ffecom_list_common_);
13369 /* ffecom_sym_exec_transition -- Perform exec transition on all symbols
13371 ffecom_sym_exec_transition();
13373 Does backend-specific stuff and also calls ffest_sym_exec_transition
13374 to do the necessary FFE stuff.
13376 See the long-winded description in ffecom_sym_learned for info
13377 on handling the situation where backtracking is inhibited. */
13380 ffecom_sym_exec_transition (ffesymbol s)
13382 s = ffest_sym_exec_transition (s);
13387 /* ffecom_sym_learned -- Initial or more info gained on symbol after exec
13390 s = ffecom_sym_learned(s);
13392 Called when a new symbol is seen after the exec transition or when more
13393 info (perhaps) is gained for an UNCERTAIN symbol. The symbol state when
13394 it arrives here is that all its latest info is updated already, so its
13395 state may be UNCERTAIN or UNDERSTOOD, it might already have the hook
13396 field filled in if its gone through here or exec_transition first, and
13399 The backend probably wants to check ffesymbol_retractable() to see if
13400 backtracking is in effect. If so, the FFE's changes to the symbol may
13401 be retracted (undone) or committed (ratified), at which time the
13402 appropriate ffecom_sym_retract or _commit function will be called
13405 If the backend has its own backtracking mechanism, great, use it so that
13406 committal is a simple operation. Though it doesn't make much difference,
13407 I suppose: the reason for tentative symbol evolution in the FFE is to
13408 enable error detection in weird incorrect statements early and to disable
13409 incorrect error detection on a correct statement. The backend is not
13410 likely to introduce any information that'll get involved in these
13411 considerations, so it is probably just fine that the implementation
13412 model for this fn and for _exec_transition is to not do anything
13413 (besides the required FFE stuff) if ffesymbol_retractable() returns TRUE
13414 and instead wait until ffecom_sym_commit is called (which it never
13415 will be as long as we're using ambiguity-detecting statement analysis in
13416 the FFE, which we are initially to shake out the code, but don't depend
13417 on this), otherwise go ahead and do whatever is needed.
13419 In essence, then, when this fn and _exec_transition get called while
13420 backtracking is enabled, a general mechanism would be to flag which (or
13421 both) of these were called (and in what order? neat question as to what
13422 might happen that I'm too lame to think through right now) and then when
13423 _commit is called reproduce the original calling sequence, if any, for
13424 the two fns (at which point backtracking will, of course, be disabled). */
13427 ffecom_sym_learned (ffesymbol s)
13429 ffestorag_exec_layout (s);
13434 /* ffecom_sym_retract -- Symbol's state being retracted from reality
13437 ffecom_sym_retract(s);
13439 Does whatever the backend needs when a symbol is retracted after having
13440 been backtrackable for a period of time. */
13442 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13444 ffecom_sym_retract (ffesymbol s UNUSED)
13446 assert (!ffesymbol_retractable ());
13448 #if 0 /* GCC doesn't commit any backtrackable sins,
13449 so nothing needed here. */
13450 switch (ffesymbol_hook (s).state)
13452 case 0: /* nothing happened yet. */
13455 case 1: /* exec transition happened. */
13458 case 2: /* learned happened. */
13461 case 3: /* learned then exec. */
13464 case 4: /* exec then learned. */
13468 assert ("bad hook state" == NULL);
13475 /* Create temporary gcc label. */
13477 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13479 ffecom_temp_label ()
13482 static int mynumber = 0;
13484 glabel = build_decl (LABEL_DECL,
13485 ffecom_get_invented_identifier ("__g77_label_%d",
13488 DECL_CONTEXT (glabel) = current_function_decl;
13489 DECL_MODE (glabel) = VOIDmode;
13495 /* Return an expression that is usable as an arg in a conditional context
13496 (IF, DO WHILE, .NOT., and so on).
13498 Use the one provided for the back end as of >2.6.0. */
13500 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13502 ffecom_truth_value (tree expr)
13504 return truthvalue_conversion (expr);
13508 /* Return the inversion of a truth value (the inversion of what
13509 ffecom_truth_value builds).
13511 Apparently invert_truthvalue, which is properly in the back end, is
13512 enough for now, so just use it. */
13514 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13516 ffecom_truth_value_invert (tree expr)
13518 return invert_truthvalue (ffecom_truth_value (expr));
13523 /* Return the tree that is the type of the expression, as would be
13524 returned in TREE_TYPE(ffecom_expr(expr)), without otherwise
13525 transforming the expression, generating temporaries, etc. */
13528 ffecom_type_expr (ffebld expr)
13530 ffeinfoBasictype bt;
13531 ffeinfoKindtype kt;
13534 assert (expr != NULL);
13536 bt = ffeinfo_basictype (ffebld_info (expr));
13537 kt = ffeinfo_kindtype (ffebld_info (expr));
13538 tree_type = ffecom_tree_type[bt][kt];
13540 switch (ffebld_op (expr))
13542 case FFEBLD_opCONTER:
13543 case FFEBLD_opSYMTER:
13544 case FFEBLD_opARRAYREF:
13545 case FFEBLD_opUPLUS:
13546 case FFEBLD_opPAREN:
13547 case FFEBLD_opUMINUS:
13549 case FFEBLD_opSUBTRACT:
13550 case FFEBLD_opMULTIPLY:
13551 case FFEBLD_opDIVIDE:
13552 case FFEBLD_opPOWER:
13554 case FFEBLD_opFUNCREF:
13555 case FFEBLD_opSUBRREF:
13559 case FFEBLD_opNEQV:
13561 case FFEBLD_opCONVERT:
13568 case FFEBLD_opPERCENT_LOC:
13571 case FFEBLD_opACCTER:
13572 case FFEBLD_opARRTER:
13573 case FFEBLD_opITEM:
13574 case FFEBLD_opSTAR:
13575 case FFEBLD_opBOUNDS:
13576 case FFEBLD_opREPEAT:
13577 case FFEBLD_opLABTER:
13578 case FFEBLD_opLABTOK:
13579 case FFEBLD_opIMPDO:
13580 case FFEBLD_opCONCATENATE:
13581 case FFEBLD_opSUBSTR:
13583 assert ("bad op for ffecom_type_expr" == NULL);
13584 /* Fall through. */
13586 return error_mark_node;
13590 /* Return PARM_DECL for arg#1 of master fn containing alternate ENTRY points
13592 If the PARM_DECL already exists, return it, else create it. It's an
13593 integer_type_node argument for the master function that implements a
13594 subroutine or function with more than one entrypoint and is bound at
13595 run time with the entrypoint number (0 for SUBROUTINE/FUNCTION, 1 for
13596 first ENTRY statement, and so on). */
13598 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13600 ffecom_which_entrypoint_decl ()
13602 assert (ffecom_which_entrypoint_decl_ != NULL_TREE);
13604 return ffecom_which_entrypoint_decl_;
13609 /* The following sections consists of private and public functions
13610 that have the same names and perform roughly the same functions
13611 as counterparts in the C front end. Changes in the C front end
13612 might affect how things should be done here. Only functions
13613 needed by the back end should be public here; the rest should
13614 be private (static in the C sense). Functions needed by other
13615 g77 front-end modules should be accessed by them via public
13616 ffecom_* names, which should themselves call private versions
13617 in this section so the private versions are easy to recognize
13618 when upgrading to a new gcc and finding interesting changes
13621 Functions named after rule "foo:" in c-parse.y are named
13622 "bison_rule_foo_" so they are easy to find. */
13624 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13627 bison_rule_pushlevel_ ()
13629 emit_line_note (input_filename, lineno);
13631 clear_last_expr ();
13633 expand_start_bindings (0);
13637 bison_rule_compstmt_ ()
13640 int keep = kept_level_p ();
13642 /* Make the temps go away. */
13644 current_binding_level->names = NULL_TREE;
13646 emit_line_note (input_filename, lineno);
13647 expand_end_bindings (getdecls (), keep, 0);
13648 t = poplevel (keep, 1, 0);
13654 /* Return a definition for a builtin function named NAME and whose data type
13655 is TYPE. TYPE should be a function type with argument types.
13656 FUNCTION_CODE tells later passes how to compile calls to this function.
13657 See tree.h for its possible values.
13659 If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME,
13660 the name to be called if we can't opencode the function. */
13663 builtin_function (const char *name, tree type, int function_code,
13664 enum built_in_class class,
13665 const char *library_name)
13667 tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
13668 DECL_EXTERNAL (decl) = 1;
13669 TREE_PUBLIC (decl) = 1;
13671 DECL_ASSEMBLER_NAME (decl) = get_identifier (library_name);
13672 make_decl_rtl (decl, NULL_PTR, 1);
13674 DECL_BUILT_IN_CLASS (decl) = class;
13675 DECL_FUNCTION_CODE (decl) = function_code;
13680 /* Handle when a new declaration NEWDECL
13681 has the same name as an old one OLDDECL
13682 in the same binding contour.
13683 Prints an error message if appropriate.
13685 If safely possible, alter OLDDECL to look like NEWDECL, and return 1.
13686 Otherwise, return 0. */
13689 duplicate_decls (tree newdecl, tree olddecl)
13691 int types_match = 1;
13692 int new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL
13693 && DECL_INITIAL (newdecl) != 0);
13694 tree oldtype = TREE_TYPE (olddecl);
13695 tree newtype = TREE_TYPE (newdecl);
13697 if (olddecl == newdecl)
13700 if (TREE_CODE (newtype) == ERROR_MARK
13701 || TREE_CODE (oldtype) == ERROR_MARK)
13704 /* New decl is completely inconsistent with the old one =>
13705 tell caller to replace the old one.
13706 This is always an error except in the case of shadowing a builtin. */
13707 if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
13710 /* For real parm decl following a forward decl,
13711 return 1 so old decl will be reused. */
13712 if (types_match && TREE_CODE (newdecl) == PARM_DECL
13713 && TREE_ASM_WRITTEN (olddecl) && ! TREE_ASM_WRITTEN (newdecl))
13716 /* The new declaration is the same kind of object as the old one.
13717 The declarations may partially match. Print warnings if they don't
13718 match enough. Ultimately, copy most of the information from the new
13719 decl to the old one, and keep using the old one. */
13721 if (TREE_CODE (olddecl) == FUNCTION_DECL
13722 && DECL_BUILT_IN (olddecl))
13724 /* A function declaration for a built-in function. */
13725 if (!TREE_PUBLIC (newdecl))
13727 else if (!types_match)
13729 /* Accept the return type of the new declaration if same modes. */
13730 tree oldreturntype = TREE_TYPE (TREE_TYPE (olddecl));
13731 tree newreturntype = TREE_TYPE (TREE_TYPE (newdecl));
13733 if (TYPE_MODE (oldreturntype) == TYPE_MODE (newreturntype))
13735 /* Function types may be shared, so we can't just modify
13736 the return type of olddecl's function type. */
13738 = build_function_type (newreturntype,
13739 TYPE_ARG_TYPES (TREE_TYPE (olddecl)));
13743 TREE_TYPE (olddecl) = newtype;
13749 else if (TREE_CODE (olddecl) == FUNCTION_DECL
13750 && DECL_SOURCE_LINE (olddecl) == 0)
13752 /* A function declaration for a predeclared function
13753 that isn't actually built in. */
13754 if (!TREE_PUBLIC (newdecl))
13756 else if (!types_match)
13758 /* If the types don't match, preserve volatility indication.
13759 Later on, we will discard everything else about the
13760 default declaration. */
13761 TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
13765 /* Copy all the DECL_... slots specified in the new decl
13766 except for any that we copy here from the old type.
13768 Past this point, we don't change OLDTYPE and NEWTYPE
13769 even if we change the types of NEWDECL and OLDDECL. */
13773 /* Merge the data types specified in the two decls. */
13774 if (TREE_CODE (newdecl) != FUNCTION_DECL || !DECL_BUILT_IN (olddecl))
13775 TREE_TYPE (newdecl)
13776 = TREE_TYPE (olddecl)
13777 = TREE_TYPE (newdecl);
13779 /* Lay the type out, unless already done. */
13780 if (oldtype != TREE_TYPE (newdecl))
13782 if (TREE_TYPE (newdecl) != error_mark_node)
13783 layout_type (TREE_TYPE (newdecl));
13784 if (TREE_CODE (newdecl) != FUNCTION_DECL
13785 && TREE_CODE (newdecl) != TYPE_DECL
13786 && TREE_CODE (newdecl) != CONST_DECL)
13787 layout_decl (newdecl, 0);
13791 /* Since the type is OLDDECL's, make OLDDECL's size go with. */
13792 DECL_SIZE (newdecl) = DECL_SIZE (olddecl);
13793 DECL_SIZE_UNIT (newdecl) = DECL_SIZE_UNIT (olddecl);
13794 if (TREE_CODE (olddecl) != FUNCTION_DECL)
13795 if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl))
13796 DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl);
13799 /* Keep the old rtl since we can safely use it. */
13800 DECL_RTL (newdecl) = DECL_RTL (olddecl);
13802 /* Merge the type qualifiers. */
13803 if (DECL_BUILT_IN_NONANSI (olddecl) && TREE_THIS_VOLATILE (olddecl)
13804 && !TREE_THIS_VOLATILE (newdecl))
13805 TREE_THIS_VOLATILE (olddecl) = 0;
13806 if (TREE_READONLY (newdecl))
13807 TREE_READONLY (olddecl) = 1;
13808 if (TREE_THIS_VOLATILE (newdecl))
13810 TREE_THIS_VOLATILE (olddecl) = 1;
13811 if (TREE_CODE (newdecl) == VAR_DECL)
13812 make_var_volatile (newdecl);
13815 /* Keep source location of definition rather than declaration.
13816 Likewise, keep decl at outer scope. */
13817 if ((DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0)
13818 || (DECL_CONTEXT (newdecl) != 0 && DECL_CONTEXT (olddecl) == 0))
13820 DECL_SOURCE_LINE (newdecl) = DECL_SOURCE_LINE (olddecl);
13821 DECL_SOURCE_FILE (newdecl) = DECL_SOURCE_FILE (olddecl);
13823 if (DECL_CONTEXT (olddecl) == 0
13824 && TREE_CODE (newdecl) != FUNCTION_DECL)
13825 DECL_CONTEXT (newdecl) = 0;
13828 /* Merge the unused-warning information. */
13829 if (DECL_IN_SYSTEM_HEADER (olddecl))
13830 DECL_IN_SYSTEM_HEADER (newdecl) = 1;
13831 else if (DECL_IN_SYSTEM_HEADER (newdecl))
13832 DECL_IN_SYSTEM_HEADER (olddecl) = 1;
13834 /* Merge the initialization information. */
13835 if (DECL_INITIAL (newdecl) == 0)
13836 DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
13838 /* Merge the section attribute.
13839 We want to issue an error if the sections conflict but that must be
13840 done later in decl_attributes since we are called before attributes
13842 if (DECL_SECTION_NAME (newdecl) == NULL_TREE)
13843 DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl);
13846 if (TREE_CODE (newdecl) == FUNCTION_DECL)
13848 DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl);
13849 DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
13853 /* If cannot merge, then use the new type and qualifiers,
13854 and don't preserve the old rtl. */
13857 TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
13858 TREE_READONLY (olddecl) = TREE_READONLY (newdecl);
13859 TREE_THIS_VOLATILE (olddecl) = TREE_THIS_VOLATILE (newdecl);
13860 TREE_SIDE_EFFECTS (olddecl) = TREE_SIDE_EFFECTS (newdecl);
13863 /* Merge the storage class information. */
13864 /* For functions, static overrides non-static. */
13865 if (TREE_CODE (newdecl) == FUNCTION_DECL)
13867 TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl);
13868 /* This is since we don't automatically
13869 copy the attributes of NEWDECL into OLDDECL. */
13870 TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
13871 /* If this clears `static', clear it in the identifier too. */
13872 if (! TREE_PUBLIC (olddecl))
13873 TREE_PUBLIC (DECL_NAME (olddecl)) = 0;
13875 if (DECL_EXTERNAL (newdecl))
13877 TREE_STATIC (newdecl) = TREE_STATIC (olddecl);
13878 DECL_EXTERNAL (newdecl) = DECL_EXTERNAL (olddecl);
13879 /* An extern decl does not override previous storage class. */
13880 TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
13884 TREE_STATIC (olddecl) = TREE_STATIC (newdecl);
13885 TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
13888 /* If either decl says `inline', this fn is inline,
13889 unless its definition was passed already. */
13890 if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == 0)
13891 DECL_INLINE (olddecl) = 1;
13892 DECL_INLINE (newdecl) = DECL_INLINE (olddecl);
13894 /* Get rid of any built-in function if new arg types don't match it
13895 or if we have a function definition. */
13896 if (TREE_CODE (newdecl) == FUNCTION_DECL
13897 && DECL_BUILT_IN (olddecl)
13898 && (!types_match || new_is_definition))
13900 TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
13901 DECL_BUILT_IN_CLASS (olddecl) = NOT_BUILT_IN;
13904 /* If redeclaring a builtin function, and not a definition,
13906 Also preserve various other info from the definition. */
13907 if (TREE_CODE (newdecl) == FUNCTION_DECL && !new_is_definition)
13909 if (DECL_BUILT_IN (olddecl))
13911 DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl);
13912 DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
13915 DECL_FRAME_SIZE (newdecl) = DECL_FRAME_SIZE (olddecl);
13917 DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
13918 DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
13919 DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl);
13920 DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
13923 /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
13924 But preserve olddecl's DECL_UID. */
13926 register unsigned olddecl_uid = DECL_UID (olddecl);
13928 memcpy ((char *) olddecl + sizeof (struct tree_common),
13929 (char *) newdecl + sizeof (struct tree_common),
13930 sizeof (struct tree_decl) - sizeof (struct tree_common));
13931 DECL_UID (olddecl) = olddecl_uid;
13937 /* Finish processing of a declaration;
13938 install its initial value.
13939 If the length of an array type is not known before,
13940 it must be determined now, from the initial value, or it is an error. */
13943 finish_decl (tree decl, tree init, bool is_top_level)
13945 register tree type = TREE_TYPE (decl);
13946 int was_incomplete = (DECL_SIZE (decl) == 0);
13947 int temporary = allocation_temporary_p ();
13948 bool at_top_level = (current_binding_level == global_binding_level);
13949 bool top_level = is_top_level || at_top_level;
13951 /* Caller should pass TRUE for is_top_level only if we wouldn't be at top
13953 assert (!is_top_level || !at_top_level);
13955 if (TREE_CODE (decl) == PARM_DECL)
13956 assert (init == NULL_TREE);
13957 /* Remember that PARM_DECL doesn't have a DECL_INITIAL field per se -- it
13958 overlaps DECL_ARG_TYPE. */
13959 else if (init == NULL_TREE)
13960 assert (DECL_INITIAL (decl) == NULL_TREE);
13962 assert (DECL_INITIAL (decl) == error_mark_node);
13964 if (init != NULL_TREE)
13966 if (TREE_CODE (decl) != TYPE_DECL)
13967 DECL_INITIAL (decl) = init;
13970 /* typedef foo = bar; store the type of bar as the type of foo. */
13971 TREE_TYPE (decl) = TREE_TYPE (init);
13972 DECL_INITIAL (decl) = init = 0;
13976 /* Pop back to the obstack that is current for this binding level. This is
13977 because MAXINDEX, rtl, etc. to be made below must go in the permanent
13978 obstack. But don't discard the temporary data yet. */
13981 /* Deduce size of array from initialization, if not already known */
13983 if (TREE_CODE (type) == ARRAY_TYPE
13984 && TYPE_DOMAIN (type) == 0
13985 && TREE_CODE (decl) != TYPE_DECL)
13987 assert (top_level);
13988 assert (was_incomplete);
13990 layout_decl (decl, 0);
13993 if (TREE_CODE (decl) == VAR_DECL)
13995 if (DECL_SIZE (decl) == NULL_TREE
13996 && TYPE_SIZE (TREE_TYPE (decl)) != NULL_TREE)
13997 layout_decl (decl, 0);
13999 if (DECL_SIZE (decl) == NULL_TREE
14000 && (TREE_STATIC (decl)
14002 /* A static variable with an incomplete type is an error if it is
14003 initialized. Also if it is not file scope. Otherwise, let it
14004 through, but if it is not `extern' then it may cause an error
14006 (DECL_INITIAL (decl) != 0 || DECL_CONTEXT (decl) != 0)
14008 /* An automatic variable with an incomplete type is an error. */
14009 !DECL_EXTERNAL (decl)))
14011 assert ("storage size not known" == NULL);
14015 if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl))
14016 && (DECL_SIZE (decl) != 0)
14017 && (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST))
14019 assert ("storage size not constant" == NULL);
14024 /* Output the assembler code and/or RTL code for variables and functions,
14025 unless the type is an undefined structure or union. If not, it will get
14026 done when the type is completed. */
14028 if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)
14030 rest_of_decl_compilation (decl, NULL,
14031 DECL_CONTEXT (decl) == 0,
14034 if (DECL_CONTEXT (decl) != 0)
14036 /* Recompute the RTL of a local array now if it used to be an
14037 incomplete type. */
14039 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
14041 /* If we used it already as memory, it must stay in memory. */
14042 TREE_ADDRESSABLE (decl) = TREE_USED (decl);
14043 /* If it's still incomplete now, no init will save it. */
14044 if (DECL_SIZE (decl) == 0)
14045 DECL_INITIAL (decl) = 0;
14046 expand_decl (decl);
14048 /* Compute and store the initial value. */
14049 if (TREE_CODE (decl) != FUNCTION_DECL)
14050 expand_decl_init (decl);
14053 else if (TREE_CODE (decl) == TYPE_DECL)
14055 rest_of_decl_compilation (decl, NULL_PTR,
14056 DECL_CONTEXT (decl) == 0,
14060 if (!(TREE_CODE (decl) == FUNCTION_DECL && DECL_INLINE (decl))
14062 /* DECL_INITIAL is not defined in PARM_DECLs, since it shares space with
14064 && TREE_CODE (decl) != PARM_DECL)
14066 /* We need to remember that this array HAD an initialization, but
14067 discard the actual temporary nodes, since we can't have a permanent
14068 node keep pointing to them. */
14069 /* We make an exception for inline functions, since it's normal for a
14070 local extern redeclaration of an inline function to have a copy of
14071 the top-level decl's DECL_INLINE. */
14072 if ((DECL_INITIAL (decl) != 0)
14073 && (DECL_INITIAL (decl) != error_mark_node))
14075 /* If this is a const variable, then preserve the
14076 initializer instead of discarding it so that we can optimize
14077 references to it. */
14078 /* This test used to include TREE_STATIC, but this won't be set
14079 for function level initializers. */
14080 if (TREE_READONLY (decl))
14082 preserve_initializer ();
14084 /* The initializer and DECL must have the same (or equivalent
14085 types), but if the initializer is a STRING_CST, its type
14086 might not be on the right obstack, so copy the type
14088 TREE_TYPE (DECL_INITIAL (decl)) = type;
14091 DECL_INITIAL (decl) = error_mark_node;
14095 /* If we have gone back from temporary to permanent allocation, actually
14096 free the temporary space that we no longer need. */
14097 if (temporary && !allocation_temporary_p ())
14098 permanent_allocation (0);
14100 /* At the end of a declaration, throw away any variable type sizes of types
14101 defined inside that declaration. There is no use computing them in the
14102 following function definition. */
14103 if (current_binding_level == global_binding_level)
14104 get_pending_sizes ();
14107 /* Finish up a function declaration and compile that function
14108 all the way to assembler language output. The free the storage
14109 for the function definition.
14111 This is called after parsing the body of the function definition.
14113 NESTED is nonzero if the function being finished is nested in another. */
14116 finish_function (int nested)
14118 register tree fndecl = current_function_decl;
14120 assert (fndecl != NULL_TREE);
14121 if (TREE_CODE (fndecl) != ERROR_MARK)
14124 assert (DECL_CONTEXT (fndecl) != NULL_TREE);
14126 assert (DECL_CONTEXT (fndecl) == NULL_TREE);
14129 /* TREE_READONLY (fndecl) = 1;
14130 This caused &foo to be of type ptr-to-const-function
14131 which then got a warning when stored in a ptr-to-function variable. */
14133 poplevel (1, 0, 1);
14135 if (TREE_CODE (fndecl) != ERROR_MARK)
14137 BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
14139 /* Must mark the RESULT_DECL as being in this function. */
14141 DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;
14143 /* Obey `register' declarations if `setjmp' is called in this fn. */
14144 /* Generate rtl for function exit. */
14145 expand_function_end (input_filename, lineno, 0);
14147 /* So we can tell if jump_optimize sets it to 1. */
14150 /* If this is a nested function, protect the local variables in the stack
14151 above us from being collected while we're compiling this function. */
14152 if (ggc_p && nested)
14153 ggc_push_context ();
14155 /* Run the optimizers and output the assembler code for this function. */
14156 rest_of_compilation (fndecl);
14158 /* Undo the GC context switch. */
14159 if (ggc_p && nested)
14160 ggc_pop_context ();
14163 /* Free all the tree nodes making up this function. */
14164 /* Switch back to allocating nodes permanently until we start another
14167 permanent_allocation (1);
14169 if (TREE_CODE (fndecl) != ERROR_MARK
14171 && DECL_SAVED_INSNS (fndecl) == 0)
14173 /* Stop pointing to the local nodes about to be freed. */
14174 /* But DECL_INITIAL must remain nonzero so we know this was an actual
14175 function definition. */
14176 /* For a nested function, this is done in pop_f_function_context. */
14177 /* If rest_of_compilation set this to 0, leave it 0. */
14178 if (DECL_INITIAL (fndecl) != 0)
14179 DECL_INITIAL (fndecl) = error_mark_node;
14180 DECL_ARGUMENTS (fndecl) = 0;
14185 /* Let the error reporting routines know that we're outside a function.
14186 For a nested function, this value is used in pop_c_function_context
14187 and then reset via pop_function_context. */
14188 ffecom_outer_function_decl_ = current_function_decl = NULL;
14192 /* Plug-in replacement for identifying the name of a decl and, for a
14193 function, what we call it in diagnostics. For now, "program unit"
14194 should suffice, since it's a bit of a hassle to figure out which
14195 of several kinds of things it is. Note that it could conceivably
14196 be a statement function, which probably isn't really a program unit
14197 per se, but if that comes up, it should be easy to check (being a
14198 nested function and all). */
14200 static const char *
14201 lang_printable_name (tree decl, int v)
14203 /* Just to keep GCC quiet about the unused variable.
14204 In theory, differing values of V should produce different
14209 if (TREE_CODE (decl) == ERROR_MARK)
14210 return "erroneous code";
14211 return IDENTIFIER_POINTER (DECL_NAME (decl));
14215 /* g77's function to print out name of current function that caused
14220 lang_print_error_function (const char *file)
14222 static ffeglobal last_g = NULL;
14223 static ffesymbol last_s = NULL;
14228 if ((ffecom_primary_entry_ == NULL)
14229 || (ffesymbol_global (ffecom_primary_entry_) == NULL))
14237 g = ffesymbol_global (ffecom_primary_entry_);
14238 if (ffecom_nested_entry_ == NULL)
14240 s = ffecom_primary_entry_;
14241 switch (ffesymbol_kind (s))
14243 case FFEINFO_kindFUNCTION:
14247 case FFEINFO_kindSUBROUTINE:
14248 kind = "subroutine";
14251 case FFEINFO_kindPROGRAM:
14255 case FFEINFO_kindBLOCKDATA:
14256 kind = "block-data";
14260 kind = ffeinfo_kind_message (ffesymbol_kind (s));
14266 s = ffecom_nested_entry_;
14267 kind = "statement function";
14271 if ((last_g != g) || (last_s != s))
14274 fprintf (stderr, "%s: ", file);
14277 fprintf (stderr, "Outside of any program unit:\n");
14280 const char *name = ffesymbol_text (s);
14282 fprintf (stderr, "In %s `%s':\n", kind, name);
14291 /* Similar to `lookup_name' but look only at current binding level. */
14294 lookup_name_current_level (tree name)
14298 if (current_binding_level == global_binding_level)
14299 return IDENTIFIER_GLOBAL_VALUE (name);
14301 if (IDENTIFIER_LOCAL_VALUE (name) == 0)
14304 for (t = current_binding_level->names; t; t = TREE_CHAIN (t))
14305 if (DECL_NAME (t) == name)
14311 /* Create a new `struct binding_level'. */
14313 static struct binding_level *
14314 make_binding_level ()
14317 return (struct binding_level *) xmalloc (sizeof (struct binding_level));
14320 /* Save and restore the variables in this file and elsewhere
14321 that keep track of the progress of compilation of the current function.
14322 Used for nested functions. */
14326 struct f_function *next;
14328 tree shadowed_labels;
14329 struct binding_level *binding_level;
14332 struct f_function *f_function_chain;
14334 /* Restore the variables used during compilation of a C function. */
14337 pop_f_function_context ()
14339 struct f_function *p = f_function_chain;
14342 /* Bring back all the labels that were shadowed. */
14343 for (link = shadowed_labels; link; link = TREE_CHAIN (link))
14344 if (DECL_NAME (TREE_VALUE (link)) != 0)
14345 IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link)))
14346 = TREE_VALUE (link);
14348 if (current_function_decl != error_mark_node
14349 && DECL_SAVED_INSNS (current_function_decl) == 0)
14351 /* Stop pointing to the local nodes about to be freed. */
14352 /* But DECL_INITIAL must remain nonzero so we know this was an actual
14353 function definition. */
14354 DECL_INITIAL (current_function_decl) = error_mark_node;
14355 DECL_ARGUMENTS (current_function_decl) = 0;
14358 pop_function_context ();
14360 f_function_chain = p->next;
14362 named_labels = p->named_labels;
14363 shadowed_labels = p->shadowed_labels;
14364 current_binding_level = p->binding_level;
14369 /* Save and reinitialize the variables
14370 used during compilation of a C function. */
14373 push_f_function_context ()
14375 struct f_function *p
14376 = (struct f_function *) xmalloc (sizeof (struct f_function));
14378 push_function_context ();
14380 p->next = f_function_chain;
14381 f_function_chain = p;
14383 p->named_labels = named_labels;
14384 p->shadowed_labels = shadowed_labels;
14385 p->binding_level = current_binding_level;
14389 push_parm_decl (tree parm)
14391 int old_immediate_size_expand = immediate_size_expand;
14393 /* Don't try computing parm sizes now -- wait till fn is called. */
14395 immediate_size_expand = 0;
14397 push_obstacks_nochange ();
14399 /* Fill in arg stuff. */
14401 DECL_ARG_TYPE (parm) = TREE_TYPE (parm);
14402 DECL_ARG_TYPE_AS_WRITTEN (parm) = TREE_TYPE (parm);
14403 TREE_READONLY (parm) = 1; /* All implementation args are read-only. */
14405 parm = pushdecl (parm);
14407 immediate_size_expand = old_immediate_size_expand;
14409 finish_decl (parm, NULL_TREE, FALSE);
14412 /* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL, if appropriate. */
14415 pushdecl_top_level (x)
14419 register struct binding_level *b = current_binding_level;
14420 register tree f = current_function_decl;
14422 current_binding_level = global_binding_level;
14423 current_function_decl = NULL_TREE;
14425 current_binding_level = b;
14426 current_function_decl = f;
14430 /* Store the list of declarations of the current level.
14431 This is done for the parameter declarations of a function being defined,
14432 after they are modified in the light of any missing parameters. */
14438 return current_binding_level->names = decls;
14441 /* Store the parameter declarations into the current function declaration.
14442 This is called after parsing the parameter declarations, before
14443 digesting the body of the function.
14445 For an old-style definition, modify the function's type
14446 to specify at least the number of arguments. */
14449 store_parm_decls (int is_main_program UNUSED)
14451 register tree fndecl = current_function_decl;
14453 if (fndecl == error_mark_node)
14456 /* This is a chain of PARM_DECLs from old-style parm declarations. */
14457 DECL_ARGUMENTS (fndecl) = storedecls (nreverse (getdecls ()));
14459 /* Initialize the RTL code for the function. */
14461 init_function_start (fndecl, input_filename, lineno);
14463 /* Set up parameters and prepare for return, for the function. */
14465 expand_function_start (fndecl, 0);
14469 start_decl (tree decl, bool is_top_level)
14472 bool at_top_level = (current_binding_level == global_binding_level);
14473 bool top_level = is_top_level || at_top_level;
14475 /* Caller should pass TRUE for is_top_level only if we wouldn't be at top
14477 assert (!is_top_level || !at_top_level);
14479 /* The corresponding pop_obstacks is in finish_decl. */
14480 push_obstacks_nochange ();
14482 if (DECL_INITIAL (decl) != NULL_TREE)
14484 assert (DECL_INITIAL (decl) == error_mark_node);
14485 assert (!DECL_EXTERNAL (decl));
14487 else if (top_level)
14488 assert ((TREE_STATIC (decl) == 1) || DECL_EXTERNAL (decl) == 1);
14490 /* For Fortran, we by default put things in .common when possible. */
14491 DECL_COMMON (decl) = 1;
14493 /* Add this decl to the current binding level. TEM may equal DECL or it may
14494 be a previous decl of the same name. */
14496 tem = pushdecl_top_level (decl);
14498 tem = pushdecl (decl);
14500 /* For a local variable, define the RTL now. */
14502 /* But not if this is a duplicate decl and we preserved the rtl from the
14503 previous one (which may or may not happen). */
14504 && DECL_RTL (tem) == 0)
14506 if (TYPE_SIZE (TREE_TYPE (tem)) != 0)
14508 else if (TREE_CODE (TREE_TYPE (tem)) == ARRAY_TYPE
14509 && DECL_INITIAL (tem) != 0)
14513 if (DECL_INITIAL (tem) != NULL_TREE)
14515 /* When parsing and digesting the initializer, use temporary storage.
14516 Do this even if we will ignore the value. */
14518 temporary_allocation ();
14524 /* Create the FUNCTION_DECL for a function definition.
14525 DECLSPECS and DECLARATOR are the parts of the declaration;
14526 they describe the function's name and the type it returns,
14527 but twisted together in a fashion that parallels the syntax of C.
14529 This function creates a binding context for the function body
14530 as well as setting up the FUNCTION_DECL in current_function_decl.
14532 Returns 1 on success. If the DECLARATOR is not suitable for a function
14533 (it defines a datum instead), we return 0, which tells
14534 yyparse to report a parse error.
14536 NESTED is nonzero for a function nested within another function. */
14539 start_function (tree name, tree type, int nested, int public)
14543 int old_immediate_size_expand = immediate_size_expand;
14546 shadowed_labels = 0;
14548 /* Don't expand any sizes in the return type of the function. */
14549 immediate_size_expand = 0;
14554 assert (current_function_decl != NULL_TREE);
14555 assert (DECL_CONTEXT (current_function_decl) == NULL_TREE);
14559 assert (current_function_decl == NULL_TREE);
14562 if (TREE_CODE (type) == ERROR_MARK)
14563 decl1 = current_function_decl = error_mark_node;
14566 decl1 = build_decl (FUNCTION_DECL,
14569 TREE_PUBLIC (decl1) = public ? 1 : 0;
14571 DECL_INLINE (decl1) = 1;
14572 TREE_STATIC (decl1) = 1;
14573 DECL_EXTERNAL (decl1) = 0;
14575 announce_function (decl1);
14577 /* Make the init_value nonzero so pushdecl knows this is not tentative.
14578 error_mark_node is replaced below (in poplevel) with the BLOCK. */
14579 DECL_INITIAL (decl1) = error_mark_node;
14581 /* Record the decl so that the function name is defined. If we already have
14582 a decl for this name, and it is a FUNCTION_DECL, use the old decl. */
14584 current_function_decl = pushdecl (decl1);
14588 ffecom_outer_function_decl_ = current_function_decl;
14591 current_binding_level->prep_state = 2;
14593 if (TREE_CODE (current_function_decl) != ERROR_MARK)
14595 make_function_rtl (current_function_decl);
14597 restype = TREE_TYPE (TREE_TYPE (current_function_decl));
14598 DECL_RESULT (current_function_decl)
14599 = build_decl (RESULT_DECL, NULL_TREE, restype);
14603 /* Allocate further tree nodes temporarily during compilation of this
14605 temporary_allocation ();
14607 if (!nested && (TREE_CODE (current_function_decl) != ERROR_MARK))
14608 TREE_ADDRESSABLE (current_function_decl) = 1;
14610 immediate_size_expand = old_immediate_size_expand;
14613 /* Here are the public functions the GNU back end needs. */
14616 convert (type, expr)
14619 register tree e = expr;
14620 register enum tree_code code = TREE_CODE (type);
14622 if (type == TREE_TYPE (e)
14623 || TREE_CODE (e) == ERROR_MARK)
14625 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
14626 return fold (build1 (NOP_EXPR, type, e));
14627 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
14628 || code == ERROR_MARK)
14629 return error_mark_node;
14630 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
14632 assert ("void value not ignored as it ought to be" == NULL);
14633 return error_mark_node;
14635 if (code == VOID_TYPE)
14636 return build1 (CONVERT_EXPR, type, e);
14637 if ((code != RECORD_TYPE)
14638 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
14639 e = ffecom_1 (REALPART_EXPR, TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e))),
14641 if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)
14642 return fold (convert_to_integer (type, e));
14643 if (code == POINTER_TYPE)
14644 return fold (convert_to_pointer (type, e));
14645 if (code == REAL_TYPE)
14646 return fold (convert_to_real (type, e));
14647 if (code == COMPLEX_TYPE)
14648 return fold (convert_to_complex (type, e));
14649 if (code == RECORD_TYPE)
14650 return fold (ffecom_convert_to_complex_ (type, e));
14652 assert ("conversion to non-scalar type requested" == NULL);
14653 return error_mark_node;
14656 /* integrate_decl_tree calls this function, but since we don't use the
14657 DECL_LANG_SPECIFIC field, this is a no-op. */
14660 copy_lang_decl (node)
14665 /* Return the list of declarations of the current level.
14666 Note that this list is in reverse order unless/until
14667 you nreverse it; and when you do nreverse it, you must
14668 store the result back using `storedecls' or you will lose. */
14673 return current_binding_level->names;
14676 /* Nonzero if we are currently in the global binding level. */
14679 global_bindings_p ()
14681 return current_binding_level == global_binding_level;
14684 /* Print an error message for invalid use of an incomplete type.
14685 VALUE is the expression that was used (or 0 if that isn't known)
14686 and TYPE is the type that was invalid. */
14689 incomplete_type_error (value, type)
14693 if (TREE_CODE (type) == ERROR_MARK)
14696 assert ("incomplete type?!?" == NULL);
14699 /* Mark ARG for GC. */
14701 mark_binding_level (void *arg)
14703 struct binding_level *level = *(struct binding_level **) arg;
14707 ggc_mark_tree (level->names);
14708 ggc_mark_tree (level->blocks);
14709 ggc_mark_tree (level->this_block);
14710 level = level->level_chain;
14715 init_decl_processing ()
14717 static tree *const tree_roots[] = {
14718 ¤t_function_decl,
14720 &ffecom_tree_fun_type_void,
14721 &ffecom_integer_zero_node,
14722 &ffecom_integer_one_node,
14723 &ffecom_tree_subr_type,
14724 &ffecom_tree_ptr_to_subr_type,
14725 &ffecom_tree_blockdata_type,
14726 &ffecom_tree_xargc_,
14727 &ffecom_f2c_integer_type_node,
14728 &ffecom_f2c_ptr_to_integer_type_node,
14729 &ffecom_f2c_address_type_node,
14730 &ffecom_f2c_real_type_node,
14731 &ffecom_f2c_ptr_to_real_type_node,
14732 &ffecom_f2c_doublereal_type_node,
14733 &ffecom_f2c_complex_type_node,
14734 &ffecom_f2c_doublecomplex_type_node,
14735 &ffecom_f2c_longint_type_node,
14736 &ffecom_f2c_logical_type_node,
14737 &ffecom_f2c_flag_type_node,
14738 &ffecom_f2c_ftnlen_type_node,
14739 &ffecom_f2c_ftnlen_zero_node,
14740 &ffecom_f2c_ftnlen_one_node,
14741 &ffecom_f2c_ftnlen_two_node,
14742 &ffecom_f2c_ptr_to_ftnlen_type_node,
14743 &ffecom_f2c_ftnint_type_node,
14744 &ffecom_f2c_ptr_to_ftnint_type_node,
14745 &ffecom_outer_function_decl_,
14746 &ffecom_previous_function_decl_,
14747 &ffecom_which_entrypoint_decl_,
14748 &ffecom_float_zero_,
14749 &ffecom_float_half_,
14750 &ffecom_double_zero_,
14751 &ffecom_double_half_,
14752 &ffecom_func_result_,
14753 &ffecom_func_length_,
14754 &ffecom_multi_type_node_,
14755 &ffecom_multi_retval_,
14763 /* Record our roots. */
14764 for (i = 0; i < sizeof(tree_roots)/sizeof(tree_roots[0]); i++)
14765 ggc_add_tree_root (tree_roots[i], 1);
14766 ggc_add_tree_root (&ffecom_tree_type[0][0],
14767 FFEINFO_basictype*FFEINFO_kindtype);
14768 ggc_add_tree_root (&ffecom_tree_fun_type[0][0],
14769 FFEINFO_basictype*FFEINFO_kindtype);
14770 ggc_add_tree_root (&ffecom_tree_ptr_to_fun_type[0][0],
14771 FFEINFO_basictype*FFEINFO_kindtype);
14772 ggc_add_tree_root (ffecom_gfrt_, FFECOM_gfrt);
14773 ggc_add_root (¤t_binding_level, 1, sizeof current_binding_level,
14774 mark_binding_level);
14775 ggc_add_root (&free_binding_level, 1, sizeof current_binding_level,
14776 mark_binding_level);
14777 ggc_add_root (&tracker_head, 1, sizeof tracker_head, mark_tracker_head);
14783 init_parse (filename)
14786 /* Open input file. */
14787 if (filename == 0 || !strcmp (filename, "-"))
14790 filename = "stdin";
14793 finput = fopen (filename, "r");
14795 pfatal_with_name (filename);
14797 #ifdef IO_BUFFER_SIZE
14798 setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
14801 /* Make identifier nodes long enough for the language-specific slots. */
14802 set_identifier_size (sizeof (struct lang_identifier));
14803 decl_printable_name = lang_printable_name;
14805 print_error_function = lang_print_error_function;
14817 /* Delete the node BLOCK from the current binding level.
14818 This is used for the block inside a stmt expr ({...})
14819 so that the block can be reinserted where appropriate. */
14822 delete_block (block)
14826 if (current_binding_level->blocks == block)
14827 current_binding_level->blocks = TREE_CHAIN (block);
14828 for (t = current_binding_level->blocks; t;)
14830 if (TREE_CHAIN (t) == block)
14831 TREE_CHAIN (t) = TREE_CHAIN (block);
14833 t = TREE_CHAIN (t);
14835 TREE_CHAIN (block) = NULL;
14836 /* Clear TREE_USED which is always set by poplevel.
14837 The flag is set again if insert_block is called. */
14838 TREE_USED (block) = 0;
14842 insert_block (block)
14845 TREE_USED (block) = 1;
14846 current_binding_level->blocks
14847 = chainon (current_binding_level->blocks, block);
14851 lang_decode_option (argc, argv)
14855 return ffe_decode_option (argc, argv);
14858 /* used by print-tree.c */
14861 lang_print_xnode (file, node, indent)
14871 ffe_terminate_0 ();
14873 if (ffe_is_ffedebug ())
14874 malloc_pool_display (malloc_pool_image ());
14884 lang_init_options ()
14886 /* Set default options for Fortran. */
14887 flag_move_all_movables = 1;
14888 flag_reduce_all_givs = 1;
14889 flag_argument_noalias = 2;
14890 flag_errno_math = 0;
14891 flag_complex_divide_method = 1;
14897 /* If the file is output from cpp, it should contain a first line
14898 `# 1 "real-filename"', and the current design of gcc (toplev.c
14899 in particular and the way it sets up information relied on by
14900 INCLUDE) requires that we read this now, and store the
14901 "real-filename" info in master_input_filename. Ask the lexer
14902 to try doing this. */
14903 ffelex_hash_kludge (finput);
14907 mark_addressable (exp)
14910 register tree x = exp;
14912 switch (TREE_CODE (x))
14915 case COMPONENT_REF:
14917 x = TREE_OPERAND (x, 0);
14921 TREE_ADDRESSABLE (x) = 1;
14928 if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
14929 && DECL_NONLOCAL (x))
14931 if (TREE_PUBLIC (x))
14933 assert ("address of global register var requested" == NULL);
14936 assert ("address of register variable requested" == NULL);
14938 else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x))
14940 if (TREE_PUBLIC (x))
14942 assert ("address of global register var requested" == NULL);
14945 assert ("address of register var requested" == NULL);
14947 put_var_into_stack (x);
14950 case FUNCTION_DECL:
14951 TREE_ADDRESSABLE (x) = 1;
14952 #if 0 /* poplevel deals with this now. */
14953 if (DECL_CONTEXT (x) == 0)
14954 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (x)) = 1;
14962 /* If DECL has a cleanup, build and return that cleanup here.
14963 This is a callback called by expand_expr. */
14966 maybe_build_cleanup (decl)
14969 /* There are no cleanups in Fortran. */
14973 /* Exit a binding level.
14974 Pop the level off, and restore the state of the identifier-decl mappings
14975 that were in effect when this level was entered.
14977 If KEEP is nonzero, this level had explicit declarations, so
14978 and create a "block" (a BLOCK node) for the level
14979 to record its declarations and subblocks for symbol table output.
14981 If FUNCTIONBODY is nonzero, this level is the body of a function,
14982 so create a block as if KEEP were set and also clear out all
14985 If REVERSE is nonzero, reverse the order of decls before putting
14986 them into the BLOCK. */
14989 poplevel (keep, reverse, functionbody)
14994 register tree link;
14995 /* The chain of decls was accumulated in reverse order.
14996 Put it into forward order, just for cleanliness. */
14998 tree subblocks = current_binding_level->blocks;
15001 int block_previously_created;
15003 /* Get the decls in the order they were written.
15004 Usually current_binding_level->names is in reverse order.
15005 But parameter decls were previously put in forward order. */
15008 current_binding_level->names
15009 = decls = nreverse (current_binding_level->names);
15011 decls = current_binding_level->names;
15013 /* Output any nested inline functions within this block
15014 if they weren't already output. */
15016 for (decl = decls; decl; decl = TREE_CHAIN (decl))
15017 if (TREE_CODE (decl) == FUNCTION_DECL
15018 && ! TREE_ASM_WRITTEN (decl)
15019 && DECL_INITIAL (decl) != 0
15020 && TREE_ADDRESSABLE (decl))
15022 /* If this decl was copied from a file-scope decl
15023 on account of a block-scope extern decl,
15024 propagate TREE_ADDRESSABLE to the file-scope decl.
15026 DECL_ABSTRACT_ORIGIN can be set to itself if warn_return_type is
15027 true, since then the decl goes through save_for_inline_copying. */
15028 if (DECL_ABSTRACT_ORIGIN (decl) != 0
15029 && DECL_ABSTRACT_ORIGIN (decl) != decl)
15030 TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1;
15031 else if (DECL_SAVED_INSNS (decl) != 0)
15033 push_function_context ();
15034 output_inline_function (decl);
15035 pop_function_context ();
15039 /* If there were any declarations or structure tags in that level,
15040 or if this level is a function body,
15041 create a BLOCK to record them for the life of this function. */
15044 block_previously_created = (current_binding_level->this_block != 0);
15045 if (block_previously_created)
15046 block = current_binding_level->this_block;
15047 else if (keep || functionbody)
15048 block = make_node (BLOCK);
15051 BLOCK_VARS (block) = decls;
15052 BLOCK_SUBBLOCKS (block) = subblocks;
15055 /* In each subblock, record that this is its superior. */
15057 for (link = subblocks; link; link = TREE_CHAIN (link))
15058 BLOCK_SUPERCONTEXT (link) = block;
15060 /* Clear out the meanings of the local variables of this level. */
15062 for (link = decls; link; link = TREE_CHAIN (link))
15064 if (DECL_NAME (link) != 0)
15066 /* If the ident. was used or addressed via a local extern decl,
15067 don't forget that fact. */
15068 if (DECL_EXTERNAL (link))
15070 if (TREE_USED (link))
15071 TREE_USED (DECL_NAME (link)) = 1;
15072 if (TREE_ADDRESSABLE (link))
15073 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (link)) = 1;
15075 IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = 0;
15079 /* If the level being exited is the top level of a function,
15080 check over all the labels, and clear out the current
15081 (function local) meanings of their names. */
15085 /* If this is the top level block of a function,
15086 the vars are the function's parameters.
15087 Don't leave them in the BLOCK because they are
15088 found in the FUNCTION_DECL instead. */
15090 BLOCK_VARS (block) = 0;
15093 /* Pop the current level, and free the structure for reuse. */
15096 register struct binding_level *level = current_binding_level;
15097 current_binding_level = current_binding_level->level_chain;
15099 level->level_chain = free_binding_level;
15100 free_binding_level = level;
15103 /* Dispose of the block that we just made inside some higher level. */
15105 && current_function_decl != error_mark_node)
15106 DECL_INITIAL (current_function_decl) = block;
15109 if (!block_previously_created)
15110 current_binding_level->blocks
15111 = chainon (current_binding_level->blocks, block);
15113 /* If we did not make a block for the level just exited,
15114 any blocks made for inner levels
15115 (since they cannot be recorded as subblocks in that level)
15116 must be carried forward so they will later become subblocks
15117 of something else. */
15118 else if (subblocks)
15119 current_binding_level->blocks
15120 = chainon (current_binding_level->blocks, subblocks);
15123 TREE_USED (block) = 1;
15128 print_lang_decl (file, node, indent)
15136 print_lang_identifier (file, node, indent)
15141 print_node (file, "global", IDENTIFIER_GLOBAL_VALUE (node), indent + 4);
15142 print_node (file, "local", IDENTIFIER_LOCAL_VALUE (node), indent + 4);
15146 print_lang_statistics ()
15151 print_lang_type (file, node, indent)
15158 /* Record a decl-node X as belonging to the current lexical scope.
15159 Check for errors (such as an incompatible declaration for the same
15160 name already seen in the same scope).
15162 Returns either X or an old decl for the same name.
15163 If an old decl is returned, it may have been smashed
15164 to agree with what X says. */
15171 register tree name = DECL_NAME (x);
15172 register struct binding_level *b = current_binding_level;
15174 if ((TREE_CODE (x) == FUNCTION_DECL)
15175 && (DECL_INITIAL (x) == 0)
15176 && DECL_EXTERNAL (x))
15177 DECL_CONTEXT (x) = NULL_TREE;
15179 DECL_CONTEXT (x) = current_function_decl;
15183 if (IDENTIFIER_INVENTED (name))
15186 DECL_ARTIFICIAL (x) = 1;
15188 DECL_IN_SYSTEM_HEADER (x) = 1;
15191 t = lookup_name_current_level (name);
15193 assert ((t == NULL_TREE) || (DECL_CONTEXT (x) == NULL_TREE));
15195 /* Don't push non-parms onto list for parms until we understand
15196 why we're doing this and whether it works. */
15198 assert ((b == global_binding_level)
15199 || !ffecom_transform_only_dummies_
15200 || TREE_CODE (x) == PARM_DECL);
15202 if ((t != NULL_TREE) && duplicate_decls (x, t))
15205 /* If we are processing a typedef statement, generate a whole new
15206 ..._TYPE node (which will be just an variant of the existing
15207 ..._TYPE node with identical properties) and then install the
15208 TYPE_DECL node generated to represent the typedef name as the
15209 TYPE_NAME of this brand new (duplicate) ..._TYPE node.
15211 The whole point here is to end up with a situation where each and every
15212 ..._TYPE node the compiler creates will be uniquely associated with
15213 AT MOST one node representing a typedef name. This way, even though
15214 the compiler substitutes corresponding ..._TYPE nodes for TYPE_DECL
15215 (i.e. "typedef name") nodes very early on, later parts of the
15216 compiler can always do the reverse translation and get back the
15217 corresponding typedef name. For example, given:
15219 typedef struct S MY_TYPE; MY_TYPE object;
15221 Later parts of the compiler might only know that `object' was of type
15222 `struct S' if it were not for code just below. With this code
15223 however, later parts of the compiler see something like:
15225 struct S' == struct S typedef struct S' MY_TYPE; struct S' object;
15227 And they can then deduce (from the node for type struct S') that the
15228 original object declaration was:
15232 Being able to do this is important for proper support of protoize, and
15233 also for generating precise symbolic debugging information which
15234 takes full account of the programmer's (typedef) vocabulary.
15236 Obviously, we don't want to generate a duplicate ..._TYPE node if the
15237 TYPE_DECL node that we are now processing really represents a
15238 standard built-in type.
15240 Since all standard types are effectively declared at line zero in the
15241 source file, we can easily check to see if we are working on a
15242 standard type by checking the current value of lineno. */
15244 if (TREE_CODE (x) == TYPE_DECL)
15246 if (DECL_SOURCE_LINE (x) == 0)
15248 if (TYPE_NAME (TREE_TYPE (x)) == 0)
15249 TYPE_NAME (TREE_TYPE (x)) = x;
15251 else if (TREE_TYPE (x) != error_mark_node)
15253 tree tt = TREE_TYPE (x);
15255 tt = build_type_copy (tt);
15256 TYPE_NAME (tt) = x;
15257 TREE_TYPE (x) = tt;
15261 /* This name is new in its binding level. Install the new declaration
15263 if (b == global_binding_level)
15264 IDENTIFIER_GLOBAL_VALUE (name) = x;
15266 IDENTIFIER_LOCAL_VALUE (name) = x;
15269 /* Put decls on list in reverse order. We will reverse them later if
15271 TREE_CHAIN (x) = b->names;
15277 /* Nonzero if the current level needs to have a BLOCK made. */
15284 for (decl = current_binding_level->names;
15286 decl = TREE_CHAIN (decl))
15288 if (TREE_USED (decl) || TREE_CODE (decl) != VAR_DECL
15289 || (DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl)))
15290 /* Currently, there aren't supposed to be non-artificial names
15291 at other than the top block for a function -- they're
15292 believed to always be temps. But it's wise to check anyway. */
15298 /* Enter a new binding level.
15299 If TAG_TRANSPARENT is nonzero, do so only for the name space of variables,
15300 not for that of tags. */
15303 pushlevel (tag_transparent)
15304 int tag_transparent;
15306 register struct binding_level *newlevel = NULL_BINDING_LEVEL;
15308 assert (! tag_transparent);
15310 if (current_binding_level == global_binding_level)
15315 /* Reuse or create a struct for this binding level. */
15317 if (free_binding_level)
15319 newlevel = free_binding_level;
15320 free_binding_level = free_binding_level->level_chain;
15324 newlevel = make_binding_level ();
15327 /* Add this level to the front of the chain (stack) of levels that
15330 *newlevel = clear_binding_level;
15331 newlevel->level_chain = current_binding_level;
15332 current_binding_level = newlevel;
15335 /* Set the BLOCK node for the innermost scope
15336 (the one we are currently in). */
15340 register tree block;
15342 current_binding_level->this_block = block;
15345 /* ~~gcc/tree.h *should* declare this, because toplev.c references it. */
15347 /* Can't 'yydebug' a front end not generated by yacc/bison! */
15350 set_yydebug (value)
15354 fprintf (stderr, "warning: no yacc/bison-generated output to debug!\n");
15358 signed_or_unsigned_type (unsignedp, type)
15364 if (! INTEGRAL_TYPE_P (type))
15366 if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node))
15367 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
15368 if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
15369 return unsignedp ? unsigned_type_node : integer_type_node;
15370 if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node))
15371 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
15372 if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node))
15373 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
15374 if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node))
15375 return (unsignedp ? long_long_unsigned_type_node
15376 : long_long_integer_type_node);
15378 type2 = type_for_size (TYPE_PRECISION (type), unsignedp);
15379 if (type2 == NULL_TREE)
15389 tree type1 = TYPE_MAIN_VARIANT (type);
15390 ffeinfoKindtype kt;
15393 if (type1 == unsigned_char_type_node || type1 == char_type_node)
15394 return signed_char_type_node;
15395 if (type1 == unsigned_type_node)
15396 return integer_type_node;
15397 if (type1 == short_unsigned_type_node)
15398 return short_integer_type_node;
15399 if (type1 == long_unsigned_type_node)
15400 return long_integer_type_node;
15401 if (type1 == long_long_unsigned_type_node)
15402 return long_long_integer_type_node;
15403 #if 0 /* gcc/c-* files only */
15404 if (type1 == unsigned_intDI_type_node)
15405 return intDI_type_node;
15406 if (type1 == unsigned_intSI_type_node)
15407 return intSI_type_node;
15408 if (type1 == unsigned_intHI_type_node)
15409 return intHI_type_node;
15410 if (type1 == unsigned_intQI_type_node)
15411 return intQI_type_node;
15414 type2 = type_for_size (TYPE_PRECISION (type1), 0);
15415 if (type2 != NULL_TREE)
15418 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
15420 type2 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
15422 if (type1 == type2)
15423 return ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
15429 /* Prepare expr to be an argument of a TRUTH_NOT_EXPR,
15430 or validate its data type for an `if' or `while' statement or ?..: exp.
15432 This preparation consists of taking the ordinary
15433 representation of an expression expr and producing a valid tree
15434 boolean expression describing whether expr is nonzero. We could
15435 simply always do build_binary_op (NE_EXPR, expr, integer_zero_node, 1),
15436 but we optimize comparisons, &&, ||, and !.
15438 The resulting type should always be `integer_type_node'. */
15441 truthvalue_conversion (expr)
15444 if (TREE_CODE (expr) == ERROR_MARK)
15447 #if 0 /* This appears to be wrong for C++. */
15448 /* These really should return error_mark_node after 2.4 is stable.
15449 But not all callers handle ERROR_MARK properly. */
15450 switch (TREE_CODE (TREE_TYPE (expr)))
15453 error ("struct type value used where scalar is required");
15454 return integer_zero_node;
15457 error ("union type value used where scalar is required");
15458 return integer_zero_node;
15461 error ("array type value used where scalar is required");
15462 return integer_zero_node;
15469 switch (TREE_CODE (expr))
15471 /* It is simpler and generates better code to have only TRUTH_*_EXPR
15472 or comparison expressions as truth values at this level. */
15474 case COMPONENT_REF:
15475 /* A one-bit unsigned bit-field is already acceptable. */
15476 if (1 == TREE_INT_CST_LOW (DECL_SIZE (TREE_OPERAND (expr, 1)))
15477 && TREE_UNSIGNED (TREE_OPERAND (expr, 1)))
15483 /* It is simpler and generates better code to have only TRUTH_*_EXPR
15484 or comparison expressions as truth values at this level. */
15486 if (integer_zerop (TREE_OPERAND (expr, 1)))
15487 return build_unary_op (TRUTH_NOT_EXPR, TREE_OPERAND (expr, 0), 0);
15489 case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
15490 case TRUTH_ANDIF_EXPR:
15491 case TRUTH_ORIF_EXPR:
15492 case TRUTH_AND_EXPR:
15493 case TRUTH_OR_EXPR:
15494 case TRUTH_XOR_EXPR:
15495 TREE_TYPE (expr) = integer_type_node;
15502 return integer_zerop (expr) ? integer_zero_node : integer_one_node;
15505 return real_zerop (expr) ? integer_zero_node : integer_one_node;
15508 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 0)))
15509 return build (COMPOUND_EXPR, integer_type_node,
15510 TREE_OPERAND (expr, 0), integer_one_node);
15512 return integer_one_node;
15515 return ffecom_2 ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))
15516 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
15518 truthvalue_conversion (TREE_OPERAND (expr, 0)),
15519 truthvalue_conversion (TREE_OPERAND (expr, 1)));
15525 /* These don't change whether an object is non-zero or zero. */
15526 return truthvalue_conversion (TREE_OPERAND (expr, 0));
15530 /* These don't change whether an object is zero or non-zero, but
15531 we can't ignore them if their second arg has side-effects. */
15532 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)))
15533 return build (COMPOUND_EXPR, integer_type_node, TREE_OPERAND (expr, 1),
15534 truthvalue_conversion (TREE_OPERAND (expr, 0)));
15536 return truthvalue_conversion (TREE_OPERAND (expr, 0));
15539 /* Distribute the conversion into the arms of a COND_EXPR. */
15540 return fold (build (COND_EXPR, integer_type_node, TREE_OPERAND (expr, 0),
15541 truthvalue_conversion (TREE_OPERAND (expr, 1)),
15542 truthvalue_conversion (TREE_OPERAND (expr, 2))));
15545 /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
15546 since that affects how `default_conversion' will behave. */
15547 if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE
15548 || TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)
15550 /* fall through... */
15552 /* If this is widening the argument, we can ignore it. */
15553 if (TYPE_PRECISION (TREE_TYPE (expr))
15554 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
15555 return truthvalue_conversion (TREE_OPERAND (expr, 0));
15559 /* With IEEE arithmetic, x - x may not equal 0, so we can't optimize
15561 if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
15562 && TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE)
15564 /* fall through... */
15566 /* This and MINUS_EXPR can be changed into a comparison of the
15568 if (TREE_TYPE (TREE_OPERAND (expr, 0))
15569 == TREE_TYPE (TREE_OPERAND (expr, 1)))
15570 return ffecom_2 (NE_EXPR, integer_type_node,
15571 TREE_OPERAND (expr, 0),
15572 TREE_OPERAND (expr, 1));
15573 return ffecom_2 (NE_EXPR, integer_type_node,
15574 TREE_OPERAND (expr, 0),
15575 fold (build1 (NOP_EXPR,
15576 TREE_TYPE (TREE_OPERAND (expr, 0)),
15577 TREE_OPERAND (expr, 1))));
15580 if (integer_onep (TREE_OPERAND (expr, 1)))
15585 #if 0 /* No such thing in Fortran. */
15586 if (warn_parentheses && C_EXP_ORIGINAL_CODE (expr) == MODIFY_EXPR)
15587 warning ("suggest parentheses around assignment used as truth value");
15595 if (TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE)
15597 ((TREE_SIDE_EFFECTS (expr)
15598 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
15600 truthvalue_conversion (ffecom_1 (REALPART_EXPR,
15601 TREE_TYPE (TREE_TYPE (expr)),
15603 truthvalue_conversion (ffecom_1 (IMAGPART_EXPR,
15604 TREE_TYPE (TREE_TYPE (expr)),
15607 return ffecom_2 (NE_EXPR, integer_type_node,
15609 convert (TREE_TYPE (expr), integer_zero_node));
15613 type_for_mode (mode, unsignedp)
15614 enum machine_mode mode;
15621 if (mode == TYPE_MODE (integer_type_node))
15622 return unsignedp ? unsigned_type_node : integer_type_node;
15624 if (mode == TYPE_MODE (signed_char_type_node))
15625 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
15627 if (mode == TYPE_MODE (short_integer_type_node))
15628 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
15630 if (mode == TYPE_MODE (long_integer_type_node))
15631 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
15633 if (mode == TYPE_MODE (long_long_integer_type_node))
15634 return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node;
15636 #if HOST_BITS_PER_WIDE_INT >= 64
15637 if (mode == TYPE_MODE (intTI_type_node))
15638 return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
15641 if (mode == TYPE_MODE (float_type_node))
15642 return float_type_node;
15644 if (mode == TYPE_MODE (double_type_node))
15645 return double_type_node;
15647 if (mode == TYPE_MODE (build_pointer_type (char_type_node)))
15648 return build_pointer_type (char_type_node);
15650 if (mode == TYPE_MODE (build_pointer_type (integer_type_node)))
15651 return build_pointer_type (integer_type_node);
15653 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
15654 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
15656 if (((t = ffecom_tree_type[i][j]) != NULL_TREE)
15657 && (mode == TYPE_MODE (t)))
15659 if ((i == FFEINFO_basictypeINTEGER) && unsignedp)
15660 return ffecom_tree_type[FFEINFO_basictypeHOLLERITH][j];
15670 type_for_size (bits, unsignedp)
15674 ffeinfoKindtype kt;
15677 if (bits == TYPE_PRECISION (integer_type_node))
15678 return unsignedp ? unsigned_type_node : integer_type_node;
15680 if (bits == TYPE_PRECISION (signed_char_type_node))
15681 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
15683 if (bits == TYPE_PRECISION (short_integer_type_node))
15684 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
15686 if (bits == TYPE_PRECISION (long_integer_type_node))
15687 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
15689 if (bits == TYPE_PRECISION (long_long_integer_type_node))
15690 return (unsignedp ? long_long_unsigned_type_node
15691 : long_long_integer_type_node);
15693 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
15695 type_node = ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
15697 if ((type_node != NULL_TREE) && (bits == TYPE_PRECISION (type_node)))
15698 return unsignedp ? ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt]
15706 unsigned_type (type)
15709 tree type1 = TYPE_MAIN_VARIANT (type);
15710 ffeinfoKindtype kt;
15713 if (type1 == signed_char_type_node || type1 == char_type_node)
15714 return unsigned_char_type_node;
15715 if (type1 == integer_type_node)
15716 return unsigned_type_node;
15717 if (type1 == short_integer_type_node)
15718 return short_unsigned_type_node;
15719 if (type1 == long_integer_type_node)
15720 return long_unsigned_type_node;
15721 if (type1 == long_long_integer_type_node)
15722 return long_long_unsigned_type_node;
15723 #if 0 /* gcc/c-* files only */
15724 if (type1 == intDI_type_node)
15725 return unsigned_intDI_type_node;
15726 if (type1 == intSI_type_node)
15727 return unsigned_intSI_type_node;
15728 if (type1 == intHI_type_node)
15729 return unsigned_intHI_type_node;
15730 if (type1 == intQI_type_node)
15731 return unsigned_intQI_type_node;
15734 type2 = type_for_size (TYPE_PRECISION (type1), 1);
15735 if (type2 != NULL_TREE)
15738 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
15740 type2 = ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
15742 if (type1 == type2)
15743 return ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
15749 /* Callback routines for garbage collection. */
15755 union tree_node *t ATTRIBUTE_UNUSED;
15757 if (TREE_CODE (t) == IDENTIFIER_NODE)
15759 struct lang_identifier *i = (struct lang_identifier *) t;
15760 ggc_mark_tree (IDENTIFIER_GLOBAL_VALUE (i));
15761 ggc_mark_tree (IDENTIFIER_LOCAL_VALUE (i));
15762 ggc_mark_tree (IDENTIFIER_LABEL_VALUE (i));
15764 else if (TYPE_P (t) && TYPE_LANG_SPECIFIC (t))
15765 ggc_mark (TYPE_LANG_SPECIFIC (t));
15769 lang_mark_false_label_stack (l)
15770 struct label_node *l;
15772 /* Fortran doesn't use false_label_stack. It better be NULL. */
15777 #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
15779 #if FFECOM_GCC_INCLUDE
15781 /* From gcc/cccp.c, the code to handle -I. */
15783 /* Skip leading "./" from a directory name.
15784 This may yield the empty string, which represents the current directory. */
15786 static const char *
15787 skip_redundant_dir_prefix (const char *dir)
15789 while (dir[0] == '.' && dir[1] == '/')
15790 for (dir += 2; *dir == '/'; dir++)
15792 if (dir[0] == '.' && !dir[1])
15797 /* The file_name_map structure holds a mapping of file names for a
15798 particular directory. This mapping is read from the file named
15799 FILE_NAME_MAP_FILE in that directory. Such a file can be used to
15800 map filenames on a file system with severe filename restrictions,
15801 such as DOS. The format of the file name map file is just a series
15802 of lines with two tokens on each line. The first token is the name
15803 to map, and the second token is the actual name to use. */
15805 struct file_name_map
15807 struct file_name_map *map_next;
15812 #define FILE_NAME_MAP_FILE "header.gcc"
15814 /* Current maximum length of directory names in the search path
15815 for include files. (Altered as we get more of them.) */
15817 static int max_include_len = 0;
15819 struct file_name_list
15821 struct file_name_list *next;
15823 /* Mapping of file names for this directory. */
15824 struct file_name_map *name_map;
15825 /* Non-zero if name_map is valid. */
15829 static struct file_name_list *include = NULL; /* First dir to search */
15830 static struct file_name_list *last_include = NULL; /* Last in chain */
15832 /* I/O buffer structure.
15833 The `fname' field is nonzero for source files and #include files
15834 and for the dummy text used for -D and -U.
15835 It is zero for rescanning results of macro expansion
15836 and for expanding macro arguments. */
15837 #define INPUT_STACK_MAX 400
15838 static struct file_buf {
15840 /* Filename specified with #line command. */
15841 const char *nominal_fname;
15842 /* Record where in the search path this file was found.
15843 For #include_next. */
15844 struct file_name_list *dir;
15846 ffewhereColumn column;
15847 } instack[INPUT_STACK_MAX];
15849 static int last_error_tick = 0; /* Incremented each time we print it. */
15850 static int input_file_stack_tick = 0; /* Incremented when status changes. */
15852 /* Current nesting level of input sources.
15853 `instack[indepth]' is the level currently being read. */
15854 static int indepth = -1;
15856 typedef struct file_buf FILE_BUF;
15858 typedef unsigned char U_CHAR;
15860 /* table to tell if char can be part of a C identifier. */
15861 U_CHAR is_idchar[256];
15862 /* table to tell if char can be first char of a c identifier. */
15863 U_CHAR is_idstart[256];
15864 /* table to tell if c is horizontal space. */
15865 U_CHAR is_hor_space[256];
15866 /* table to tell if c is horizontal or vertical space. */
15867 static U_CHAR is_space[256];
15869 #define SKIP_WHITE_SPACE(p) do { while (is_hor_space[*p]) p++; } while (0)
15870 #define SKIP_ALL_WHITE_SPACE(p) do { while (is_space[*p]) p++; } while (0)
15872 /* Nonzero means -I- has been seen,
15873 so don't look for #include "foo" the source-file directory. */
15874 static int ignore_srcdir;
15876 #ifndef INCLUDE_LEN_FUDGE
15877 #define INCLUDE_LEN_FUDGE 0
15880 static void append_include_chain (struct file_name_list *first,
15881 struct file_name_list *last);
15882 static FILE *open_include_file (char *filename,
15883 struct file_name_list *searchptr);
15884 static void print_containing_files (ffebadSeverity sev);
15885 static const char *skip_redundant_dir_prefix (const char *);
15886 static char *read_filename_string (int ch, FILE *f);
15887 static struct file_name_map *read_name_map (const char *dirname);
15889 /* Append a chain of `struct file_name_list's
15890 to the end of the main include chain.
15891 FIRST is the beginning of the chain to append, and LAST is the end. */
15894 append_include_chain (first, last)
15895 struct file_name_list *first, *last;
15897 struct file_name_list *dir;
15899 if (!first || !last)
15905 last_include->next = first;
15907 for (dir = first; ; dir = dir->next) {
15908 int len = strlen (dir->fname) + INCLUDE_LEN_FUDGE;
15909 if (len > max_include_len)
15910 max_include_len = len;
15916 last_include = last;
15919 /* Try to open include file FILENAME. SEARCHPTR is the directory
15920 being tried from the include file search path. This function maps
15921 filenames on file systems based on information read by
15925 open_include_file (filename, searchptr)
15927 struct file_name_list *searchptr;
15929 register struct file_name_map *map;
15930 register char *from;
15933 if (searchptr && ! searchptr->got_name_map)
15935 searchptr->name_map = read_name_map (searchptr->fname
15936 ? searchptr->fname : ".");
15937 searchptr->got_name_map = 1;
15940 /* First check the mapping for the directory we are using. */
15941 if (searchptr && searchptr->name_map)
15944 if (searchptr->fname)
15945 from += strlen (searchptr->fname) + 1;
15946 for (map = searchptr->name_map; map; map = map->map_next)
15948 if (! strcmp (map->map_from, from))
15950 /* Found a match. */
15951 return fopen (map->map_to, "r");
15956 /* Try to find a mapping file for the particular directory we are
15957 looking in. Thus #include <sys/types.h> will look up sys/types.h
15958 in /usr/include/header.gcc and look up types.h in
15959 /usr/include/sys/header.gcc. */
15960 p = rindex (filename, '/');
15961 #ifdef DIR_SEPARATOR
15962 if (! p) p = rindex (filename, DIR_SEPARATOR);
15964 char *tmp = rindex (filename, DIR_SEPARATOR);
15965 if (tmp != NULL && tmp > p) p = tmp;
15971 && searchptr->fname
15972 && strlen (searchptr->fname) == (size_t) (p - filename)
15973 && ! strncmp (searchptr->fname, filename, (int) (p - filename)))
15975 /* FILENAME is in SEARCHPTR, which we've already checked. */
15976 return fopen (filename, "r");
15982 map = read_name_map (".");
15986 dir = (char *) xmalloc (p - filename + 1);
15987 memcpy (dir, filename, p - filename);
15988 dir[p - filename] = '\0';
15990 map = read_name_map (dir);
15993 for (; map; map = map->map_next)
15994 if (! strcmp (map->map_from, from))
15995 return fopen (map->map_to, "r");
15997 return fopen (filename, "r");
16000 /* Print the file names and line numbers of the #include
16001 commands which led to the current file. */
16004 print_containing_files (ffebadSeverity sev)
16006 FILE_BUF *ip = NULL;
16012 /* If stack of files hasn't changed since we last printed
16013 this info, don't repeat it. */
16014 if (last_error_tick == input_file_stack_tick)
16017 for (i = indepth; i >= 0; i--)
16018 if (instack[i].fname != NULL) {
16023 /* Give up if we don't find a source file. */
16027 /* Find the other, outer source files. */
16028 for (i--; i >= 0; i--)
16029 if (instack[i].fname != NULL)
16035 str1 = "In file included";
16047 ffebad_start_msg ("%A from %B at %0%C", sev);
16048 ffebad_here (0, ip->line, ip->column);
16049 ffebad_string (str1);
16050 ffebad_string (ip->nominal_fname);
16051 ffebad_string (str2);
16055 /* Record we have printed the status as of this time. */
16056 last_error_tick = input_file_stack_tick;
16059 /* Read a space delimited string of unlimited length from a stdio
16063 read_filename_string (ch, f)
16071 set = alloc = xmalloc (len + 1);
16072 if (! is_space[ch])
16075 while ((ch = getc (f)) != EOF && ! is_space[ch])
16077 if (set - alloc == len)
16080 alloc = xrealloc (alloc, len + 1);
16081 set = alloc + len / 2;
16091 /* Read the file name map file for DIRNAME. */
16093 static struct file_name_map *
16094 read_name_map (dirname)
16095 const char *dirname;
16097 /* This structure holds a linked list of file name maps, one per
16099 struct file_name_map_list
16101 struct file_name_map_list *map_list_next;
16102 char *map_list_name;
16103 struct file_name_map *map_list_map;
16105 static struct file_name_map_list *map_list;
16106 register struct file_name_map_list *map_list_ptr;
16110 int separator_needed;
16112 dirname = skip_redundant_dir_prefix (dirname);
16114 for (map_list_ptr = map_list; map_list_ptr;
16115 map_list_ptr = map_list_ptr->map_list_next)
16116 if (! strcmp (map_list_ptr->map_list_name, dirname))
16117 return map_list_ptr->map_list_map;
16119 map_list_ptr = ((struct file_name_map_list *)
16120 xmalloc (sizeof (struct file_name_map_list)));
16121 map_list_ptr->map_list_name = xstrdup (dirname);
16122 map_list_ptr->map_list_map = NULL;
16124 dirlen = strlen (dirname);
16125 separator_needed = dirlen != 0 && dirname[dirlen - 1] != '/';
16126 name = (char *) xmalloc (dirlen + strlen (FILE_NAME_MAP_FILE) + 2);
16127 strcpy (name, dirname);
16128 name[dirlen] = '/';
16129 strcpy (name + dirlen + separator_needed, FILE_NAME_MAP_FILE);
16130 f = fopen (name, "r");
16133 map_list_ptr->map_list_map = NULL;
16138 while ((ch = getc (f)) != EOF)
16141 struct file_name_map *ptr;
16145 from = read_filename_string (ch, f);
16146 while ((ch = getc (f)) != EOF && is_hor_space[ch])
16148 to = read_filename_string (ch, f);
16150 ptr = ((struct file_name_map *)
16151 xmalloc (sizeof (struct file_name_map)));
16152 ptr->map_from = from;
16154 /* Make the real filename absolute. */
16159 ptr->map_to = xmalloc (dirlen + strlen (to) + 2);
16160 strcpy (ptr->map_to, dirname);
16161 ptr->map_to[dirlen] = '/';
16162 strcpy (ptr->map_to + dirlen + separator_needed, to);
16166 ptr->map_next = map_list_ptr->map_list_map;
16167 map_list_ptr->map_list_map = ptr;
16169 while ((ch = getc (f)) != '\n')
16176 map_list_ptr->map_list_next = map_list;
16177 map_list = map_list_ptr;
16179 return map_list_ptr->map_list_map;
16183 ffecom_file_ (const char *name)
16187 /* Do partial setup of input buffer for the sake of generating
16188 early #line directives (when -g is in effect). */
16190 fp = &instack[++indepth];
16191 memset ((char *) fp, 0, sizeof (FILE_BUF));
16194 fp->nominal_fname = fp->fname = name;
16197 /* Initialize syntactic classifications of characters. */
16200 ffecom_initialize_char_syntax_ ()
16205 * Set up is_idchar and is_idstart tables. These should be
16206 * faster than saying (is_alpha (c) || c == '_'), etc.
16207 * Set up these things before calling any routines tthat
16210 for (i = 'a'; i <= 'z'; i++) {
16211 is_idchar[i - 'a' + 'A'] = 1;
16213 is_idstart[i - 'a' + 'A'] = 1;
16216 for (i = '0'; i <= '9'; i++)
16218 is_idchar['_'] = 1;
16219 is_idstart['_'] = 1;
16221 /* horizontal space table */
16222 is_hor_space[' '] = 1;
16223 is_hor_space['\t'] = 1;
16224 is_hor_space['\v'] = 1;
16225 is_hor_space['\f'] = 1;
16226 is_hor_space['\r'] = 1;
16229 is_space['\t'] = 1;
16230 is_space['\v'] = 1;
16231 is_space['\f'] = 1;
16232 is_space['\n'] = 1;
16233 is_space['\r'] = 1;
16237 ffecom_close_include_ (FILE *f)
16242 input_file_stack_tick++;
16244 ffewhere_line_kill (instack[indepth].line);
16245 ffewhere_column_kill (instack[indepth].column);
16249 ffecom_decode_include_option_ (char *spec)
16251 struct file_name_list *dirtmp;
16253 if (! ignore_srcdir && !strcmp (spec, "-"))
16257 dirtmp = (struct file_name_list *)
16258 xmalloc (sizeof (struct file_name_list));
16259 dirtmp->next = 0; /* New one goes on the end */
16261 dirtmp->fname = spec;
16263 fatal ("Directory name must immediately follow -I option with no intervening spaces, as in `-Idir', not `-I dir'");
16264 dirtmp->got_name_map = 0;
16265 append_include_chain (dirtmp, dirtmp);
16270 /* Open INCLUDEd file. */
16273 ffecom_open_include_ (char *name, ffewhereLine l, ffewhereColumn c)
16276 size_t flen = strlen (fbeg);
16277 struct file_name_list *search_start = include; /* Chain of dirs to search */
16278 struct file_name_list dsp[1]; /* First in chain, if #include "..." */
16279 struct file_name_list *searchptr = 0;
16280 char *fname; /* Dynamically allocated fname buffer */
16287 dsp[0].fname = NULL;
16289 /* If -I- was specified, don't search current dir, only spec'd ones. */
16290 if (!ignore_srcdir)
16292 for (fp = &instack[indepth]; fp >= instack; fp--)
16298 if ((nam = fp->nominal_fname) != NULL)
16300 /* Found a named file. Figure out dir of the file,
16301 and put it in front of the search list. */
16302 dsp[0].next = search_start;
16303 search_start = dsp;
16305 ep = rindex (nam, '/');
16306 #ifdef DIR_SEPARATOR
16307 if (ep == NULL) ep = rindex (nam, DIR_SEPARATOR);
16309 char *tmp = rindex (nam, DIR_SEPARATOR);
16310 if (tmp != NULL && tmp > ep) ep = tmp;
16314 ep = rindex (nam, ']');
16315 if (ep == NULL) ep = rindex (nam, '>');
16316 if (ep == NULL) ep = rindex (nam, ':');
16317 if (ep != NULL) ep++;
16322 dsp[0].fname = (char *) xmalloc (n + 1);
16323 strncpy (dsp[0].fname, nam, n);
16324 dsp[0].fname[n] = '\0';
16325 if (n + INCLUDE_LEN_FUDGE > max_include_len)
16326 max_include_len = n + INCLUDE_LEN_FUDGE;
16329 dsp[0].fname = NULL; /* Current directory */
16330 dsp[0].got_name_map = 0;
16336 /* Allocate this permanently, because it gets stored in the definitions
16338 fname = xmalloc (max_include_len + flen + 4);
16339 /* + 2 above for slash and terminating null. */
16340 /* + 2 added for '.h' on VMS (to support '#include filename') (NOT USED
16343 /* If specified file name is absolute, just open it. */
16346 #ifdef DIR_SEPARATOR
16347 || *fbeg == DIR_SEPARATOR
16351 strncpy (fname, (char *) fbeg, flen);
16353 f = open_include_file (fname, NULL_PTR);
16359 /* Search directory path, trying to open the file.
16360 Copy each filename tried into FNAME. */
16362 for (searchptr = search_start; searchptr; searchptr = searchptr->next)
16364 if (searchptr->fname)
16366 /* The empty string in a search path is ignored.
16367 This makes it possible to turn off entirely
16368 a standard piece of the list. */
16369 if (searchptr->fname[0] == 0)
16371 strcpy (fname, skip_redundant_dir_prefix (searchptr->fname));
16372 if (fname[0] && fname[strlen (fname) - 1] != '/')
16373 strcat (fname, "/");
16374 fname[strlen (fname) + flen] = 0;
16379 strncat (fname, fbeg, flen);
16381 /* Change this 1/2 Unix 1/2 VMS file specification into a
16382 full VMS file specification */
16383 if (searchptr->fname && (searchptr->fname[0] != 0))
16385 /* Fix up the filename */
16386 hack_vms_include_specification (fname);
16390 /* This is a normal VMS filespec, so use it unchanged. */
16391 strncpy (fname, (char *) fbeg, flen);
16393 #if 0 /* Not for g77. */
16394 /* if it's '#include filename', add the missing .h */
16395 if (index (fname, '.') == NULL)
16396 strcat (fname, ".h");
16400 f = open_include_file (fname, searchptr);
16402 if (f == NULL && errno == EACCES)
16404 print_containing_files (FFEBAD_severityWARNING);
16405 ffebad_start_msg ("At %0, INCLUDE file %A exists, but is not readable",
16406 FFEBAD_severityWARNING);
16407 ffebad_string (fname);
16408 ffebad_here (0, l, c);
16419 /* A file that was not found. */
16421 strncpy (fname, (char *) fbeg, flen);
16423 print_containing_files (ffebad_severity (FFEBAD_OPEN_INCLUDE));
16424 ffebad_start (FFEBAD_OPEN_INCLUDE);
16425 ffebad_here (0, l, c);
16426 ffebad_string (fname);
16430 if (dsp[0].fname != NULL)
16431 free (dsp[0].fname);
16436 if (indepth >= (INPUT_STACK_MAX - 1))
16438 print_containing_files (FFEBAD_severityFATAL);
16439 ffebad_start_msg ("At %0, INCLUDE nesting too deep",
16440 FFEBAD_severityFATAL);
16441 ffebad_string (fname);
16442 ffebad_here (0, l, c);
16447 instack[indepth].line = ffewhere_line_use (l);
16448 instack[indepth].column = ffewhere_column_use (c);
16450 fp = &instack[indepth + 1];
16451 memset ((char *) fp, 0, sizeof (FILE_BUF));
16452 fp->nominal_fname = fp->fname = fname;
16453 fp->dir = searchptr;
16456 input_file_stack_tick++;
16460 #endif /* FFECOM_GCC_INCLUDE */
16462 /**INDENT* (Do not reformat this comment even with -fca option.)
16463 Data-gathering files: Given the source file listed below, compiled with
16464 f2c I obtained the output file listed after that, and from the output
16465 file I derived the above code.
16467 -------- (begin input file to f2c)
16473 double precision D1,D2
16475 call getem(A1,A2,C1,C2,I1,I2,R1,R2,D1,D2)
16502 c FFEINTRIN_impACOS
16503 call fooR(ACOS(R1))
16504 c FFEINTRIN_impAIMAG
16505 call fooR(AIMAG(C1))
16506 c FFEINTRIN_impAINT
16507 call fooR(AINT(R1))
16508 c FFEINTRIN_impALOG
16509 call fooR(ALOG(R1))
16510 c FFEINTRIN_impALOG10
16511 call fooR(ALOG10(R1))
16512 c FFEINTRIN_impAMAX0
16513 call fooR(AMAX0(I1,I2))
16514 c FFEINTRIN_impAMAX1
16515 call fooR(AMAX1(R1,R2))
16516 c FFEINTRIN_impAMIN0
16517 call fooR(AMIN0(I1,I2))
16518 c FFEINTRIN_impAMIN1
16519 call fooR(AMIN1(R1,R2))
16520 c FFEINTRIN_impAMOD
16521 call fooR(AMOD(R1,R2))
16522 c FFEINTRIN_impANINT
16523 call fooR(ANINT(R1))
16524 c FFEINTRIN_impASIN
16525 call fooR(ASIN(R1))
16526 c FFEINTRIN_impATAN
16527 call fooR(ATAN(R1))
16528 c FFEINTRIN_impATAN2
16529 call fooR(ATAN2(R1,R2))
16530 c FFEINTRIN_impCABS
16531 call fooR(CABS(C1))
16532 c FFEINTRIN_impCCOS
16533 call fooC(CCOS(C1))
16534 c FFEINTRIN_impCEXP
16535 call fooC(CEXP(C1))
16536 c FFEINTRIN_impCHAR
16537 call fooA(CHAR(I1))
16538 c FFEINTRIN_impCLOG
16539 call fooC(CLOG(C1))
16540 c FFEINTRIN_impCONJG
16541 call fooC(CONJG(C1))
16544 c FFEINTRIN_impCOSH
16545 call fooR(COSH(R1))
16546 c FFEINTRIN_impCSIN
16547 call fooC(CSIN(C1))
16548 c FFEINTRIN_impCSQRT
16549 call fooC(CSQRT(C1))
16550 c FFEINTRIN_impDABS
16551 call fooD(DABS(D1))
16552 c FFEINTRIN_impDACOS
16553 call fooD(DACOS(D1))
16554 c FFEINTRIN_impDASIN
16555 call fooD(DASIN(D1))
16556 c FFEINTRIN_impDATAN
16557 call fooD(DATAN(D1))
16558 c FFEINTRIN_impDATAN2
16559 call fooD(DATAN2(D1,D2))
16560 c FFEINTRIN_impDCOS
16561 call fooD(DCOS(D1))
16562 c FFEINTRIN_impDCOSH
16563 call fooD(DCOSH(D1))
16564 c FFEINTRIN_impDDIM
16565 call fooD(DDIM(D1,D2))
16566 c FFEINTRIN_impDEXP
16567 call fooD(DEXP(D1))
16569 call fooR(DIM(R1,R2))
16570 c FFEINTRIN_impDINT
16571 call fooD(DINT(D1))
16572 c FFEINTRIN_impDLOG
16573 call fooD(DLOG(D1))
16574 c FFEINTRIN_impDLOG10
16575 call fooD(DLOG10(D1))
16576 c FFEINTRIN_impDMAX1
16577 call fooD(DMAX1(D1,D2))
16578 c FFEINTRIN_impDMIN1
16579 call fooD(DMIN1(D1,D2))
16580 c FFEINTRIN_impDMOD
16581 call fooD(DMOD(D1,D2))
16582 c FFEINTRIN_impDNINT
16583 call fooD(DNINT(D1))
16584 c FFEINTRIN_impDPROD
16585 call fooD(DPROD(R1,R2))
16586 c FFEINTRIN_impDSIGN
16587 call fooD(DSIGN(D1,D2))
16588 c FFEINTRIN_impDSIN
16589 call fooD(DSIN(D1))
16590 c FFEINTRIN_impDSINH
16591 call fooD(DSINH(D1))
16592 c FFEINTRIN_impDSQRT
16593 call fooD(DSQRT(D1))
16594 c FFEINTRIN_impDTAN
16595 call fooD(DTAN(D1))
16596 c FFEINTRIN_impDTANH
16597 call fooD(DTANH(D1))
16600 c FFEINTRIN_impIABS
16601 call fooI(IABS(I1))
16602 c FFEINTRIN_impICHAR
16603 call fooI(ICHAR(A1))
16604 c FFEINTRIN_impIDIM
16605 call fooI(IDIM(I1,I2))
16606 c FFEINTRIN_impIDNINT
16607 call fooI(IDNINT(D1))
16608 c FFEINTRIN_impINDEX
16609 call fooI(INDEX(A1,A2))
16610 c FFEINTRIN_impISIGN
16611 call fooI(ISIGN(I1,I2))
16615 call fooL(LGE(A1,A2))
16617 call fooL(LGT(A1,A2))
16619 call fooL(LLE(A1,A2))
16621 call fooL(LLT(A1,A2))
16622 c FFEINTRIN_impMAX0
16623 call fooI(MAX0(I1,I2))
16624 c FFEINTRIN_impMAX1
16625 call fooI(MAX1(R1,R2))
16626 c FFEINTRIN_impMIN0
16627 call fooI(MIN0(I1,I2))
16628 c FFEINTRIN_impMIN1
16629 call fooI(MIN1(R1,R2))
16631 call fooI(MOD(I1,I2))
16632 c FFEINTRIN_impNINT
16633 call fooI(NINT(R1))
16634 c FFEINTRIN_impSIGN
16635 call fooR(SIGN(R1,R2))
16638 c FFEINTRIN_impSINH
16639 call fooR(SINH(R1))
16640 c FFEINTRIN_impSQRT
16641 call fooR(SQRT(R1))
16644 c FFEINTRIN_impTANH
16645 call fooR(TANH(R1))
16646 c FFEINTRIN_imp_CMPLX_C
16647 call fooC(cmplx(C1,C2))
16648 c FFEINTRIN_imp_CMPLX_D
16649 call fooZ(cmplx(D1,D2))
16650 c FFEINTRIN_imp_CMPLX_I
16651 call fooC(cmplx(I1,I2))
16652 c FFEINTRIN_imp_CMPLX_R
16653 call fooC(cmplx(R1,R2))
16654 c FFEINTRIN_imp_DBLE_C
16655 call fooD(dble(C1))
16656 c FFEINTRIN_imp_DBLE_D
16657 call fooD(dble(D1))
16658 c FFEINTRIN_imp_DBLE_I
16659 call fooD(dble(I1))
16660 c FFEINTRIN_imp_DBLE_R
16661 call fooD(dble(R1))
16662 c FFEINTRIN_imp_INT_C
16664 c FFEINTRIN_imp_INT_D
16666 c FFEINTRIN_imp_INT_I
16668 c FFEINTRIN_imp_INT_R
16670 c FFEINTRIN_imp_REAL_C
16671 call fooR(real(C1))
16672 c FFEINTRIN_imp_REAL_D
16673 call fooR(real(D1))
16674 c FFEINTRIN_imp_REAL_I
16675 call fooR(real(I1))
16676 c FFEINTRIN_imp_REAL_R
16677 call fooR(real(R1))
16679 c FFEINTRIN_imp_INT_D:
16681 c FFEINTRIN_specIDINT
16682 call fooI(IDINT(D1))
16684 c FFEINTRIN_imp_INT_R:
16686 c FFEINTRIN_specIFIX
16687 call fooI(IFIX(R1))
16688 c FFEINTRIN_specINT
16691 c FFEINTRIN_imp_REAL_D:
16693 c FFEINTRIN_specSNGL
16694 call fooR(SNGL(D1))
16696 c FFEINTRIN_imp_REAL_I:
16698 c FFEINTRIN_specFLOAT
16699 call fooR(FLOAT(I1))
16700 c FFEINTRIN_specREAL
16701 call fooR(REAL(I1))
16704 -------- (end input file to f2c)
16706 -------- (begin output from providing above input file as input to:
16707 -------- `f2c | gcc -E -C - | sed -e "s:/[*]*://:g" -e "s:[*]*[/]://:g" \
16708 -------- -e "s:^#.*$::g"')
16710 // -- translated by f2c (version 19950223).
16711 You must link the resulting object file with the libraries:
16712 -lf2c -lm (in that order)
16716 // f2c.h -- Standard Fortran to C header file //
16718 /// barf [ba:rf] 2. "He suggested using FORTRAN, and everybody barfed."
16720 - From The Shogakukan DICTIONARY OF NEW ENGLISH (Second edition) //
16725 // F2C_INTEGER will normally be `int' but would be `long' on 16-bit systems //
16726 // we assume short, float are OK //
16727 typedef long int // long int // integer;
16728 typedef char *address;
16729 typedef short int shortint;
16730 typedef float real;
16731 typedef double doublereal;
16732 typedef struct { real r, i; } complex;
16733 typedef struct { doublereal r, i; } doublecomplex;
16734 typedef long int // long int // logical;
16735 typedef short int shortlogical;
16736 typedef char logical1;
16737 typedef char integer1;
16738 // typedef long long longint; // // system-dependent //
16743 // Extern is for use with -E //
16757 typedef long int // int or long int // flag;
16758 typedef long int // int or long int // ftnlen;
16759 typedef long int // int or long int // ftnint;
16762 //external read, write//
16771 //internal read, write//
16801 //rewind, backspace, endfile//
16813 ftnint *inex; //parameters in standard's order//
16839 union Multitype { // for multiple entry points //
16850 typedef union Multitype Multitype;
16852 typedef long Long; // No longer used; formerly in Namelist //
16854 struct Vardesc { // for Namelist //
16860 typedef struct Vardesc Vardesc;
16867 typedef struct Namelist Namelist;
16876 // procedure parameter types for -A and -C++ //
16881 typedef int // Unknown procedure type // (*U_fp)();
16882 typedef shortint (*J_fp)();
16883 typedef integer (*I_fp)();
16884 typedef real (*R_fp)();
16885 typedef doublereal (*D_fp)(), (*E_fp)();
16886 typedef // Complex // void (*C_fp)();
16887 typedef // Double Complex // void (*Z_fp)();
16888 typedef logical (*L_fp)();
16889 typedef shortlogical (*K_fp)();
16890 typedef // Character // void (*H_fp)();
16891 typedef // Subroutine // int (*S_fp)();
16893 // E_fp is for real functions when -R is not specified //
16894 typedef void C_f; // complex function //
16895 typedef void H_f; // character function //
16896 typedef void Z_f; // double complex function //
16897 typedef doublereal E_f; // real function with -R not specified //
16899 // undef any lower-case symbols that your C compiler predefines, e.g.: //
16902 // (No such symbols should be defined in a strict ANSI C compiler.
16903 We can avoid trouble with f2c-translated code by using
16904 gcc -ansi [-traditional].) //
16928 // Main program // MAIN__()
16930 // System generated locals //
16933 doublereal d__1, d__2;
16935 doublecomplex z__1, z__2, z__3;
16939 // Builtin functions //
16942 double pow_ri(), pow_di();
16946 double acos(), r_imag(), r_int(), log(), r_lg10(), r_mod(), r_nint(),
16947 asin(), atan(), atan2(), c_abs();
16948 void c_cos(), c_exp(), c_log(), r_cnjg();
16949 double cos(), cosh();
16950 void c_sin(), c_sqrt();
16951 double d_dim(), exp(), r_dim(), d_int(), d_lg10(), d_mod(), d_nint(),
16952 d_sign(), sin(), sinh(), sqrt(), tan(), tanh();
16953 integer i_dim(), i_dnnt(), i_indx(), i_sign(), i_len();
16954 logical l_ge(), l_gt(), l_le(), l_lt();
16958 // Local variables //
16959 extern // Subroutine // int fooa_(), fooc_(), food_(), fooi_(), foor_(),
16960 fool_(), fooz_(), getem_();
16961 static char a1[10], a2[10];
16962 static complex c1, c2;
16963 static doublereal d1, d2;
16964 static integer i1, i2;
16965 static real r1, r2;
16968 getem_(a1, a2, &c1, &c2, &i1, &i2, &r1, &r2, &d1, &d2, 10L, 10L);
16976 d__1 = (doublereal) i1;
16977 q__1.r = c1.r / d__1, q__1.i = c1.i / d__1;
16987 c_div(&q__1, &c1, &c2);
16989 q__1.r = c1.r / r1, q__1.i = c1.i / r1;
16991 z__1.r = c1.r / d1, z__1.i = c1.i / d1;
16994 i__1 = pow_ii(&i1, &i2);
16996 r__1 = pow_ri(&r1, &i1);
16998 d__1 = pow_di(&d1, &i1);
17000 pow_ci(&q__1, &c1, &i1);
17002 d__1 = (doublereal) r1;
17003 d__2 = (doublereal) r2;
17004 r__1 = pow_dd(&d__1, &d__2);
17006 d__2 = (doublereal) r1;
17007 d__1 = pow_dd(&d__2, &d1);
17009 d__1 = pow_dd(&d1, &d2);
17011 d__2 = (doublereal) r1;
17012 d__1 = pow_dd(&d1, &d__2);
17014 z__2.r = c1.r, z__2.i = c1.i;
17015 z__3.r = c2.r, z__3.i = c2.i;
17016 pow_zz(&z__1, &z__2, &z__3);
17017 q__1.r = z__1.r, q__1.i = z__1.i;
17019 z__2.r = c1.r, z__2.i = c1.i;
17020 z__3.r = r1, z__3.i = 0.;
17021 pow_zz(&z__1, &z__2, &z__3);
17022 q__1.r = z__1.r, q__1.i = z__1.i;
17024 z__2.r = c1.r, z__2.i = c1.i;
17025 z__3.r = d1, z__3.i = 0.;
17026 pow_zz(&z__1, &z__2, &z__3);
17028 // FFEINTRIN_impABS //
17029 r__1 = (doublereal)(( r1 ) >= 0 ? ( r1 ) : -( r1 )) ;
17031 // FFEINTRIN_impACOS //
17034 // FFEINTRIN_impAIMAG //
17035 r__1 = r_imag(&c1);
17037 // FFEINTRIN_impAINT //
17040 // FFEINTRIN_impALOG //
17043 // FFEINTRIN_impALOG10 //
17044 r__1 = r_lg10(&r1);
17046 // FFEINTRIN_impAMAX0 //
17047 r__1 = (real) (( i1 ) >= ( i2 ) ? ( i1 ) : ( i2 )) ;
17049 // FFEINTRIN_impAMAX1 //
17050 r__1 = (doublereal)(( r1 ) >= ( r2 ) ? ( r1 ) : ( r2 )) ;
17052 // FFEINTRIN_impAMIN0 //
17053 r__1 = (real) (( i1 ) <= ( i2 ) ? ( i1 ) : ( i2 )) ;
17055 // FFEINTRIN_impAMIN1 //
17056 r__1 = (doublereal)(( r1 ) <= ( r2 ) ? ( r1 ) : ( r2 )) ;
17058 // FFEINTRIN_impAMOD //
17059 r__1 = r_mod(&r1, &r2);
17061 // FFEINTRIN_impANINT //
17062 r__1 = r_nint(&r1);
17064 // FFEINTRIN_impASIN //
17067 // FFEINTRIN_impATAN //
17070 // FFEINTRIN_impATAN2 //
17071 r__1 = atan2(r1, r2);
17073 // FFEINTRIN_impCABS //
17076 // FFEINTRIN_impCCOS //
17079 // FFEINTRIN_impCEXP //
17082 // FFEINTRIN_impCHAR //
17083 *(unsigned char *)&ch__1[0] = i1;
17085 // FFEINTRIN_impCLOG //
17088 // FFEINTRIN_impCONJG //
17089 r_cnjg(&q__1, &c1);
17091 // FFEINTRIN_impCOS //
17094 // FFEINTRIN_impCOSH //
17097 // FFEINTRIN_impCSIN //
17100 // FFEINTRIN_impCSQRT //
17101 c_sqrt(&q__1, &c1);
17103 // FFEINTRIN_impDABS //
17104 d__1 = (( d1 ) >= 0 ? ( d1 ) : -( d1 )) ;
17106 // FFEINTRIN_impDACOS //
17109 // FFEINTRIN_impDASIN //
17112 // FFEINTRIN_impDATAN //
17115 // FFEINTRIN_impDATAN2 //
17116 d__1 = atan2(d1, d2);
17118 // FFEINTRIN_impDCOS //
17121 // FFEINTRIN_impDCOSH //
17124 // FFEINTRIN_impDDIM //
17125 d__1 = d_dim(&d1, &d2);
17127 // FFEINTRIN_impDEXP //
17130 // FFEINTRIN_impDIM //
17131 r__1 = r_dim(&r1, &r2);
17133 // FFEINTRIN_impDINT //
17136 // FFEINTRIN_impDLOG //
17139 // FFEINTRIN_impDLOG10 //
17140 d__1 = d_lg10(&d1);
17142 // FFEINTRIN_impDMAX1 //
17143 d__1 = (( d1 ) >= ( d2 ) ? ( d1 ) : ( d2 )) ;
17145 // FFEINTRIN_impDMIN1 //
17146 d__1 = (( d1 ) <= ( d2 ) ? ( d1 ) : ( d2 )) ;
17148 // FFEINTRIN_impDMOD //
17149 d__1 = d_mod(&d1, &d2);
17151 // FFEINTRIN_impDNINT //
17152 d__1 = d_nint(&d1);
17154 // FFEINTRIN_impDPROD //
17155 d__1 = (doublereal) r1 * r2;
17157 // FFEINTRIN_impDSIGN //
17158 d__1 = d_sign(&d1, &d2);
17160 // FFEINTRIN_impDSIN //
17163 // FFEINTRIN_impDSINH //
17166 // FFEINTRIN_impDSQRT //
17169 // FFEINTRIN_impDTAN //
17172 // FFEINTRIN_impDTANH //
17175 // FFEINTRIN_impEXP //
17178 // FFEINTRIN_impIABS //
17179 i__1 = (( i1 ) >= 0 ? ( i1 ) : -( i1 )) ;
17181 // FFEINTRIN_impICHAR //
17182 i__1 = *(unsigned char *)a1;
17184 // FFEINTRIN_impIDIM //
17185 i__1 = i_dim(&i1, &i2);
17187 // FFEINTRIN_impIDNINT //
17188 i__1 = i_dnnt(&d1);
17190 // FFEINTRIN_impINDEX //
17191 i__1 = i_indx(a1, a2, 10L, 10L);
17193 // FFEINTRIN_impISIGN //
17194 i__1 = i_sign(&i1, &i2);
17196 // FFEINTRIN_impLEN //
17197 i__1 = i_len(a1, 10L);
17199 // FFEINTRIN_impLGE //
17200 L__1 = l_ge(a1, a2, 10L, 10L);
17202 // FFEINTRIN_impLGT //
17203 L__1 = l_gt(a1, a2, 10L, 10L);
17205 // FFEINTRIN_impLLE //
17206 L__1 = l_le(a1, a2, 10L, 10L);
17208 // FFEINTRIN_impLLT //
17209 L__1 = l_lt(a1, a2, 10L, 10L);
17211 // FFEINTRIN_impMAX0 //
17212 i__1 = (( i1 ) >= ( i2 ) ? ( i1 ) : ( i2 )) ;
17214 // FFEINTRIN_impMAX1 //
17215 i__1 = (integer) (doublereal)(( r1 ) >= ( r2 ) ? ( r1 ) : ( r2 )) ;
17217 // FFEINTRIN_impMIN0 //
17218 i__1 = (( i1 ) <= ( i2 ) ? ( i1 ) : ( i2 )) ;
17220 // FFEINTRIN_impMIN1 //
17221 i__1 = (integer) (doublereal)(( r1 ) <= ( r2 ) ? ( r1 ) : ( r2 )) ;
17223 // FFEINTRIN_impMOD //
17226 // FFEINTRIN_impNINT //
17227 i__1 = i_nint(&r1);
17229 // FFEINTRIN_impSIGN //
17230 r__1 = r_sign(&r1, &r2);
17232 // FFEINTRIN_impSIN //
17235 // FFEINTRIN_impSINH //
17238 // FFEINTRIN_impSQRT //
17241 // FFEINTRIN_impTAN //
17244 // FFEINTRIN_impTANH //
17247 // FFEINTRIN_imp_CMPLX_C //
17250 q__1.r = r__1, q__1.i = r__2;
17252 // FFEINTRIN_imp_CMPLX_D //
17253 z__1.r = d1, z__1.i = d2;
17255 // FFEINTRIN_imp_CMPLX_I //
17258 q__1.r = r__1, q__1.i = r__2;
17260 // FFEINTRIN_imp_CMPLX_R //
17261 q__1.r = r1, q__1.i = r2;
17263 // FFEINTRIN_imp_DBLE_C //
17264 d__1 = (doublereal) c1.r;
17266 // FFEINTRIN_imp_DBLE_D //
17269 // FFEINTRIN_imp_DBLE_I //
17270 d__1 = (doublereal) i1;
17272 // FFEINTRIN_imp_DBLE_R //
17273 d__1 = (doublereal) r1;
17275 // FFEINTRIN_imp_INT_C //
17276 i__1 = (integer) c1.r;
17278 // FFEINTRIN_imp_INT_D //
17279 i__1 = (integer) d1;
17281 // FFEINTRIN_imp_INT_I //
17284 // FFEINTRIN_imp_INT_R //
17285 i__1 = (integer) r1;
17287 // FFEINTRIN_imp_REAL_C //
17290 // FFEINTRIN_imp_REAL_D //
17293 // FFEINTRIN_imp_REAL_I //
17296 // FFEINTRIN_imp_REAL_R //
17300 // FFEINTRIN_imp_INT_D: //
17302 // FFEINTRIN_specIDINT //
17303 i__1 = (integer) d1;
17306 // FFEINTRIN_imp_INT_R: //
17308 // FFEINTRIN_specIFIX //
17309 i__1 = (integer) r1;
17311 // FFEINTRIN_specINT //
17312 i__1 = (integer) r1;
17315 // FFEINTRIN_imp_REAL_D: //
17317 // FFEINTRIN_specSNGL //
17321 // FFEINTRIN_imp_REAL_I: //
17323 // FFEINTRIN_specFLOAT //
17326 // FFEINTRIN_specREAL //
17332 -------- (end output file from f2c)