1 /* com.c -- Implementation File (module.c template V1.0)
2 Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
3 Free Software Foundation, Inc.
4 Contributed by James Craig Burley.
6 This file is part of GNU Fortran.
8 GNU Fortran is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU Fortran is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Fortran; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
27 Contains compiler-specific functions.
32 /* Understanding this module means understanding the interface between
33 the g77 front end and the gcc back end (or, perhaps, some other
34 back end). In here are the functions called by the front end proper
35 to notify whatever back end is in place about certain things, and
36 also the back-end-specific functions. It's a bear to deal with, so
37 lately I've been trying to simplify things, especially with regard
38 to the gcc-back-end-specific stuff.
40 Building expressions generally seems quite easy, but building decls
41 has been challenging and is undergoing revision. gcc has several
44 TYPE_DECL -- a type (int, float, struct, function, etc.)
45 CONST_DECL -- a constant of some type other than function
46 LABEL_DECL -- a variable or a constant?
47 PARM_DECL -- an argument to a function (a variable that is a dummy)
48 RESULT_DECL -- the return value of a function (a variable)
49 VAR_DECL -- other variable (can hold a ptr-to-function, struct, int, etc.)
50 FUNCTION_DECL -- a function (either the actual function or an extern ref)
51 FIELD_DECL -- a field in a struct or union (goes into types)
53 g77 has a set of functions that somewhat parallels the gcc front end
54 when it comes to building decls:
56 Internal Function (one we define, not just declare as extern):
57 if (is_nested) push_f_function_context ();
58 start_function (get_identifier ("function_name"), function_type,
59 is_nested, is_public);
60 // for each arg, build PARM_DECL and call push_parm_decl (decl) with it;
61 store_parm_decls (is_main_program);
62 ffecom_start_compstmt ();
63 // for stmts and decls inside function, do appropriate things;
64 ffecom_end_compstmt ();
65 finish_function (is_nested);
66 if (is_nested) pop_f_function_context ();
71 // fill in external, public, static, &c for decl, and
72 // set DECL_INITIAL to error_mark_node if going to initialize
73 // set is_top_level TRUE only if not at top level and decl
74 // must go in top level (i.e. not within current function decl context)
75 d = start_decl (decl, is_top_level);
76 init = ...; // if have initializer
77 finish_decl (d, init, is_top_level);
89 #include "output.h" /* Must follow tree.h so TREE_CODE is defined! */
92 #include "diagnostic.h"
94 #include "langhooks.h"
95 #include "langhooks-def.h"
97 /* VMS-specific definitions */
100 #define O_RDONLY 0 /* Open arg for Read/Only */
101 #define O_WRONLY 1 /* Open arg for Write/Only */
102 #define read(fd,buf,size) VMS_read (fd,buf,size)
103 #define write(fd,buf,size) VMS_write (fd,buf,size)
104 #define open(fname,mode,prot) VMS_open (fname,mode,prot)
105 #define fopen(fname,mode) VMS_fopen (fname,mode)
106 #define freopen(fname,mode,ofile) VMS_freopen (fname,mode,ofile)
107 #define strncat(dst,src,cnt) VMS_strncat (dst,src,cnt)
108 #define fstat(fd,stbuf) VMS_fstat (fd,stbuf)
109 static int VMS_fstat (), VMS_stat ();
110 static char * VMS_strncat ();
111 static int VMS_read ();
112 static int VMS_write ();
113 static int VMS_open ();
114 static FILE * VMS_fopen ();
115 static FILE * VMS_freopen ();
116 static void hack_vms_include_specification ();
117 typedef struct { unsigned :16, :16, :16; } vms_ino_t;
118 #define ino_t vms_ino_t
119 #define INCLUDE_LEN_FUDGE 10 /* leave room for VMS syntax conversion */
122 #define FFECOM_DETERMINE_TYPES 1 /* for com.h */
139 /* Externals defined here. */
141 /* Stream for reading from the input file. */
144 /* These definitions parallel those in c-decl.c so that code from that
145 module can be used pretty much as is. Much of these defs aren't
146 otherwise used, i.e. by g77 code per se, except some of them are used
147 to build some of them that are. The ones that are global (i.e. not
148 "static") are those that ste.c and such might use (directly
149 or by using com macros that reference them in their definitions). */
151 tree string_type_node;
153 /* The rest of these are inventions for g77, though there might be
154 similar things in the C front end. As they are found, these
155 inventions should be renamed to be canonical. Note that only
156 the ones currently required to be global are so. */
158 static tree ffecom_tree_fun_type_void;
160 tree ffecom_integer_type_node; /* Abbrev for _tree_type[blah][blah]. */
161 tree ffecom_integer_zero_node; /* Like *_*_* with g77's integer type. */
162 tree ffecom_integer_one_node; /* " */
163 tree ffecom_tree_type[FFEINFO_basictype][FFEINFO_kindtype];
165 /* _fun_type things are the f2c-specific versions. For -fno-f2c,
166 just use build_function_type and build_pointer_type on the
167 appropriate _tree_type array element. */
169 static tree ffecom_tree_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
170 static tree ffecom_tree_ptr_to_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
171 static tree ffecom_tree_subr_type;
172 static tree ffecom_tree_ptr_to_subr_type;
173 static tree ffecom_tree_blockdata_type;
175 static tree ffecom_tree_xargc_;
177 ffecomSymbol ffecom_symbol_null_
186 ffeinfoKindtype ffecom_pointer_kind_ = FFEINFO_basictypeNONE;
187 ffeinfoKindtype ffecom_label_kind_ = FFEINFO_basictypeNONE;
189 int ffecom_f2c_typecode_[FFEINFO_basictype][FFEINFO_kindtype];
190 tree ffecom_f2c_integer_type_node;
191 tree ffecom_f2c_ptr_to_integer_type_node;
192 tree ffecom_f2c_address_type_node;
193 tree ffecom_f2c_real_type_node;
194 tree ffecom_f2c_ptr_to_real_type_node;
195 tree ffecom_f2c_doublereal_type_node;
196 tree ffecom_f2c_complex_type_node;
197 tree ffecom_f2c_doublecomplex_type_node;
198 tree ffecom_f2c_longint_type_node;
199 tree ffecom_f2c_logical_type_node;
200 tree ffecom_f2c_flag_type_node;
201 tree ffecom_f2c_ftnlen_type_node;
202 tree ffecom_f2c_ftnlen_zero_node;
203 tree ffecom_f2c_ftnlen_one_node;
204 tree ffecom_f2c_ftnlen_two_node;
205 tree ffecom_f2c_ptr_to_ftnlen_type_node;
206 tree ffecom_f2c_ftnint_type_node;
207 tree ffecom_f2c_ptr_to_ftnint_type_node;
209 /* Simple definitions and enumerations. */
211 #ifndef FFECOM_sizeMAXSTACKITEM
212 #define FFECOM_sizeMAXSTACKITEM 32*1024 /* Keep user-declared things
213 larger than this # bytes
214 off stack if possible. */
217 /* For systems that have large enough stacks, they should define
218 this to 0, and here, for ease of use later on, we just undefine
221 #if FFECOM_sizeMAXSTACKITEM == 0
222 #undef FFECOM_sizeMAXSTACKITEM
228 FFECOM_rttypeVOIDSTAR_, /* C's `void *' type. */
229 FFECOM_rttypeFTNINT_, /* f2c's `ftnint' type. */
230 FFECOM_rttypeINTEGER_, /* f2c's `integer' type. */
231 FFECOM_rttypeLONGINT_, /* f2c's `longint' type. */
232 FFECOM_rttypeLOGICAL_, /* f2c's `logical' type. */
233 FFECOM_rttypeREAL_F2C_, /* f2c's `real' returned as `double'. */
234 FFECOM_rttypeREAL_GNU_, /* `real' returned as such. */
235 FFECOM_rttypeCOMPLEX_F2C_, /* f2c's `complex' returned via 1st arg. */
236 FFECOM_rttypeCOMPLEX_GNU_, /* f2c's `complex' returned directly. */
237 FFECOM_rttypeDOUBLE_, /* C's `double' type. */
238 FFECOM_rttypeDOUBLEREAL_, /* f2c's `doublereal' type. */
239 FFECOM_rttypeDBLCMPLX_F2C_, /* f2c's `doublecomplex' returned via 1st arg. */
240 FFECOM_rttypeDBLCMPLX_GNU_, /* f2c's `doublecomplex' returned directly. */
241 FFECOM_rttypeCHARACTER_, /* f2c `char *'/`ftnlen' pair. */
245 /* Internal typedefs. */
247 typedef struct _ffecom_concat_list_ ffecomConcatList_;
249 /* Private include files. */
252 /* Internal structure definitions. */
254 struct _ffecom_concat_list_
259 ffetargetCharacterSize minlen;
260 ffetargetCharacterSize maxlen;
263 /* Static functions (internal). */
265 static tree ffe_type_for_mode PARAMS ((enum machine_mode, int));
266 static tree ffe_type_for_size PARAMS ((unsigned int, int));
267 static tree ffe_unsigned_type PARAMS ((tree));
268 static tree ffe_signed_type PARAMS ((tree));
269 static tree ffe_signed_or_unsigned_type PARAMS ((int, tree));
270 static bool ffe_mark_addressable PARAMS ((tree));
271 static tree ffe_truthvalue_conversion PARAMS ((tree));
272 static void ffecom_init_decl_processing PARAMS ((void));
273 static tree ffecom_arglist_expr_ (const char *argstring, ffebld args);
274 static tree ffecom_widest_expr_type_ (ffebld list);
275 static bool ffecom_overlap_ (tree dest_decl, tree dest_offset,
276 tree dest_size, tree source_tree,
277 ffebld source, bool scalar_arg);
278 static bool ffecom_args_overlapping_ (tree dest_tree, ffebld dest,
279 tree args, tree callee_commons,
281 static tree ffecom_build_f2c_string_ (int i, const char *s);
282 static tree ffecom_call_ (tree fn, ffeinfoKindtype kt,
283 bool is_f2c_complex, tree type,
284 tree args, tree dest_tree,
285 ffebld dest, bool *dest_used,
286 tree callee_commons, bool scalar_args, tree hook);
287 static tree ffecom_call_binop_ (tree fn, ffeinfoKindtype kt,
288 bool is_f2c_complex, tree type,
289 ffebld left, ffebld right,
290 tree dest_tree, ffebld dest,
291 bool *dest_used, tree callee_commons,
292 bool scalar_args, bool ref, tree hook);
293 static void ffecom_char_args_x_ (tree *xitem, tree *length,
294 ffebld expr, bool with_null);
295 static tree ffecom_check_size_overflow_ (ffesymbol s, tree type, bool dummy);
296 static tree ffecom_char_enhance_arg_ (tree *xtype, ffesymbol s);
297 static ffecomConcatList_
298 ffecom_concat_list_gather_ (ffecomConcatList_ catlist,
300 ffetargetCharacterSize max);
301 static void ffecom_concat_list_kill_ (ffecomConcatList_ catlist);
302 static ffecomConcatList_ ffecom_concat_list_new_ (ffebld expr,
303 ffetargetCharacterSize max);
304 static void ffecom_debug_kludge_ (tree aggr, const char *aggr_type,
305 ffesymbol member, tree member_type,
306 ffetargetOffset offset);
307 static void ffecom_do_entry_ (ffesymbol fn, int entrynum);
308 static tree ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest,
309 bool *dest_used, bool assignp, bool widenp);
310 static tree ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree,
311 ffebld dest, bool *dest_used);
312 static tree ffecom_expr_power_integer_ (ffebld expr);
313 static void ffecom_expr_transform_ (ffebld expr);
314 static void ffecom_f2c_make_type_ (tree *type, int tcode, const char *name);
315 static void ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size,
317 static ffeglobal ffecom_finish_global_ (ffeglobal global);
318 static ffesymbol ffecom_finish_symbol_transform_ (ffesymbol s);
319 static tree ffecom_get_appended_identifier_ (char us, const char *text);
320 static tree ffecom_get_external_identifier_ (ffesymbol s);
321 static tree ffecom_get_identifier_ (const char *text);
322 static tree ffecom_gen_sfuncdef_ (ffesymbol s,
325 static const char *ffecom_gfrt_args_ (ffecomGfrt ix);
326 static tree ffecom_gfrt_tree_ (ffecomGfrt ix);
327 static tree ffecom_init_zero_ (tree decl);
328 static tree ffecom_intrinsic_ichar_ (tree tree_type, ffebld arg,
330 static tree ffecom_intrinsic_len_ (ffebld expr);
331 static void ffecom_let_char_ (tree dest_tree,
333 ffetargetCharacterSize dest_size,
335 static void ffecom_make_gfrt_ (ffecomGfrt ix);
336 static void ffecom_member_phase1_ (ffestorag mst, ffestorag st);
337 static void ffecom_member_phase2_ (ffestorag mst, ffestorag st);
338 static void ffecom_prepare_let_char_ (ffetargetCharacterSize dest_size,
340 static void ffecom_push_dummy_decls_ (ffebld dumlist,
342 static void ffecom_start_progunit_ (void);
343 static ffesymbol ffecom_sym_transform_ (ffesymbol s);
344 static ffesymbol ffecom_sym_transform_assign_ (ffesymbol s);
345 static void ffecom_transform_common_ (ffesymbol s);
346 static void ffecom_transform_equiv_ (ffestorag st);
347 static tree ffecom_transform_namelist_ (ffesymbol s);
348 static void ffecom_tree_canonize_ptr_ (tree *decl, tree *offset,
350 static void ffecom_tree_canonize_ref_ (tree *decl, tree *offset,
351 tree *size, tree tree);
352 static tree ffecom_tree_divide_ (tree tree_type, tree left, tree right,
353 tree dest_tree, ffebld dest,
354 bool *dest_used, tree hook);
355 static tree ffecom_type_localvar_ (ffesymbol s,
358 static tree ffecom_type_namelist_ (void);
359 static tree ffecom_type_vardesc_ (void);
360 static tree ffecom_vardesc_ (ffebld expr);
361 static tree ffecom_vardesc_array_ (ffesymbol s);
362 static tree ffecom_vardesc_dims_ (ffesymbol s);
363 static tree ffecom_convert_narrow_ (tree type, tree expr);
364 static tree ffecom_convert_widen_ (tree type, tree expr);
366 /* These are static functions that parallel those found in the C front
367 end and thus have the same names. */
369 static tree bison_rule_compstmt_ (void);
370 static void bison_rule_pushlevel_ (void);
371 static void delete_block (tree block);
372 static int duplicate_decls (tree newdecl, tree olddecl);
373 static void finish_decl (tree decl, tree init, bool is_top_level);
374 static void finish_function (int nested);
375 static const char *ffe_printable_name (tree decl, int v);
376 static void ffe_print_error_function (diagnostic_context *, const char *);
377 static tree lookup_name_current_level (tree name);
378 static struct binding_level *make_binding_level (void);
379 static void pop_f_function_context (void);
380 static void push_f_function_context (void);
381 static void push_parm_decl (tree parm);
382 static tree pushdecl_top_level (tree decl);
383 static int kept_level_p (void);
384 static tree storedecls (tree decls);
385 static void store_parm_decls (int is_main_program);
386 static tree start_decl (tree decl, bool is_top_level);
387 static void start_function (tree name, tree type, int nested, int public);
388 static void ffecom_file_ (const char *name);
389 static void ffecom_close_include_ (FILE *f);
390 static int ffecom_decode_include_option_ (char *spec);
391 static FILE *ffecom_open_include_ (char *name, ffewhereLine l,
394 /* Static objects accessed by functions in this module. */
396 static ffesymbol ffecom_primary_entry_ = NULL;
397 static ffesymbol ffecom_nested_entry_ = NULL;
398 static ffeinfoKind ffecom_primary_entry_kind_;
399 static bool ffecom_primary_entry_is_proc_;
400 static tree ffecom_outer_function_decl_;
401 static tree ffecom_previous_function_decl_;
402 static tree ffecom_which_entrypoint_decl_;
403 static tree ffecom_float_zero_ = NULL_TREE;
404 static tree ffecom_float_half_ = NULL_TREE;
405 static tree ffecom_double_zero_ = NULL_TREE;
406 static tree ffecom_double_half_ = NULL_TREE;
407 static tree ffecom_func_result_;/* For functions. */
408 static tree ffecom_func_length_;/* For CHARACTER fns. */
409 static ffebld ffecom_list_blockdata_;
410 static ffebld ffecom_list_common_;
411 static ffebld ffecom_master_arglist_;
412 static ffeinfoBasictype ffecom_master_bt_;
413 static ffeinfoKindtype ffecom_master_kt_;
414 static ffetargetCharacterSize ffecom_master_size_;
415 static int ffecom_num_fns_ = 0;
416 static int ffecom_num_entrypoints_ = 0;
417 static bool ffecom_is_altreturning_ = FALSE;
418 static tree ffecom_multi_type_node_;
419 static tree ffecom_multi_retval_;
421 ffecom_multi_fields_[FFEINFO_basictype][FFEINFO_kindtype];
422 static bool ffecom_member_namelisted_; /* _member_phase1_ namelisted? */
423 static bool ffecom_doing_entry_ = FALSE;
424 static bool ffecom_transform_only_dummies_ = FALSE;
425 static int ffecom_typesize_pointer_;
426 static int ffecom_typesize_integer1_;
428 /* Holds pointer-to-function expressions. */
430 static tree ffecom_gfrt_[FFECOM_gfrt]
433 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) NULL_TREE,
434 #include "com-rt.def"
438 /* Holds the external names of the functions. */
440 static const char *const ffecom_gfrt_name_[FFECOM_gfrt]
443 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) NAME,
444 #include "com-rt.def"
448 /* Whether the function returns. */
450 static const bool ffecom_gfrt_volatile_[FFECOM_gfrt]
453 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) VOLATILE,
454 #include "com-rt.def"
458 /* Whether the function returns type complex. */
460 static const bool ffecom_gfrt_complex_[FFECOM_gfrt]
463 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) COMPLEX,
464 #include "com-rt.def"
468 /* Whether the function is const
469 (i.e., has no side effects and only depends on its arguments). */
471 static const bool ffecom_gfrt_const_[FFECOM_gfrt]
474 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) CONST,
475 #include "com-rt.def"
479 /* Type code for the function return value. */
481 static const ffecomRttype_ ffecom_gfrt_type_[FFECOM_gfrt]
484 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) TYPE,
485 #include "com-rt.def"
489 /* String of codes for the function's arguments. */
491 static const char *const ffecom_gfrt_argstring_[FFECOM_gfrt]
494 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) ARGS,
495 #include "com-rt.def"
499 /* Internal macros. */
501 /* We let tm.h override the types used here, to handle trivial differences
502 such as the choice of unsigned int or long unsigned int for size_t.
503 When machines start needing nontrivial differences in the size type,
504 it would be best to do something here to figure out automatically
505 from other information what type to use. */
508 #define SIZE_TYPE "long unsigned int"
511 #define ffecom_concat_list_count_(catlist) ((catlist).count)
512 #define ffecom_concat_list_expr_(catlist,i) ((catlist).exprs[(i)])
513 #define ffecom_concat_list_maxlen_(catlist) ((catlist).maxlen)
514 #define ffecom_concat_list_minlen_(catlist) ((catlist).minlen)
516 #define ffecom_char_args_(i,l,e) ffecom_char_args_x_((i),(l),(e),FALSE)
517 #define ffecom_char_args_with_null_(i,l,e) ffecom_char_args_x_((i),(l),(e),TRUE)
519 /* For each binding contour we allocate a binding_level structure
520 * which records the names defined in that contour.
523 * 1) one for each function definition,
524 * where internal declarations of the parameters appear.
526 * The current meaning of a name can be found by searching the levels from
527 * the current one out to the global one.
530 /* Note that the information in the `names' component of the global contour
531 is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */
535 /* A chain of _DECL nodes for all variables, constants, functions,
536 and typedef types. These are in the reverse of the order supplied.
540 /* For each level (except not the global one),
541 a chain of BLOCK nodes for all the levels
542 that were entered and exited one level down. */
545 /* The BLOCK node for this level, if one has been preallocated.
546 If 0, the BLOCK is allocated (if needed) when the level is popped. */
549 /* The binding level which this one is contained in (inherits from). */
550 struct binding_level *level_chain;
552 /* 0: no ffecom_prepare_* functions called at this level yet;
553 1: ffecom_prepare* functions called, except not ffecom_prepare_end;
554 2: ffecom_prepare_end called. */
558 #define NULL_BINDING_LEVEL (struct binding_level *) NULL
560 /* The binding level currently in effect. */
562 static struct binding_level *current_binding_level;
564 /* A chain of binding_level structures awaiting reuse. */
566 static struct binding_level *free_binding_level;
568 /* The outermost binding level, for names of file scope.
569 This is created when the compiler is started and exists
570 through the entire run. */
572 static struct binding_level *global_binding_level;
574 /* Binding level structures are initialized by copying this one. */
576 static const struct binding_level clear_binding_level
578 {NULL, NULL, NULL, NULL_BINDING_LEVEL, 0};
580 /* Language-dependent contents of an identifier. */
582 struct lang_identifier
584 struct tree_identifier ignore;
585 tree global_value, local_value, label_value;
589 /* Macros for access to language-specific slots in an identifier. */
590 /* Each of these slots contains a DECL node or null. */
592 /* This represents the value which the identifier has in the
593 file-scope namespace. */
594 #define IDENTIFIER_GLOBAL_VALUE(NODE) \
595 (((struct lang_identifier *)(NODE))->global_value)
596 /* This represents the value which the identifier has in the current
598 #define IDENTIFIER_LOCAL_VALUE(NODE) \
599 (((struct lang_identifier *)(NODE))->local_value)
600 /* This represents the value which the identifier has as a label in
601 the current label scope. */
602 #define IDENTIFIER_LABEL_VALUE(NODE) \
603 (((struct lang_identifier *)(NODE))->label_value)
604 /* This is nonzero if the identifier was "made up" by g77 code. */
605 #define IDENTIFIER_INVENTED(NODE) \
606 (((struct lang_identifier *)(NODE))->invented)
608 /* In identifiers, C uses the following fields in a special way:
609 TREE_PUBLIC to record that there was a previous local extern decl.
610 TREE_USED to record that such a decl was used.
611 TREE_ADDRESSABLE to record that the address of such a decl was used. */
613 /* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function
614 that have names. Here so we can clear out their names' definitions
615 at the end of the function. */
617 static tree named_labels;
619 /* A list of LABEL_DECLs from outer contexts that are currently shadowed. */
621 static tree shadowed_labels;
623 /* Return the subscript expression, modified to do range-checking.
625 `array' is the array to be checked against.
626 `element' is the subscript expression to check.
627 `dim' is the dimension number (starting at 0).
628 `total_dims' is the total number of dimensions (0 for CHARACTER substring).
632 ffecom_subscript_check_ (tree array, tree element, int dim, int total_dims,
633 const char *array_name)
635 tree low = TYPE_MIN_VALUE (TYPE_DOMAIN (array));
636 tree high = TYPE_MAX_VALUE (TYPE_DOMAIN (array));
641 if (element == error_mark_node)
644 if (TREE_TYPE (low) != TREE_TYPE (element))
646 if (TYPE_PRECISION (TREE_TYPE (low))
647 > TYPE_PRECISION (TREE_TYPE (element)))
648 element = convert (TREE_TYPE (low), element);
651 low = convert (TREE_TYPE (element), low);
653 high = convert (TREE_TYPE (element), high);
657 element = ffecom_save_tree (element);
660 /* Special handling for substring range checks. Fortran allows the
661 end subscript < begin subscript, which means that expressions like
662 string(1:0) are valid (and yield a null string). In view of this,
663 enforce two simpler conditions:
664 1) element<=high for end-substring;
665 2) element>=low for start-substring.
666 Run-time character movement will enforce remaining conditions.
668 More complicated checks would be better, but present structure only
669 provides one index element at a time, so it is not possible to
670 enforce a check of both i and j in string(i:j). If it were, the
671 complete set of rules would read,
672 if ( ((j<i) && ((low<=i<=high) || (low<=j<=high))) ||
673 ((low<=i<=high) && (low<=j<=high)) )
679 cond = ffecom_2 (LE_EXPR, integer_type_node, element, high);
681 cond = ffecom_2 (LE_EXPR, integer_type_node, low, element);
685 /* Array reference substring range checking. */
687 cond = ffecom_2 (LE_EXPR, integer_type_node,
692 cond = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
694 ffecom_2 (LE_EXPR, integer_type_node,
712 var = concat (array_name, "[", (dim ? "end" : "start"),
713 "-substring]", NULL);
714 len = strlen (var) + 1;
715 arg1 = build_string (len, var);
720 len = strlen (array_name) + 1;
721 arg1 = build_string (len, array_name);
725 var = xmalloc (strlen (array_name) + 40);
726 sprintf (var, "%s[subscript-%d-of-%d]",
728 dim + 1, total_dims);
729 len = strlen (var) + 1;
730 arg1 = build_string (len, var);
736 = build_type_variant (build_array_type (char_type_node,
740 build_int_2 (len, 0))),
742 TREE_CONSTANT (arg1) = 1;
743 TREE_STATIC (arg1) = 1;
744 arg1 = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg1)),
747 /* s_rnge adds one to the element to print it, so bias against
748 that -- want to print a faithful *subscript* value. */
749 arg2 = convert (ffecom_f2c_ftnint_type_node,
750 ffecom_2 (MINUS_EXPR,
753 convert (TREE_TYPE (element),
756 proc = concat (input_filename, "/",
757 IDENTIFIER_POINTER (DECL_NAME (current_function_decl)),
759 len = strlen (proc) + 1;
760 arg3 = build_string (len, proc);
765 = build_type_variant (build_array_type (char_type_node,
769 build_int_2 (len, 0))),
771 TREE_CONSTANT (arg3) = 1;
772 TREE_STATIC (arg3) = 1;
773 arg3 = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg3)),
776 arg4 = convert (ffecom_f2c_ftnint_type_node,
777 build_int_2 (lineno, 0));
779 arg1 = build_tree_list (NULL_TREE, arg1);
780 arg2 = build_tree_list (NULL_TREE, arg2);
781 arg3 = build_tree_list (NULL_TREE, arg3);
782 arg4 = build_tree_list (NULL_TREE, arg4);
783 TREE_CHAIN (arg3) = arg4;
784 TREE_CHAIN (arg2) = arg3;
785 TREE_CHAIN (arg1) = arg2;
789 die = ffecom_call_gfrt (FFECOM_gfrtRANGE,
791 TREE_SIDE_EFFECTS (die) = 1;
793 element = ffecom_3 (COND_EXPR,
802 /* Return the computed element of an array reference.
804 `item' is NULL_TREE, or the transformed pointer to the array.
805 `expr' is the original opARRAYREF expression, which is transformed
806 if `item' is NULL_TREE.
807 `want_ptr' is non-zero if a pointer to the element, instead of
808 the element itself, is to be returned. */
811 ffecom_arrayref_ (tree item, ffebld expr, int want_ptr)
813 ffebld dims[FFECOM_dimensionsMAX];
816 int flatten = ffe_is_flatten_arrays ();
822 const char *array_name;
826 if (ffebld_op (ffebld_left (expr)) == FFEBLD_opSYMTER)
827 array_name = ffesymbol_text (ffebld_symter (ffebld_left (expr)));
829 array_name = "[expr?]";
831 /* Build up ARRAY_REFs in reverse order (since we're column major
832 here in Fortran land). */
834 for (i = 0, list = ffebld_right (expr);
836 ++i, list = ffebld_trail (list))
838 dims[i] = ffebld_head (list);
839 type = ffeinfo_type (ffebld_basictype (dims[i]),
840 ffebld_kindtype (dims[i]));
842 && ffecom_typesize_pointer_ > ffecom_typesize_integer1_
843 && ffetype_size (type) > ffecom_typesize_integer1_)
844 /* E.g. ARRAY(INDEX), given INTEGER*8 INDEX, on a system with 64-bit
845 pointers and 32-bit integers. Do the full 64-bit pointer
846 arithmetic, for codes using arrays for nonstandard heap-like
853 need_ptr = want_ptr || flatten;
858 item = ffecom_ptr_to_expr (ffebld_left (expr));
860 item = ffecom_expr (ffebld_left (expr));
862 if (item == error_mark_node)
865 if (ffeinfo_where (ffebld_info (expr)) == FFEINFO_whereFLEETING
866 && ! ffe_mark_addressable (item))
867 return error_mark_node;
870 if (item == error_mark_node)
877 for (--i, array = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item)));
879 --i, array = TYPE_MAIN_VARIANT (TREE_TYPE (array)))
881 min = TYPE_MIN_VALUE (TYPE_DOMAIN (array));
882 element = ffecom_expr_ (dims[i], NULL, NULL, NULL, FALSE, TRUE);
883 if (flag_bounds_check)
884 element = ffecom_subscript_check_ (array, element, i, total_dims,
886 if (element == error_mark_node)
889 /* Widen integral arithmetic as desired while preserving
891 tree_type = TREE_TYPE (element);
892 tree_type_x = tree_type;
894 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
895 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
896 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
898 if (TREE_TYPE (min) != tree_type_x)
899 min = convert (tree_type_x, min);
900 if (TREE_TYPE (element) != tree_type_x)
901 element = convert (tree_type_x, element);
903 item = ffecom_2 (PLUS_EXPR,
904 build_pointer_type (TREE_TYPE (array)),
906 size_binop (MULT_EXPR,
907 size_in_bytes (TREE_TYPE (array)),
909 fold (build (MINUS_EXPR,
915 item = ffecom_1 (INDIRECT_REF,
916 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item))),
926 array = TYPE_MAIN_VARIANT (TREE_TYPE (item));
928 element = ffecom_expr_ (dims[i], NULL, NULL, NULL, FALSE, TRUE);
929 if (flag_bounds_check)
930 element = ffecom_subscript_check_ (array, element, i, total_dims,
932 if (element == error_mark_node)
935 /* Widen integral arithmetic as desired while preserving
937 tree_type = TREE_TYPE (element);
938 tree_type_x = tree_type;
940 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
941 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
942 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
944 element = convert (tree_type_x, element);
946 item = ffecom_2 (ARRAY_REF,
947 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item))),
956 /* This is like gcc's stabilize_reference -- in fact, most of the code
957 comes from that -- but it handles the situation where the reference
958 is going to have its subparts picked at, and it shouldn't change
959 (or trigger extra invocations of functions in the subtrees) due to
960 this. save_expr is a bit overzealous, because we don't need the
961 entire thing calculated and saved like a temp. So, for DECLs, no
962 change is needed, because these are stable aggregates, and ARRAY_REF
963 and such might well be stable too, but for things like calculations,
964 we do need to calculate a snapshot of a value before picking at it. */
967 ffecom_stabilize_aggregate_ (tree ref)
970 enum tree_code code = TREE_CODE (ref);
977 /* No action is needed in this case. */
987 result = build_nt (code, stabilize_reference (TREE_OPERAND (ref, 0)));
991 result = build_nt (INDIRECT_REF,
992 stabilize_reference_1 (TREE_OPERAND (ref, 0)));
996 result = build_nt (COMPONENT_REF,
997 stabilize_reference (TREE_OPERAND (ref, 0)),
998 TREE_OPERAND (ref, 1));
1002 result = build_nt (BIT_FIELD_REF,
1003 stabilize_reference (TREE_OPERAND (ref, 0)),
1004 stabilize_reference_1 (TREE_OPERAND (ref, 1)),
1005 stabilize_reference_1 (TREE_OPERAND (ref, 2)));
1009 result = build_nt (ARRAY_REF,
1010 stabilize_reference (TREE_OPERAND (ref, 0)),
1011 stabilize_reference_1 (TREE_OPERAND (ref, 1)));
1015 result = build_nt (COMPOUND_EXPR,
1016 stabilize_reference_1 (TREE_OPERAND (ref, 0)),
1017 stabilize_reference (TREE_OPERAND (ref, 1)));
1025 return save_expr (ref);
1028 return error_mark_node;
1031 TREE_TYPE (result) = TREE_TYPE (ref);
1032 TREE_READONLY (result) = TREE_READONLY (ref);
1033 TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (ref);
1034 TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (ref);
1039 /* A rip-off of gcc's convert.c convert_to_complex function,
1040 reworked to handle complex implemented as C structures
1041 (RECORD_TYPE with two fields, real and imaginary `r' and `i'). */
1044 ffecom_convert_to_complex_ (tree type, tree expr)
1046 register enum tree_code form = TREE_CODE (TREE_TYPE (expr));
1049 assert (TREE_CODE (type) == RECORD_TYPE);
1051 subtype = TREE_TYPE (TYPE_FIELDS (type));
1053 if (form == REAL_TYPE || form == INTEGER_TYPE || form == ENUMERAL_TYPE)
1055 expr = convert (subtype, expr);
1056 return ffecom_2 (COMPLEX_EXPR, type, expr,
1057 convert (subtype, integer_zero_node));
1060 if (form == RECORD_TYPE)
1062 tree elt_type = TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr)));
1063 if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype))
1067 expr = save_expr (expr);
1068 return ffecom_2 (COMPLEX_EXPR,
1071 ffecom_1 (REALPART_EXPR,
1072 TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))),
1075 ffecom_1 (IMAGPART_EXPR,
1076 TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))),
1081 if (form == POINTER_TYPE || form == REFERENCE_TYPE)
1082 error ("pointer value used where a complex was expected");
1084 error ("aggregate value used where a complex was expected");
1086 return ffecom_2 (COMPLEX_EXPR, type,
1087 convert (subtype, integer_zero_node),
1088 convert (subtype, integer_zero_node));
1091 /* Like gcc's convert(), but crashes if widening might happen. */
1094 ffecom_convert_narrow_ (type, expr)
1097 register tree e = expr;
1098 register enum tree_code code = TREE_CODE (type);
1100 if (type == TREE_TYPE (e)
1101 || TREE_CODE (e) == ERROR_MARK)
1103 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
1104 return fold (build1 (NOP_EXPR, type, e));
1105 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
1106 || code == ERROR_MARK)
1107 return error_mark_node;
1108 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
1110 assert ("void value not ignored as it ought to be" == NULL);
1111 return error_mark_node;
1113 assert (code != VOID_TYPE);
1114 if ((code != RECORD_TYPE)
1115 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
1116 assert ("converting COMPLEX to REAL" == NULL);
1117 assert (code != ENUMERAL_TYPE);
1118 if (code == INTEGER_TYPE)
1120 assert ((TREE_CODE (TREE_TYPE (e)) == INTEGER_TYPE
1121 && TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (e)))
1122 || (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE
1123 && (TYPE_PRECISION (type)
1124 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e))))));
1125 return fold (convert_to_integer (type, e));
1127 if (code == POINTER_TYPE)
1129 assert (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE);
1130 return fold (convert_to_pointer (type, e));
1132 if (code == REAL_TYPE)
1134 assert (TREE_CODE (TREE_TYPE (e)) == REAL_TYPE);
1135 assert (TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (e)));
1136 return fold (convert_to_real (type, e));
1138 if (code == COMPLEX_TYPE)
1140 assert (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE);
1141 assert (TYPE_PRECISION (TREE_TYPE (type)) <= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e))));
1142 return fold (convert_to_complex (type, e));
1144 if (code == RECORD_TYPE)
1146 assert (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE);
1147 /* Check that at least the first field name agrees. */
1148 assert (DECL_NAME (TYPE_FIELDS (type))
1149 == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e))));
1150 assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1151 <= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))));
1152 if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1153 == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))))
1155 return fold (ffecom_convert_to_complex_ (type, e));
1158 assert ("conversion to non-scalar type requested" == NULL);
1159 return error_mark_node;
1162 /* Like gcc's convert(), but crashes if narrowing might happen. */
1165 ffecom_convert_widen_ (type, expr)
1168 register tree e = expr;
1169 register enum tree_code code = TREE_CODE (type);
1171 if (type == TREE_TYPE (e)
1172 || TREE_CODE (e) == ERROR_MARK)
1174 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
1175 return fold (build1 (NOP_EXPR, type, e));
1176 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
1177 || code == ERROR_MARK)
1178 return error_mark_node;
1179 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
1181 assert ("void value not ignored as it ought to be" == NULL);
1182 return error_mark_node;
1184 assert (code != VOID_TYPE);
1185 if ((code != RECORD_TYPE)
1186 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
1187 assert ("narrowing COMPLEX to REAL" == NULL);
1188 assert (code != ENUMERAL_TYPE);
1189 if (code == INTEGER_TYPE)
1191 assert ((TREE_CODE (TREE_TYPE (e)) == INTEGER_TYPE
1192 && TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (e)))
1193 || (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE
1194 && (TYPE_PRECISION (type)
1195 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e))))));
1196 return fold (convert_to_integer (type, e));
1198 if (code == POINTER_TYPE)
1200 assert (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE);
1201 return fold (convert_to_pointer (type, e));
1203 if (code == REAL_TYPE)
1205 assert (TREE_CODE (TREE_TYPE (e)) == REAL_TYPE);
1206 assert (TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (e)));
1207 return fold (convert_to_real (type, e));
1209 if (code == COMPLEX_TYPE)
1211 assert (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE);
1212 assert (TYPE_PRECISION (TREE_TYPE (type)) >= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e))));
1213 return fold (convert_to_complex (type, e));
1215 if (code == RECORD_TYPE)
1217 assert (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE);
1218 /* Check that at least the first field name agrees. */
1219 assert (DECL_NAME (TYPE_FIELDS (type))
1220 == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e))));
1221 assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1222 >= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))));
1223 if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1224 == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))))
1226 return fold (ffecom_convert_to_complex_ (type, e));
1229 assert ("conversion to non-scalar type requested" == NULL);
1230 return error_mark_node;
1233 /* Handles making a COMPLEX type, either the standard
1234 (but buggy?) gbe way, or the safer (but less elegant?)
1238 ffecom_make_complex_type_ (tree subtype)
1244 if (ffe_is_emulate_complex ())
1246 type = make_node (RECORD_TYPE);
1247 realfield = ffecom_decl_field (type, NULL_TREE, "r", subtype);
1248 imagfield = ffecom_decl_field (type, realfield, "i", subtype);
1249 TYPE_FIELDS (type) = realfield;
1254 type = make_node (COMPLEX_TYPE);
1255 TREE_TYPE (type) = subtype;
1262 /* Chooses either the gbe or the f2c way to build a
1263 complex constant. */
1266 ffecom_build_complex_constant_ (tree type, tree realpart, tree imagpart)
1270 if (ffe_is_emulate_complex ())
1272 bothparts = build_tree_list (TYPE_FIELDS (type), realpart);
1273 TREE_CHAIN (bothparts) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), imagpart);
1274 bothparts = build (CONSTRUCTOR, type, NULL_TREE, bothparts);
1278 bothparts = build_complex (type, realpart, imagpart);
1285 ffecom_arglist_expr_ (const char *c, ffebld expr)
1288 tree *plist = &list;
1289 tree trail = NULL_TREE; /* Append char length args here. */
1290 tree *ptrail = &trail;
1295 tree wanted = NULL_TREE;
1296 static const char zed[] = "0";
1301 while (expr != NULL)
1324 wanted = ffecom_f2c_complex_type_node;
1328 wanted = ffecom_f2c_doublereal_type_node;
1332 wanted = ffecom_f2c_doublecomplex_type_node;
1336 wanted = ffecom_f2c_real_type_node;
1340 wanted = ffecom_f2c_integer_type_node;
1344 wanted = ffecom_f2c_longint_type_node;
1348 assert ("bad argstring code" == NULL);
1354 exprh = ffebld_head (expr);
1358 if ((wanted == NULL_TREE)
1361 (ffecom_tree_type[ffeinfo_basictype (ffebld_info (exprh))]
1362 [ffeinfo_kindtype (ffebld_info (exprh))])
1363 == TYPE_MODE (wanted))))
1365 = build_tree_list (NULL_TREE,
1366 ffecom_arg_ptr_to_expr (exprh,
1370 item = ffecom_arg_expr (exprh, &length);
1371 item = ffecom_convert_widen_ (wanted, item);
1374 item = ffecom_1 (ADDR_EXPR,
1375 build_pointer_type (TREE_TYPE (item)),
1379 = build_tree_list (NULL_TREE,
1383 plist = &TREE_CHAIN (*plist);
1384 expr = ffebld_trail (expr);
1385 if (length != NULL_TREE)
1387 *ptrail = build_tree_list (NULL_TREE, length);
1388 ptrail = &TREE_CHAIN (*ptrail);
1392 /* We've run out of args in the call; if the implementation expects
1393 more, supply null pointers for them, which the implementation can
1394 check to see if an arg was omitted. */
1396 while (*c != '\0' && *c != '0')
1401 assert ("missing arg to run-time routine!" == NULL);
1416 assert ("bad arg string code" == NULL);
1420 = build_tree_list (NULL_TREE,
1422 plist = &TREE_CHAIN (*plist);
1431 ffecom_widest_expr_type_ (ffebld list)
1434 ffebld widest = NULL;
1436 ffetype widest_type = NULL;
1439 for (; list != NULL; list = ffebld_trail (list))
1441 item = ffebld_head (list);
1444 if ((widest != NULL)
1445 && (ffeinfo_basictype (ffebld_info (item))
1446 != ffeinfo_basictype (ffebld_info (widest))))
1448 type = ffeinfo_type (ffeinfo_basictype (ffebld_info (item)),
1449 ffeinfo_kindtype (ffebld_info (item)));
1450 if ((widest == FFEINFO_kindtypeNONE)
1451 || (ffetype_size (type)
1452 > ffetype_size (widest_type)))
1459 assert (widest != NULL);
1460 t = ffecom_tree_type[ffeinfo_basictype (ffebld_info (widest))]
1461 [ffeinfo_kindtype (ffebld_info (widest))];
1462 assert (t != NULL_TREE);
1466 /* Check whether a partial overlap between two expressions is possible.
1468 Can *starting* to write a portion of expr1 change the value
1469 computed (perhaps already, *partially*) by expr2?
1471 Currently, this is a concern only for a COMPLEX expr1. But if it
1472 isn't in COMMON or local EQUIVALENCE, since we don't support
1473 aliasing of arguments, it isn't a concern. */
1476 ffecom_possible_partial_overlap_ (ffebld expr1, ffebld expr2 ATTRIBUTE_UNUSED)
1481 switch (ffebld_op (expr1))
1483 case FFEBLD_opSYMTER:
1484 sym = ffebld_symter (expr1);
1487 case FFEBLD_opARRAYREF:
1488 if (ffebld_op (ffebld_left (expr1)) != FFEBLD_opSYMTER)
1490 sym = ffebld_symter (ffebld_left (expr1));
1497 if (ffesymbol_where (sym) != FFEINFO_whereCOMMON
1498 && (ffesymbol_where (sym) != FFEINFO_whereLOCAL
1499 || ! (st = ffesymbol_storage (sym))
1500 || ! ffestorag_parent (st)))
1503 /* It's in COMMON or local EQUIVALENCE. */
1508 /* Check whether dest and source might overlap. ffebld versions of these
1509 might or might not be passed, will be NULL if not.
1511 The test is really whether source_tree is modifiable and, if modified,
1512 might overlap destination such that the value(s) in the destination might
1513 change before it is finally modified. dest_* are the canonized
1514 destination itself. */
1517 ffecom_overlap_ (tree dest_decl, tree dest_offset, tree dest_size,
1518 tree source_tree, ffebld source UNUSED,
1526 if (source_tree == NULL_TREE)
1529 switch (TREE_CODE (source_tree))
1532 case IDENTIFIER_NODE:
1543 case TRUNC_DIV_EXPR:
1545 case FLOOR_DIV_EXPR:
1546 case ROUND_DIV_EXPR:
1547 case TRUNC_MOD_EXPR:
1549 case FLOOR_MOD_EXPR:
1550 case ROUND_MOD_EXPR:
1552 case EXACT_DIV_EXPR:
1553 case FIX_TRUNC_EXPR:
1555 case FIX_FLOOR_EXPR:
1556 case FIX_ROUND_EXPR:
1570 case BIT_ANDTC_EXPR:
1572 case TRUTH_ANDIF_EXPR:
1573 case TRUTH_ORIF_EXPR:
1574 case TRUTH_AND_EXPR:
1576 case TRUTH_XOR_EXPR:
1577 case TRUTH_NOT_EXPR:
1593 return ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1594 TREE_OPERAND (source_tree, 1), NULL,
1598 return ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1599 TREE_OPERAND (source_tree, 0), NULL,
1604 case NON_LVALUE_EXPR:
1606 if (TREE_CODE (TREE_TYPE (source_tree)) != POINTER_TYPE)
1609 ffecom_tree_canonize_ptr_ (&source_decl, &source_offset,
1611 source_size = TYPE_SIZE (TREE_TYPE (TREE_TYPE (source_tree)));
1616 ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1617 TREE_OPERAND (source_tree, 1), NULL,
1619 || ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1620 TREE_OPERAND (source_tree, 2), NULL,
1625 ffecom_tree_canonize_ref_ (&source_decl, &source_offset,
1627 TREE_OPERAND (source_tree, 0));
1631 if (TREE_CODE (TREE_TYPE (source_tree)) != POINTER_TYPE)
1634 source_decl = source_tree;
1635 source_offset = bitsize_zero_node;
1636 source_size = TYPE_SIZE (TREE_TYPE (TREE_TYPE (source_tree)));
1640 case REFERENCE_EXPR:
1641 case PREDECREMENT_EXPR:
1642 case PREINCREMENT_EXPR:
1643 case POSTDECREMENT_EXPR:
1644 case POSTINCREMENT_EXPR:
1652 /* Come here when source_decl, source_offset, and source_size filled
1653 in appropriately. */
1655 if (source_decl == NULL_TREE)
1656 return FALSE; /* No decl involved, so no overlap. */
1658 if (source_decl != dest_decl)
1659 return FALSE; /* Different decl, no overlap. */
1661 if (TREE_CODE (dest_size) == ERROR_MARK)
1662 return TRUE; /* Assignment into entire assumed-size
1663 array? Shouldn't happen.... */
1665 t = ffecom_2 (LE_EXPR, integer_type_node,
1666 ffecom_2 (PLUS_EXPR, TREE_TYPE (dest_offset),
1668 convert (TREE_TYPE (dest_offset),
1670 convert (TREE_TYPE (dest_offset),
1673 if (integer_onep (t))
1674 return FALSE; /* Destination precedes source. */
1677 || (source_size == NULL_TREE)
1678 || (TREE_CODE (source_size) == ERROR_MARK)
1679 || integer_zerop (source_size))
1680 return TRUE; /* No way to tell if dest follows source. */
1682 t = ffecom_2 (LE_EXPR, integer_type_node,
1683 ffecom_2 (PLUS_EXPR, TREE_TYPE (source_offset),
1685 convert (TREE_TYPE (source_offset),
1687 convert (TREE_TYPE (source_offset),
1690 if (integer_onep (t))
1691 return FALSE; /* Destination follows source. */
1693 return TRUE; /* Destination and source overlap. */
1696 /* Check whether dest might overlap any of a list of arguments or is
1697 in a COMMON area the callee might know about (and thus modify). */
1700 ffecom_args_overlapping_ (tree dest_tree, ffebld dest UNUSED,
1701 tree args, tree callee_commons,
1709 ffecom_tree_canonize_ref_ (&dest_decl, &dest_offset, &dest_size,
1712 if (dest_decl == NULL_TREE)
1713 return FALSE; /* Seems unlikely! */
1715 /* If the decl cannot be determined reliably, or if its in COMMON
1716 and the callee isn't known to not futz with COMMON via other
1717 means, overlap might happen. */
1719 if ((TREE_CODE (dest_decl) == ERROR_MARK)
1720 || ((callee_commons != NULL_TREE)
1721 && TREE_PUBLIC (dest_decl)))
1724 for (; args != NULL_TREE; args = TREE_CHAIN (args))
1726 if (((arg = TREE_VALUE (args)) != NULL_TREE)
1727 && ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1728 arg, NULL, scalar_args))
1735 /* Build a string for a variable name as used by NAMELIST. This means that
1736 if we're using the f2c library, we build an uppercase string, since
1740 ffecom_build_f2c_string_ (int i, const char *s)
1742 if (!ffe_is_f2c_library ())
1743 return build_string (i, s);
1752 if (((size_t) i) > ARRAY_SIZE (space))
1753 tmp = malloc_new_ks (malloc_pool_image (), "f2c_string", i);
1757 for (p = s, q = tmp; *p != '\0'; ++p, ++q)
1761 t = build_string (i, tmp);
1763 if (((size_t) i) > ARRAY_SIZE (space))
1764 malloc_kill_ks (malloc_pool_image (), tmp, i);
1770 /* Returns CALL_EXPR or equivalent with given type (pass NULL_TREE for
1771 type to just get whatever the function returns), handling the
1772 f2c value-returning convention, if required, by prepending
1773 to the arglist a pointer to a temporary to receive the return value. */
1776 ffecom_call_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex,
1777 tree type, tree args, tree dest_tree,
1778 ffebld dest, bool *dest_used, tree callee_commons,
1779 bool scalar_args, tree hook)
1784 if (dest_used != NULL)
1789 if ((dest_used == NULL)
1791 || (ffeinfo_basictype (ffebld_info (dest))
1792 != FFEINFO_basictypeCOMPLEX)
1793 || (ffeinfo_kindtype (ffebld_info (dest)) != kt)
1794 || ((type != NULL_TREE) && (TREE_TYPE (dest_tree) != type))
1795 || ffecom_args_overlapping_ (dest_tree, dest, args,
1800 tempvar = ffecom_make_tempvar (ffecom_tree_type
1801 [FFEINFO_basictypeCOMPLEX][kt],
1802 FFETARGET_charactersizeNONE,
1812 tempvar = dest_tree;
1817 = build_tree_list (NULL_TREE,
1818 ffecom_1 (ADDR_EXPR,
1819 build_pointer_type (TREE_TYPE (tempvar)),
1821 TREE_CHAIN (item) = args;
1823 item = ffecom_3s (CALL_EXPR, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), fn,
1826 if (tempvar != dest_tree)
1827 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), item, tempvar);
1830 item = ffecom_3s (CALL_EXPR, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), fn,
1833 if ((type != NULL_TREE) && (TREE_TYPE (item) != type))
1834 item = ffecom_convert_narrow_ (type, item);
1839 /* Given two arguments, transform them and make a call to the given
1840 function via ffecom_call_. */
1843 ffecom_call_binop_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex,
1844 tree type, ffebld left, ffebld right,
1845 tree dest_tree, ffebld dest, bool *dest_used,
1846 tree callee_commons, bool scalar_args, bool ref, tree hook)
1855 /* Pass arguments by reference. */
1856 left_tree = ffecom_arg_ptr_to_expr (left, &left_length);
1857 right_tree = ffecom_arg_ptr_to_expr (right, &right_length);
1861 /* Pass arguments by value. */
1862 left_tree = ffecom_arg_expr (left, &left_length);
1863 right_tree = ffecom_arg_expr (right, &right_length);
1867 left_tree = build_tree_list (NULL_TREE, left_tree);
1868 right_tree = build_tree_list (NULL_TREE, right_tree);
1869 TREE_CHAIN (left_tree) = right_tree;
1871 if (left_length != NULL_TREE)
1873 left_length = build_tree_list (NULL_TREE, left_length);
1874 TREE_CHAIN (right_tree) = left_length;
1877 if (right_length != NULL_TREE)
1879 right_length = build_tree_list (NULL_TREE, right_length);
1880 if (left_length != NULL_TREE)
1881 TREE_CHAIN (left_length) = right_length;
1883 TREE_CHAIN (right_tree) = right_length;
1886 return ffecom_call_ (fn, kt, is_f2c_complex, type, left_tree,
1887 dest_tree, dest, dest_used, callee_commons,
1891 /* Return ptr/length args for char subexpression
1893 Handles CHARACTER-type CONTER, SYMTER, SUBSTR, ARRAYREF, and FUNCREF
1894 subexpressions by constructing the appropriate trees for the ptr-to-
1895 character-text and length-of-character-text arguments in a calling
1898 Note that if with_null is TRUE, and the expression is an opCONTER,
1899 a null byte is appended to the string. */
1902 ffecom_char_args_x_ (tree *xitem, tree *length, ffebld expr, bool with_null)
1906 ffetargetCharacter1 val;
1907 ffetargetCharacterSize newlen;
1909 switch (ffebld_op (expr))
1911 case FFEBLD_opCONTER:
1912 val = ffebld_constant_character1 (ffebld_conter (expr));
1913 newlen = ffetarget_length_character1 (val);
1916 /* Begin FFETARGET-NULL-KLUDGE. */
1920 *length = build_int_2 (newlen, 0);
1921 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
1922 high = build_int_2 (newlen, 0);
1923 TREE_TYPE (high) = ffecom_f2c_ftnlen_type_node;
1924 item = build_string (newlen,
1925 ffetarget_text_character1 (val));
1926 /* End FFETARGET-NULL-KLUDGE. */
1928 = build_type_variant
1932 (ffecom_f2c_ftnlen_type_node,
1933 ffecom_f2c_ftnlen_one_node,
1936 TREE_CONSTANT (item) = 1;
1937 TREE_STATIC (item) = 1;
1938 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
1942 case FFEBLD_opSYMTER:
1944 ffesymbol s = ffebld_symter (expr);
1946 item = ffesymbol_hook (s).decl_tree;
1947 if (item == NULL_TREE)
1949 s = ffecom_sym_transform_ (s);
1950 item = ffesymbol_hook (s).decl_tree;
1952 if (ffesymbol_kind (s) == FFEINFO_kindENTITY)
1954 if (ffesymbol_size (s) == FFETARGET_charactersizeNONE)
1955 *length = ffesymbol_hook (s).length_tree;
1958 *length = build_int_2 (ffesymbol_size (s), 0);
1959 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
1962 else if (item == error_mark_node)
1963 *length = error_mark_node;
1965 /* FFEINFO_kindFUNCTION. */
1966 *length = NULL_TREE;
1967 if (!ffesymbol_hook (s).addr
1968 && (item != error_mark_node))
1969 item = ffecom_1 (ADDR_EXPR,
1970 build_pointer_type (TREE_TYPE (item)),
1975 case FFEBLD_opARRAYREF:
1977 ffecom_char_args_ (&item, length, ffebld_left (expr));
1979 if (item == error_mark_node || *length == error_mark_node)
1981 item = *length = error_mark_node;
1985 item = ffecom_arrayref_ (item, expr, 1);
1989 case FFEBLD_opSUBSTR:
1993 ffebld thing = ffebld_right (expr);
1996 const char *char_name;
2000 assert (ffebld_op (thing) == FFEBLD_opITEM);
2001 start = ffebld_head (thing);
2002 thing = ffebld_trail (thing);
2003 assert (ffebld_trail (thing) == NULL);
2004 end = ffebld_head (thing);
2006 /* Determine name for pretty-printing range-check errors. */
2007 for (left_symter = ffebld_left (expr);
2008 left_symter && ffebld_op (left_symter) == FFEBLD_opARRAYREF;
2009 left_symter = ffebld_left (left_symter))
2011 if (ffebld_op (left_symter) == FFEBLD_opSYMTER)
2012 char_name = ffesymbol_text (ffebld_symter (left_symter));
2014 char_name = "[expr?]";
2016 ffecom_char_args_ (&item, length, ffebld_left (expr));
2018 if (item == error_mark_node || *length == error_mark_node)
2020 item = *length = error_mark_node;
2024 array = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item)));
2026 /* ~~~~Handle INTEGER*8 start/end, a la FFEBLD_opARRAYREF. */
2034 end_tree = ffecom_expr (end);
2035 if (flag_bounds_check)
2036 end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0,
2038 end_tree = convert (ffecom_f2c_ftnlen_type_node,
2041 if (end_tree == error_mark_node)
2043 item = *length = error_mark_node;
2052 start_tree = ffecom_expr (start);
2053 if (flag_bounds_check)
2054 start_tree = ffecom_subscript_check_ (array, start_tree, 0, 0,
2056 start_tree = convert (ffecom_f2c_ftnlen_type_node,
2059 if (start_tree == error_mark_node)
2061 item = *length = error_mark_node;
2065 start_tree = ffecom_save_tree (start_tree);
2067 item = ffecom_2 (PLUS_EXPR, TREE_TYPE (item),
2069 ffecom_2 (MINUS_EXPR,
2070 TREE_TYPE (start_tree),
2072 ffecom_f2c_ftnlen_one_node));
2076 *length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
2077 ffecom_f2c_ftnlen_one_node,
2078 ffecom_2 (MINUS_EXPR,
2079 ffecom_f2c_ftnlen_type_node,
2085 end_tree = ffecom_expr (end);
2086 if (flag_bounds_check)
2087 end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0,
2089 end_tree = convert (ffecom_f2c_ftnlen_type_node,
2092 if (end_tree == error_mark_node)
2094 item = *length = error_mark_node;
2098 *length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
2099 ffecom_f2c_ftnlen_one_node,
2100 ffecom_2 (MINUS_EXPR,
2101 ffecom_f2c_ftnlen_type_node,
2102 end_tree, start_tree));
2108 case FFEBLD_opFUNCREF:
2110 ffesymbol s = ffebld_symter (ffebld_left (expr));
2113 ffetargetCharacterSize size = ffeinfo_size (ffebld_info (expr));
2116 if (size == FFETARGET_charactersizeNONE)
2117 /* ~~Kludge alert! This should someday be fixed. */
2120 *length = build_int_2 (size, 0);
2121 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
2123 if (ffeinfo_where (ffebld_info (ffebld_left (expr)))
2124 == FFEINFO_whereINTRINSIC)
2128 /* Invocation of an intrinsic returning CHARACTER*1. */
2129 item = ffecom_expr_intrinsic_ (expr, NULL_TREE,
2133 ix = ffeintrin_gfrt_direct (ffebld_symter_implementation (ffebld_left (expr)));
2134 assert (ix != FFECOM_gfrt);
2135 item = ffecom_gfrt_tree_ (ix);
2140 item = ffesymbol_hook (s).decl_tree;
2141 if (item == NULL_TREE)
2143 s = ffecom_sym_transform_ (s);
2144 item = ffesymbol_hook (s).decl_tree;
2146 if (item == error_mark_node)
2148 item = *length = error_mark_node;
2152 if (!ffesymbol_hook (s).addr)
2153 item = ffecom_1_fn (item);
2157 tempvar = ffecom_push_tempvar (char_type_node, size, -1, TRUE);
2159 tempvar = ffebld_nonter_hook (expr);
2162 tempvar = ffecom_1 (ADDR_EXPR,
2163 build_pointer_type (TREE_TYPE (tempvar)),
2166 args = build_tree_list (NULL_TREE, tempvar);
2168 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT) /* Sfunc args by value. */
2169 TREE_CHAIN (args) = ffecom_list_expr (ffebld_right (expr));
2172 TREE_CHAIN (args) = build_tree_list (NULL_TREE, *length);
2173 if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC)
2175 TREE_CHAIN (TREE_CHAIN (args))
2176 = ffecom_arglist_expr_ (ffecom_gfrt_args_ (ix),
2177 ffebld_right (expr));
2181 TREE_CHAIN (TREE_CHAIN (args))
2182 = ffecom_list_ptr_to_expr (ffebld_right (expr));
2186 item = ffecom_3s (CALL_EXPR,
2187 TREE_TYPE (TREE_TYPE (TREE_TYPE (item))),
2188 item, args, NULL_TREE);
2189 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), item,
2194 case FFEBLD_opCONVERT:
2196 ffecom_char_args_ (&item, length, ffebld_left (expr));
2198 if (item == error_mark_node || *length == error_mark_node)
2200 item = *length = error_mark_node;
2204 if ((ffebld_size_known (ffebld_left (expr))
2205 == FFETARGET_charactersizeNONE)
2206 || (ffebld_size_known (ffebld_left (expr)) < (ffebld_size (expr))))
2207 { /* Possible blank-padding needed, copy into
2214 tempvar = ffecom_make_tempvar (char_type_node,
2215 ffebld_size (expr), -1);
2217 tempvar = ffebld_nonter_hook (expr);
2220 tempvar = ffecom_1 (ADDR_EXPR,
2221 build_pointer_type (TREE_TYPE (tempvar)),
2224 newlen = build_int_2 (ffebld_size (expr), 0);
2225 TREE_TYPE (newlen) = ffecom_f2c_ftnlen_type_node;
2227 args = build_tree_list (NULL_TREE, tempvar);
2228 TREE_CHAIN (args) = build_tree_list (NULL_TREE, item);
2229 TREE_CHAIN (TREE_CHAIN (args)) = build_tree_list (NULL_TREE, newlen);
2230 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (args)))
2231 = build_tree_list (NULL_TREE, *length);
2233 item = ffecom_call_gfrt (FFECOM_gfrtCOPY, args, NULL_TREE);
2234 TREE_SIDE_EFFECTS (item) = 1;
2235 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), fold (item),
2240 { /* Just truncate the length. */
2241 *length = build_int_2 (ffebld_size (expr), 0);
2242 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
2247 assert ("bad op for single char arg expr" == NULL);
2255 /* Check the size of the type to be sure it doesn't overflow the
2256 "portable" capacities of the compiler back end. `dummy' types
2257 can generally overflow the normal sizes as long as the computations
2258 themselves don't overflow. A particular target of the back end
2259 must still enforce its size requirements, though, and the back
2260 end takes care of this in stor-layout.c. */
2263 ffecom_check_size_overflow_ (ffesymbol s, tree type, bool dummy)
2265 if (TREE_CODE (type) == ERROR_MARK)
2268 if (TYPE_SIZE (type) == NULL_TREE)
2271 if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
2274 /* An array is too large if size is negative or the type_size overflows
2275 or its "upper half" is larger than 3 (which would make the signed
2276 byte size and offset computations overflow). */
2278 if ((tree_int_cst_sgn (TYPE_SIZE (type)) < 0)
2279 || (!dummy && (TREE_INT_CST_HIGH (TYPE_SIZE (type)) > 3
2280 || TREE_OVERFLOW (TYPE_SIZE (type)))))
2282 ffebad_start (FFEBAD_ARRAY_LARGE);
2283 ffebad_string (ffesymbol_text (s));
2284 ffebad_here (0, ffesymbol_where_line (s), ffesymbol_where_column (s));
2287 return error_mark_node;
2293 /* Builds a length argument (PARM_DECL). Also wraps type in an array type
2294 where the dimension info is (1:size) where <size> is ffesymbol_size(s) if
2295 known, length_arg if not known (FFETARGET_charactersizeNONE). */
2298 ffecom_char_enhance_arg_ (tree *xtype, ffesymbol s)
2300 ffetargetCharacterSize sz = ffesymbol_size (s);
2305 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT)
2306 tlen = NULL_TREE; /* A statement function, no length passed. */
2309 if (ffesymbol_where (s) == FFEINFO_whereDUMMY)
2310 tlen = ffecom_get_invented_identifier ("__g77_length_%s",
2311 ffesymbol_text (s));
2313 tlen = ffecom_get_invented_identifier ("__g77_%s", "length");
2314 tlen = build_decl (PARM_DECL, tlen, ffecom_f2c_ftnlen_type_node);
2315 DECL_ARTIFICIAL (tlen) = 1;
2318 if (sz == FFETARGET_charactersizeNONE)
2320 assert (tlen != NULL_TREE);
2321 highval = variable_size (tlen);
2325 highval = build_int_2 (sz, 0);
2326 TREE_TYPE (highval) = ffecom_f2c_ftnlen_type_node;
2329 type = build_array_type (type,
2330 build_range_type (ffecom_f2c_ftnlen_type_node,
2331 ffecom_f2c_ftnlen_one_node,
2338 /* ffecom_concat_list_gather_ -- Gather list of concatenated string exprs
2340 ffecomConcatList_ catlist;
2341 ffebld expr; // expr of CHARACTER basictype.
2342 ffetargetCharacterSize max; // max chars to gather or _...NONE if no max
2343 catlist = ffecom_concat_list_gather_(catlist,expr,max);
2345 Scans expr for character subexpressions, updates and returns catlist
2348 static ffecomConcatList_
2349 ffecom_concat_list_gather_ (ffecomConcatList_ catlist, ffebld expr,
2350 ffetargetCharacterSize max)
2352 ffetargetCharacterSize sz;
2359 if ((max != FFETARGET_charactersizeNONE) && (catlist.minlen >= max))
2360 return catlist; /* Don't append any more items. */
2362 switch (ffebld_op (expr))
2364 case FFEBLD_opCONTER:
2365 case FFEBLD_opSYMTER:
2366 case FFEBLD_opARRAYREF:
2367 case FFEBLD_opFUNCREF:
2368 case FFEBLD_opSUBSTR:
2369 case FFEBLD_opCONVERT: /* Callers should strip this off beforehand
2370 if they don't need to preserve it. */
2371 if (catlist.count == catlist.max)
2372 { /* Make a (larger) list. */
2376 newmax = (catlist.max == 0) ? 8 : catlist.max * 2;
2377 newx = malloc_new_ks (malloc_pool_image (), "catlist",
2378 newmax * sizeof (newx[0]));
2379 if (catlist.max != 0)
2381 memcpy (newx, catlist.exprs, catlist.max * sizeof (newx[0]));
2382 malloc_kill_ks (malloc_pool_image (), catlist.exprs,
2383 catlist.max * sizeof (newx[0]));
2385 catlist.max = newmax;
2386 catlist.exprs = newx;
2388 if ((sz = ffebld_size_known (expr)) != FFETARGET_charactersizeNONE)
2389 catlist.minlen += sz;
2391 ++catlist.minlen; /* Not true for F90; can be 0 length. */
2392 if ((sz = ffebld_size_max (expr)) == FFETARGET_charactersizeNONE)
2393 catlist.maxlen = sz;
2395 catlist.maxlen += sz;
2396 if ((max != FFETARGET_charactersizeNONE) && (catlist.minlen > max))
2397 { /* This item overlaps (or is beyond) the end
2398 of the destination. */
2399 switch (ffebld_op (expr))
2401 case FFEBLD_opCONTER:
2402 case FFEBLD_opSYMTER:
2403 case FFEBLD_opARRAYREF:
2404 case FFEBLD_opFUNCREF:
2405 case FFEBLD_opSUBSTR:
2406 /* ~~Do useful truncations here. */
2410 assert ("op changed or inconsistent switches!" == NULL);
2414 catlist.exprs[catlist.count++] = expr;
2417 case FFEBLD_opPAREN:
2418 expr = ffebld_left (expr);
2419 goto recurse; /* :::::::::::::::::::: */
2421 case FFEBLD_opCONCATENATE:
2422 catlist = ffecom_concat_list_gather_ (catlist, ffebld_left (expr), max);
2423 expr = ffebld_right (expr);
2424 goto recurse; /* :::::::::::::::::::: */
2426 #if 0 /* Breaks passing small actual arg to larger
2427 dummy arg of sfunc */
2428 case FFEBLD_opCONVERT:
2429 expr = ffebld_left (expr);
2431 ffetargetCharacterSize cmax;
2433 cmax = catlist.len + ffebld_size_known (expr);
2435 if ((max == FFETARGET_charactersizeNONE) || (max > cmax))
2438 goto recurse; /* :::::::::::::::::::: */
2445 assert ("bad op in _gather_" == NULL);
2450 /* ffecom_concat_list_kill_ -- Kill list of concatenated string exprs
2452 ffecomConcatList_ catlist;
2453 ffecom_concat_list_kill_(catlist);
2455 Anything allocated within the list info is deallocated. */
2458 ffecom_concat_list_kill_ (ffecomConcatList_ catlist)
2460 if (catlist.max != 0)
2461 malloc_kill_ks (malloc_pool_image (), catlist.exprs,
2462 catlist.max * sizeof (catlist.exprs[0]));
2465 /* Make list of concatenated string exprs.
2467 Returns a flattened list of concatenated subexpressions given a
2468 tree of such expressions. */
2470 static ffecomConcatList_
2471 ffecom_concat_list_new_ (ffebld expr, ffetargetCharacterSize max)
2473 ffecomConcatList_ catlist;
2475 catlist.maxlen = catlist.minlen = catlist.max = catlist.count = 0;
2476 return ffecom_concat_list_gather_ (catlist, expr, max);
2479 /* Provide some kind of useful info on member of aggregate area,
2480 since current g77/gcc technology does not provide debug info
2481 on these members. */
2484 ffecom_debug_kludge_ (tree aggr, const char *aggr_type, ffesymbol member,
2485 tree member_type UNUSED, ffetargetOffset offset)
2495 for (type_id = member_type;
2496 TREE_CODE (type_id) != IDENTIFIER_NODE;
2499 switch (TREE_CODE (type_id))
2503 type_id = TYPE_NAME (type_id);
2508 type_id = TREE_TYPE (type_id);
2512 assert ("no IDENTIFIER_NODE for type!" == NULL);
2513 type_id = error_mark_node;
2519 if (ffecom_transform_only_dummies_
2520 || !ffe_is_debug_kludge ())
2521 return; /* Can't do this yet, maybe later. */
2524 + strlen (aggr_type)
2525 + IDENTIFIER_LENGTH (DECL_NAME (aggr));
2527 + IDENTIFIER_LENGTH (type_id);
2530 if (((size_t) len) >= ARRAY_SIZE (space))
2531 buff = malloc_new_ks (malloc_pool_image (), "debug_kludge", len + 1);
2535 sprintf (&buff[0], "At (%s) `%s' plus %ld bytes",
2537 IDENTIFIER_POINTER (DECL_NAME (aggr)),
2540 value = build_string (len, buff);
2542 = build_type_variant (build_array_type (char_type_node,
2546 build_int_2 (strlen (buff), 0))),
2548 decl = build_decl (VAR_DECL,
2549 ffecom_get_identifier_ (ffesymbol_text (member)),
2551 TREE_CONSTANT (decl) = 1;
2552 TREE_STATIC (decl) = 1;
2553 DECL_INITIAL (decl) = error_mark_node;
2554 DECL_IN_SYSTEM_HEADER (decl) = 1; /* Don't let -Wunused complain. */
2555 decl = start_decl (decl, FALSE);
2556 finish_decl (decl, value, FALSE);
2558 if (buff != &space[0])
2559 malloc_kill_ks (malloc_pool_image (), buff, len + 1);
2562 /* ffecom_do_entry_ -- Do compilation of a particular entrypoint
2564 ffesymbol fn; // the SUBROUTINE, FUNCTION, or ENTRY symbol itself
2565 int i; // entry# for this entrypoint (used by master fn)
2566 ffecom_do_entrypoint_(s,i);
2568 Makes a public entry point that calls our private master fn (already
2572 ffecom_do_entry_ (ffesymbol fn, int entrynum)
2575 tree type; /* Type of function. */
2576 tree multi_retval; /* Var holding return value (union). */
2577 tree result; /* Var holding result. */
2578 ffeinfoBasictype bt;
2582 bool charfunc; /* All entry points return same type
2584 bool cmplxfunc; /* Use f2c way of returning COMPLEX. */
2585 bool multi; /* Master fn has multiple return types. */
2586 bool altreturning = FALSE; /* This entry point has alternate returns. */
2587 int old_lineno = lineno;
2588 const char *old_input_filename = input_filename;
2590 input_filename = ffesymbol_where_filename (fn);
2591 lineno = ffesymbol_where_filelinenum (fn);
2593 ffecom_doing_entry_ = TRUE; /* Don't bother with array dimensions. */
2595 switch (ffecom_primary_entry_kind_)
2597 case FFEINFO_kindFUNCTION:
2599 /* Determine actual return type for function. */
2601 gt = FFEGLOBAL_typeFUNC;
2602 bt = ffesymbol_basictype (fn);
2603 kt = ffesymbol_kindtype (fn);
2604 if (bt == FFEINFO_basictypeNONE)
2606 ffeimplic_establish_symbol (fn);
2607 if (ffesymbol_funcresult (fn) != NULL)
2608 ffeimplic_establish_symbol (ffesymbol_funcresult (fn));
2609 bt = ffesymbol_basictype (fn);
2610 kt = ffesymbol_kindtype (fn);
2613 if (bt == FFEINFO_basictypeCHARACTER)
2614 charfunc = TRUE, cmplxfunc = FALSE;
2615 else if ((bt == FFEINFO_basictypeCOMPLEX)
2616 && ffesymbol_is_f2c (fn))
2617 charfunc = FALSE, cmplxfunc = TRUE;
2619 charfunc = cmplxfunc = FALSE;
2622 type = ffecom_tree_fun_type_void;
2623 else if (ffesymbol_is_f2c (fn))
2624 type = ffecom_tree_fun_type[bt][kt];
2626 type = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
2628 if ((type == NULL_TREE)
2629 || (TREE_TYPE (type) == NULL_TREE))
2630 type = ffecom_tree_fun_type_void; /* _sym_exec_transition. */
2632 multi = (ffecom_master_bt_ == FFEINFO_basictypeNONE);
2635 case FFEINFO_kindSUBROUTINE:
2636 gt = FFEGLOBAL_typeSUBR;
2637 bt = FFEINFO_basictypeNONE;
2638 kt = FFEINFO_kindtypeNONE;
2639 if (ffecom_is_altreturning_)
2640 { /* Am _I_ altreturning? */
2641 for (item = ffesymbol_dummyargs (fn);
2643 item = ffebld_trail (item))
2645 if (ffebld_op (ffebld_head (item)) == FFEBLD_opSTAR)
2647 altreturning = TRUE;
2652 type = ffecom_tree_subr_type;
2654 type = ffecom_tree_fun_type_void;
2657 type = ffecom_tree_fun_type_void;
2664 assert ("say what??" == NULL);
2666 case FFEINFO_kindANY:
2667 gt = FFEGLOBAL_typeANY;
2668 bt = FFEINFO_basictypeNONE;
2669 kt = FFEINFO_kindtypeNONE;
2670 type = error_mark_node;
2677 /* build_decl uses the current lineno and input_filename to set the decl
2678 source info. So, I've putzed with ffestd and ffeste code to update that
2679 source info to point to the appropriate statement just before calling
2680 ffecom_do_entrypoint (which calls this fn). */
2682 start_function (ffecom_get_external_identifier_ (fn),
2684 0, /* nested/inline */
2685 1); /* TREE_PUBLIC */
2687 if (((g = ffesymbol_global (fn)) != NULL)
2688 && ((ffeglobal_type (g) == gt)
2689 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
2691 ffeglobal_set_hook (g, current_function_decl);
2694 /* Reset args in master arg list so they get retransitioned. */
2696 for (item = ffecom_master_arglist_;
2698 item = ffebld_trail (item))
2703 arg = ffebld_head (item);
2704 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2705 continue; /* Alternate return or some such thing. */
2706 s = ffebld_symter (arg);
2707 ffesymbol_hook (s).decl_tree = NULL_TREE;
2708 ffesymbol_hook (s).length_tree = NULL_TREE;
2711 /* Build dummy arg list for this entry point. */
2713 if (charfunc || cmplxfunc)
2714 { /* Prepend arg for where result goes. */
2719 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
2721 type = ffecom_tree_type[FFEINFO_basictypeCOMPLEX][kt];
2723 result = ffecom_get_invented_identifier ("__g77_%s", "result");
2725 /* Make length arg _and_ enhance type info for CHAR arg itself. */
2728 length = ffecom_char_enhance_arg_ (&type, fn);
2730 length = NULL_TREE; /* Not ref'd if !charfunc. */
2732 type = build_pointer_type (type);
2733 result = build_decl (PARM_DECL, result, type);
2735 push_parm_decl (result);
2736 ffecom_func_result_ = result;
2740 push_parm_decl (length);
2741 ffecom_func_length_ = length;
2745 result = DECL_RESULT (current_function_decl);
2747 ffecom_push_dummy_decls_ (ffesymbol_dummyargs (fn), FALSE);
2749 store_parm_decls (0);
2751 ffecom_start_compstmt ();
2752 /* Disallow temp vars at this level. */
2753 current_binding_level->prep_state = 2;
2755 /* Make local var to hold return type for multi-type master fn. */
2759 multi_retval = ffecom_get_invented_identifier ("__g77_%s",
2761 multi_retval = build_decl (VAR_DECL, multi_retval,
2762 ffecom_multi_type_node_);
2763 multi_retval = start_decl (multi_retval, FALSE);
2764 finish_decl (multi_retval, NULL_TREE, FALSE);
2767 multi_retval = NULL_TREE; /* Not actually ref'd if !multi. */
2769 /* Here we emit the actual code for the entry point. */
2775 tree arglist = NULL_TREE;
2776 tree *plist = &arglist;
2782 /* Prepare actual arg list based on master arg list. */
2784 for (list = ffecom_master_arglist_;
2786 list = ffebld_trail (list))
2788 arg = ffebld_head (list);
2789 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2791 s = ffebld_symter (arg);
2792 if (ffesymbol_hook (s).decl_tree == NULL_TREE
2793 || ffesymbol_hook (s).decl_tree == error_mark_node)
2794 actarg = null_pointer_node; /* We don't have this arg. */
2796 actarg = ffesymbol_hook (s).decl_tree;
2797 *plist = build_tree_list (NULL_TREE, actarg);
2798 plist = &TREE_CHAIN (*plist);
2801 /* This code appends the length arguments for character
2802 variables/arrays. */
2804 for (list = ffecom_master_arglist_;
2806 list = ffebld_trail (list))
2808 arg = ffebld_head (list);
2809 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2811 s = ffebld_symter (arg);
2812 if (ffesymbol_basictype (s) != FFEINFO_basictypeCHARACTER)
2813 continue; /* Only looking for CHARACTER arguments. */
2814 if (ffesymbol_kind (s) != FFEINFO_kindENTITY)
2815 continue; /* Only looking for variables and arrays. */
2816 if (ffesymbol_hook (s).length_tree == NULL_TREE
2817 || ffesymbol_hook (s).length_tree == error_mark_node)
2818 actarg = ffecom_f2c_ftnlen_zero_node; /* We don't have this arg. */
2820 actarg = ffesymbol_hook (s).length_tree;
2821 *plist = build_tree_list (NULL_TREE, actarg);
2822 plist = &TREE_CHAIN (*plist);
2825 /* Prepend character-value return info to actual arg list. */
2829 prepend = build_tree_list (NULL_TREE, ffecom_func_result_);
2830 TREE_CHAIN (prepend)
2831 = build_tree_list (NULL_TREE, ffecom_func_length_);
2832 TREE_CHAIN (TREE_CHAIN (prepend)) = arglist;
2836 /* Prepend multi-type return value to actual arg list. */
2841 = build_tree_list (NULL_TREE,
2842 ffecom_1 (ADDR_EXPR,
2843 build_pointer_type (TREE_TYPE (multi_retval)),
2845 TREE_CHAIN (prepend) = arglist;
2849 /* Prepend my entry-point number to the actual arg list. */
2851 prepend = build_tree_list (NULL_TREE, build_int_2 (entrynum, 0));
2852 TREE_CHAIN (prepend) = arglist;
2855 /* Build the call to the master function. */
2857 master_fn = ffecom_1_fn (ffecom_previous_function_decl_);
2858 call = ffecom_3s (CALL_EXPR,
2859 TREE_TYPE (TREE_TYPE (TREE_TYPE (master_fn))),
2860 master_fn, arglist, NULL_TREE);
2862 /* Decide whether the master function is a function or subroutine, and
2863 handle the return value for my entry point. */
2865 if (charfunc || ((ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE)
2868 expand_expr_stmt (call);
2869 expand_null_return ();
2871 else if (multi && cmplxfunc)
2873 expand_expr_stmt (call);
2875 = ffecom_1 (INDIRECT_REF,
2876 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result))),
2878 result = ffecom_modify (NULL_TREE, result,
2879 ffecom_2 (COMPONENT_REF, TREE_TYPE (result),
2881 ffecom_multi_fields_[bt][kt]));
2882 expand_expr_stmt (result);
2883 expand_null_return ();
2887 expand_expr_stmt (call);
2889 = ffecom_modify (NULL_TREE, result,
2890 convert (TREE_TYPE (result),
2891 ffecom_2 (COMPONENT_REF,
2892 ffecom_tree_type[bt][kt],
2894 ffecom_multi_fields_[bt][kt])));
2895 expand_return (result);
2900 = ffecom_1 (INDIRECT_REF,
2901 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result))),
2903 result = ffecom_modify (NULL_TREE, result, call);
2904 expand_expr_stmt (result);
2905 expand_null_return ();
2909 result = ffecom_modify (NULL_TREE,
2911 convert (TREE_TYPE (result),
2913 expand_return (result);
2917 ffecom_end_compstmt ();
2919 finish_function (0);
2921 lineno = old_lineno;
2922 input_filename = old_input_filename;
2924 ffecom_doing_entry_ = FALSE;
2927 /* Transform expr into gcc tree with possible destination
2929 Recursive descent on expr while making corresponding tree nodes and
2930 attaching type info and such. If destination supplied and compatible
2931 with temporary that would be made in certain cases, temporary isn't
2932 made, destination used instead, and dest_used flag set TRUE. */
2935 ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest,
2936 bool *dest_used, bool assignp, bool widenp)
2941 ffeinfoBasictype bt;
2944 tree dt; /* decl_tree for an ffesymbol. */
2945 tree tree_type, tree_type_x;
2948 enum tree_code code;
2950 assert (expr != NULL);
2952 if (dest_used != NULL)
2955 bt = ffeinfo_basictype (ffebld_info (expr));
2956 kt = ffeinfo_kindtype (ffebld_info (expr));
2957 tree_type = ffecom_tree_type[bt][kt];
2959 /* Widen integral arithmetic as desired while preserving signedness. */
2960 tree_type_x = NULL_TREE;
2961 if (widenp && tree_type
2962 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
2963 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
2964 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
2966 switch (ffebld_op (expr))
2968 case FFEBLD_opACCTER:
2971 ffebit bits = ffebld_accter_bits (expr);
2972 ffetargetOffset source_offset = 0;
2973 ffetargetOffset dest_offset = ffebld_accter_pad (expr);
2976 assert (dest_offset == 0
2977 || (bt == FFEINFO_basictypeCHARACTER
2978 && kt == FFEINFO_kindtypeCHARACTER1));
2983 ffebldConstantUnion cu;
2986 ffebldConstantArray ca = ffebld_accter (expr);
2988 ffebit_test (bits, source_offset, &value, &length);
2994 for (i = 0; i < length; ++i)
2996 cu = ffebld_constantarray_get (ca, bt, kt,
2999 t = ffecom_constantunion (&cu, bt, kt, tree_type);
3002 && dest_offset != 0)
3003 purpose = build_int_2 (dest_offset, 0);
3005 purpose = NULL_TREE;
3007 if (list == NULL_TREE)
3008 list = item = build_tree_list (purpose, t);
3011 TREE_CHAIN (item) = build_tree_list (purpose, t);
3012 item = TREE_CHAIN (item);
3016 source_offset += length;
3017 dest_offset += length;
3021 item = build_int_2 ((ffebld_accter_size (expr)
3022 + ffebld_accter_pad (expr)) - 1, 0);
3023 ffebit_kill (ffebld_accter_bits (expr));
3024 TREE_TYPE (item) = ffecom_integer_type_node;
3028 build_range_type (ffecom_integer_type_node,
3029 ffecom_integer_zero_node,
3031 list = build (CONSTRUCTOR, item, NULL_TREE, list);
3032 TREE_CONSTANT (list) = 1;
3033 TREE_STATIC (list) = 1;
3036 case FFEBLD_opARRTER:
3041 if (ffebld_arrter_pad (expr) == 0)
3045 assert (bt == FFEINFO_basictypeCHARACTER
3046 && kt == FFEINFO_kindtypeCHARACTER1);
3048 /* Becomes PURPOSE first time through loop. */
3049 item = build_int_2 (ffebld_arrter_pad (expr), 0);
3052 for (i = 0; i < ffebld_arrter_size (expr); ++i)
3054 ffebldConstantUnion cu
3055 = ffebld_constantarray_get (ffebld_arrter (expr), bt, kt, i);
3057 t = ffecom_constantunion (&cu, bt, kt, tree_type);
3059 if (list == NULL_TREE)
3060 /* Assume item is PURPOSE first time through loop. */
3061 list = item = build_tree_list (item, t);
3064 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
3065 item = TREE_CHAIN (item);
3070 item = build_int_2 ((ffebld_arrter_size (expr)
3071 + ffebld_arrter_pad (expr)) - 1, 0);
3072 TREE_TYPE (item) = ffecom_integer_type_node;
3076 build_range_type (ffecom_integer_type_node,
3077 ffecom_integer_zero_node,
3079 list = build (CONSTRUCTOR, item, NULL_TREE, list);
3080 TREE_CONSTANT (list) = 1;
3081 TREE_STATIC (list) = 1;
3084 case FFEBLD_opCONTER:
3085 assert (ffebld_conter_pad (expr) == 0);
3087 = ffecom_constantunion (&ffebld_constant_union (ffebld_conter (expr)),
3091 case FFEBLD_opSYMTER:
3092 if ((ffebld_symter_generic (expr) != FFEINTRIN_genNONE)
3093 || (ffebld_symter_specific (expr) != FFEINTRIN_specNONE))
3094 return ffecom_ptr_to_expr (expr); /* Same as %REF(intrinsic). */
3095 s = ffebld_symter (expr);
3096 t = ffesymbol_hook (s).decl_tree;
3099 { /* ASSIGN'ed-label expr. */
3100 if (ffe_is_ugly_assign ())
3102 /* User explicitly wants ASSIGN'ed variables to be at the same
3103 memory address as the variables when used in non-ASSIGN
3104 contexts. That can make old, arcane, non-standard code
3105 work, but don't try to do it when a pointer wouldn't fit
3106 in the normal variable (take other approach, and warn,
3111 s = ffecom_sym_transform_ (s);
3112 t = ffesymbol_hook (s).decl_tree;
3113 assert (t != NULL_TREE);
3116 if (t == error_mark_node)
3119 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (t)))
3120 >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
3122 if (ffesymbol_hook (s).addr)
3123 t = ffecom_1 (INDIRECT_REF,
3124 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), t);
3128 if (ffesymbol_hook (s).assign_tree == NULL_TREE)
3130 /* xgettext:no-c-format */
3131 ffebad_start_msg ("ASSIGN'ed label cannot fit into `%A' at %0 -- using wider sibling",
3132 FFEBAD_severityWARNING);
3133 ffebad_string (ffesymbol_text (s));
3134 ffebad_here (0, ffesymbol_where_line (s),
3135 ffesymbol_where_column (s));
3140 /* Don't use the normal variable's tree for ASSIGN, though mark
3141 it as in the system header (housekeeping). Use an explicit,
3142 specially created sibling that is known to be wide enough
3143 to hold pointers to labels. */
3146 && TREE_CODE (t) == VAR_DECL)
3147 DECL_IN_SYSTEM_HEADER (t) = 1; /* Don't let -Wunused complain. */
3149 t = ffesymbol_hook (s).assign_tree;
3152 s = ffecom_sym_transform_assign_ (s);
3153 t = ffesymbol_hook (s).assign_tree;
3154 assert (t != NULL_TREE);
3161 s = ffecom_sym_transform_ (s);
3162 t = ffesymbol_hook (s).decl_tree;
3163 assert (t != NULL_TREE);
3165 if (ffesymbol_hook (s).addr)
3166 t = ffecom_1 (INDIRECT_REF,
3167 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), t);
3171 case FFEBLD_opARRAYREF:
3172 return ffecom_arrayref_ (NULL_TREE, expr, 0);
3174 case FFEBLD_opUPLUS:
3175 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3176 return ffecom_1 (NOP_EXPR, tree_type, left);
3178 case FFEBLD_opPAREN:
3179 /* ~~~Make sure Fortran rules respected here */
3180 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3181 return ffecom_1 (NOP_EXPR, tree_type, left);
3183 case FFEBLD_opUMINUS:
3184 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3187 tree_type = tree_type_x;
3188 left = convert (tree_type, left);
3190 return ffecom_1 (NEGATE_EXPR, tree_type, left);
3193 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3194 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
3197 tree_type = tree_type_x;
3198 left = convert (tree_type, left);
3199 right = convert (tree_type, right);
3201 return ffecom_2 (PLUS_EXPR, tree_type, left, right);
3203 case FFEBLD_opSUBTRACT:
3204 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3205 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
3208 tree_type = tree_type_x;
3209 left = convert (tree_type, left);
3210 right = convert (tree_type, right);
3212 return ffecom_2 (MINUS_EXPR, tree_type, left, right);
3214 case FFEBLD_opMULTIPLY:
3215 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3216 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
3219 tree_type = tree_type_x;
3220 left = convert (tree_type, left);
3221 right = convert (tree_type, right);
3223 return ffecom_2 (MULT_EXPR, tree_type, left, right);
3225 case FFEBLD_opDIVIDE:
3226 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3227 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
3230 tree_type = tree_type_x;
3231 left = convert (tree_type, left);
3232 right = convert (tree_type, right);
3234 return ffecom_tree_divide_ (tree_type, left, right,
3235 dest_tree, dest, dest_used,
3236 ffebld_nonter_hook (expr));
3238 case FFEBLD_opPOWER:
3240 ffebld left = ffebld_left (expr);
3241 ffebld right = ffebld_right (expr);
3243 ffeinfoKindtype rtkt;
3244 ffeinfoKindtype ltkt;
3247 switch (ffeinfo_basictype (ffebld_info (right)))
3250 case FFEINFO_basictypeINTEGER:
3253 item = ffecom_expr_power_integer_ (expr);
3254 if (item != NULL_TREE)
3258 rtkt = FFEINFO_kindtypeINTEGER1;
3259 switch (ffeinfo_basictype (ffebld_info (left)))
3261 case FFEINFO_basictypeINTEGER:
3262 if ((ffeinfo_kindtype (ffebld_info (left))
3263 == FFEINFO_kindtypeINTEGER4)
3264 || (ffeinfo_kindtype (ffebld_info (right))
3265 == FFEINFO_kindtypeINTEGER4))
3267 code = FFECOM_gfrtPOW_QQ;
3268 ltkt = FFEINFO_kindtypeINTEGER4;
3269 rtkt = FFEINFO_kindtypeINTEGER4;
3273 code = FFECOM_gfrtPOW_II;
3274 ltkt = FFEINFO_kindtypeINTEGER1;
3278 case FFEINFO_basictypeREAL:
3279 if (ffeinfo_kindtype (ffebld_info (left))
3280 == FFEINFO_kindtypeREAL1)
3282 code = FFECOM_gfrtPOW_RI;
3283 ltkt = FFEINFO_kindtypeREAL1;
3287 code = FFECOM_gfrtPOW_DI;
3288 ltkt = FFEINFO_kindtypeREAL2;
3292 case FFEINFO_basictypeCOMPLEX:
3293 if (ffeinfo_kindtype (ffebld_info (left))
3294 == FFEINFO_kindtypeREAL1)
3296 code = FFECOM_gfrtPOW_CI; /* Overlapping result okay. */
3297 ltkt = FFEINFO_kindtypeREAL1;
3301 code = FFECOM_gfrtPOW_ZI; /* Overlapping result okay. */
3302 ltkt = FFEINFO_kindtypeREAL2;
3307 assert ("bad pow_*i" == NULL);
3308 code = FFECOM_gfrtPOW_CI; /* Overlapping result okay. */
3309 ltkt = FFEINFO_kindtypeREAL1;
3312 if (ffeinfo_kindtype (ffebld_info (left)) != ltkt)
3313 left = ffeexpr_convert (left, NULL, NULL,
3314 ffeinfo_basictype (ffebld_info (left)),
3316 FFETARGET_charactersizeNONE,
3317 FFEEXPR_contextLET);
3318 if (ffeinfo_kindtype (ffebld_info (right)) != rtkt)
3319 right = ffeexpr_convert (right, NULL, NULL,
3320 FFEINFO_basictypeINTEGER,
3322 FFETARGET_charactersizeNONE,
3323 FFEEXPR_contextLET);
3326 case FFEINFO_basictypeREAL:
3327 if (ffeinfo_kindtype (ffebld_info (left)) == FFEINFO_kindtypeREAL1)
3328 left = ffeexpr_convert (left, NULL, NULL, FFEINFO_basictypeREAL,
3329 FFEINFO_kindtypeREALDOUBLE, 0,
3330 FFETARGET_charactersizeNONE,
3331 FFEEXPR_contextLET);
3332 if (ffeinfo_kindtype (ffebld_info (right))
3333 == FFEINFO_kindtypeREAL1)
3334 right = ffeexpr_convert (right, NULL, NULL,
3335 FFEINFO_basictypeREAL,
3336 FFEINFO_kindtypeREALDOUBLE, 0,
3337 FFETARGET_charactersizeNONE,
3338 FFEEXPR_contextLET);
3339 /* We used to call FFECOM_gfrtPOW_DD here,
3340 which passes arguments by reference. */
3341 code = FFECOM_gfrtL_POW;
3342 /* Pass arguments by value. */
3346 case FFEINFO_basictypeCOMPLEX:
3347 if (ffeinfo_kindtype (ffebld_info (left)) == FFEINFO_kindtypeREAL1)
3348 left = ffeexpr_convert (left, NULL, NULL,
3349 FFEINFO_basictypeCOMPLEX,
3350 FFEINFO_kindtypeREALDOUBLE, 0,
3351 FFETARGET_charactersizeNONE,
3352 FFEEXPR_contextLET);
3353 if (ffeinfo_kindtype (ffebld_info (right))
3354 == FFEINFO_kindtypeREAL1)
3355 right = ffeexpr_convert (right, NULL, NULL,
3356 FFEINFO_basictypeCOMPLEX,
3357 FFEINFO_kindtypeREALDOUBLE, 0,
3358 FFETARGET_charactersizeNONE,
3359 FFEEXPR_contextLET);
3360 code = FFECOM_gfrtPOW_ZZ; /* Overlapping result okay. */
3361 ref = TRUE; /* Pass arguments by reference. */
3365 assert ("bad pow_x*" == NULL);
3366 code = FFECOM_gfrtPOW_II;
3369 return ffecom_call_binop_ (ffecom_gfrt_tree_ (code),
3370 ffecom_gfrt_kindtype (code),
3371 (ffe_is_f2c_library ()
3372 && ffecom_gfrt_complex_[code]),
3373 tree_type, left, right,
3374 dest_tree, dest, dest_used,
3375 NULL_TREE, FALSE, ref,
3376 ffebld_nonter_hook (expr));
3382 case FFEINFO_basictypeLOGICAL:
3383 item = ffecom_truth_value_invert (ffecom_expr (ffebld_left (expr)));
3384 return convert (tree_type, item);
3386 case FFEINFO_basictypeINTEGER:
3387 return ffecom_1 (BIT_NOT_EXPR, tree_type,
3388 ffecom_expr (ffebld_left (expr)));
3391 assert ("NOT bad basictype" == NULL);
3393 case FFEINFO_basictypeANY:
3394 return error_mark_node;
3398 case FFEBLD_opFUNCREF:
3399 assert (ffeinfo_basictype (ffebld_info (expr))
3400 != FFEINFO_basictypeCHARACTER);
3402 case FFEBLD_opSUBRREF:
3403 if (ffeinfo_where (ffebld_info (ffebld_left (expr)))
3404 == FFEINFO_whereINTRINSIC)
3405 { /* Invocation of an intrinsic. */
3406 item = ffecom_expr_intrinsic_ (expr, dest_tree, dest,
3410 s = ffebld_symter (ffebld_left (expr));
3411 dt = ffesymbol_hook (s).decl_tree;
3412 if (dt == NULL_TREE)
3414 s = ffecom_sym_transform_ (s);
3415 dt = ffesymbol_hook (s).decl_tree;
3417 if (dt == error_mark_node)
3420 if (ffesymbol_hook (s).addr)
3423 item = ffecom_1_fn (dt);
3425 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT)
3426 args = ffecom_list_expr (ffebld_right (expr));
3428 args = ffecom_list_ptr_to_expr (ffebld_right (expr));
3430 if (args == error_mark_node)
3431 return error_mark_node;
3433 item = ffecom_call_ (item, kt,
3434 ffesymbol_is_f2c (s)
3435 && (bt == FFEINFO_basictypeCOMPLEX)
3436 && (ffesymbol_where (s)
3437 != FFEINFO_whereCONSTANT),
3440 dest_tree, dest, dest_used,
3441 error_mark_node, FALSE,
3442 ffebld_nonter_hook (expr));
3443 TREE_SIDE_EFFECTS (item) = 1;
3449 case FFEINFO_basictypeLOGICAL:
3451 = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
3452 ffecom_truth_value (ffecom_expr (ffebld_left (expr))),
3453 ffecom_truth_value (ffecom_expr (ffebld_right (expr))));
3454 return convert (tree_type, item);
3456 case FFEINFO_basictypeINTEGER:
3457 return ffecom_2 (BIT_AND_EXPR, tree_type,
3458 ffecom_expr (ffebld_left (expr)),
3459 ffecom_expr (ffebld_right (expr)));
3462 assert ("AND bad basictype" == NULL);
3464 case FFEINFO_basictypeANY:
3465 return error_mark_node;
3472 case FFEINFO_basictypeLOGICAL:
3474 = ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
3475 ffecom_truth_value (ffecom_expr (ffebld_left (expr))),
3476 ffecom_truth_value (ffecom_expr (ffebld_right (expr))));
3477 return convert (tree_type, item);
3479 case FFEINFO_basictypeINTEGER:
3480 return ffecom_2 (BIT_IOR_EXPR, tree_type,
3481 ffecom_expr (ffebld_left (expr)),
3482 ffecom_expr (ffebld_right (expr)));
3485 assert ("OR bad basictype" == NULL);
3487 case FFEINFO_basictypeANY:
3488 return error_mark_node;
3496 case FFEINFO_basictypeLOGICAL:
3498 = ffecom_2 (NE_EXPR, integer_type_node,
3499 ffecom_expr (ffebld_left (expr)),
3500 ffecom_expr (ffebld_right (expr)));
3501 return convert (tree_type, ffecom_truth_value (item));
3503 case FFEINFO_basictypeINTEGER:
3504 return ffecom_2 (BIT_XOR_EXPR, tree_type,
3505 ffecom_expr (ffebld_left (expr)),
3506 ffecom_expr (ffebld_right (expr)));
3509 assert ("XOR/NEQV bad basictype" == NULL);
3511 case FFEINFO_basictypeANY:
3512 return error_mark_node;
3519 case FFEINFO_basictypeLOGICAL:
3521 = ffecom_2 (EQ_EXPR, integer_type_node,
3522 ffecom_expr (ffebld_left (expr)),
3523 ffecom_expr (ffebld_right (expr)));
3524 return convert (tree_type, ffecom_truth_value (item));
3526 case FFEINFO_basictypeINTEGER:
3528 ffecom_1 (BIT_NOT_EXPR, tree_type,
3529 ffecom_2 (BIT_XOR_EXPR, tree_type,
3530 ffecom_expr (ffebld_left (expr)),
3531 ffecom_expr (ffebld_right (expr))));
3534 assert ("EQV bad basictype" == NULL);
3536 case FFEINFO_basictypeANY:
3537 return error_mark_node;
3541 case FFEBLD_opCONVERT:
3542 if (ffebld_op (ffebld_left (expr)) == FFEBLD_opANY)
3543 return error_mark_node;
3547 case FFEINFO_basictypeLOGICAL:
3548 case FFEINFO_basictypeINTEGER:
3549 case FFEINFO_basictypeREAL:
3550 return convert (tree_type, ffecom_expr (ffebld_left (expr)));
3552 case FFEINFO_basictypeCOMPLEX:
3553 switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr))))
3555 case FFEINFO_basictypeINTEGER:
3556 case FFEINFO_basictypeLOGICAL:
3557 case FFEINFO_basictypeREAL:
3558 item = ffecom_expr (ffebld_left (expr));
3559 if (item == error_mark_node)
3560 return error_mark_node;
3561 /* convert() takes care of converting to the subtype first,
3562 at least in gcc-2.7.2. */
3563 item = convert (tree_type, item);
3566 case FFEINFO_basictypeCOMPLEX:
3567 return convert (tree_type, ffecom_expr (ffebld_left (expr)));
3570 assert ("CONVERT COMPLEX bad basictype" == NULL);
3572 case FFEINFO_basictypeANY:
3573 return error_mark_node;
3578 assert ("CONVERT bad basictype" == NULL);
3580 case FFEINFO_basictypeANY:
3581 return error_mark_node;
3587 goto relational; /* :::::::::::::::::::: */
3591 goto relational; /* :::::::::::::::::::: */
3595 goto relational; /* :::::::::::::::::::: */
3599 goto relational; /* :::::::::::::::::::: */
3603 goto relational; /* :::::::::::::::::::: */
3608 relational: /* :::::::::::::::::::: */
3609 switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr))))
3611 case FFEINFO_basictypeLOGICAL:
3612 case FFEINFO_basictypeINTEGER:
3613 case FFEINFO_basictypeREAL:
3614 item = ffecom_2 (code, integer_type_node,
3615 ffecom_expr (ffebld_left (expr)),
3616 ffecom_expr (ffebld_right (expr)));
3617 return convert (tree_type, item);
3619 case FFEINFO_basictypeCOMPLEX:
3620 assert (code == EQ_EXPR || code == NE_EXPR);
3623 tree arg1 = ffecom_expr (ffebld_left (expr));
3624 tree arg2 = ffecom_expr (ffebld_right (expr));
3626 if (arg1 == error_mark_node || arg2 == error_mark_node)
3627 return error_mark_node;
3629 arg1 = ffecom_save_tree (arg1);
3630 arg2 = ffecom_save_tree (arg2);
3632 if (TREE_CODE (TREE_TYPE (arg1)) == COMPLEX_TYPE)
3634 real_type = TREE_TYPE (TREE_TYPE (arg1));
3635 assert (real_type == TREE_TYPE (TREE_TYPE (arg2)));
3639 real_type = TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg1)));
3640 assert (real_type == TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg2))));
3644 = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
3645 ffecom_2 (EQ_EXPR, integer_type_node,
3646 ffecom_1 (REALPART_EXPR, real_type, arg1),
3647 ffecom_1 (REALPART_EXPR, real_type, arg2)),
3648 ffecom_2 (EQ_EXPR, integer_type_node,
3649 ffecom_1 (IMAGPART_EXPR, real_type, arg1),
3650 ffecom_1 (IMAGPART_EXPR, real_type,
3652 if (code == EQ_EXPR)
3653 item = ffecom_truth_value (item);
3655 item = ffecom_truth_value_invert (item);
3656 return convert (tree_type, item);
3659 case FFEINFO_basictypeCHARACTER:
3661 ffebld left = ffebld_left (expr);
3662 ffebld right = ffebld_right (expr);
3668 /* f2c run-time functions do the implicit blank-padding for us,
3669 so we don't usually have to implement blank-padding ourselves.
3670 (The exception is when we pass an argument to a separately
3671 compiled statement function -- if we know the arg is not the
3672 same length as the dummy, we must truncate or extend it. If
3673 we "inline" statement functions, that necessity goes away as
3676 Strip off the CONVERT operators that blank-pad. (Truncation by
3677 CONVERT shouldn't happen here, but it can happen in
3680 while (ffebld_op (left) == FFEBLD_opCONVERT)
3681 left = ffebld_left (left);
3682 while (ffebld_op (right) == FFEBLD_opCONVERT)
3683 right = ffebld_left (right);
3685 left_tree = ffecom_arg_ptr_to_expr (left, &left_length);
3686 right_tree = ffecom_arg_ptr_to_expr (right, &right_length);
3688 if (left_tree == error_mark_node || left_length == error_mark_node
3689 || right_tree == error_mark_node
3690 || right_length == error_mark_node)
3691 return error_mark_node;
3693 if ((ffebld_size_known (left) == 1)
3694 && (ffebld_size_known (right) == 1))
3697 = ffecom_1 (INDIRECT_REF,
3698 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree))),
3701 = ffecom_1 (INDIRECT_REF,
3702 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree))),
3706 = ffecom_2 (code, integer_type_node,
3707 ffecom_2 (ARRAY_REF,
3708 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree))),
3711 ffecom_2 (ARRAY_REF,
3712 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree))),
3718 item = build_tree_list (NULL_TREE, left_tree);
3719 TREE_CHAIN (item) = build_tree_list (NULL_TREE, right_tree);
3720 TREE_CHAIN (TREE_CHAIN (item)) = build_tree_list (NULL_TREE,
3722 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item)))
3723 = build_tree_list (NULL_TREE, right_length);
3724 item = ffecom_call_gfrt (FFECOM_gfrtCMP, item, NULL_TREE);
3725 item = ffecom_2 (code, integer_type_node,
3727 convert (TREE_TYPE (item),
3728 integer_zero_node));
3730 item = convert (tree_type, item);
3736 assert ("relational bad basictype" == NULL);
3738 case FFEINFO_basictypeANY:
3739 return error_mark_node;
3743 case FFEBLD_opPERCENT_LOC:
3744 item = ffecom_arg_ptr_to_expr (ffebld_left (expr), &list);
3745 return convert (tree_type, item);
3747 case FFEBLD_opPERCENT_VAL:
3748 item = ffecom_arg_expr (ffebld_left (expr), &list);
3749 return convert (tree_type, item);
3753 case FFEBLD_opBOUNDS:
3754 case FFEBLD_opREPEAT:
3755 case FFEBLD_opLABTER:
3756 case FFEBLD_opLABTOK:
3757 case FFEBLD_opIMPDO:
3758 case FFEBLD_opCONCATENATE:
3759 case FFEBLD_opSUBSTR:
3761 assert ("bad op" == NULL);
3764 return error_mark_node;
3768 assert ("didn't think anything got here anymore!!" == NULL);
3770 switch (ffebld_arity (expr))
3773 TREE_OPERAND (item, 0) = ffecom_expr (ffebld_left (expr));
3774 TREE_OPERAND (item, 1) = ffecom_expr (ffebld_right (expr));
3775 if (TREE_OPERAND (item, 0) == error_mark_node
3776 || TREE_OPERAND (item, 1) == error_mark_node)
3777 return error_mark_node;
3781 TREE_OPERAND (item, 0) = ffecom_expr (ffebld_left (expr));
3782 if (TREE_OPERAND (item, 0) == error_mark_node)
3783 return error_mark_node;
3794 /* Returns the tree that does the intrinsic invocation.
3796 Note: this function applies only to intrinsics returning
3797 CHARACTER*1 or non-CHARACTER results, and to intrinsic
3801 ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree,
3802 ffebld dest, bool *dest_used)
3805 tree saved_expr1; /* For those who need it. */
3806 tree saved_expr2; /* For those who need it. */
3807 ffeinfoBasictype bt;
3811 tree real_type; /* REAL type corresponding to COMPLEX. */
3813 ffebld list = ffebld_right (expr); /* List of (some) args. */
3814 ffebld arg1; /* For handy reference. */
3817 ffeintrinImp codegen_imp;
3820 assert (ffebld_op (ffebld_left (expr)) == FFEBLD_opSYMTER);
3822 if (dest_used != NULL)
3825 bt = ffeinfo_basictype (ffebld_info (expr));
3826 kt = ffeinfo_kindtype (ffebld_info (expr));
3827 tree_type = ffecom_tree_type[bt][kt];
3831 arg1 = ffebld_head (list);
3832 if (arg1 != NULL && ffebld_op (arg1) == FFEBLD_opANY)
3833 return error_mark_node;
3834 if ((list = ffebld_trail (list)) != NULL)
3836 arg2 = ffebld_head (list);
3837 if (arg2 != NULL && ffebld_op (arg2) == FFEBLD_opANY)
3838 return error_mark_node;
3839 if ((list = ffebld_trail (list)) != NULL)
3841 arg3 = ffebld_head (list);
3842 if (arg3 != NULL && ffebld_op (arg3) == FFEBLD_opANY)
3843 return error_mark_node;
3852 arg1 = arg2 = arg3 = NULL;
3854 /* <list> ends up at the opITEM of the 3rd arg, or NULL if there are < 3
3855 args. This is used by the MAX/MIN expansions. */
3858 arg1_type = ffecom_tree_type
3859 [ffeinfo_basictype (ffebld_info (arg1))]
3860 [ffeinfo_kindtype (ffebld_info (arg1))];
3862 arg1_type = NULL_TREE; /* Really not needed, but might catch bugs
3865 /* There are several ways for each of the cases in the following switch
3866 statements to exit (from simplest to use to most complicated):
3868 break; (when expr_tree == NULL)
3870 A standard call is made to the specific intrinsic just as if it had been
3871 passed in as a dummy procedure and called as any old procedure. This
3872 method can produce slower code but in some cases it's the easiest way for
3873 now. However, if a (presumably faster) direct call is available,
3874 that is used, so this is the easiest way in many more cases now.
3876 gfrt = FFECOM_gfrtWHATEVER;
3879 gfrt contains the gfrt index of a library function to call, passing the
3880 argument(s) by value rather than by reference. Used when a more
3881 careful choice of library function is needed than that provided
3882 by the vanilla `break;'.
3886 The expr_tree has been completely set up and is ready to be returned
3887 as is. No further actions are taken. Use this when the tree is not
3888 in the simple form for one of the arity_n labels. */
3890 /* For info on how the switch statement cases were written, see the files
3891 enclosed in comments below the switch statement. */
3893 codegen_imp = ffebld_symter_implementation (ffebld_left (expr));
3894 gfrt = ffeintrin_gfrt_direct (codegen_imp);
3895 if (gfrt == FFECOM_gfrt)
3896 gfrt = ffeintrin_gfrt_indirect (codegen_imp);
3898 switch (codegen_imp)
3900 case FFEINTRIN_impABS:
3901 case FFEINTRIN_impCABS:
3902 case FFEINTRIN_impCDABS:
3903 case FFEINTRIN_impDABS:
3904 case FFEINTRIN_impIABS:
3905 if (ffeinfo_basictype (ffebld_info (arg1))
3906 == FFEINFO_basictypeCOMPLEX)
3908 if (kt == FFEINFO_kindtypeREAL1)
3909 gfrt = FFECOM_gfrtCABS;
3910 else if (kt == FFEINFO_kindtypeREAL2)
3911 gfrt = FFECOM_gfrtCDABS;
3914 return ffecom_1 (ABS_EXPR, tree_type,
3915 convert (tree_type, ffecom_expr (arg1)));
3917 case FFEINTRIN_impACOS:
3918 case FFEINTRIN_impDACOS:
3921 case FFEINTRIN_impAIMAG:
3922 case FFEINTRIN_impDIMAG:
3923 case FFEINTRIN_impIMAGPART:
3924 if (TREE_CODE (arg1_type) == COMPLEX_TYPE)
3925 arg1_type = TREE_TYPE (arg1_type);
3927 arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type));
3931 ffecom_1 (IMAGPART_EXPR, arg1_type,
3932 ffecom_expr (arg1)));
3934 case FFEINTRIN_impAINT:
3935 case FFEINTRIN_impDINT:
3937 /* ~~Someday implement FIX_TRUNC_EXPR yielding same type as arg. */
3938 return ffecom_1 (FIX_TRUNC_EXPR, tree_type, ffecom_expr (arg1));
3939 #else /* in the meantime, must use floor to avoid range problems with ints */
3940 /* r__1 = r1 >= 0 ? floor(r1) : -floor(-r1); */
3941 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
3944 ffecom_3 (COND_EXPR, double_type_node,
3946 (ffecom_2 (GE_EXPR, integer_type_node,
3949 ffecom_float_zero_))),
3950 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
3951 build_tree_list (NULL_TREE,
3952 convert (double_type_node,
3955 ffecom_1 (NEGATE_EXPR, double_type_node,
3956 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
3957 build_tree_list (NULL_TREE,
3958 convert (double_type_node,
3959 ffecom_1 (NEGATE_EXPR,
3967 case FFEINTRIN_impANINT:
3968 case FFEINTRIN_impDNINT:
3969 #if 0 /* This way of doing it won't handle real
3970 numbers of large magnitudes. */
3971 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
3972 expr_tree = convert (tree_type,
3973 convert (integer_type_node,
3974 ffecom_3 (COND_EXPR, tree_type,
3979 ffecom_float_zero_)),
3980 ffecom_2 (PLUS_EXPR,
3983 ffecom_float_half_),
3984 ffecom_2 (MINUS_EXPR,
3987 ffecom_float_half_))));
3989 #else /* So we instead call floor. */
3990 /* r__1 = r1 >= 0 ? floor(r1 + .5) : -floor(.5 - r1) */
3991 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
3994 ffecom_3 (COND_EXPR, double_type_node,
3996 (ffecom_2 (GE_EXPR, integer_type_node,
3999 ffecom_float_zero_))),
4000 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
4001 build_tree_list (NULL_TREE,
4002 convert (double_type_node,
4003 ffecom_2 (PLUS_EXPR,
4007 ffecom_float_half_)))),
4009 ffecom_1 (NEGATE_EXPR, double_type_node,
4010 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
4011 build_tree_list (NULL_TREE,
4012 convert (double_type_node,
4013 ffecom_2 (MINUS_EXPR,
4016 ffecom_float_half_),
4023 case FFEINTRIN_impASIN:
4024 case FFEINTRIN_impDASIN:
4025 case FFEINTRIN_impATAN:
4026 case FFEINTRIN_impDATAN:
4027 case FFEINTRIN_impATAN2:
4028 case FFEINTRIN_impDATAN2:
4031 case FFEINTRIN_impCHAR:
4032 case FFEINTRIN_impACHAR:
4034 tempvar = ffecom_make_tempvar (char_type_node, 1, -1);
4036 tempvar = ffebld_nonter_hook (expr);
4040 tree tmv = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (tempvar)));
4042 expr_tree = ffecom_modify (tmv,
4043 ffecom_2 (ARRAY_REF, tmv, tempvar,
4045 convert (tmv, ffecom_expr (arg1)));
4047 expr_tree = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar),
4050 expr_tree = ffecom_1 (ADDR_EXPR,
4051 build_pointer_type (TREE_TYPE (expr_tree)),
4055 case FFEINTRIN_impCMPLX:
4056 case FFEINTRIN_impDCMPLX:
4059 convert (tree_type, ffecom_expr (arg1));
4061 real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
4063 ffecom_2 (COMPLEX_EXPR, tree_type,
4064 convert (real_type, ffecom_expr (arg1)),
4066 ffecom_expr (arg2)));
4068 case FFEINTRIN_impCOMPLEX:
4070 ffecom_2 (COMPLEX_EXPR, tree_type,
4072 ffecom_expr (arg2));
4074 case FFEINTRIN_impCONJG:
4075 case FFEINTRIN_impDCONJG:
4079 real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
4080 arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4082 ffecom_2 (COMPLEX_EXPR, tree_type,
4083 ffecom_1 (REALPART_EXPR, real_type, arg1_tree),
4084 ffecom_1 (NEGATE_EXPR, real_type,
4085 ffecom_1 (IMAGPART_EXPR, real_type, arg1_tree)));
4088 case FFEINTRIN_impCOS:
4089 case FFEINTRIN_impCCOS:
4090 case FFEINTRIN_impCDCOS:
4091 case FFEINTRIN_impDCOS:
4092 if (bt == FFEINFO_basictypeCOMPLEX)
4094 if (kt == FFEINFO_kindtypeREAL1)
4095 gfrt = FFECOM_gfrtCCOS; /* Overlapping result okay. */
4096 else if (kt == FFEINFO_kindtypeREAL2)
4097 gfrt = FFECOM_gfrtCDCOS; /* Overlapping result okay. */
4101 case FFEINTRIN_impCOSH:
4102 case FFEINTRIN_impDCOSH:
4105 case FFEINTRIN_impDBLE:
4106 case FFEINTRIN_impDFLOAT:
4107 case FFEINTRIN_impDREAL:
4108 case FFEINTRIN_impFLOAT:
4109 case FFEINTRIN_impIDINT:
4110 case FFEINTRIN_impIFIX:
4111 case FFEINTRIN_impINT2:
4112 case FFEINTRIN_impINT8:
4113 case FFEINTRIN_impINT:
4114 case FFEINTRIN_impLONG:
4115 case FFEINTRIN_impREAL:
4116 case FFEINTRIN_impSHORT:
4117 case FFEINTRIN_impSNGL:
4118 return convert (tree_type, ffecom_expr (arg1));
4120 case FFEINTRIN_impDIM:
4121 case FFEINTRIN_impDDIM:
4122 case FFEINTRIN_impIDIM:
4123 saved_expr1 = ffecom_save_tree (convert (tree_type,
4124 ffecom_expr (arg1)));
4125 saved_expr2 = ffecom_save_tree (convert (tree_type,
4126 ffecom_expr (arg2)));
4128 ffecom_3 (COND_EXPR, tree_type,
4130 (ffecom_2 (GT_EXPR, integer_type_node,
4133 ffecom_2 (MINUS_EXPR, tree_type,
4136 convert (tree_type, ffecom_float_zero_));
4138 case FFEINTRIN_impDPROD:
4140 ffecom_2 (MULT_EXPR, tree_type,
4141 convert (tree_type, ffecom_expr (arg1)),
4142 convert (tree_type, ffecom_expr (arg2)));
4144 case FFEINTRIN_impEXP:
4145 case FFEINTRIN_impCDEXP:
4146 case FFEINTRIN_impCEXP:
4147 case FFEINTRIN_impDEXP:
4148 if (bt == FFEINFO_basictypeCOMPLEX)
4150 if (kt == FFEINFO_kindtypeREAL1)
4151 gfrt = FFECOM_gfrtCEXP; /* Overlapping result okay. */
4152 else if (kt == FFEINFO_kindtypeREAL2)
4153 gfrt = FFECOM_gfrtCDEXP; /* Overlapping result okay. */
4157 case FFEINTRIN_impICHAR:
4158 case FFEINTRIN_impIACHAR:
4159 #if 0 /* The simple approach. */
4160 ffecom_char_args_ (&expr_tree, &saved_expr1 /* Ignored */ , arg1);
4162 = ffecom_1 (INDIRECT_REF,
4163 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
4166 = ffecom_2 (ARRAY_REF,
4167 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
4170 return convert (tree_type, expr_tree);
4171 #else /* The more interesting (and more optimal) approach. */
4172 expr_tree = ffecom_intrinsic_ichar_ (tree_type, arg1, &saved_expr1);
4173 expr_tree = ffecom_3 (COND_EXPR, tree_type,
4176 convert (tree_type, integer_zero_node));
4180 case FFEINTRIN_impINDEX:
4183 case FFEINTRIN_impLEN:
4185 break; /* The simple approach. */
4187 return ffecom_intrinsic_len_ (arg1); /* The more optimal approach. */
4190 case FFEINTRIN_impLGE:
4191 case FFEINTRIN_impLGT:
4192 case FFEINTRIN_impLLE:
4193 case FFEINTRIN_impLLT:
4196 case FFEINTRIN_impLOG:
4197 case FFEINTRIN_impALOG:
4198 case FFEINTRIN_impCDLOG:
4199 case FFEINTRIN_impCLOG:
4200 case FFEINTRIN_impDLOG:
4201 if (bt == FFEINFO_basictypeCOMPLEX)
4203 if (kt == FFEINFO_kindtypeREAL1)
4204 gfrt = FFECOM_gfrtCLOG; /* Overlapping result okay. */
4205 else if (kt == FFEINFO_kindtypeREAL2)
4206 gfrt = FFECOM_gfrtCDLOG; /* Overlapping result okay. */
4210 case FFEINTRIN_impLOG10:
4211 case FFEINTRIN_impALOG10:
4212 case FFEINTRIN_impDLOG10:
4213 if (gfrt != FFECOM_gfrt)
4214 break; /* Already picked one, stick with it. */
4216 if (kt == FFEINFO_kindtypeREAL1)
4217 /* We used to call FFECOM_gfrtALOG10 here. */
4218 gfrt = FFECOM_gfrtL_LOG10;
4219 else if (kt == FFEINFO_kindtypeREAL2)
4220 /* We used to call FFECOM_gfrtDLOG10 here. */
4221 gfrt = FFECOM_gfrtL_LOG10;
4224 case FFEINTRIN_impMAX:
4225 case FFEINTRIN_impAMAX0:
4226 case FFEINTRIN_impAMAX1:
4227 case FFEINTRIN_impDMAX1:
4228 case FFEINTRIN_impMAX0:
4229 case FFEINTRIN_impMAX1:
4230 if (bt != ffeinfo_basictype (ffebld_info (arg1)))
4231 arg1_type = ffecom_widest_expr_type_ (ffebld_right (expr));
4233 arg1_type = tree_type;
4234 expr_tree = ffecom_2 (MAX_EXPR, arg1_type,
4235 convert (arg1_type, ffecom_expr (arg1)),
4236 convert (arg1_type, ffecom_expr (arg2)));
4237 for (; list != NULL; list = ffebld_trail (list))
4239 if ((ffebld_head (list) == NULL)
4240 || (ffebld_op (ffebld_head (list)) == FFEBLD_opANY))
4242 expr_tree = ffecom_2 (MAX_EXPR, arg1_type,
4245 ffecom_expr (ffebld_head (list))));
4247 return convert (tree_type, expr_tree);
4249 case FFEINTRIN_impMIN:
4250 case FFEINTRIN_impAMIN0:
4251 case FFEINTRIN_impAMIN1:
4252 case FFEINTRIN_impDMIN1:
4253 case FFEINTRIN_impMIN0:
4254 case FFEINTRIN_impMIN1:
4255 if (bt != ffeinfo_basictype (ffebld_info (arg1)))
4256 arg1_type = ffecom_widest_expr_type_ (ffebld_right (expr));
4258 arg1_type = tree_type;
4259 expr_tree = ffecom_2 (MIN_EXPR, arg1_type,
4260 convert (arg1_type, ffecom_expr (arg1)),
4261 convert (arg1_type, ffecom_expr (arg2)));
4262 for (; list != NULL; list = ffebld_trail (list))
4264 if ((ffebld_head (list) == NULL)
4265 || (ffebld_op (ffebld_head (list)) == FFEBLD_opANY))
4267 expr_tree = ffecom_2 (MIN_EXPR, arg1_type,
4270 ffecom_expr (ffebld_head (list))));
4272 return convert (tree_type, expr_tree);
4274 case FFEINTRIN_impMOD:
4275 case FFEINTRIN_impAMOD:
4276 case FFEINTRIN_impDMOD:
4277 if (bt != FFEINFO_basictypeREAL)
4278 return ffecom_2 (TRUNC_MOD_EXPR, tree_type,
4279 convert (tree_type, ffecom_expr (arg1)),
4280 convert (tree_type, ffecom_expr (arg2)));
4282 if (kt == FFEINFO_kindtypeREAL1)
4283 /* We used to call FFECOM_gfrtAMOD here. */
4284 gfrt = FFECOM_gfrtL_FMOD;
4285 else if (kt == FFEINFO_kindtypeREAL2)
4286 /* We used to call FFECOM_gfrtDMOD here. */
4287 gfrt = FFECOM_gfrtL_FMOD;
4290 case FFEINTRIN_impNINT:
4291 case FFEINTRIN_impIDNINT:
4293 /* ~~Ideally FIX_ROUND_EXPR would be implemented, but it ain't yet. */
4294 return ffecom_1 (FIX_ROUND_EXPR, tree_type, ffecom_expr (arg1));
4296 /* i__1 = r1 >= 0 ? floor(r1 + .5) : -floor(.5 - r1); */
4297 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
4299 convert (ffecom_integer_type_node,
4300 ffecom_3 (COND_EXPR, arg1_type,
4302 (ffecom_2 (GE_EXPR, integer_type_node,
4305 ffecom_float_zero_))),
4306 ffecom_2 (PLUS_EXPR, arg1_type,
4309 ffecom_float_half_)),
4310 ffecom_2 (MINUS_EXPR, arg1_type,
4313 ffecom_float_half_))));
4316 case FFEINTRIN_impSIGN:
4317 case FFEINTRIN_impDSIGN:
4318 case FFEINTRIN_impISIGN:
4320 tree arg2_tree = ffecom_expr (arg2);
4324 (ffecom_1 (ABS_EXPR, tree_type,
4326 ffecom_expr (arg1))));
4328 = ffecom_3 (COND_EXPR, tree_type,
4330 (ffecom_2 (GE_EXPR, integer_type_node,
4332 convert (TREE_TYPE (arg2_tree),
4333 integer_zero_node))),
4335 ffecom_1 (NEGATE_EXPR, tree_type, saved_expr1));
4336 /* Make sure SAVE_EXPRs get referenced early enough. */
4338 = ffecom_2 (COMPOUND_EXPR, tree_type,
4339 convert (void_type_node, saved_expr1),
4344 case FFEINTRIN_impSIN:
4345 case FFEINTRIN_impCDSIN:
4346 case FFEINTRIN_impCSIN:
4347 case FFEINTRIN_impDSIN:
4348 if (bt == FFEINFO_basictypeCOMPLEX)
4350 if (kt == FFEINFO_kindtypeREAL1)
4351 gfrt = FFECOM_gfrtCSIN; /* Overlapping result okay. */
4352 else if (kt == FFEINFO_kindtypeREAL2)
4353 gfrt = FFECOM_gfrtCDSIN; /* Overlapping result okay. */
4357 case FFEINTRIN_impSINH:
4358 case FFEINTRIN_impDSINH:
4361 case FFEINTRIN_impSQRT:
4362 case FFEINTRIN_impCDSQRT:
4363 case FFEINTRIN_impCSQRT:
4364 case FFEINTRIN_impDSQRT:
4365 if (bt == FFEINFO_basictypeCOMPLEX)
4367 if (kt == FFEINFO_kindtypeREAL1)
4368 gfrt = FFECOM_gfrtCSQRT; /* Overlapping result okay. */
4369 else if (kt == FFEINFO_kindtypeREAL2)
4370 gfrt = FFECOM_gfrtCDSQRT; /* Overlapping result okay. */
4374 case FFEINTRIN_impTAN:
4375 case FFEINTRIN_impDTAN:
4376 case FFEINTRIN_impTANH:
4377 case FFEINTRIN_impDTANH:
4380 case FFEINTRIN_impREALPART:
4381 if (TREE_CODE (arg1_type) == COMPLEX_TYPE)
4382 arg1_type = TREE_TYPE (arg1_type);
4384 arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type));
4388 ffecom_1 (REALPART_EXPR, arg1_type,
4389 ffecom_expr (arg1)));
4391 case FFEINTRIN_impIAND:
4392 case FFEINTRIN_impAND:
4393 return ffecom_2 (BIT_AND_EXPR, tree_type,
4395 ffecom_expr (arg1)),
4397 ffecom_expr (arg2)));
4399 case FFEINTRIN_impIOR:
4400 case FFEINTRIN_impOR:
4401 return ffecom_2 (BIT_IOR_EXPR, tree_type,
4403 ffecom_expr (arg1)),
4405 ffecom_expr (arg2)));
4407 case FFEINTRIN_impIEOR:
4408 case FFEINTRIN_impXOR:
4409 return ffecom_2 (BIT_XOR_EXPR, tree_type,
4411 ffecom_expr (arg1)),
4413 ffecom_expr (arg2)));
4415 case FFEINTRIN_impLSHIFT:
4416 return ffecom_2 (LSHIFT_EXPR, tree_type,
4418 convert (integer_type_node,
4419 ffecom_expr (arg2)));
4421 case FFEINTRIN_impRSHIFT:
4422 return ffecom_2 (RSHIFT_EXPR, tree_type,
4424 convert (integer_type_node,
4425 ffecom_expr (arg2)));
4427 case FFEINTRIN_impNOT:
4428 return ffecom_1 (BIT_NOT_EXPR, tree_type, ffecom_expr (arg1));
4430 case FFEINTRIN_impBIT_SIZE:
4431 return convert (tree_type, TYPE_SIZE (arg1_type));
4433 case FFEINTRIN_impBTEST:
4435 ffetargetLogical1 target_true;
4436 ffetargetLogical1 target_false;
4440 ffetarget_logical1 (&target_true, TRUE);
4441 ffetarget_logical1 (&target_false, FALSE);
4442 if (target_true == 1)
4443 true_tree = convert (tree_type, integer_one_node);
4445 true_tree = convert (tree_type, build_int_2 (target_true, 0));
4446 if (target_false == 0)
4447 false_tree = convert (tree_type, integer_zero_node);
4449 false_tree = convert (tree_type, build_int_2 (target_false, 0));
4452 ffecom_3 (COND_EXPR, tree_type,
4454 (ffecom_2 (EQ_EXPR, integer_type_node,
4455 ffecom_2 (BIT_AND_EXPR, arg1_type,
4457 ffecom_2 (LSHIFT_EXPR, arg1_type,
4460 convert (integer_type_node,
4461 ffecom_expr (arg2)))),
4463 integer_zero_node))),
4468 case FFEINTRIN_impIBCLR:
4470 ffecom_2 (BIT_AND_EXPR, tree_type,
4472 ffecom_1 (BIT_NOT_EXPR, tree_type,
4473 ffecom_2 (LSHIFT_EXPR, tree_type,
4476 convert (integer_type_node,
4477 ffecom_expr (arg2)))));
4479 case FFEINTRIN_impIBITS:
4481 tree arg3_tree = ffecom_save_tree (convert (integer_type_node,
4482 ffecom_expr (arg3)));
4484 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4487 = ffecom_2 (BIT_AND_EXPR, tree_type,
4488 ffecom_2 (RSHIFT_EXPR, tree_type,
4490 convert (integer_type_node,
4491 ffecom_expr (arg2))),
4493 ffecom_2 (RSHIFT_EXPR, uns_type,
4494 ffecom_1 (BIT_NOT_EXPR,
4497 integer_zero_node)),
4498 ffecom_2 (MINUS_EXPR,
4500 TYPE_SIZE (uns_type),
4502 /* Fix up, because the RSHIFT_EXPR above can't shift over TYPE_SIZE. */
4504 = ffecom_3 (COND_EXPR, tree_type,
4506 (ffecom_2 (NE_EXPR, integer_type_node,
4508 integer_zero_node)),
4510 convert (tree_type, integer_zero_node));
4514 case FFEINTRIN_impIBSET:
4516 ffecom_2 (BIT_IOR_EXPR, tree_type,
4518 ffecom_2 (LSHIFT_EXPR, tree_type,
4519 convert (tree_type, integer_one_node),
4520 convert (integer_type_node,
4521 ffecom_expr (arg2))));
4523 case FFEINTRIN_impISHFT:
4525 tree arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4526 tree arg2_tree = ffecom_save_tree (convert (integer_type_node,
4527 ffecom_expr (arg2)));
4529 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4532 = ffecom_3 (COND_EXPR, tree_type,
4534 (ffecom_2 (GE_EXPR, integer_type_node,
4536 integer_zero_node)),
4537 ffecom_2 (LSHIFT_EXPR, tree_type,
4541 ffecom_2 (RSHIFT_EXPR, uns_type,
4542 convert (uns_type, arg1_tree),
4543 ffecom_1 (NEGATE_EXPR,
4546 /* Fix up, because {L|R}SHIFT_EXPR don't go over TYPE_SIZE bounds. */
4548 = ffecom_3 (COND_EXPR, tree_type,
4550 (ffecom_2 (NE_EXPR, integer_type_node,
4554 TYPE_SIZE (uns_type))),
4556 convert (tree_type, integer_zero_node));
4557 /* Make sure SAVE_EXPRs get referenced early enough. */
4559 = ffecom_2 (COMPOUND_EXPR, tree_type,
4560 convert (void_type_node, arg1_tree),
4561 ffecom_2 (COMPOUND_EXPR, tree_type,
4562 convert (void_type_node, arg2_tree),
4567 case FFEINTRIN_impISHFTC:
4569 tree arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4570 tree arg2_tree = ffecom_save_tree (convert (integer_type_node,
4571 ffecom_expr (arg2)));
4572 tree arg3_tree = (arg3 == NULL) ? TYPE_SIZE (tree_type)
4573 : ffecom_save_tree (convert (integer_type_node, ffecom_expr (arg3)));
4579 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4582 = ffecom_2 (LSHIFT_EXPR, tree_type,
4583 ffecom_1 (BIT_NOT_EXPR, tree_type,
4584 convert (tree_type, integer_zero_node)),
4586 /* Fix up, because LSHIFT_EXPR above can't shift over TYPE_SIZE. */
4588 = ffecom_3 (COND_EXPR, tree_type,
4590 (ffecom_2 (NE_EXPR, integer_type_node,
4592 TYPE_SIZE (uns_type))),
4594 convert (tree_type, integer_zero_node));
4595 mask_arg1 = ffecom_save_tree (mask_arg1);
4597 = ffecom_2 (BIT_AND_EXPR, tree_type,
4599 ffecom_1 (BIT_NOT_EXPR, tree_type,
4601 masked_arg1 = ffecom_save_tree (masked_arg1);
4603 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4605 ffecom_2 (RSHIFT_EXPR, uns_type,
4606 convert (uns_type, masked_arg1),
4607 ffecom_1 (NEGATE_EXPR,
4610 ffecom_2 (LSHIFT_EXPR, tree_type,
4612 ffecom_2 (PLUS_EXPR, integer_type_node,
4616 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4617 ffecom_2 (LSHIFT_EXPR, tree_type,
4621 ffecom_2 (RSHIFT_EXPR, uns_type,
4622 convert (uns_type, masked_arg1),
4623 ffecom_2 (MINUS_EXPR,
4628 = ffecom_3 (COND_EXPR, tree_type,
4630 (ffecom_2 (LT_EXPR, integer_type_node,
4632 integer_zero_node)),
4636 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4637 ffecom_2 (BIT_AND_EXPR, tree_type,
4640 ffecom_2 (BIT_AND_EXPR, tree_type,
4641 ffecom_1 (BIT_NOT_EXPR, tree_type,
4645 = ffecom_3 (COND_EXPR, tree_type,
4647 (ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
4648 ffecom_2 (EQ_EXPR, integer_type_node,
4653 ffecom_2 (EQ_EXPR, integer_type_node,
4655 integer_zero_node))),
4658 /* Make sure SAVE_EXPRs get referenced early enough. */
4660 = ffecom_2 (COMPOUND_EXPR, tree_type,
4661 convert (void_type_node, arg1_tree),
4662 ffecom_2 (COMPOUND_EXPR, tree_type,
4663 convert (void_type_node, arg2_tree),
4664 ffecom_2 (COMPOUND_EXPR, tree_type,
4665 convert (void_type_node,
4667 ffecom_2 (COMPOUND_EXPR, tree_type,
4668 convert (void_type_node,
4672 = ffecom_2 (COMPOUND_EXPR, tree_type,
4673 convert (void_type_node,
4679 case FFEINTRIN_impLOC:
4681 tree arg1_tree = ffecom_expr (arg1);
4684 = convert (tree_type,
4685 ffecom_1 (ADDR_EXPR,
4686 build_pointer_type (TREE_TYPE (arg1_tree)),
4691 case FFEINTRIN_impMVBITS:
4696 ffebld arg4 = ffebld_head (ffebld_trail (list));
4699 ffebld arg5 = ffebld_head (ffebld_trail (ffebld_trail (list)));
4703 tree arg5_plus_arg3;
4705 arg2_tree = convert (integer_type_node,
4706 ffecom_expr (arg2));
4707 arg3_tree = ffecom_save_tree (convert (integer_type_node,
4708 ffecom_expr (arg3)));
4709 arg4_tree = ffecom_expr_rw (NULL_TREE, arg4);
4710 arg4_type = TREE_TYPE (arg4_tree);
4712 arg1_tree = ffecom_save_tree (convert (arg4_type,
4713 ffecom_expr (arg1)));
4715 arg5_tree = ffecom_save_tree (convert (integer_type_node,
4716 ffecom_expr (arg5)));
4719 = ffecom_2 (LSHIFT_EXPR, arg4_type,
4720 ffecom_2 (BIT_AND_EXPR, arg4_type,
4721 ffecom_2 (RSHIFT_EXPR, arg4_type,
4724 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4725 ffecom_2 (LSHIFT_EXPR, arg4_type,
4726 ffecom_1 (BIT_NOT_EXPR,
4730 integer_zero_node)),
4734 = ffecom_save_tree (ffecom_2 (PLUS_EXPR, arg4_type,
4738 = ffecom_2 (LSHIFT_EXPR, arg4_type,
4739 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4741 integer_zero_node)),
4743 /* Fix up, because LSHIFT_EXPR above can't shift over TYPE_SIZE. */
4745 = ffecom_3 (COND_EXPR, arg4_type,
4747 (ffecom_2 (NE_EXPR, integer_type_node,
4749 convert (TREE_TYPE (arg5_plus_arg3),
4750 TYPE_SIZE (arg4_type)))),
4752 convert (arg4_type, integer_zero_node));
4754 = ffecom_2 (BIT_AND_EXPR, arg4_type,
4756 ffecom_2 (BIT_IOR_EXPR, arg4_type,
4758 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4759 ffecom_2 (LSHIFT_EXPR, arg4_type,
4760 ffecom_1 (BIT_NOT_EXPR,
4764 integer_zero_node)),
4767 = ffecom_2 (BIT_IOR_EXPR, arg4_type,
4770 /* Fix up (twice), because LSHIFT_EXPR above
4771 can't shift over TYPE_SIZE. */
4773 = ffecom_3 (COND_EXPR, arg4_type,
4775 (ffecom_2 (NE_EXPR, integer_type_node,
4777 convert (TREE_TYPE (arg3_tree),
4778 integer_zero_node))),
4782 = ffecom_3 (COND_EXPR, arg4_type,
4784 (ffecom_2 (NE_EXPR, integer_type_node,
4786 convert (TREE_TYPE (arg3_tree),
4787 TYPE_SIZE (arg4_type)))),
4791 = ffecom_2s (MODIFY_EXPR, void_type_node,
4794 /* Make sure SAVE_EXPRs get referenced early enough. */
4796 = ffecom_2 (COMPOUND_EXPR, void_type_node,
4798 ffecom_2 (COMPOUND_EXPR, void_type_node,
4800 ffecom_2 (COMPOUND_EXPR, void_type_node,
4802 ffecom_2 (COMPOUND_EXPR, void_type_node,
4806 = ffecom_2 (COMPOUND_EXPR, void_type_node,
4813 case FFEINTRIN_impDERF:
4814 case FFEINTRIN_impERF:
4815 case FFEINTRIN_impDERFC:
4816 case FFEINTRIN_impERFC:
4819 case FFEINTRIN_impIARGC:
4820 /* extern int xargc; i__1 = xargc - 1; */
4821 expr_tree = ffecom_2 (MINUS_EXPR, TREE_TYPE (ffecom_tree_xargc_),
4823 convert (TREE_TYPE (ffecom_tree_xargc_),
4827 case FFEINTRIN_impSIGNAL_func:
4828 case FFEINTRIN_impSIGNAL_subr:
4834 arg1_tree = convert (ffecom_f2c_integer_type_node,
4835 ffecom_expr (arg1));
4836 arg1_tree = ffecom_1 (ADDR_EXPR,
4837 build_pointer_type (TREE_TYPE (arg1_tree)),
4840 /* Pass procedure as a pointer to it, anything else by value. */
4841 if (ffeinfo_kind (ffebld_info (arg2)) == FFEINFO_kindENTITY)
4842 arg2_tree = convert (integer_type_node, ffecom_expr (arg2));
4844 arg2_tree = ffecom_ptr_to_expr (arg2);
4845 arg2_tree = convert (TREE_TYPE (null_pointer_node),
4849 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
4851 arg3_tree = NULL_TREE;
4853 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4854 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
4855 TREE_CHAIN (arg1_tree) = arg2_tree;
4858 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4859 ffecom_gfrt_kindtype (gfrt),
4861 ((codegen_imp == FFEINTRIN_impSIGNAL_subr) ?
4865 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4866 ffebld_nonter_hook (expr));
4868 if (arg3_tree != NULL_TREE)
4870 = ffecom_modify (NULL_TREE, arg3_tree,
4871 convert (TREE_TYPE (arg3_tree),
4876 case FFEINTRIN_impALARM:
4882 arg1_tree = convert (ffecom_f2c_integer_type_node,
4883 ffecom_expr (arg1));
4884 arg1_tree = ffecom_1 (ADDR_EXPR,
4885 build_pointer_type (TREE_TYPE (arg1_tree)),
4888 /* Pass procedure as a pointer to it, anything else by value. */
4889 if (ffeinfo_kind (ffebld_info (arg2)) == FFEINFO_kindENTITY)
4890 arg2_tree = convert (integer_type_node, ffecom_expr (arg2));
4892 arg2_tree = ffecom_ptr_to_expr (arg2);
4893 arg2_tree = convert (TREE_TYPE (null_pointer_node),
4897 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
4899 arg3_tree = NULL_TREE;
4901 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4902 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
4903 TREE_CHAIN (arg1_tree) = arg2_tree;
4906 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4907 ffecom_gfrt_kindtype (gfrt),
4911 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4912 ffebld_nonter_hook (expr));
4914 if (arg3_tree != NULL_TREE)
4916 = ffecom_modify (NULL_TREE, arg3_tree,
4917 convert (TREE_TYPE (arg3_tree),
4922 case FFEINTRIN_impCHDIR_subr:
4923 case FFEINTRIN_impFDATE_subr:
4924 case FFEINTRIN_impFGET_subr:
4925 case FFEINTRIN_impFPUT_subr:
4926 case FFEINTRIN_impGETCWD_subr:
4927 case FFEINTRIN_impHOSTNM_subr:
4928 case FFEINTRIN_impSYSTEM_subr:
4929 case FFEINTRIN_impUNLINK_subr:
4931 tree arg1_len = integer_zero_node;
4935 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
4938 arg2_tree = ffecom_expr_w (NULL_TREE, arg2);
4940 arg2_tree = NULL_TREE;
4942 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4943 arg1_len = build_tree_list (NULL_TREE, arg1_len);
4944 TREE_CHAIN (arg1_tree) = arg1_len;
4947 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4948 ffecom_gfrt_kindtype (gfrt),
4952 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4953 ffebld_nonter_hook (expr));
4955 if (arg2_tree != NULL_TREE)
4957 = ffecom_modify (NULL_TREE, arg2_tree,
4958 convert (TREE_TYPE (arg2_tree),
4963 case FFEINTRIN_impEXIT:
4967 expr_tree = build_tree_list (NULL_TREE,
4968 ffecom_1 (ADDR_EXPR,
4970 (ffecom_integer_type_node),
4971 integer_zero_node));
4974 ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4975 ffecom_gfrt_kindtype (gfrt),
4979 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4980 ffebld_nonter_hook (expr));
4982 case FFEINTRIN_impFLUSH:
4984 gfrt = FFECOM_gfrtFLUSH;
4986 gfrt = FFECOM_gfrtFLUSH1;
4989 case FFEINTRIN_impCHMOD_subr:
4990 case FFEINTRIN_impLINK_subr:
4991 case FFEINTRIN_impRENAME_subr:
4992 case FFEINTRIN_impSYMLNK_subr:
4994 tree arg1_len = integer_zero_node;
4996 tree arg2_len = integer_zero_node;
5000 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
5001 arg2_tree = ffecom_arg_ptr_to_expr (arg2, &arg2_len);
5003 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5005 arg3_tree = NULL_TREE;
5007 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5008 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5009 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5010 arg2_len = build_tree_list (NULL_TREE, arg2_len);
5011 TREE_CHAIN (arg1_tree) = arg2_tree;
5012 TREE_CHAIN (arg2_tree) = arg1_len;
5013 TREE_CHAIN (arg1_len) = arg2_len;
5014 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5015 ffecom_gfrt_kindtype (gfrt),
5019 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5020 ffebld_nonter_hook (expr));
5021 if (arg3_tree != NULL_TREE)
5022 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5023 convert (TREE_TYPE (arg3_tree),
5028 case FFEINTRIN_impLSTAT_subr:
5029 case FFEINTRIN_impSTAT_subr:
5031 tree arg1_len = integer_zero_node;
5036 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
5038 arg2_tree = ffecom_ptr_to_expr (arg2);
5041 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5043 arg3_tree = NULL_TREE;
5045 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5046 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5047 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5048 TREE_CHAIN (arg1_tree) = arg2_tree;
5049 TREE_CHAIN (arg2_tree) = arg1_len;
5050 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5051 ffecom_gfrt_kindtype (gfrt),
5055 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5056 ffebld_nonter_hook (expr));
5057 if (arg3_tree != NULL_TREE)
5058 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5059 convert (TREE_TYPE (arg3_tree),
5064 case FFEINTRIN_impFGETC_subr:
5065 case FFEINTRIN_impFPUTC_subr:
5069 tree arg2_len = integer_zero_node;
5072 arg1_tree = convert (ffecom_f2c_integer_type_node,
5073 ffecom_expr (arg1));
5074 arg1_tree = ffecom_1 (ADDR_EXPR,
5075 build_pointer_type (TREE_TYPE (arg1_tree)),
5078 arg2_tree = ffecom_arg_ptr_to_expr (arg2, &arg2_len);
5080 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5082 arg3_tree = NULL_TREE;
5084 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5085 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5086 arg2_len = build_tree_list (NULL_TREE, arg2_len);
5087 TREE_CHAIN (arg1_tree) = arg2_tree;
5088 TREE_CHAIN (arg2_tree) = arg2_len;
5090 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5091 ffecom_gfrt_kindtype (gfrt),
5095 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5096 ffebld_nonter_hook (expr));
5097 if (arg3_tree != NULL_TREE)
5098 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5099 convert (TREE_TYPE (arg3_tree),
5104 case FFEINTRIN_impFSTAT_subr:
5110 arg1_tree = convert (ffecom_f2c_integer_type_node,
5111 ffecom_expr (arg1));
5112 arg1_tree = ffecom_1 (ADDR_EXPR,
5113 build_pointer_type (TREE_TYPE (arg1_tree)),
5116 arg2_tree = convert (ffecom_f2c_ptr_to_integer_type_node,
5117 ffecom_ptr_to_expr (arg2));
5120 arg3_tree = NULL_TREE;
5122 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5124 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5125 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5126 TREE_CHAIN (arg1_tree) = arg2_tree;
5127 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5128 ffecom_gfrt_kindtype (gfrt),
5132 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5133 ffebld_nonter_hook (expr));
5134 if (arg3_tree != NULL_TREE) {
5135 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5136 convert (TREE_TYPE (arg3_tree),
5142 case FFEINTRIN_impKILL_subr:
5148 arg1_tree = convert (ffecom_f2c_integer_type_node,
5149 ffecom_expr (arg1));
5150 arg1_tree = ffecom_1 (ADDR_EXPR,
5151 build_pointer_type (TREE_TYPE (arg1_tree)),
5154 arg2_tree = convert (ffecom_f2c_integer_type_node,
5155 ffecom_expr (arg2));
5156 arg2_tree = ffecom_1 (ADDR_EXPR,
5157 build_pointer_type (TREE_TYPE (arg2_tree)),
5161 arg3_tree = NULL_TREE;
5163 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5165 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5166 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5167 TREE_CHAIN (arg1_tree) = arg2_tree;
5168 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5169 ffecom_gfrt_kindtype (gfrt),
5173 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5174 ffebld_nonter_hook (expr));
5175 if (arg3_tree != NULL_TREE) {
5176 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5177 convert (TREE_TYPE (arg3_tree),
5183 case FFEINTRIN_impCTIME_subr:
5184 case FFEINTRIN_impTTYNAM_subr:
5186 tree arg1_len = integer_zero_node;
5190 arg1_tree = ffecom_arg_ptr_to_expr (arg2, &arg1_len);
5192 arg2_tree = convert (((codegen_imp == FFEINTRIN_impCTIME_subr) ?
5193 ffecom_f2c_longint_type_node :
5194 ffecom_f2c_integer_type_node),
5195 ffecom_expr (arg1));
5196 arg2_tree = ffecom_1 (ADDR_EXPR,
5197 build_pointer_type (TREE_TYPE (arg2_tree)),
5200 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5201 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5202 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5203 TREE_CHAIN (arg1_len) = arg2_tree;
5204 TREE_CHAIN (arg1_tree) = arg1_len;
5207 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5208 ffecom_gfrt_kindtype (gfrt),
5212 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5213 ffebld_nonter_hook (expr));
5214 TREE_SIDE_EFFECTS (expr_tree) = 1;
5218 case FFEINTRIN_impIRAND:
5219 case FFEINTRIN_impRAND:
5220 /* Arg defaults to 0 (normal random case) */
5225 arg1_tree = ffecom_integer_zero_node;
5227 arg1_tree = ffecom_expr (arg1);
5228 arg1_tree = convert (ffecom_f2c_integer_type_node,
5230 arg1_tree = ffecom_1 (ADDR_EXPR,
5231 build_pointer_type (TREE_TYPE (arg1_tree)),
5233 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5235 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5236 ffecom_gfrt_kindtype (gfrt),
5238 ((codegen_imp == FFEINTRIN_impIRAND) ?
5239 ffecom_f2c_integer_type_node :
5240 ffecom_f2c_real_type_node),
5242 dest_tree, dest, dest_used,
5244 ffebld_nonter_hook (expr));
5248 case FFEINTRIN_impFTELL_subr:
5249 case FFEINTRIN_impUMASK_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)),
5261 arg2_tree = NULL_TREE;
5263 arg2_tree = ffecom_expr_w (NULL_TREE, arg2);
5265 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5266 ffecom_gfrt_kindtype (gfrt),
5269 build_tree_list (NULL_TREE, arg1_tree),
5270 NULL_TREE, NULL, NULL, NULL_TREE,
5272 ffebld_nonter_hook (expr));
5273 if (arg2_tree != NULL_TREE) {
5274 expr_tree = ffecom_modify (NULL_TREE, arg2_tree,
5275 convert (TREE_TYPE (arg2_tree),
5281 case FFEINTRIN_impCPU_TIME:
5282 case FFEINTRIN_impSECOND_subr:
5286 arg1_tree = ffecom_expr_w (NULL_TREE, arg1);
5289 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5290 ffecom_gfrt_kindtype (gfrt),
5294 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5295 ffebld_nonter_hook (expr));
5298 = ffecom_modify (NULL_TREE, arg1_tree,
5299 convert (TREE_TYPE (arg1_tree),
5304 case FFEINTRIN_impDTIME_subr:
5305 case FFEINTRIN_impETIME_subr:
5310 result_tree = ffecom_expr_w (NULL_TREE, arg2);
5312 arg1_tree = ffecom_ptr_to_expr (arg1);
5314 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5315 ffecom_gfrt_kindtype (gfrt),
5318 build_tree_list (NULL_TREE, arg1_tree),
5319 NULL_TREE, NULL, NULL, NULL_TREE,
5321 ffebld_nonter_hook (expr));
5322 expr_tree = ffecom_modify (NULL_TREE, result_tree,
5323 convert (TREE_TYPE (result_tree),
5328 /* Straightforward calls of libf2c routines: */
5329 case FFEINTRIN_impABORT:
5330 case FFEINTRIN_impACCESS:
5331 case FFEINTRIN_impBESJ0:
5332 case FFEINTRIN_impBESJ1:
5333 case FFEINTRIN_impBESJN:
5334 case FFEINTRIN_impBESY0:
5335 case FFEINTRIN_impBESY1:
5336 case FFEINTRIN_impBESYN:
5337 case FFEINTRIN_impCHDIR_func:
5338 case FFEINTRIN_impCHMOD_func:
5339 case FFEINTRIN_impDATE:
5340 case FFEINTRIN_impDATE_AND_TIME:
5341 case FFEINTRIN_impDBESJ0:
5342 case FFEINTRIN_impDBESJ1:
5343 case FFEINTRIN_impDBESJN:
5344 case FFEINTRIN_impDBESY0:
5345 case FFEINTRIN_impDBESY1:
5346 case FFEINTRIN_impDBESYN:
5347 case FFEINTRIN_impDTIME_func:
5348 case FFEINTRIN_impETIME_func:
5349 case FFEINTRIN_impFGETC_func:
5350 case FFEINTRIN_impFGET_func:
5351 case FFEINTRIN_impFNUM:
5352 case FFEINTRIN_impFPUTC_func:
5353 case FFEINTRIN_impFPUT_func:
5354 case FFEINTRIN_impFSEEK:
5355 case FFEINTRIN_impFSTAT_func:
5356 case FFEINTRIN_impFTELL_func:
5357 case FFEINTRIN_impGERROR:
5358 case FFEINTRIN_impGETARG:
5359 case FFEINTRIN_impGETCWD_func:
5360 case FFEINTRIN_impGETENV:
5361 case FFEINTRIN_impGETGID:
5362 case FFEINTRIN_impGETLOG:
5363 case FFEINTRIN_impGETPID:
5364 case FFEINTRIN_impGETUID:
5365 case FFEINTRIN_impGMTIME:
5366 case FFEINTRIN_impHOSTNM_func:
5367 case FFEINTRIN_impIDATE_unix:
5368 case FFEINTRIN_impIDATE_vxt:
5369 case FFEINTRIN_impIERRNO:
5370 case FFEINTRIN_impISATTY:
5371 case FFEINTRIN_impITIME:
5372 case FFEINTRIN_impKILL_func:
5373 case FFEINTRIN_impLINK_func:
5374 case FFEINTRIN_impLNBLNK:
5375 case FFEINTRIN_impLSTAT_func:
5376 case FFEINTRIN_impLTIME:
5377 case FFEINTRIN_impMCLOCK8:
5378 case FFEINTRIN_impMCLOCK:
5379 case FFEINTRIN_impPERROR:
5380 case FFEINTRIN_impRENAME_func:
5381 case FFEINTRIN_impSECNDS:
5382 case FFEINTRIN_impSECOND_func:
5383 case FFEINTRIN_impSLEEP:
5384 case FFEINTRIN_impSRAND:
5385 case FFEINTRIN_impSTAT_func:
5386 case FFEINTRIN_impSYMLNK_func:
5387 case FFEINTRIN_impSYSTEM_CLOCK:
5388 case FFEINTRIN_impSYSTEM_func:
5389 case FFEINTRIN_impTIME8:
5390 case FFEINTRIN_impTIME_unix:
5391 case FFEINTRIN_impTIME_vxt:
5392 case FFEINTRIN_impUMASK_func:
5393 case FFEINTRIN_impUNLINK_func:
5396 case FFEINTRIN_impCTIME_func: /* CHARACTER functions not handled here. */
5397 case FFEINTRIN_impFDATE_func: /* CHARACTER functions not handled here. */
5398 case FFEINTRIN_impTTYNAM_func: /* CHARACTER functions not handled here. */
5399 case FFEINTRIN_impNONE:
5400 case FFEINTRIN_imp: /* Hush up gcc warning. */
5401 fprintf (stderr, "No %s implementation.\n",
5402 ffeintrin_name_implementation (ffebld_symter_implementation (ffebld_left (expr))));
5403 assert ("unimplemented intrinsic" == NULL);
5404 return error_mark_node;
5407 assert (gfrt != FFECOM_gfrt); /* Must have an implementation! */
5409 expr_tree = ffecom_arglist_expr_ (ffecom_gfrt_args_ (gfrt),
5410 ffebld_right (expr));
5412 return ffecom_call_ (ffecom_gfrt_tree_ (gfrt), ffecom_gfrt_kindtype (gfrt),
5413 (ffe_is_f2c_library () && ffecom_gfrt_complex_[gfrt]),
5415 expr_tree, dest_tree, dest, dest_used,
5417 ffebld_nonter_hook (expr));
5419 /* See bottom of this file for f2c transforms used to determine
5420 many of the above implementations. The info seems to confuse
5421 Emacs's C mode indentation, which is why it's been moved to
5422 the bottom of this source file. */
5425 /* For power (exponentiation) where right-hand operand is type INTEGER,
5426 generate in-line code to do it the fast way (which, if the operand
5427 is a constant, might just mean a series of multiplies). */
5430 ffecom_expr_power_integer_ (ffebld expr)
5432 tree l = ffecom_expr (ffebld_left (expr));
5433 tree r = ffecom_expr (ffebld_right (expr));
5434 tree ltype = TREE_TYPE (l);
5435 tree rtype = TREE_TYPE (r);
5436 tree result = NULL_TREE;
5438 if (l == error_mark_node
5439 || r == error_mark_node)
5440 return error_mark_node;
5442 if (TREE_CODE (r) == INTEGER_CST)
5444 int sgn = tree_int_cst_sgn (r);
5447 return convert (ltype, integer_one_node);
5449 if ((TREE_CODE (ltype) == INTEGER_TYPE)
5452 /* Reciprocal of integer is either 0, -1, or 1, so after
5453 calculating that (which we leave to the back end to do
5454 or not do optimally), don't bother with any multiplying. */
5456 result = ffecom_tree_divide_ (ltype,
5457 convert (ltype, integer_one_node),
5459 NULL_TREE, NULL, NULL, NULL_TREE);
5460 r = ffecom_1 (NEGATE_EXPR,
5463 if ((TREE_INT_CST_LOW (r) & 1) == 0)
5464 result = ffecom_1 (ABS_EXPR, rtype,
5468 /* Generate appropriate series of multiplies, preceded
5469 by divide if the exponent is negative. */
5475 l = ffecom_tree_divide_ (ltype,
5476 convert (ltype, integer_one_node),
5478 NULL_TREE, NULL, NULL,
5479 ffebld_nonter_hook (expr));
5480 r = ffecom_1 (NEGATE_EXPR, rtype, r);
5481 assert (TREE_CODE (r) == INTEGER_CST);
5483 if (tree_int_cst_sgn (r) < 0)
5484 { /* The "most negative" number. */
5485 r = ffecom_1 (NEGATE_EXPR, rtype,
5486 ffecom_2 (RSHIFT_EXPR, rtype,
5490 l = ffecom_2 (MULT_EXPR, ltype,
5498 if (TREE_INT_CST_LOW (r) & 1)
5500 if (result == NULL_TREE)
5503 result = ffecom_2 (MULT_EXPR, ltype,
5508 r = ffecom_2 (RSHIFT_EXPR, rtype,
5511 if (integer_zerop (r))
5513 assert (TREE_CODE (r) == INTEGER_CST);
5516 l = ffecom_2 (MULT_EXPR, ltype,
5523 /* Though rhs isn't a constant, in-line code cannot be expanded
5524 while transforming dummies
5525 because the back end cannot be easily convinced to generate
5526 stores (MODIFY_EXPR), handle temporaries, and so on before
5527 all the appropriate rtx's have been generated for things like
5528 dummy args referenced in rhs -- which doesn't happen until
5529 store_parm_decls() is called (expand_function_start, I believe,
5530 does the actual rtx-stuffing of PARM_DECLs).
5532 So, in this case, let the caller generate the call to the
5533 run-time-library function to evaluate the power for us. */
5535 if (ffecom_transform_only_dummies_)
5538 /* Right-hand operand not a constant, expand in-line code to figure
5539 out how to do the multiplies, &c.
5541 The returned expression is expressed this way in GNU C, where l and
5544 ({ typeof (r) rtmp = r;
5545 typeof (l) ltmp = l;
5552 if ((basetypeof (l) == basetypeof (int))
5555 result = ((typeof (l)) 1) / ltmp;
5556 if ((ltmp < 0) && (((-rtmp) & 1) == 0))
5562 if ((basetypeof (l) != basetypeof (int))
5565 ltmp = ((typeof (l)) 1) / ltmp;
5569 rtmp = -(rtmp >> 1);
5577 if ((rtmp >>= 1) == 0)
5586 Note that some of the above is compile-time collapsable, such as
5587 the first part of the if statements that checks the base type of
5588 l against int. The if statements are phrased that way to suggest
5589 an easy way to generate the if/else constructs here, knowing that
5590 the back end should (and probably does) eliminate the resulting
5591 dead code (either the int case or the non-int case), something
5592 it couldn't do without the redundant phrasing, requiring explicit
5593 dead-code elimination here, which would be kind of difficult to
5600 tree basetypeof_l_is_int;
5605 = build_int_2 ((TREE_CODE (ltype) == INTEGER_TYPE), 0);
5607 se = expand_start_stmt_expr (/*has_scope=*/1);
5609 ffecom_start_compstmt ();
5612 rtmp = ffecom_make_tempvar ("power_r", rtype,
5613 FFETARGET_charactersizeNONE, -1);
5614 ltmp = ffecom_make_tempvar ("power_l", ltype,
5615 FFETARGET_charactersizeNONE, -1);
5616 result = ffecom_make_tempvar ("power_res", ltype,
5617 FFETARGET_charactersizeNONE, -1);
5618 if (TREE_CODE (ltype) == COMPLEX_TYPE
5619 || TREE_CODE (ltype) == RECORD_TYPE)
5620 divide = ffecom_make_tempvar ("power_div", ltype,
5621 FFETARGET_charactersizeNONE, -1);
5628 hook = ffebld_nonter_hook (expr);
5630 assert (TREE_CODE (hook) == TREE_VEC);
5631 assert (TREE_VEC_LENGTH (hook) == 4);
5632 rtmp = TREE_VEC_ELT (hook, 0);
5633 ltmp = TREE_VEC_ELT (hook, 1);
5634 result = TREE_VEC_ELT (hook, 2);
5635 divide = TREE_VEC_ELT (hook, 3);
5636 if (TREE_CODE (ltype) == COMPLEX_TYPE
5637 || TREE_CODE (ltype) == RECORD_TYPE)
5644 expand_expr_stmt (ffecom_modify (void_type_node,
5647 expand_expr_stmt (ffecom_modify (void_type_node,
5650 expand_start_cond (ffecom_truth_value
5651 (ffecom_2 (EQ_EXPR, integer_type_node,
5653 convert (rtype, integer_zero_node))),
5655 expand_expr_stmt (ffecom_modify (void_type_node,
5657 convert (ltype, integer_one_node)));
5658 expand_start_else ();
5659 if (! integer_zerop (basetypeof_l_is_int))
5661 expand_start_cond (ffecom_2 (LT_EXPR, integer_type_node,
5664 integer_zero_node)),
5666 expand_expr_stmt (ffecom_modify (void_type_node,
5670 convert (ltype, integer_one_node),
5672 NULL_TREE, NULL, NULL,
5674 expand_start_cond (ffecom_truth_value
5675 (ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
5676 ffecom_2 (LT_EXPR, integer_type_node,
5679 integer_zero_node)),
5680 ffecom_2 (EQ_EXPR, integer_type_node,
5681 ffecom_2 (BIT_AND_EXPR,
5683 ffecom_1 (NEGATE_EXPR,
5689 integer_zero_node)))),
5691 expand_expr_stmt (ffecom_modify (void_type_node,
5693 ffecom_1 (NEGATE_EXPR,
5697 expand_start_else ();
5699 expand_expr_stmt (ffecom_modify (void_type_node,
5701 convert (ltype, integer_one_node)));
5702 expand_start_cond (ffecom_truth_value
5703 (ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
5704 ffecom_truth_value_invert
5705 (basetypeof_l_is_int),
5706 ffecom_2 (LT_EXPR, integer_type_node,
5709 integer_zero_node)))),
5711 expand_expr_stmt (ffecom_modify (void_type_node,
5715 convert (ltype, integer_one_node),
5717 NULL_TREE, NULL, NULL,
5719 expand_expr_stmt (ffecom_modify (void_type_node,
5721 ffecom_1 (NEGATE_EXPR, rtype,
5723 expand_start_cond (ffecom_truth_value
5724 (ffecom_2 (LT_EXPR, integer_type_node,
5726 convert (rtype, integer_zero_node))),
5728 expand_expr_stmt (ffecom_modify (void_type_node,
5730 ffecom_1 (NEGATE_EXPR, rtype,
5731 ffecom_2 (RSHIFT_EXPR,
5734 integer_one_node))));
5735 expand_expr_stmt (ffecom_modify (void_type_node,
5737 ffecom_2 (MULT_EXPR, ltype,
5742 expand_start_loop (1);
5743 expand_start_cond (ffecom_truth_value
5744 (ffecom_2 (BIT_AND_EXPR, rtype,
5746 convert (rtype, integer_one_node))),
5748 expand_expr_stmt (ffecom_modify (void_type_node,
5750 ffecom_2 (MULT_EXPR, ltype,
5754 expand_exit_loop_if_false (NULL,
5756 (ffecom_modify (rtype,
5758 ffecom_2 (RSHIFT_EXPR,
5761 integer_one_node))));
5762 expand_expr_stmt (ffecom_modify (void_type_node,
5764 ffecom_2 (MULT_EXPR, ltype,
5769 if (!integer_zerop (basetypeof_l_is_int))
5771 expand_expr_stmt (result);
5773 t = ffecom_end_compstmt ();
5775 result = expand_end_stmt_expr (se);
5777 /* This code comes from c-parse.in, after its expand_end_stmt_expr. */
5779 if (TREE_CODE (t) == BLOCK)
5781 /* Make a BIND_EXPR for the BLOCK already made. */
5782 result = build (BIND_EXPR, TREE_TYPE (result),
5783 NULL_TREE, result, t);
5784 /* Remove the block from the tree at this point.
5785 It gets put back at the proper place
5786 when the BIND_EXPR is expanded. */
5796 /* ffecom_expr_transform_ -- Transform symbols in expr
5798 ffebld expr; // FFE expression.
5799 ffecom_expr_transform_ (expr);
5801 Recursive descent on expr while transforming any untransformed SYMTERs. */
5804 ffecom_expr_transform_ (ffebld expr)
5814 switch (ffebld_op (expr))
5816 case FFEBLD_opSYMTER:
5817 s = ffebld_symter (expr);
5818 t = ffesymbol_hook (s).decl_tree;
5819 if ((t == NULL_TREE)
5820 && ((ffesymbol_kind (s) != FFEINFO_kindNONE)
5821 || ((ffesymbol_where (s) != FFEINFO_whereNONE)
5822 && (ffesymbol_where (s) != FFEINFO_whereINTRINSIC))))
5824 s = ffecom_sym_transform_ (s);
5825 t = ffesymbol_hook (s).decl_tree; /* Sfunc expr non-dummy,
5828 break; /* Ok if (t == NULL) here. */
5831 ffecom_expr_transform_ (ffebld_head (expr));
5832 expr = ffebld_trail (expr);
5833 goto tail_recurse; /* :::::::::::::::::::: */
5839 switch (ffebld_arity (expr))
5842 ffecom_expr_transform_ (ffebld_left (expr));
5843 expr = ffebld_right (expr);
5844 goto tail_recurse; /* :::::::::::::::::::: */
5847 expr = ffebld_left (expr);
5848 goto tail_recurse; /* :::::::::::::::::::: */
5857 /* Make a type based on info in live f2c.h file. */
5860 ffecom_f2c_make_type_ (tree *type, int tcode, const char *name)
5864 case FFECOM_f2ccodeCHAR:
5865 *type = make_signed_type (CHAR_TYPE_SIZE);
5868 case FFECOM_f2ccodeSHORT:
5869 *type = make_signed_type (SHORT_TYPE_SIZE);
5872 case FFECOM_f2ccodeINT:
5873 *type = make_signed_type (INT_TYPE_SIZE);
5876 case FFECOM_f2ccodeLONG:
5877 *type = make_signed_type (LONG_TYPE_SIZE);
5880 case FFECOM_f2ccodeLONGLONG:
5881 *type = make_signed_type (LONG_LONG_TYPE_SIZE);
5884 case FFECOM_f2ccodeCHARPTR:
5885 *type = build_pointer_type (DEFAULT_SIGNED_CHAR
5886 ? signed_char_type_node
5887 : unsigned_char_type_node);
5890 case FFECOM_f2ccodeFLOAT:
5891 *type = make_node (REAL_TYPE);
5892 TYPE_PRECISION (*type) = FLOAT_TYPE_SIZE;
5893 layout_type (*type);
5896 case FFECOM_f2ccodeDOUBLE:
5897 *type = make_node (REAL_TYPE);
5898 TYPE_PRECISION (*type) = DOUBLE_TYPE_SIZE;
5899 layout_type (*type);
5902 case FFECOM_f2ccodeLONGDOUBLE:
5903 *type = make_node (REAL_TYPE);
5904 TYPE_PRECISION (*type) = LONG_DOUBLE_TYPE_SIZE;
5905 layout_type (*type);
5908 case FFECOM_f2ccodeTWOREALS:
5909 *type = ffecom_make_complex_type_ (ffecom_f2c_real_type_node);
5912 case FFECOM_f2ccodeTWODOUBLEREALS:
5913 *type = ffecom_make_complex_type_ (ffecom_f2c_doublereal_type_node);
5917 assert ("unexpected FFECOM_f2ccodeXYZZY!" == NULL);
5918 *type = error_mark_node;
5922 pushdecl (build_decl (TYPE_DECL,
5923 ffecom_get_invented_identifier ("__g77_f2c_%s", name),
5927 /* Set the f2c list-directed-I/O code for whatever (integral) type has the
5931 ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size,
5937 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
5938 if ((t = ffecom_tree_type[bt][j]) != NULL_TREE
5939 && compare_tree_int (TYPE_SIZE (t), size) == 0)
5941 assert (code != -1);
5942 ffecom_f2c_typecode_[bt][j] = code;
5947 /* Finish up globals after doing all program units in file
5949 Need to handle only uninitialized COMMON areas. */
5952 ffecom_finish_global_ (ffeglobal global)
5958 if (ffeglobal_type (global) != FFEGLOBAL_typeCOMMON)
5961 if (ffeglobal_common_init (global))
5964 cbt = ffeglobal_hook (global);
5965 if ((cbt == NULL_TREE)
5966 || !ffeglobal_common_have_size (global))
5967 return global; /* No need to make common, never ref'd. */
5969 DECL_EXTERNAL (cbt) = 0;
5971 /* Give the array a size now. */
5973 size = build_int_2 ((ffeglobal_common_size (global)
5974 + ffeglobal_common_pad (global)) - 1,
5977 cbtype = TREE_TYPE (cbt);
5978 TYPE_DOMAIN (cbtype) = build_range_type (integer_type_node,
5981 if (!TREE_TYPE (size))
5982 TREE_TYPE (size) = TYPE_DOMAIN (cbtype);
5983 layout_type (cbtype);
5985 cbt = start_decl (cbt, FALSE);
5986 assert (cbt == ffeglobal_hook (global));
5988 finish_decl (cbt, NULL_TREE, FALSE);
5993 /* Finish up any untransformed symbols. */
5996 ffecom_finish_symbol_transform_ (ffesymbol s)
5998 if ((s == NULL) || (TREE_CODE (current_function_decl) == ERROR_MARK))
6001 /* It's easy to know to transform an untransformed symbol, to make sure
6002 we put out debugging info for it. But COMMON variables, unlike
6003 EQUIVALENCE ones, aren't given declarations in addition to the
6004 tree expressions that specify offsets, because COMMON variables
6005 can be referenced in the outer scope where only dummy arguments
6006 (PARM_DECLs) should really be seen. To be safe, just don't do any
6007 VAR_DECLs for COMMON variables when we transform them for real
6008 use, and therefore we do all the VAR_DECL creating here. */
6010 if (ffesymbol_hook (s).decl_tree == NULL_TREE)
6012 if (ffesymbol_kind (s) != FFEINFO_kindNONE
6013 || (ffesymbol_where (s) != FFEINFO_whereNONE
6014 && ffesymbol_where (s) != FFEINFO_whereINTRINSIC
6015 && ffesymbol_where (s) != FFEINFO_whereDUMMY))
6016 /* Not transformed, and not CHARACTER*(*), and not a dummy
6017 argument, which can happen only if the entry point names
6018 it "rides in on" are all invalidated for other reasons. */
6019 s = ffecom_sym_transform_ (s);
6022 if ((ffesymbol_where (s) == FFEINFO_whereCOMMON)
6023 && (ffesymbol_hook (s).decl_tree != error_mark_node))
6025 /* This isn't working, at least for dbxout. The .s file looks
6026 okay to me (burley), but in gdb 4.9 at least, the variables
6027 appear to reside somewhere outside of the common area, so
6028 it doesn't make sense to mislead anyone by generating the info
6029 on those variables until this is fixed. NOTE: Same problem
6030 with EQUIVALENCE, sadly...see similar #if later. */
6031 ffecom_member_phase2_ (ffesymbol_storage (ffesymbol_common (s)),
6032 ffesymbol_storage (s));
6038 /* Append underscore(s) to name before calling get_identifier. "us"
6039 is nonzero if the name already contains an underscore and thus
6040 needs two underscores appended. */
6043 ffecom_get_appended_identifier_ (char us, const char *name)
6049 newname = xmalloc ((i = strlen (name)) + 1
6050 + ffe_is_underscoring ()
6052 memcpy (newname, name, i);
6054 newname[i + us] = '_';
6055 newname[i + 1 + us] = '\0';
6056 id = get_identifier (newname);
6063 /* Decide whether to append underscore to name before calling
6067 ffecom_get_external_identifier_ (ffesymbol s)
6070 const char *name = ffesymbol_text (s);
6072 /* If name is a built-in name, just return it as is. */
6074 if (!ffe_is_underscoring ()
6075 || (strcmp (name, FFETARGET_nameBLANK_COMMON) == 0)
6076 #if FFETARGET_isENFORCED_MAIN_NAME
6077 || (strcmp (name, FFETARGET_nameENFORCED_NAME) == 0)
6079 || (strcmp (name, FFETARGET_nameUNNAMED_MAIN) == 0)
6081 || (strcmp (name, FFETARGET_nameUNNAMED_BLOCK_DATA) == 0))
6082 return get_identifier (name);
6084 us = ffe_is_second_underscore ()
6085 ? (strchr (name, '_') != NULL)
6088 return ffecom_get_appended_identifier_ (us, name);
6091 /* Decide whether to append underscore to internal name before calling
6094 This is for non-external, top-function-context names only. Transform
6095 identifier so it doesn't conflict with the transformed result
6096 of using a _different_ external name. E.g. if "CALL FOO" is
6097 transformed into "FOO_();", then the variable in "FOO_ = 3"
6098 must be transformed into something that does not conflict, since
6099 these two things should be independent.
6101 The transformation is as follows. If the name does not contain
6102 an underscore, there is no possible conflict, so just return.
6103 If the name does contain an underscore, then transform it just
6104 like we transform an external identifier. */
6107 ffecom_get_identifier_ (const char *name)
6109 /* If name does not contain an underscore, just return it as is. */
6111 if (!ffe_is_underscoring ()
6112 || (strchr (name, '_') == NULL))
6113 return get_identifier (name);
6115 return ffecom_get_appended_identifier_ (ffe_is_second_underscore (),
6119 /* ffecom_gen_sfuncdef_ -- Generate definition of statement function
6122 ffesymbol s; // kindFUNCTION, whereIMMEDIATE.
6123 t = ffecom_gen_sfuncdef_(s,ffesymbol_basictype(s),
6124 ffesymbol_kindtype(s));
6126 Call after setting up containing function and getting trees for all
6130 ffecom_gen_sfuncdef_ (ffesymbol s, ffeinfoBasictype bt, ffeinfoKindtype kt)
6132 ffebld expr = ffesymbol_sfexpr (s);
6136 bool charfunc = (bt == FFEINFO_basictypeCHARACTER);
6137 static bool recurse = FALSE;
6138 int old_lineno = lineno;
6139 const char *old_input_filename = input_filename;
6141 ffecom_nested_entry_ = s;
6143 /* For now, we don't have a handy pointer to where the sfunc is actually
6144 defined, though that should be easy to add to an ffesymbol. (The
6145 token/where info available might well point to the place where the type
6146 of the sfunc is declared, especially if that precedes the place where
6147 the sfunc itself is defined, which is typically the case.) We should
6148 put out a null pointer rather than point somewhere wrong, but I want to
6149 see how it works at this point. */
6151 input_filename = ffesymbol_where_filename (s);
6152 lineno = ffesymbol_where_filelinenum (s);
6154 /* Pretransform the expression so any newly discovered things belong to the
6155 outer program unit, not to the statement function. */
6157 ffecom_expr_transform_ (expr);
6159 /* Make sure no recursive invocation of this fn (a specific case of failing
6160 to pretransform an sfunc's expression, i.e. where its expression
6161 references another untransformed sfunc) happens. */
6166 push_f_function_context ();
6169 type = void_type_node;
6172 type = ffecom_tree_type[bt][kt];
6173 if (type == NULL_TREE)
6174 type = integer_type_node; /* _sym_exec_transition reports
6178 start_function (ffecom_get_identifier_ (ffesymbol_text (s)),
6179 build_function_type (type, NULL_TREE),
6180 1, /* nested/inline */
6181 0); /* TREE_PUBLIC */
6183 /* We don't worry about COMPLEX return values here, because this is
6184 entirely internal to our code, and gcc has the ability to return COMPLEX
6185 directly as a value. */
6188 { /* Prepend arg for where result goes. */
6191 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
6193 result = ffecom_get_invented_identifier ("__g77_%s", "result");
6195 ffecom_char_enhance_arg_ (&type, s); /* Ignore returned length. */
6197 type = build_pointer_type (type);
6198 result = build_decl (PARM_DECL, result, type);
6200 push_parm_decl (result);
6203 result = NULL_TREE; /* Not ref'd if !charfunc. */
6205 ffecom_push_dummy_decls_ (ffesymbol_dummyargs (s), TRUE);
6207 store_parm_decls (0);
6209 ffecom_start_compstmt ();
6215 ffetargetCharacterSize sz = ffesymbol_size (s);
6218 result_length = build_int_2 (sz, 0);
6219 TREE_TYPE (result_length) = ffecom_f2c_ftnlen_type_node;
6221 ffecom_prepare_let_char_ (sz, expr);
6223 ffecom_prepare_end ();
6225 ffecom_let_char_ (result, result_length, sz, expr);
6226 expand_null_return ();
6230 ffecom_prepare_expr (expr);
6232 ffecom_prepare_end ();
6234 expand_return (ffecom_modify (NULL_TREE,
6235 DECL_RESULT (current_function_decl),
6236 ffecom_expr (expr)));
6240 ffecom_end_compstmt ();
6242 func = current_function_decl;
6243 finish_function (1);
6245 pop_f_function_context ();
6249 lineno = old_lineno;
6250 input_filename = old_input_filename;
6252 ffecom_nested_entry_ = NULL;
6258 ffecom_gfrt_args_ (ffecomGfrt ix)
6260 return ffecom_gfrt_argstring_[ix];
6264 ffecom_gfrt_tree_ (ffecomGfrt ix)
6266 if (ffecom_gfrt_[ix] == NULL_TREE)
6267 ffecom_make_gfrt_ (ix);
6269 return ffecom_1 (ADDR_EXPR,
6270 build_pointer_type (TREE_TYPE (ffecom_gfrt_[ix])),
6274 /* Return initialize-to-zero expression for this VAR_DECL. */
6276 /* A somewhat evil way to prevent the garbage collector
6277 from collecting 'tree' structures. */
6278 #define NUM_TRACKED_CHUNK 63
6279 static struct tree_ggc_tracker
6281 struct tree_ggc_tracker *next;
6282 tree trees[NUM_TRACKED_CHUNK];
6283 } *tracker_head = NULL;
6286 mark_tracker_head (void *arg)
6288 struct tree_ggc_tracker *head;
6291 for (head = * (struct tree_ggc_tracker **) arg;
6296 for (i = 0; i < NUM_TRACKED_CHUNK; i++)
6297 ggc_mark_tree (head->trees[i]);
6302 ffecom_save_tree_forever (tree t)
6305 if (tracker_head != NULL)
6306 for (i = 0; i < NUM_TRACKED_CHUNK; i++)
6307 if (tracker_head->trees[i] == NULL)
6309 tracker_head->trees[i] = t;
6314 /* Need to allocate a new block. */
6315 struct tree_ggc_tracker *old_head = tracker_head;
6317 tracker_head = ggc_alloc (sizeof (*tracker_head));
6318 tracker_head->next = old_head;
6319 tracker_head->trees[0] = t;
6320 for (i = 1; i < NUM_TRACKED_CHUNK; i++)
6321 tracker_head->trees[i] = NULL;
6326 ffecom_init_zero_ (tree decl)
6329 int incremental = TREE_STATIC (decl);
6330 tree type = TREE_TYPE (decl);
6334 make_decl_rtl (decl, NULL);
6335 assemble_variable (decl, TREE_PUBLIC (decl) ? 1 : 0, 0, 1);
6338 if ((TREE_CODE (type) != ARRAY_TYPE)
6339 && (TREE_CODE (type) != RECORD_TYPE)
6340 && (TREE_CODE (type) != UNION_TYPE)
6342 init = convert (type, integer_zero_node);
6343 else if (!incremental)
6345 init = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
6346 TREE_CONSTANT (init) = 1;
6347 TREE_STATIC (init) = 1;
6351 assemble_zeros (int_size_in_bytes (type));
6352 init = error_mark_node;
6359 ffecom_intrinsic_ichar_ (tree tree_type, ffebld arg,
6365 switch (ffebld_op (arg))
6367 case FFEBLD_opCONTER: /* For F90, check 0-length. */
6368 if (ffetarget_length_character1
6369 (ffebld_constant_character1
6370 (ffebld_conter (arg))) == 0)
6372 *maybe_tree = integer_zero_node;
6373 return convert (tree_type, integer_zero_node);
6376 *maybe_tree = integer_one_node;
6377 expr_tree = build_int_2 (*ffetarget_text_character1
6378 (ffebld_constant_character1
6379 (ffebld_conter (arg))),
6381 TREE_TYPE (expr_tree) = tree_type;
6384 case FFEBLD_opSYMTER:
6385 case FFEBLD_opARRAYREF:
6386 case FFEBLD_opFUNCREF:
6387 case FFEBLD_opSUBSTR:
6388 ffecom_char_args_ (&expr_tree, &length_tree, arg);
6390 if ((expr_tree == error_mark_node)
6391 || (length_tree == error_mark_node))
6393 *maybe_tree = error_mark_node;
6394 return error_mark_node;
6397 if (integer_zerop (length_tree))
6399 *maybe_tree = integer_zero_node;
6400 return convert (tree_type, integer_zero_node);
6404 = ffecom_1 (INDIRECT_REF,
6405 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
6408 = ffecom_2 (ARRAY_REF,
6409 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
6412 expr_tree = convert (tree_type, expr_tree);
6414 if (TREE_CODE (length_tree) == INTEGER_CST)
6415 *maybe_tree = integer_one_node;
6416 else /* Must check length at run time. */
6418 = ffecom_truth_value
6419 (ffecom_2 (GT_EXPR, integer_type_node,
6421 ffecom_f2c_ftnlen_zero_node));
6424 case FFEBLD_opPAREN:
6425 case FFEBLD_opCONVERT:
6426 if (ffeinfo_size (ffebld_info (arg)) == 0)
6428 *maybe_tree = integer_zero_node;
6429 return convert (tree_type, integer_zero_node);
6431 return ffecom_intrinsic_ichar_ (tree_type, ffebld_left (arg),
6434 case FFEBLD_opCONCATENATE:
6441 expr_left = ffecom_intrinsic_ichar_ (tree_type, ffebld_left (arg),
6443 expr_right = ffecom_intrinsic_ichar_ (tree_type, ffebld_right (arg),
6445 *maybe_tree = ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
6448 expr_tree = ffecom_3 (COND_EXPR, tree_type,
6456 assert ("bad op in ICHAR" == NULL);
6457 return error_mark_node;
6461 /* ffecom_intrinsic_len_ -- Return length info for char arg (LEN())
6465 length_arg = ffecom_intrinsic_len_ (expr);
6467 Handles CHARACTER-type CONTER, SYMTER, SUBSTR, ARRAYREF, and FUNCREF
6468 subexpressions by constructing the appropriate tree for the
6469 length-of-character-text argument in a calling sequence. */
6472 ffecom_intrinsic_len_ (ffebld expr)
6474 ffetargetCharacter1 val;
6477 switch (ffebld_op (expr))
6479 case FFEBLD_opCONTER:
6480 val = ffebld_constant_character1 (ffebld_conter (expr));
6481 length = build_int_2 (ffetarget_length_character1 (val), 0);
6482 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6485 case FFEBLD_opSYMTER:
6487 ffesymbol s = ffebld_symter (expr);
6490 item = ffesymbol_hook (s).decl_tree;
6491 if (item == NULL_TREE)
6493 s = ffecom_sym_transform_ (s);
6494 item = ffesymbol_hook (s).decl_tree;
6496 if (ffesymbol_kind (s) == FFEINFO_kindENTITY)
6498 if (ffesymbol_size (s) == FFETARGET_charactersizeNONE)
6499 length = ffesymbol_hook (s).length_tree;
6502 length = build_int_2 (ffesymbol_size (s), 0);
6503 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6506 else if (item == error_mark_node)
6507 length = error_mark_node;
6508 else /* FFEINFO_kindFUNCTION: */
6513 case FFEBLD_opARRAYREF:
6514 length = ffecom_intrinsic_len_ (ffebld_left (expr));
6517 case FFEBLD_opSUBSTR:
6521 ffebld thing = ffebld_right (expr);
6525 assert (ffebld_op (thing) == FFEBLD_opITEM);
6526 start = ffebld_head (thing);
6527 thing = ffebld_trail (thing);
6528 assert (ffebld_trail (thing) == NULL);
6529 end = ffebld_head (thing);
6531 length = ffecom_intrinsic_len_ (ffebld_left (expr));
6533 if (length == error_mark_node)
6542 length = convert (ffecom_f2c_ftnlen_type_node,
6548 start_tree = convert (ffecom_f2c_ftnlen_type_node,
6549 ffecom_expr (start));
6551 if (start_tree == error_mark_node)
6553 length = error_mark_node;
6559 length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6560 ffecom_f2c_ftnlen_one_node,
6561 ffecom_2 (MINUS_EXPR,
6562 ffecom_f2c_ftnlen_type_node,
6568 end_tree = convert (ffecom_f2c_ftnlen_type_node,
6571 if (end_tree == error_mark_node)
6573 length = error_mark_node;
6577 length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6578 ffecom_f2c_ftnlen_one_node,
6579 ffecom_2 (MINUS_EXPR,
6580 ffecom_f2c_ftnlen_type_node,
6581 end_tree, start_tree));
6587 case FFEBLD_opCONCATENATE:
6589 = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6590 ffecom_intrinsic_len_ (ffebld_left (expr)),
6591 ffecom_intrinsic_len_ (ffebld_right (expr)));
6594 case FFEBLD_opFUNCREF:
6595 case FFEBLD_opCONVERT:
6596 length = build_int_2 (ffebld_size (expr), 0);
6597 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6601 assert ("bad op for single char arg expr" == NULL);
6602 length = ffecom_f2c_ftnlen_zero_node;
6606 assert (length != NULL_TREE);
6611 /* Handle CHARACTER assignments.
6613 Generates code to do the assignment. Used by ordinary assignment
6614 statement handler ffecom_let_stmt and by statement-function
6615 handler to generate code for a statement function. */
6618 ffecom_let_char_ (tree dest_tree, tree dest_length,
6619 ffetargetCharacterSize dest_size, ffebld source)
6621 ffecomConcatList_ catlist;
6626 if ((dest_tree == error_mark_node)
6627 || (dest_length == error_mark_node))
6630 assert (dest_tree != NULL_TREE);
6631 assert (dest_length != NULL_TREE);
6633 /* Source might be an opCONVERT, which just means it is a different size
6634 than the destination. Since the underlying implementation here handles
6635 that (directly or via the s_copy or s_cat run-time-library functions),
6636 we don't need the "convenience" of an opCONVERT that tells us to
6637 truncate or blank-pad, particularly since the resulting implementation
6638 would probably be slower than otherwise. */
6640 while (ffebld_op (source) == FFEBLD_opCONVERT)
6641 source = ffebld_left (source);
6643 catlist = ffecom_concat_list_new_ (source, dest_size);
6644 switch (ffecom_concat_list_count_ (catlist))
6646 case 0: /* Shouldn't happen, but in case it does... */
6647 ffecom_concat_list_kill_ (catlist);
6648 source_tree = null_pointer_node;
6649 source_length = ffecom_f2c_ftnlen_zero_node;
6650 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6651 TREE_CHAIN (expr_tree) = build_tree_list (NULL_TREE, source_tree);
6652 TREE_CHAIN (TREE_CHAIN (expr_tree))
6653 = build_tree_list (NULL_TREE, dest_length);
6654 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6655 = build_tree_list (NULL_TREE, source_length);
6657 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCOPY, expr_tree, NULL_TREE);
6658 TREE_SIDE_EFFECTS (expr_tree) = 1;
6660 expand_expr_stmt (expr_tree);
6664 case 1: /* The (fairly) easy case. */
6665 ffecom_char_args_ (&source_tree, &source_length,
6666 ffecom_concat_list_expr_ (catlist, 0));
6667 ffecom_concat_list_kill_ (catlist);
6668 assert (source_tree != NULL_TREE);
6669 assert (source_length != NULL_TREE);
6671 if ((source_tree == error_mark_node)
6672 || (source_length == error_mark_node))
6678 = ffecom_1 (INDIRECT_REF,
6679 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6683 = ffecom_2 (ARRAY_REF,
6684 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6689 = ffecom_1 (INDIRECT_REF,
6690 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6694 = ffecom_2 (ARRAY_REF,
6695 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6700 expr_tree = ffecom_modify (void_type_node, dest_tree, source_tree);
6702 expand_expr_stmt (expr_tree);
6707 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6708 TREE_CHAIN (expr_tree) = build_tree_list (NULL_TREE, source_tree);
6709 TREE_CHAIN (TREE_CHAIN (expr_tree))
6710 = build_tree_list (NULL_TREE, dest_length);
6711 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6712 = build_tree_list (NULL_TREE, source_length);
6714 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCOPY, expr_tree, NULL_TREE);
6715 TREE_SIDE_EFFECTS (expr_tree) = 1;
6717 expand_expr_stmt (expr_tree);
6721 default: /* Must actually concatenate things. */
6725 /* Heavy-duty concatenation. */
6728 int count = ffecom_concat_list_count_ (catlist);
6740 = ffecom_push_tempvar (ffecom_f2c_ftnlen_type_node,
6741 FFETARGET_charactersizeNONE, count, TRUE);
6742 item_array = items = ffecom_push_tempvar (ffecom_f2c_address_type_node,
6743 FFETARGET_charactersizeNONE,
6749 hook = ffebld_nonter_hook (source);
6751 assert (TREE_CODE (hook) == TREE_VEC);
6752 assert (TREE_VEC_LENGTH (hook) == 2);
6753 length_array = lengths = TREE_VEC_ELT (hook, 0);
6754 item_array = items = TREE_VEC_ELT (hook, 1);
6758 for (i = 0; i < count; ++i)
6760 ffecom_char_args_ (&citem, &clength,
6761 ffecom_concat_list_expr_ (catlist, i));
6762 if ((citem == error_mark_node)
6763 || (clength == error_mark_node))
6765 ffecom_concat_list_kill_ (catlist);
6770 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (items),
6771 ffecom_modify (void_type_node,
6772 ffecom_2 (ARRAY_REF,
6773 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array))),
6775 build_int_2 (i, 0)),
6779 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (lengths),
6780 ffecom_modify (void_type_node,
6781 ffecom_2 (ARRAY_REF,
6782 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array))),
6784 build_int_2 (i, 0)),
6789 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6790 TREE_CHAIN (expr_tree)
6791 = build_tree_list (NULL_TREE,
6792 ffecom_1 (ADDR_EXPR,
6793 build_pointer_type (TREE_TYPE (items)),
6795 TREE_CHAIN (TREE_CHAIN (expr_tree))
6796 = build_tree_list (NULL_TREE,
6797 ffecom_1 (ADDR_EXPR,
6798 build_pointer_type (TREE_TYPE (lengths)),
6800 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6803 ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
6804 convert (ffecom_f2c_ftnlen_type_node,
6805 build_int_2 (count, 0))));
6806 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree))))
6807 = build_tree_list (NULL_TREE, dest_length);
6809 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCAT, expr_tree, NULL_TREE);
6810 TREE_SIDE_EFFECTS (expr_tree) = 1;
6812 expand_expr_stmt (expr_tree);
6815 ffecom_concat_list_kill_ (catlist);
6818 /* ffecom_make_gfrt_ -- Make initial info for run-time routine
6821 ffecom_make_gfrt_(ix);
6823 Assumes gfrt_[ix] is NULL_TREE, and replaces it with the FUNCTION_DECL
6824 for the indicated run-time routine (ix). */
6827 ffecom_make_gfrt_ (ffecomGfrt ix)
6832 switch (ffecom_gfrt_type_[ix])
6834 case FFECOM_rttypeVOID_:
6835 ttype = void_type_node;
6838 case FFECOM_rttypeVOIDSTAR_:
6839 ttype = TREE_TYPE (null_pointer_node); /* `void *'. */
6842 case FFECOM_rttypeFTNINT_:
6843 ttype = ffecom_f2c_ftnint_type_node;
6846 case FFECOM_rttypeINTEGER_:
6847 ttype = ffecom_f2c_integer_type_node;
6850 case FFECOM_rttypeLONGINT_:
6851 ttype = ffecom_f2c_longint_type_node;
6854 case FFECOM_rttypeLOGICAL_:
6855 ttype = ffecom_f2c_logical_type_node;
6858 case FFECOM_rttypeREAL_F2C_:
6859 ttype = double_type_node;
6862 case FFECOM_rttypeREAL_GNU_:
6863 ttype = float_type_node;
6866 case FFECOM_rttypeCOMPLEX_F2C_:
6867 ttype = void_type_node;
6870 case FFECOM_rttypeCOMPLEX_GNU_:
6871 ttype = ffecom_f2c_complex_type_node;
6874 case FFECOM_rttypeDOUBLE_:
6875 ttype = double_type_node;
6878 case FFECOM_rttypeDOUBLEREAL_:
6879 ttype = ffecom_f2c_doublereal_type_node;
6882 case FFECOM_rttypeDBLCMPLX_F2C_:
6883 ttype = void_type_node;
6886 case FFECOM_rttypeDBLCMPLX_GNU_:
6887 ttype = ffecom_f2c_doublecomplex_type_node;
6890 case FFECOM_rttypeCHARACTER_:
6891 ttype = void_type_node;
6896 assert ("bad rttype" == NULL);
6900 ttype = build_function_type (ttype, NULL_TREE);
6901 t = build_decl (FUNCTION_DECL,
6902 get_identifier (ffecom_gfrt_name_[ix]),
6904 DECL_EXTERNAL (t) = 1;
6905 TREE_READONLY (t) = ffecom_gfrt_const_[ix] ? 1 : 0;
6906 TREE_PUBLIC (t) = 1;
6907 TREE_THIS_VOLATILE (t) = ffecom_gfrt_volatile_[ix] ? 1 : 0;
6909 /* Sanity check: A function that's const cannot be volatile. */
6911 assert (ffecom_gfrt_const_[ix] ? !ffecom_gfrt_volatile_[ix] : 1);
6913 /* Sanity check: A function that's const cannot return complex. */
6915 assert (ffecom_gfrt_const_[ix] ? !ffecom_gfrt_complex_[ix] : 1);
6917 t = start_decl (t, TRUE);
6919 finish_decl (t, NULL_TREE, TRUE);
6921 ffecom_gfrt_[ix] = t;
6924 /* Phase 1 pass over each member of a COMMON/EQUIVALENCE group. */
6927 ffecom_member_phase1_ (ffestorag mst UNUSED, ffestorag st)
6929 ffesymbol s = ffestorag_symbol (st);
6931 if (ffesymbol_namelisted (s))
6932 ffecom_member_namelisted_ = TRUE;
6935 /* Phase 2 pass over each member of a COMMON/EQUIVALENCE group. Declare
6936 the member so debugger will see it. Otherwise nobody should be
6937 referencing the member. */
6940 ffecom_member_phase2_ (ffestorag mst, ffestorag st)
6948 || ((mt = ffestorag_hook (mst)) == NULL)
6949 || (mt == error_mark_node))
6953 || ((s = ffestorag_symbol (st)) == NULL))
6956 type = ffecom_type_localvar_ (s,
6957 ffesymbol_basictype (s),
6958 ffesymbol_kindtype (s));
6959 if (type == error_mark_node)
6962 t = build_decl (VAR_DECL,
6963 ffecom_get_identifier_ (ffesymbol_text (s)),
6966 TREE_STATIC (t) = TREE_STATIC (mt);
6967 DECL_INITIAL (t) = NULL_TREE;
6968 TREE_ASM_WRITTEN (t) = 1;
6972 gen_rtx (MEM, TYPE_MODE (type),
6973 plus_constant (XEXP (DECL_RTL (mt), 0),
6974 ffestorag_modulo (mst)
6975 + ffestorag_offset (st)
6976 - ffestorag_offset (mst))));
6978 t = start_decl (t, FALSE);
6980 finish_decl (t, NULL_TREE, FALSE);
6983 /* Prepare source expression for assignment into a destination perhaps known
6984 to be of a specific size. */
6987 ffecom_prepare_let_char_ (ffetargetCharacterSize dest_size, ffebld source)
6989 ffecomConcatList_ catlist;
6994 tree tempvar = NULL_TREE;
6996 while (ffebld_op (source) == FFEBLD_opCONVERT)
6997 source = ffebld_left (source);
6999 catlist = ffecom_concat_list_new_ (source, dest_size);
7000 count = ffecom_concat_list_count_ (catlist);
7005 = ffecom_make_tempvar ("let_char_len", ffecom_f2c_ftnlen_type_node,
7006 FFETARGET_charactersizeNONE, count);
7008 = ffecom_make_tempvar ("let_char_item", ffecom_f2c_address_type_node,
7009 FFETARGET_charactersizeNONE, count);
7011 tempvar = make_tree_vec (2);
7012 TREE_VEC_ELT (tempvar, 0) = ltmp;
7013 TREE_VEC_ELT (tempvar, 1) = itmp;
7016 for (i = 0; i < count; ++i)
7017 ffecom_prepare_arg_ptr_to_expr (ffecom_concat_list_expr_ (catlist, i));
7019 ffecom_concat_list_kill_ (catlist);
7023 ffebld_nonter_set_hook (source, tempvar);
7024 current_binding_level->prep_state = 1;
7028 /* ffecom_push_dummy_decls_ -- Transform dummy args, push parm decls in order
7030 Ignores STAR (alternate-return) dummies. All other get exec-transitioned
7031 (which generates their trees) and then their trees get push_parm_decl'd.
7033 The second arg is TRUE if the dummies are for a statement function, in
7034 which case lengths are not pushed for character arguments (since they are
7035 always known by both the caller and the callee, though the code allows
7036 for someday permitting CHAR*(*) stmtfunc dummies). */
7039 ffecom_push_dummy_decls_ (ffebld dummy_list, bool stmtfunc)
7046 ffecom_transform_only_dummies_ = TRUE;
7048 /* First push the parms corresponding to actual dummy "contents". */
7050 for (dumlist = dummy_list; dumlist != NULL; dumlist = ffebld_trail (dumlist))
7052 dummy = ffebld_head (dumlist);
7053 switch (ffebld_op (dummy))
7057 continue; /* Forget alternate returns. */
7062 assert (ffebld_op (dummy) == FFEBLD_opSYMTER);
7063 s = ffebld_symter (dummy);
7064 parm = ffesymbol_hook (s).decl_tree;
7065 if (parm == NULL_TREE)
7067 s = ffecom_sym_transform_ (s);
7068 parm = ffesymbol_hook (s).decl_tree;
7069 assert (parm != NULL_TREE);
7071 if (parm != error_mark_node)
7072 push_parm_decl (parm);
7075 /* Then, for CHARACTER dummies, push the parms giving their lengths. */
7077 for (dumlist = dummy_list; dumlist != NULL; dumlist = ffebld_trail (dumlist))
7079 dummy = ffebld_head (dumlist);
7080 switch (ffebld_op (dummy))
7084 continue; /* Forget alternate returns, they mean
7090 s = ffebld_symter (dummy);
7091 if (ffesymbol_basictype (s) != FFEINFO_basictypeCHARACTER)
7092 continue; /* Only looking for CHARACTER arguments. */
7093 if (stmtfunc && (ffesymbol_size (s) != FFETARGET_charactersizeNONE))
7094 continue; /* Stmtfunc arg with known size needs no
7096 if (ffesymbol_kind (s) != FFEINFO_kindENTITY)
7097 continue; /* Only looking for variables and arrays. */
7098 parm = ffesymbol_hook (s).length_tree;
7099 assert (parm != NULL_TREE);
7100 if (parm != error_mark_node)
7101 push_parm_decl (parm);
7104 ffecom_transform_only_dummies_ = FALSE;
7107 /* ffecom_start_progunit_ -- Beginning of program unit
7109 Does GNU back end stuff necessary to teach it about the start of its
7110 equivalent of a Fortran program unit. */
7113 ffecom_start_progunit_ ()
7115 ffesymbol fn = ffecom_primary_entry_;
7117 tree id; /* Identifier (name) of function. */
7118 tree type; /* Type of function. */
7119 tree result; /* Result of function. */
7120 ffeinfoBasictype bt;
7124 ffeglobalType egt = FFEGLOBAL_type;
7127 bool altentries = (ffecom_num_entrypoints_ != 0);
7130 && (ffecom_primary_entry_kind_ == FFEINFO_kindFUNCTION)
7131 && (ffecom_master_bt_ == FFEINFO_basictypeNONE);
7132 bool main_program = FALSE;
7133 int old_lineno = lineno;
7134 const char *old_input_filename = input_filename;
7136 assert (fn != NULL);
7137 assert (ffesymbol_hook (fn).decl_tree == NULL_TREE);
7139 input_filename = ffesymbol_where_filename (fn);
7140 lineno = ffesymbol_where_filelinenum (fn);
7142 switch (ffecom_primary_entry_kind_)
7144 case FFEINFO_kindPROGRAM:
7145 main_program = TRUE;
7146 gt = FFEGLOBAL_typeMAIN;
7147 bt = FFEINFO_basictypeNONE;
7148 kt = FFEINFO_kindtypeNONE;
7149 type = ffecom_tree_fun_type_void;
7154 case FFEINFO_kindBLOCKDATA:
7155 gt = FFEGLOBAL_typeBDATA;
7156 bt = FFEINFO_basictypeNONE;
7157 kt = FFEINFO_kindtypeNONE;
7158 type = ffecom_tree_fun_type_void;
7163 case FFEINFO_kindFUNCTION:
7164 gt = FFEGLOBAL_typeFUNC;
7165 egt = FFEGLOBAL_typeEXT;
7166 bt = ffesymbol_basictype (fn);
7167 kt = ffesymbol_kindtype (fn);
7168 if (bt == FFEINFO_basictypeNONE)
7170 ffeimplic_establish_symbol (fn);
7171 if (ffesymbol_funcresult (fn) != NULL)
7172 ffeimplic_establish_symbol (ffesymbol_funcresult (fn));
7173 bt = ffesymbol_basictype (fn);
7174 kt = ffesymbol_kindtype (fn);
7178 charfunc = cmplxfunc = FALSE;
7179 else if (bt == FFEINFO_basictypeCHARACTER)
7180 charfunc = TRUE, cmplxfunc = FALSE;
7181 else if ((bt == FFEINFO_basictypeCOMPLEX)
7182 && ffesymbol_is_f2c (fn)
7184 charfunc = FALSE, cmplxfunc = TRUE;
7186 charfunc = cmplxfunc = FALSE;
7188 if (multi || charfunc)
7189 type = ffecom_tree_fun_type_void;
7190 else if (ffesymbol_is_f2c (fn) && !altentries)
7191 type = ffecom_tree_fun_type[bt][kt];
7193 type = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
7195 if ((type == NULL_TREE)
7196 || (TREE_TYPE (type) == NULL_TREE))
7197 type = ffecom_tree_fun_type_void; /* _sym_exec_transition. */
7200 case FFEINFO_kindSUBROUTINE:
7201 gt = FFEGLOBAL_typeSUBR;
7202 egt = FFEGLOBAL_typeEXT;
7203 bt = FFEINFO_basictypeNONE;
7204 kt = FFEINFO_kindtypeNONE;
7205 if (ffecom_is_altreturning_)
7206 type = ffecom_tree_subr_type;
7208 type = ffecom_tree_fun_type_void;
7214 assert ("say what??" == NULL);
7216 case FFEINFO_kindANY:
7217 gt = FFEGLOBAL_typeANY;
7218 bt = FFEINFO_basictypeNONE;
7219 kt = FFEINFO_kindtypeNONE;
7220 type = error_mark_node;
7228 id = ffecom_get_invented_identifier ("__g77_masterfun_%s",
7229 ffesymbol_text (fn));
7231 #if FFETARGET_isENFORCED_MAIN
7232 else if (main_program)
7233 id = get_identifier (FFETARGET_nameENFORCED_MAIN_NAME);
7236 id = ffecom_get_external_identifier_ (fn);
7240 0, /* nested/inline */
7241 !altentries); /* TREE_PUBLIC */
7243 TREE_USED (current_function_decl) = 1; /* Avoid spurious warning if altentries. */
7246 && ((g = ffesymbol_global (fn)) != NULL)
7247 && ((ffeglobal_type (g) == gt)
7248 || (ffeglobal_type (g) == egt)))
7250 ffeglobal_set_hook (g, current_function_decl);
7253 /* Arg handling needs exec-transitioned ffesymbols to work with. But
7254 exec-transitioning needs current_function_decl to be filled in. So we
7255 do these things in two phases. */
7258 { /* 1st arg identifies which entrypoint. */
7259 ffecom_which_entrypoint_decl_
7260 = build_decl (PARM_DECL,
7261 ffecom_get_invented_identifier ("__g77_%s",
7262 "which_entrypoint"),
7264 push_parm_decl (ffecom_which_entrypoint_decl_);
7270 { /* Arg for result (return value). */
7275 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
7277 type = ffecom_tree_type[FFEINFO_basictypeCOMPLEX][kt];
7279 type = ffecom_multi_type_node_;
7281 result = ffecom_get_invented_identifier ("__g77_%s", "result");
7283 /* Make length arg _and_ enhance type info for CHAR arg itself. */
7286 length = ffecom_char_enhance_arg_ (&type, fn);
7288 length = NULL_TREE; /* Not ref'd if !charfunc. */
7290 type = build_pointer_type (type);
7291 result = build_decl (PARM_DECL, result, type);
7293 push_parm_decl (result);
7295 ffecom_multi_retval_ = result;
7297 ffecom_func_result_ = result;
7301 push_parm_decl (length);
7302 ffecom_func_length_ = length;
7306 if (ffecom_primary_entry_is_proc_)
7309 arglist = ffecom_master_arglist_;
7311 arglist = ffesymbol_dummyargs (fn);
7312 ffecom_push_dummy_decls_ (arglist, FALSE);
7315 if (TREE_CODE (current_function_decl) != ERROR_MARK)
7316 store_parm_decls (main_program ? 1 : 0);
7318 ffecom_start_compstmt ();
7319 /* Disallow temp vars at this level. */
7320 current_binding_level->prep_state = 2;
7322 lineno = old_lineno;
7323 input_filename = old_input_filename;
7325 /* This handles any symbols still untransformed, in case -g specified.
7326 This used to be done in ffecom_finish_progunit, but it turns out to
7327 be necessary to do it here so that statement functions are
7328 expanded before code. But don't bother for BLOCK DATA. */
7330 if (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA)
7331 ffesymbol_drive (ffecom_finish_symbol_transform_);
7334 /* ffecom_sym_transform_ -- Transform FFE sym into backend sym
7337 ffecom_sym_transform_(s);
7339 The ffesymbol_hook info for s is updated with appropriate backend info
7343 ffecom_sym_transform_ (ffesymbol s)
7345 tree t; /* Transformed thingy. */
7346 tree tlen; /* Length if CHAR*(*). */
7347 bool addr; /* Is t the address of the thingy? */
7348 ffeinfoBasictype bt;
7351 int old_lineno = lineno;
7352 const char *old_input_filename = input_filename;
7354 /* Must ensure special ASSIGN variables are declared at top of outermost
7355 block, else they'll end up in the innermost block when their first
7356 ASSIGN is seen, which leaves them out of scope when they're the
7357 subject of a GOTO or I/O statement.
7359 We make this variable even if -fugly-assign. Just let it go unused,
7360 in case it turns out there are cases where we really want to use this
7361 variable anyway (e.g. ASSIGN to INTEGER*2 variable). */
7363 if (! ffecom_transform_only_dummies_
7364 && ffesymbol_assigned (s)
7365 && ! ffesymbol_hook (s).assign_tree)
7366 s = ffecom_sym_transform_assign_ (s);
7368 if (ffesymbol_sfdummyparent (s) == NULL)
7370 input_filename = ffesymbol_where_filename (s);
7371 lineno = ffesymbol_where_filelinenum (s);
7375 ffesymbol sf = ffesymbol_sfdummyparent (s);
7377 input_filename = ffesymbol_where_filename (sf);
7378 lineno = ffesymbol_where_filelinenum (sf);
7381 bt = ffeinfo_basictype (ffebld_info (s));
7382 kt = ffeinfo_kindtype (ffebld_info (s));
7388 switch (ffesymbol_kind (s))
7390 case FFEINFO_kindNONE:
7391 switch (ffesymbol_where (s))
7393 case FFEINFO_whereDUMMY: /* Subroutine or function. */
7394 assert (ffecom_transform_only_dummies_);
7396 /* Before 0.4, this could be ENTITY/DUMMY, but see
7397 ffestu_sym_end_transition -- no longer true (in particular, if
7398 it could be an ENTITY, it _will_ be made one, so that
7399 possibility won't come through here). So we never make length
7400 arg for CHARACTER type. */
7402 t = build_decl (PARM_DECL,
7403 ffecom_get_identifier_ (ffesymbol_text (s)),
7404 ffecom_tree_ptr_to_subr_type);
7405 DECL_ARTIFICIAL (t) = 1;
7409 case FFEINFO_whereGLOBAL: /* Subroutine or function. */
7410 assert (!ffecom_transform_only_dummies_);
7412 if (((g = ffesymbol_global (s)) != NULL)
7413 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
7414 || (ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
7415 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
7416 && (ffeglobal_hook (g) != NULL_TREE)
7417 && ffe_is_globals ())
7419 t = ffeglobal_hook (g);
7423 t = build_decl (FUNCTION_DECL,
7424 ffecom_get_external_identifier_ (s),
7425 ffecom_tree_subr_type); /* Assume subr. */
7426 DECL_EXTERNAL (t) = 1;
7427 TREE_PUBLIC (t) = 1;
7429 t = start_decl (t, FALSE);
7430 finish_decl (t, NULL_TREE, FALSE);
7433 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
7434 || (ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
7435 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
7436 ffeglobal_set_hook (g, t);
7438 ffecom_save_tree_forever (t);
7443 assert ("NONE where unexpected" == NULL);
7445 case FFEINFO_whereANY:
7450 case FFEINFO_kindENTITY:
7451 switch (ffeinfo_where (ffesymbol_info (s)))
7454 case FFEINFO_whereCONSTANT:
7455 /* ~~Debugging info needed? */
7456 assert (!ffecom_transform_only_dummies_);
7457 t = error_mark_node; /* Shouldn't ever see this in expr. */
7460 case FFEINFO_whereLOCAL:
7461 assert (!ffecom_transform_only_dummies_);
7464 ffestorag st = ffesymbol_storage (s);
7468 && (ffestorag_size (st) == 0))
7470 t = error_mark_node;
7474 type = ffecom_type_localvar_ (s, bt, kt);
7476 if (type == error_mark_node)
7478 t = error_mark_node;
7483 && (ffestorag_parent (st) != NULL))
7484 { /* Child of EQUIVALENCE parent. */
7487 ffetargetOffset offset;
7489 est = ffestorag_parent (st);
7490 ffecom_transform_equiv_ (est);
7492 et = ffestorag_hook (est);
7493 assert (et != NULL_TREE);
7495 if (! TREE_STATIC (et))
7496 put_var_into_stack (et);
7498 offset = ffestorag_modulo (est)
7499 + ffestorag_offset (ffesymbol_storage (s))
7500 - ffestorag_offset (est);
7502 ffecom_debug_kludge_ (et, "EQUIVALENCE", s, type, offset);
7504 /* (t_type *) (((char *) &et) + offset) */
7506 t = convert (string_type_node, /* (char *) */
7507 ffecom_1 (ADDR_EXPR,
7508 build_pointer_type (TREE_TYPE (et)),
7510 t = ffecom_2 (PLUS_EXPR, TREE_TYPE (t),
7512 build_int_2 (offset, 0));
7513 t = convert (build_pointer_type (type),
7515 TREE_CONSTANT (t) = staticp (et);
7522 bool init = ffesymbol_is_init (s);
7524 t = build_decl (VAR_DECL,
7525 ffecom_get_identifier_ (ffesymbol_text (s)),
7529 || ffesymbol_namelisted (s)
7530 #ifdef FFECOM_sizeMAXSTACKITEM
7532 && (ffestorag_size (st) > FFECOM_sizeMAXSTACKITEM))
7534 || ((ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
7535 && (ffecom_primary_entry_kind_
7536 != FFEINFO_kindBLOCKDATA)
7537 && (ffesymbol_is_save (s) || ffe_is_saveall ())))
7538 TREE_STATIC (t) = !ffesymbol_attr (s, FFESYMBOL_attrADJUSTABLE);
7540 TREE_STATIC (t) = 0; /* No need to make static. */
7542 if (init || ffe_is_init_local_zero ())
7543 DECL_INITIAL (t) = error_mark_node;
7545 /* Keep -Wunused from complaining about var if it
7546 is used as sfunc arg or DATA implied-DO. */
7547 if (ffesymbol_attrs (s) & FFESYMBOL_attrsSFARG)
7548 DECL_IN_SYSTEM_HEADER (t) = 1;
7550 t = start_decl (t, FALSE);
7554 if (ffesymbol_init (s) != NULL)
7555 initexpr = ffecom_expr (ffesymbol_init (s));
7557 initexpr = ffecom_init_zero_ (t);
7559 else if (ffe_is_init_local_zero ())
7560 initexpr = ffecom_init_zero_ (t);
7562 initexpr = NULL_TREE; /* Not ref'd if !init. */
7564 finish_decl (t, initexpr, FALSE);
7566 if (st != NULL && DECL_SIZE (t) != error_mark_node)
7568 assert (TREE_CODE (DECL_SIZE_UNIT (t)) == INTEGER_CST);
7569 assert (0 == compare_tree_int (DECL_SIZE_UNIT (t),
7570 ffestorag_size (st)));
7576 case FFEINFO_whereRESULT:
7577 assert (!ffecom_transform_only_dummies_);
7579 if (bt == FFEINFO_basictypeCHARACTER)
7580 { /* Result is already in list of dummies, use
7582 t = ffecom_func_result_;
7583 tlen = ffecom_func_length_;
7587 if ((ffecom_num_entrypoints_ == 0)
7588 && (bt == FFEINFO_basictypeCOMPLEX)
7589 && (ffesymbol_is_f2c (ffecom_primary_entry_)))
7590 { /* Result is already in list of dummies, use
7592 t = ffecom_func_result_;
7596 if (ffecom_func_result_ != NULL_TREE)
7598 t = ffecom_func_result_;
7601 if ((ffecom_num_entrypoints_ != 0)
7602 && (ffecom_master_bt_ == FFEINFO_basictypeNONE))
7604 assert (ffecom_multi_retval_ != NULL_TREE);
7605 t = ffecom_1 (INDIRECT_REF, ffecom_multi_type_node_,
7606 ffecom_multi_retval_);
7607 t = ffecom_2 (COMPONENT_REF, ffecom_tree_type[bt][kt],
7608 t, ffecom_multi_fields_[bt][kt]);
7613 t = build_decl (VAR_DECL,
7614 ffecom_get_identifier_ (ffesymbol_text (s)),
7615 ffecom_tree_type[bt][kt]);
7616 TREE_STATIC (t) = 0; /* Put result on stack. */
7617 t = start_decl (t, FALSE);
7618 finish_decl (t, NULL_TREE, FALSE);
7620 ffecom_func_result_ = t;
7624 case FFEINFO_whereDUMMY:
7632 bool adjustable = FALSE; /* Conditionally adjustable? */
7634 type = ffecom_tree_type[bt][kt];
7635 if (ffesymbol_sfdummyparent (s) != NULL)
7637 if (current_function_decl == ffecom_outer_function_decl_)
7638 { /* Exec transition before sfunc
7639 context; get it later. */
7642 t = ffecom_get_identifier_ (ffesymbol_text
7643 (ffesymbol_sfdummyparent (s)));
7646 t = ffecom_get_identifier_ (ffesymbol_text (s));
7648 assert (ffecom_transform_only_dummies_);
7650 old_sizes = get_pending_sizes ();
7651 put_pending_sizes (old_sizes);
7653 if (bt == FFEINFO_basictypeCHARACTER)
7654 tlen = ffecom_char_enhance_arg_ (&type, s);
7655 type = ffecom_check_size_overflow_ (s, type, TRUE);
7657 for (dl = ffesymbol_dims (s); dl != NULL; dl = ffebld_trail (dl))
7659 if (type == error_mark_node)
7662 dim = ffebld_head (dl);
7663 assert (ffebld_op (dim) == FFEBLD_opBOUNDS);
7664 if ((ffebld_left (dim) == NULL) || ffecom_doing_entry_)
7665 low = ffecom_integer_one_node;
7667 low = ffecom_expr (ffebld_left (dim));
7668 assert (ffebld_right (dim) != NULL);
7669 if ((ffebld_op (ffebld_right (dim)) == FFEBLD_opSTAR)
7670 || ffecom_doing_entry_)
7672 /* Used to just do high=low. But for ffecom_tree_
7673 canonize_ref_, it probably is important to correctly
7674 assess the size. E.g. given COMPLEX C(*),CFUNC and
7675 C(2)=CFUNC(C), overlap can happen, while it can't
7676 for, say, C(1)=CFUNC(C(2)). */
7677 /* Even more recently used to set to INT_MAX, but that
7678 broke when some overflow checking went into the back
7679 end. Now we just leave the upper bound unspecified. */
7683 high = ffecom_expr (ffebld_right (dim));
7685 /* Determine whether array is conditionally adjustable,
7686 to decide whether back-end magic is needed.
7688 Normally the front end uses the back-end function
7689 variable_size to wrap SAVE_EXPR's around expressions
7690 affecting the size/shape of an array so that the
7691 size/shape info doesn't change during execution
7692 of the compiled code even though variables and
7693 functions referenced in those expressions might.
7695 variable_size also makes sure those saved expressions
7696 get evaluated immediately upon entry to the
7697 compiled procedure -- the front end normally doesn't
7698 have to worry about that.
7700 However, there is a problem with this that affects
7701 g77's implementation of entry points, and that is
7702 that it is _not_ true that each invocation of the
7703 compiled procedure is permitted to evaluate
7704 array size/shape info -- because it is possible
7705 that, for some invocations, that info is invalid (in
7706 which case it is "promised" -- i.e. a violation of
7707 the Fortran standard -- that the compiled code
7708 won't reference the array or its size/shape
7709 during that particular invocation).
7711 To phrase this in C terms, consider this gcc function:
7713 void foo (int *n, float (*a)[*n])
7715 // a is "pointer to array ...", fyi.
7718 Suppose that, for some invocations, it is permitted
7719 for a caller of foo to do this:
7723 Now the _written_ code for foo can take such a call
7724 into account by either testing explicitly for whether
7725 (a == NULL) || (n == NULL) -- presumably it is
7726 not permitted to reference *a in various fashions
7727 if (n == NULL) I suppose -- or it can avoid it by
7728 looking at other info (other arguments, static/global
7731 However, this won't work in gcc 2.5.8 because it'll
7732 automatically emit the code to save the "*n"
7733 expression, which'll yield a NULL dereference for
7734 the "foo (NULL, NULL)" call, something the code
7735 for foo cannot prevent.
7737 g77 definitely needs to avoid executing such
7738 code anytime the pointer to the adjustable array
7739 is NULL, because even if its bounds expressions
7740 don't have any references to possible "absent"
7741 variables like "*n" -- say all variable references
7742 are to COMMON variables, i.e. global (though in C,
7743 local static could actually make sense) -- the
7744 expressions could yield other run-time problems
7745 for allowably "dead" values in those variables.
7747 For example, let's consider a more complicated
7753 void foo (float (*a)[i/j])
7758 The above is (essentially) quite valid for Fortran
7759 but, again, for a call like "foo (NULL);", it is
7760 permitted for i and j to be undefined when the
7761 call is made. If j happened to be zero, for
7762 example, emitting the code to evaluate "i/j"
7763 could result in a run-time error.
7765 Offhand, though I don't have my F77 or F90
7766 standards handy, it might even be valid for a
7767 bounds expression to contain a function reference,
7768 in which case I doubt it is permitted for an
7769 implementation to invoke that function in the
7770 Fortran case involved here (invocation of an
7771 alternate ENTRY point that doesn't have the adjustable
7772 array as one of its arguments).
7774 So, the code that the compiler would normally emit
7775 to preevaluate the size/shape info for an
7776 adjustable array _must not_ be executed at run time
7777 in certain cases. Specifically, for Fortran,
7778 the case is when the pointer to the adjustable
7779 array == NULL. (For gnu-ish C, it might be nice
7780 for the source code itself to specify an expression
7781 that, if TRUE, inhibits execution of the code. Or
7782 reverse the sense for elegance.)
7784 (Note that g77 could use a different test than NULL,
7785 actually, since it happens to always pass an
7786 integer to the called function that specifies which
7787 entry point is being invoked. Hmm, this might
7788 solve the next problem.)
7790 One way a user could, I suppose, write "foo" so
7791 it works is to insert COND_EXPR's for the
7792 size/shape info so the dangerous stuff isn't
7793 actually done, as in:
7795 void foo (int *n, float (*a)[(a == NULL) ? 0 : *n])
7800 The next problem is that the front end needs to
7801 be able to tell the back end about the array's
7802 decl _before_ it tells it about the conditional
7803 expression to inhibit evaluation of size/shape info,
7806 To solve this, the front end needs to be able
7807 to give the back end the expression to inhibit
7808 generation of the preevaluation code _after_
7809 it makes the decl for the adjustable array.
7811 Until then, the above example using the COND_EXPR
7812 doesn't pass muster with gcc because the "(a == NULL)"
7813 part has a reference to "a", which is still
7814 undefined at that point.
7816 g77 will therefore use a different mechanism in the
7820 && ((TREE_CODE (low) != INTEGER_CST)
7821 || (high && TREE_CODE (high) != INTEGER_CST)))
7824 #if 0 /* Old approach -- see below. */
7825 if (TREE_CODE (low) != INTEGER_CST)
7826 low = ffecom_3 (COND_EXPR, integer_type_node,
7827 ffecom_adjarray_passed_ (s),
7829 ffecom_integer_zero_node);
7831 if (high && TREE_CODE (high) != INTEGER_CST)
7832 high = ffecom_3 (COND_EXPR, integer_type_node,
7833 ffecom_adjarray_passed_ (s),
7835 ffecom_integer_zero_node);
7838 /* ~~~gcc/stor-layout.c (layout_type) should do this,
7839 probably. Fixes 950302-1.f. */
7841 if (TREE_CODE (low) != INTEGER_CST)
7842 low = variable_size (low);
7844 /* ~~~Similarly, this fixes dumb0.f. The C front end
7845 does this, which is why dumb0.c would work. */
7847 if (high && TREE_CODE (high) != INTEGER_CST)
7848 high = variable_size (high);
7853 build_range_type (ffecom_integer_type_node,
7855 type = ffecom_check_size_overflow_ (s, type, TRUE);
7858 if (type == error_mark_node)
7860 t = error_mark_node;
7864 if ((ffesymbol_sfdummyparent (s) == NULL)
7865 || (ffesymbol_basictype (s) == FFEINFO_basictypeCHARACTER))
7867 type = build_pointer_type (type);
7871 t = build_decl (PARM_DECL, t, type);
7872 DECL_ARTIFICIAL (t) = 1;
7874 /* If this arg is present in every entry point's list of
7875 dummy args, then we're done. */
7877 if (ffesymbol_numentries (s)
7878 == (ffecom_num_entrypoints_ + 1))
7883 /* If variable_size in stor-layout has been called during
7884 the above, then get_pending_sizes should have the
7885 yet-to-be-evaluated saved expressions pending.
7886 Make the whole lot of them get emitted, conditionally
7887 on whether the array decl ("t" above) is not NULL. */
7890 tree sizes = get_pending_sizes ();
7895 tem = TREE_CHAIN (tem))
7897 tree temv = TREE_VALUE (tem);
7903 = ffecom_2 (COMPOUND_EXPR,
7912 = ffecom_3 (COND_EXPR,
7919 convert (TREE_TYPE (sizes),
7920 integer_zero_node));
7921 sizes = ffecom_save_tree (sizes);
7924 = tree_cons (NULL_TREE, sizes, tem);
7928 put_pending_sizes (sizes);
7934 && (ffesymbol_numentries (s)
7935 != ffecom_num_entrypoints_ + 1))
7937 = ffecom_2 (NE_EXPR, integer_type_node,
7943 && (ffesymbol_numentries (s)
7944 != ffecom_num_entrypoints_ + 1))
7946 ffebad_start (FFEBAD_MISSING_ADJARRAY_UNSUPPORTED);
7947 ffebad_here (0, ffesymbol_where_line (s),
7948 ffesymbol_where_column (s));
7949 ffebad_string (ffesymbol_text (s));
7958 case FFEINFO_whereCOMMON:
7963 ffestorag st = ffesymbol_storage (s);
7966 cs = ffesymbol_common (s); /* The COMMON area itself. */
7967 if (st != NULL) /* Else not laid out. */
7969 ffecom_transform_common_ (cs);
7970 st = ffesymbol_storage (s);
7973 type = ffecom_type_localvar_ (s, bt, kt);
7975 cg = ffesymbol_global (cs); /* The global COMMON info. */
7977 || (ffeglobal_type (cg) != FFEGLOBAL_typeCOMMON))
7980 ct = ffeglobal_hook (cg); /* The common area's tree. */
7982 if ((ct == NULL_TREE)
7984 || (type == error_mark_node))
7985 t = error_mark_node;
7988 ffetargetOffset offset;
7991 cst = ffestorag_parent (st);
7992 assert (cst == ffesymbol_storage (cs));
7994 offset = ffestorag_modulo (cst)
7995 + ffestorag_offset (st)
7996 - ffestorag_offset (cst);
7998 ffecom_debug_kludge_ (ct, "COMMON", s, type, offset);
8000 /* (t_type *) (((char *) &ct) + offset) */
8002 t = convert (string_type_node, /* (char *) */
8003 ffecom_1 (ADDR_EXPR,
8004 build_pointer_type (TREE_TYPE (ct)),
8006 t = ffecom_2 (PLUS_EXPR, TREE_TYPE (t),
8008 build_int_2 (offset, 0));
8009 t = convert (build_pointer_type (type),
8011 TREE_CONSTANT (t) = 1;
8018 case FFEINFO_whereIMMEDIATE:
8019 case FFEINFO_whereGLOBAL:
8020 case FFEINFO_whereFLEETING:
8021 case FFEINFO_whereFLEETING_CADDR:
8022 case FFEINFO_whereFLEETING_IADDR:
8023 case FFEINFO_whereINTRINSIC:
8024 case FFEINFO_whereCONSTANT_SUBOBJECT:
8026 assert ("ENTITY where unheard of" == NULL);
8028 case FFEINFO_whereANY:
8029 t = error_mark_node;
8034 case FFEINFO_kindFUNCTION:
8035 switch (ffeinfo_where (ffesymbol_info (s)))
8037 case FFEINFO_whereLOCAL: /* Me. */
8038 assert (!ffecom_transform_only_dummies_);
8039 t = current_function_decl;
8042 case FFEINFO_whereGLOBAL:
8043 assert (!ffecom_transform_only_dummies_);
8045 if (((g = ffesymbol_global (s)) != NULL)
8046 && ((ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
8047 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
8048 && (ffeglobal_hook (g) != NULL_TREE)
8049 && ffe_is_globals ())
8051 t = ffeglobal_hook (g);
8055 if (ffesymbol_is_f2c (s)
8056 && (ffesymbol_where (s) != FFEINFO_whereCONSTANT))
8057 t = ffecom_tree_fun_type[bt][kt];
8059 t = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
8061 t = build_decl (FUNCTION_DECL,
8062 ffecom_get_external_identifier_ (s),
8064 DECL_EXTERNAL (t) = 1;
8065 TREE_PUBLIC (t) = 1;
8067 t = start_decl (t, FALSE);
8068 finish_decl (t, NULL_TREE, FALSE);
8071 && ((ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
8072 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
8073 ffeglobal_set_hook (g, t);
8075 ffecom_save_tree_forever (t);
8079 case FFEINFO_whereDUMMY:
8080 assert (ffecom_transform_only_dummies_);
8082 if (ffesymbol_is_f2c (s)
8083 && (ffesymbol_where (s) != FFEINFO_whereCONSTANT))
8084 t = ffecom_tree_ptr_to_fun_type[bt][kt];
8086 t = build_pointer_type
8087 (build_function_type (ffecom_tree_type[bt][kt], NULL_TREE));
8089 t = build_decl (PARM_DECL,
8090 ffecom_get_identifier_ (ffesymbol_text (s)),
8092 DECL_ARTIFICIAL (t) = 1;
8096 case FFEINFO_whereCONSTANT: /* Statement function. */
8097 assert (!ffecom_transform_only_dummies_);
8098 t = ffecom_gen_sfuncdef_ (s, bt, kt);
8101 case FFEINFO_whereINTRINSIC:
8102 assert (!ffecom_transform_only_dummies_);
8103 break; /* Let actual references generate their
8107 assert ("FUNCTION where unheard of" == NULL);
8109 case FFEINFO_whereANY:
8110 t = error_mark_node;
8115 case FFEINFO_kindSUBROUTINE:
8116 switch (ffeinfo_where (ffesymbol_info (s)))
8118 case FFEINFO_whereLOCAL: /* Me. */
8119 assert (!ffecom_transform_only_dummies_);
8120 t = current_function_decl;
8123 case FFEINFO_whereGLOBAL:
8124 assert (!ffecom_transform_only_dummies_);
8126 if (((g = ffesymbol_global (s)) != NULL)
8127 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
8128 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
8129 && (ffeglobal_hook (g) != NULL_TREE)
8130 && ffe_is_globals ())
8132 t = ffeglobal_hook (g);
8136 t = build_decl (FUNCTION_DECL,
8137 ffecom_get_external_identifier_ (s),
8138 ffecom_tree_subr_type);
8139 DECL_EXTERNAL (t) = 1;
8140 TREE_PUBLIC (t) = 1;
8142 t = start_decl (t, FALSE);
8143 finish_decl (t, NULL_TREE, FALSE);
8146 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
8147 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
8148 ffeglobal_set_hook (g, t);
8150 ffecom_save_tree_forever (t);
8154 case FFEINFO_whereDUMMY:
8155 assert (ffecom_transform_only_dummies_);
8157 t = build_decl (PARM_DECL,
8158 ffecom_get_identifier_ (ffesymbol_text (s)),
8159 ffecom_tree_ptr_to_subr_type);
8160 DECL_ARTIFICIAL (t) = 1;
8164 case FFEINFO_whereINTRINSIC:
8165 assert (!ffecom_transform_only_dummies_);
8166 break; /* Let actual references generate their
8170 assert ("SUBROUTINE where unheard of" == NULL);
8172 case FFEINFO_whereANY:
8173 t = error_mark_node;
8178 case FFEINFO_kindPROGRAM:
8179 switch (ffeinfo_where (ffesymbol_info (s)))
8181 case FFEINFO_whereLOCAL: /* Me. */
8182 assert (!ffecom_transform_only_dummies_);
8183 t = current_function_decl;
8186 case FFEINFO_whereCOMMON:
8187 case FFEINFO_whereDUMMY:
8188 case FFEINFO_whereGLOBAL:
8189 case FFEINFO_whereRESULT:
8190 case FFEINFO_whereFLEETING:
8191 case FFEINFO_whereFLEETING_CADDR:
8192 case FFEINFO_whereFLEETING_IADDR:
8193 case FFEINFO_whereIMMEDIATE:
8194 case FFEINFO_whereINTRINSIC:
8195 case FFEINFO_whereCONSTANT:
8196 case FFEINFO_whereCONSTANT_SUBOBJECT:
8198 assert ("PROGRAM where unheard of" == NULL);
8200 case FFEINFO_whereANY:
8201 t = error_mark_node;
8206 case FFEINFO_kindBLOCKDATA:
8207 switch (ffeinfo_where (ffesymbol_info (s)))
8209 case FFEINFO_whereLOCAL: /* Me. */
8210 assert (!ffecom_transform_only_dummies_);
8211 t = current_function_decl;
8214 case FFEINFO_whereGLOBAL:
8215 assert (!ffecom_transform_only_dummies_);
8217 t = build_decl (FUNCTION_DECL,
8218 ffecom_get_external_identifier_ (s),
8219 ffecom_tree_blockdata_type);
8220 DECL_EXTERNAL (t) = 1;
8221 TREE_PUBLIC (t) = 1;
8223 t = start_decl (t, FALSE);
8224 finish_decl (t, NULL_TREE, FALSE);
8226 ffecom_save_tree_forever (t);
8230 case FFEINFO_whereCOMMON:
8231 case FFEINFO_whereDUMMY:
8232 case FFEINFO_whereRESULT:
8233 case FFEINFO_whereFLEETING:
8234 case FFEINFO_whereFLEETING_CADDR:
8235 case FFEINFO_whereFLEETING_IADDR:
8236 case FFEINFO_whereIMMEDIATE:
8237 case FFEINFO_whereINTRINSIC:
8238 case FFEINFO_whereCONSTANT:
8239 case FFEINFO_whereCONSTANT_SUBOBJECT:
8241 assert ("BLOCKDATA where unheard of" == NULL);
8243 case FFEINFO_whereANY:
8244 t = error_mark_node;
8249 case FFEINFO_kindCOMMON:
8250 switch (ffeinfo_where (ffesymbol_info (s)))
8252 case FFEINFO_whereLOCAL:
8253 assert (!ffecom_transform_only_dummies_);
8254 ffecom_transform_common_ (s);
8257 case FFEINFO_whereNONE:
8258 case FFEINFO_whereCOMMON:
8259 case FFEINFO_whereDUMMY:
8260 case FFEINFO_whereGLOBAL:
8261 case FFEINFO_whereRESULT:
8262 case FFEINFO_whereFLEETING:
8263 case FFEINFO_whereFLEETING_CADDR:
8264 case FFEINFO_whereFLEETING_IADDR:
8265 case FFEINFO_whereIMMEDIATE:
8266 case FFEINFO_whereINTRINSIC:
8267 case FFEINFO_whereCONSTANT:
8268 case FFEINFO_whereCONSTANT_SUBOBJECT:
8270 assert ("COMMON where unheard of" == NULL);
8272 case FFEINFO_whereANY:
8273 t = error_mark_node;
8278 case FFEINFO_kindCONSTRUCT:
8279 switch (ffeinfo_where (ffesymbol_info (s)))
8281 case FFEINFO_whereLOCAL:
8282 assert (!ffecom_transform_only_dummies_);
8285 case FFEINFO_whereNONE:
8286 case FFEINFO_whereCOMMON:
8287 case FFEINFO_whereDUMMY:
8288 case FFEINFO_whereGLOBAL:
8289 case FFEINFO_whereRESULT:
8290 case FFEINFO_whereFLEETING:
8291 case FFEINFO_whereFLEETING_CADDR:
8292 case FFEINFO_whereFLEETING_IADDR:
8293 case FFEINFO_whereIMMEDIATE:
8294 case FFEINFO_whereINTRINSIC:
8295 case FFEINFO_whereCONSTANT:
8296 case FFEINFO_whereCONSTANT_SUBOBJECT:
8298 assert ("CONSTRUCT where unheard of" == NULL);
8300 case FFEINFO_whereANY:
8301 t = error_mark_node;
8306 case FFEINFO_kindNAMELIST:
8307 switch (ffeinfo_where (ffesymbol_info (s)))
8309 case FFEINFO_whereLOCAL:
8310 assert (!ffecom_transform_only_dummies_);
8311 t = ffecom_transform_namelist_ (s);
8314 case FFEINFO_whereNONE:
8315 case FFEINFO_whereCOMMON:
8316 case FFEINFO_whereDUMMY:
8317 case FFEINFO_whereGLOBAL:
8318 case FFEINFO_whereRESULT:
8319 case FFEINFO_whereFLEETING:
8320 case FFEINFO_whereFLEETING_CADDR:
8321 case FFEINFO_whereFLEETING_IADDR:
8322 case FFEINFO_whereIMMEDIATE:
8323 case FFEINFO_whereINTRINSIC:
8324 case FFEINFO_whereCONSTANT:
8325 case FFEINFO_whereCONSTANT_SUBOBJECT:
8327 assert ("NAMELIST where unheard of" == NULL);
8329 case FFEINFO_whereANY:
8330 t = error_mark_node;
8336 assert ("kind unheard of" == NULL);
8338 case FFEINFO_kindANY:
8339 t = error_mark_node;
8343 ffesymbol_hook (s).decl_tree = t;
8344 ffesymbol_hook (s).length_tree = tlen;
8345 ffesymbol_hook (s).addr = addr;
8347 lineno = old_lineno;
8348 input_filename = old_input_filename;
8353 /* Transform into ASSIGNable symbol.
8355 Symbol has already been transformed, but for whatever reason, the
8356 resulting decl_tree has been deemed not usable for an ASSIGN target.
8357 (E.g. it isn't wide enough to hold a pointer.) So, here we invent
8358 another local symbol of type void * and stuff that in the assign_tree
8359 argument. The F77/F90 standards allow this implementation. */
8362 ffecom_sym_transform_assign_ (ffesymbol s)
8364 tree t; /* Transformed thingy. */
8365 int old_lineno = lineno;
8366 const char *old_input_filename = input_filename;
8368 if (ffesymbol_sfdummyparent (s) == NULL)
8370 input_filename = ffesymbol_where_filename (s);
8371 lineno = ffesymbol_where_filelinenum (s);
8375 ffesymbol sf = ffesymbol_sfdummyparent (s);
8377 input_filename = ffesymbol_where_filename (sf);
8378 lineno = ffesymbol_where_filelinenum (sf);
8381 assert (!ffecom_transform_only_dummies_);
8383 t = build_decl (VAR_DECL,
8384 ffecom_get_invented_identifier ("__g77_ASSIGN_%s",
8385 ffesymbol_text (s)),
8386 TREE_TYPE (null_pointer_node));
8388 switch (ffesymbol_where (s))
8390 case FFEINFO_whereLOCAL:
8391 /* Unlike for regular vars, SAVE status is easy to determine for
8392 ASSIGNed vars, since there's no initialization, there's no
8393 effective storage association (so "SAVE J" does not apply to
8394 K even given "EQUIVALENCE (J,K)"), there's no size issue
8395 to worry about, etc. */
8396 if ((ffesymbol_is_save (s) || ffe_is_saveall ())
8397 && (ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
8398 && (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA))
8399 TREE_STATIC (t) = 1; /* SAVEd in proc, make static. */
8401 TREE_STATIC (t) = 0; /* No need to make static. */
8404 case FFEINFO_whereCOMMON:
8405 TREE_STATIC (t) = 1; /* Assume COMMONs always SAVEd. */
8408 case FFEINFO_whereDUMMY:
8409 /* Note that twinning a DUMMY means the caller won't see
8410 the ASSIGNed value. But both F77 and F90 allow implementations
8411 to do this, i.e. disallow Fortran code that would try and
8412 take advantage of actually putting a label into a variable
8413 via a dummy argument (or any other storage association, for
8415 TREE_STATIC (t) = 0;
8419 TREE_STATIC (t) = 0;
8423 t = start_decl (t, FALSE);
8424 finish_decl (t, NULL_TREE, FALSE);
8426 ffesymbol_hook (s).assign_tree = t;
8428 lineno = old_lineno;
8429 input_filename = old_input_filename;
8434 /* Implement COMMON area in back end.
8436 Because COMMON-based variables can be referenced in the dimension
8437 expressions of dummy (adjustable) arrays, and because dummies
8438 (in the gcc back end) need to be put in the outer binding level
8439 of a function (which has two binding levels, the outer holding
8440 the dummies and the inner holding the other vars), special care
8441 must be taken to handle COMMON areas.
8443 The current strategy is basically to always tell the back end about
8444 the COMMON area as a top-level external reference to just a block
8445 of storage of the master type of that area (e.g. integer, real,
8446 character, whatever -- not a structure). As a distinct action,
8447 if initial values are provided, tell the back end about the area
8448 as a top-level non-external (initialized) area and remember not to
8449 allow further initialization or expansion of the area. Meanwhile,
8450 if no initialization happens at all, tell the back end about
8451 the largest size we've seen declared so the space does get reserved.
8452 (This function doesn't handle all that stuff, but it does some
8453 of the important things.)
8455 Meanwhile, for COMMON variables themselves, just keep creating
8456 references like *((float *) (&common_area + offset)) each time
8457 we reference the variable. In other words, don't make a VAR_DECL
8458 or any kind of component reference (like we used to do before 0.4),
8459 though we might do that as well just for debugging purposes (and
8460 stuff the rtl with the appropriate offset expression). */
8463 ffecom_transform_common_ (ffesymbol s)
8465 ffestorag st = ffesymbol_storage (s);
8466 ffeglobal g = ffesymbol_global (s);
8471 bool is_init = ffestorag_is_init (st);
8473 assert (st != NULL);
8476 || (ffeglobal_type (g) != FFEGLOBAL_typeCOMMON))
8479 /* First update the size of the area in global terms. */
8481 ffeglobal_size_common (s, ffestorag_size (st));
8483 if (!ffeglobal_common_init (g))
8484 is_init = FALSE; /* No explicit init, don't let erroneous joins init. */
8486 cbt = ffeglobal_hook (g);
8488 /* If we already have declared this common block for a previous program
8489 unit, and either we already initialized it or we don't have new
8490 initialization for it, just return what we have without changing it. */
8492 if ((cbt != NULL_TREE)
8494 || !DECL_EXTERNAL (cbt)))
8496 if (st->hook == NULL) ffestorag_set_hook (st, cbt);
8500 /* Process inits. */
8504 if (ffestorag_init (st) != NULL)
8508 /* Set the padding for the expression, so ffecom_expr
8509 knows to insert that many zeros. */
8510 switch (ffebld_op (sexp = ffestorag_init (st)))
8512 case FFEBLD_opCONTER:
8513 ffebld_conter_set_pad (sexp, ffestorag_modulo (st));
8516 case FFEBLD_opARRTER:
8517 ffebld_arrter_set_pad (sexp, ffestorag_modulo (st));
8520 case FFEBLD_opACCTER:
8521 ffebld_accter_set_pad (sexp, ffestorag_modulo (st));
8525 assert ("bad op for cmn init (pad)" == NULL);
8529 init = ffecom_expr (sexp);
8530 if (init == error_mark_node)
8531 { /* Hopefully the back end complained! */
8533 if (cbt != NULL_TREE)
8538 init = error_mark_node;
8543 /* cbtype must be permanently allocated! */
8545 /* Allocate the MAX of the areas so far, seen filewide. */
8546 high = build_int_2 ((ffeglobal_common_size (g)
8547 + ffeglobal_common_pad (g)) - 1, 0);
8548 TREE_TYPE (high) = ffecom_integer_type_node;
8551 cbtype = build_array_type (char_type_node,
8552 build_range_type (integer_type_node,
8556 cbtype = build_array_type (char_type_node, NULL_TREE);
8558 if (cbt == NULL_TREE)
8561 = build_decl (VAR_DECL,
8562 ffecom_get_external_identifier_ (s),
8564 TREE_STATIC (cbt) = 1;
8565 TREE_PUBLIC (cbt) = 1;
8570 TREE_TYPE (cbt) = cbtype;
8572 DECL_EXTERNAL (cbt) = init ? 0 : 1;
8573 DECL_INITIAL (cbt) = init ? error_mark_node : NULL_TREE;
8575 cbt = start_decl (cbt, TRUE);
8576 if (ffeglobal_hook (g) != NULL)
8577 assert (cbt == ffeglobal_hook (g));
8579 assert (!init || !DECL_EXTERNAL (cbt));
8581 /* Make sure that any type can live in COMMON and be referenced
8582 without getting a bus error. We could pick the most restrictive
8583 alignment of all entities actually placed in the COMMON, but
8584 this seems easy enough. */
8586 DECL_ALIGN (cbt) = BIGGEST_ALIGNMENT;
8587 DECL_USER_ALIGN (cbt) = 0;
8589 if (is_init && (ffestorag_init (st) == NULL))
8590 init = ffecom_init_zero_ (cbt);
8592 finish_decl (cbt, init, TRUE);
8595 ffestorag_set_init (st, ffebld_new_any ());
8599 assert (DECL_SIZE_UNIT (cbt) != NULL_TREE);
8600 assert (TREE_CODE (DECL_SIZE_UNIT (cbt)) == INTEGER_CST);
8601 assert (0 == compare_tree_int (DECL_SIZE_UNIT (cbt),
8602 (ffeglobal_common_size (g)
8603 + ffeglobal_common_pad (g))));
8606 ffeglobal_set_hook (g, cbt);
8608 ffestorag_set_hook (st, cbt);
8610 ffecom_save_tree_forever (cbt);
8613 /* Make master area for local EQUIVALENCE. */
8616 ffecom_transform_equiv_ (ffestorag eqst)
8622 bool is_init = ffestorag_is_init (eqst);
8624 assert (eqst != NULL);
8626 eqt = ffestorag_hook (eqst);
8628 if (eqt != NULL_TREE)
8631 /* Process inits. */
8635 if (ffestorag_init (eqst) != NULL)
8639 /* Set the padding for the expression, so ffecom_expr
8640 knows to insert that many zeros. */
8641 switch (ffebld_op (sexp = ffestorag_init (eqst)))
8643 case FFEBLD_opCONTER:
8644 ffebld_conter_set_pad (sexp, ffestorag_modulo (eqst));
8647 case FFEBLD_opARRTER:
8648 ffebld_arrter_set_pad (sexp, ffestorag_modulo (eqst));
8651 case FFEBLD_opACCTER:
8652 ffebld_accter_set_pad (sexp, ffestorag_modulo (eqst));
8656 assert ("bad op for eqv init (pad)" == NULL);
8660 init = ffecom_expr (sexp);
8661 if (init == error_mark_node)
8662 init = NULL_TREE; /* Hopefully the back end complained! */
8665 init = error_mark_node;
8667 else if (ffe_is_init_local_zero ())
8668 init = error_mark_node;
8672 ffecom_member_namelisted_ = FALSE;
8673 ffestorag_drive (ffestorag_list_equivs (eqst),
8674 &ffecom_member_phase1_,
8677 high = build_int_2 ((ffestorag_size (eqst)
8678 + ffestorag_modulo (eqst)) - 1, 0);
8679 TREE_TYPE (high) = ffecom_integer_type_node;
8681 eqtype = build_array_type (char_type_node,
8682 build_range_type (ffecom_integer_type_node,
8683 ffecom_integer_zero_node,
8686 eqt = build_decl (VAR_DECL,
8687 ffecom_get_invented_identifier ("__g77_equiv_%s",
8689 (ffestorag_symbol (eqst))),
8691 DECL_EXTERNAL (eqt) = 0;
8693 || ffecom_member_namelisted_
8694 #ifdef FFECOM_sizeMAXSTACKITEM
8695 || (ffestorag_size (eqst) > FFECOM_sizeMAXSTACKITEM)
8697 || ((ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
8698 && (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA)
8699 && (ffestorag_is_save (eqst) || ffe_is_saveall ())))
8700 TREE_STATIC (eqt) = 1;
8702 TREE_STATIC (eqt) = 0;
8703 TREE_PUBLIC (eqt) = 0;
8704 TREE_ADDRESSABLE (eqt) = 1; /* Ensure non-register allocation */
8705 DECL_CONTEXT (eqt) = current_function_decl;
8707 DECL_INITIAL (eqt) = error_mark_node;
8709 DECL_INITIAL (eqt) = NULL_TREE;
8711 eqt = start_decl (eqt, FALSE);
8713 /* Make sure that any type can live in EQUIVALENCE and be referenced
8714 without getting a bus error. We could pick the most restrictive
8715 alignment of all entities actually placed in the EQUIVALENCE, but
8716 this seems easy enough. */
8718 DECL_ALIGN (eqt) = BIGGEST_ALIGNMENT;
8719 DECL_USER_ALIGN (eqt) = 0;
8721 if ((!is_init && ffe_is_init_local_zero ())
8722 || (is_init && (ffestorag_init (eqst) == NULL)))
8723 init = ffecom_init_zero_ (eqt);
8725 finish_decl (eqt, init, FALSE);
8728 ffestorag_set_init (eqst, ffebld_new_any ());
8731 assert (TREE_CODE (DECL_SIZE_UNIT (eqt)) == INTEGER_CST);
8732 assert (0 == compare_tree_int (DECL_SIZE_UNIT (eqt),
8733 (ffestorag_size (eqst)
8734 + ffestorag_modulo (eqst))));
8737 ffestorag_set_hook (eqst, eqt);
8739 ffestorag_drive (ffestorag_list_equivs (eqst),
8740 &ffecom_member_phase2_,
8744 /* Implement NAMELIST in back end. See f2c/format.c for more info. */
8747 ffecom_transform_namelist_ (ffesymbol s)
8750 tree nmltype = ffecom_type_namelist_ ();
8758 static int mynumber = 0;
8760 nmlt = build_decl (VAR_DECL,
8761 ffecom_get_invented_identifier ("__g77_namelist_%d",
8764 TREE_STATIC (nmlt) = 1;
8765 DECL_INITIAL (nmlt) = error_mark_node;
8767 nmlt = start_decl (nmlt, FALSE);
8769 /* Process inits. */
8771 i = strlen (ffesymbol_text (s));
8773 high = build_int_2 (i, 0);
8774 TREE_TYPE (high) = ffecom_f2c_ftnlen_type_node;
8776 nameinit = ffecom_build_f2c_string_ (i + 1,
8777 ffesymbol_text (s));
8778 TREE_TYPE (nameinit)
8779 = build_type_variant
8782 build_range_type (ffecom_f2c_ftnlen_type_node,
8783 ffecom_f2c_ftnlen_one_node,
8786 TREE_CONSTANT (nameinit) = 1;
8787 TREE_STATIC (nameinit) = 1;
8788 nameinit = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (nameinit)),
8791 varsinit = ffecom_vardesc_array_ (s);
8792 varsinit = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (varsinit)),
8794 TREE_CONSTANT (varsinit) = 1;
8795 TREE_STATIC (varsinit) = 1;
8800 for (i = 0, b = ffesymbol_namelist (s); b != NULL; b = ffebld_trail (b))
8803 nvarsinit = build_int_2 (i, 0);
8804 TREE_TYPE (nvarsinit) = integer_type_node;
8805 TREE_CONSTANT (nvarsinit) = 1;
8806 TREE_STATIC (nvarsinit) = 1;
8808 nmlinits = build_tree_list ((field = TYPE_FIELDS (nmltype)), nameinit);
8809 TREE_CHAIN (nmlinits) = build_tree_list ((field = TREE_CHAIN (field)),
8811 TREE_CHAIN (TREE_CHAIN (nmlinits))
8812 = build_tree_list ((field = TREE_CHAIN (field)), nvarsinit);
8814 nmlinits = build (CONSTRUCTOR, nmltype, NULL_TREE, nmlinits);
8815 TREE_CONSTANT (nmlinits) = 1;
8816 TREE_STATIC (nmlinits) = 1;
8818 finish_decl (nmlt, nmlinits, FALSE);
8820 nmlt = ffecom_1 (ADDR_EXPR, build_pointer_type (nmltype), nmlt);
8825 /* A subroutine of ffecom_tree_canonize_ref_. The incoming tree is
8826 analyzed on the assumption it is calculating a pointer to be
8827 indirected through. It must return the proper decl and offset,
8828 taking into account different units of measurements for offsets. */
8831 ffecom_tree_canonize_ptr_ (tree *decl, tree *offset,
8834 switch (TREE_CODE (t))
8838 case NON_LVALUE_EXPR:
8839 ffecom_tree_canonize_ptr_ (decl, offset, TREE_OPERAND (t, 0));
8843 ffecom_tree_canonize_ptr_ (decl, offset, TREE_OPERAND (t, 0));
8844 if ((*decl == NULL_TREE)
8845 || (*decl == error_mark_node))
8848 if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST)
8850 /* An offset into COMMON. */
8851 *offset = fold (build (PLUS_EXPR, TREE_TYPE (*offset),
8852 *offset, TREE_OPERAND (t, 1)));
8853 /* Convert offset (presumably in bytes) into canonical units
8854 (presumably bits). */
8855 *offset = size_binop (MULT_EXPR,
8856 convert (bitsizetype, *offset),
8857 TYPE_SIZE (TREE_TYPE (TREE_TYPE (t))));
8860 /* Not a COMMON reference, so an unrecognized pattern. */
8861 *decl = error_mark_node;
8866 *offset = bitsize_zero_node;
8870 if (TREE_CODE (TREE_OPERAND (t, 0)) == VAR_DECL)
8872 /* A reference to COMMON. */
8873 *decl = TREE_OPERAND (t, 0);
8874 *offset = bitsize_zero_node;
8879 /* Not a COMMON reference, so an unrecognized pattern. */
8880 *decl = error_mark_node;
8885 /* Given a tree that is possibly intended for use as an lvalue, return
8886 information representing a canonical view of that tree as a decl, an
8887 offset into that decl, and a size for the lvalue.
8889 If there's no applicable decl, NULL_TREE is returned for the decl,
8890 and the other fields are left undefined.
8892 If the tree doesn't fit the recognizable forms, an ERROR_MARK node
8893 is returned for the decl, and the other fields are left undefined.
8895 Otherwise, the decl returned currently is either a VAR_DECL or a
8898 The offset returned is always valid, but of course not necessarily
8899 a constant, and not necessarily converted into the appropriate
8900 type, leaving that up to the caller (so as to avoid that overhead
8901 if the decls being looked at are different anyway).
8903 If the size cannot be determined (e.g. an adjustable array),
8904 an ERROR_MARK node is returned for the size. Otherwise, the
8905 size returned is valid, not necessarily a constant, and not
8906 necessarily converted into the appropriate type as with the
8909 Note that the offset and size expressions are expressed in the
8910 base storage units (usually bits) rather than in the units of
8911 the type of the decl, because two decls with different types
8912 might overlap but with apparently non-overlapping array offsets,
8913 whereas converting the array offsets to consistant offsets will
8914 reveal the overlap. */
8917 ffecom_tree_canonize_ref_ (tree *decl, tree *offset,
8920 /* The default path is to report a nonexistant decl. */
8926 switch (TREE_CODE (t))
8929 case IDENTIFIER_NODE:
8938 case TRUNC_DIV_EXPR:
8940 case FLOOR_DIV_EXPR:
8941 case ROUND_DIV_EXPR:
8942 case TRUNC_MOD_EXPR:
8944 case FLOOR_MOD_EXPR:
8945 case ROUND_MOD_EXPR:
8947 case EXACT_DIV_EXPR:
8948 case FIX_TRUNC_EXPR:
8950 case FIX_FLOOR_EXPR:
8951 case FIX_ROUND_EXPR:
8965 case BIT_ANDTC_EXPR:
8967 case TRUTH_ANDIF_EXPR:
8968 case TRUTH_ORIF_EXPR:
8969 case TRUTH_AND_EXPR:
8971 case TRUTH_XOR_EXPR:
8972 case TRUTH_NOT_EXPR:
8992 *offset = bitsize_zero_node;
8993 *size = TYPE_SIZE (TREE_TYPE (t));
8998 tree array = TREE_OPERAND (t, 0);
8999 tree element = TREE_OPERAND (t, 1);
9002 if ((array == NULL_TREE)
9003 || (element == NULL_TREE))
9005 *decl = error_mark_node;
9009 ffecom_tree_canonize_ref_ (decl, &init_offset, size,
9011 if ((*decl == NULL_TREE)
9012 || (*decl == error_mark_node))
9015 /* Calculate ((element - base) * NBBY) + init_offset. */
9016 *offset = fold (build (MINUS_EXPR, TREE_TYPE (element),
9018 TYPE_MIN_VALUE (TYPE_DOMAIN
9019 (TREE_TYPE (array)))));
9021 *offset = size_binop (MULT_EXPR,
9022 convert (bitsizetype, *offset),
9023 TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))));
9025 *offset = size_binop (PLUS_EXPR, init_offset, *offset);
9027 *size = TYPE_SIZE (TREE_TYPE (t));
9033 /* Most of this code is to handle references to COMMON. And so
9034 far that is useful only for calling library functions, since
9035 external (user) functions might reference common areas. But
9036 even calling an external function, it's worthwhile to decode
9037 COMMON references because if not storing into COMMON, we don't
9038 want COMMON-based arguments to gratuitously force use of a
9041 *size = TYPE_SIZE (TREE_TYPE (t));
9043 ffecom_tree_canonize_ptr_ (decl, offset,
9044 TREE_OPERAND (t, 0));
9051 case NON_LVALUE_EXPR:
9054 case COND_EXPR: /* More cases than we can handle. */
9056 case REFERENCE_EXPR:
9057 case PREDECREMENT_EXPR:
9058 case PREINCREMENT_EXPR:
9059 case POSTDECREMENT_EXPR:
9060 case POSTINCREMENT_EXPR:
9063 *decl = error_mark_node;
9068 /* Do divide operation appropriate to type of operands. */
9071 ffecom_tree_divide_ (tree tree_type, tree left, tree right,
9072 tree dest_tree, ffebld dest, bool *dest_used,
9075 if ((left == error_mark_node)
9076 || (right == error_mark_node))
9077 return error_mark_node;
9079 switch (TREE_CODE (tree_type))
9082 return ffecom_2 (TRUNC_DIV_EXPR, tree_type,
9087 if (! optimize_size)
9088 return ffecom_2 (RDIV_EXPR, tree_type,
9094 if (TREE_TYPE (tree_type)
9095 == ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1])
9096 ix = FFECOM_gfrtDIV_CC; /* Overlapping result okay. */
9098 ix = FFECOM_gfrtDIV_ZZ; /* Overlapping result okay. */
9100 left = ffecom_1 (ADDR_EXPR,
9101 build_pointer_type (TREE_TYPE (left)),
9103 left = build_tree_list (NULL_TREE, left);
9104 right = ffecom_1 (ADDR_EXPR,
9105 build_pointer_type (TREE_TYPE (right)),
9107 right = build_tree_list (NULL_TREE, right);
9108 TREE_CHAIN (left) = right;
9110 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
9111 ffecom_gfrt_kindtype (ix),
9112 ffe_is_f2c_library (),
9115 dest_tree, dest, dest_used,
9116 NULL_TREE, TRUE, hook);
9124 if (TREE_TYPE (TYPE_FIELDS (tree_type))
9125 == ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1])
9126 ix = FFECOM_gfrtDIV_CC; /* Overlapping result okay. */
9128 ix = FFECOM_gfrtDIV_ZZ; /* Overlapping result okay. */
9130 left = ffecom_1 (ADDR_EXPR,
9131 build_pointer_type (TREE_TYPE (left)),
9133 left = build_tree_list (NULL_TREE, left);
9134 right = ffecom_1 (ADDR_EXPR,
9135 build_pointer_type (TREE_TYPE (right)),
9137 right = build_tree_list (NULL_TREE, right);
9138 TREE_CHAIN (left) = right;
9140 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
9141 ffecom_gfrt_kindtype (ix),
9142 ffe_is_f2c_library (),
9145 dest_tree, dest, dest_used,
9146 NULL_TREE, TRUE, hook);
9151 return ffecom_2 (RDIV_EXPR, tree_type,
9157 /* Build type info for non-dummy variable. */
9160 ffecom_type_localvar_ (ffesymbol s, ffeinfoBasictype bt,
9169 type = ffecom_tree_type[bt][kt];
9170 if (bt == FFEINFO_basictypeCHARACTER)
9172 hight = build_int_2 (ffesymbol_size (s), 0);
9173 TREE_TYPE (hight) = ffecom_f2c_ftnlen_type_node;
9178 build_range_type (ffecom_f2c_ftnlen_type_node,
9179 ffecom_f2c_ftnlen_one_node,
9181 type = ffecom_check_size_overflow_ (s, type, FALSE);
9184 for (dl = ffesymbol_dims (s); dl != NULL; dl = ffebld_trail (dl))
9186 if (type == error_mark_node)
9189 dim = ffebld_head (dl);
9190 assert (ffebld_op (dim) == FFEBLD_opBOUNDS);
9192 if (ffebld_left (dim) == NULL)
9193 lowt = integer_one_node;
9195 lowt = ffecom_expr (ffebld_left (dim));
9197 if (TREE_CODE (lowt) != INTEGER_CST)
9198 lowt = variable_size (lowt);
9200 assert (ffebld_right (dim) != NULL);
9201 hight = ffecom_expr (ffebld_right (dim));
9203 if (TREE_CODE (hight) != INTEGER_CST)
9204 hight = variable_size (hight);
9206 type = build_array_type (type,
9207 build_range_type (ffecom_integer_type_node,
9209 type = ffecom_check_size_overflow_ (s, type, FALSE);
9215 /* Build Namelist type. */
9218 ffecom_type_namelist_ ()
9220 static tree type = NULL_TREE;
9222 if (type == NULL_TREE)
9224 static tree namefield, varsfield, nvarsfield;
9227 vardesctype = ffecom_type_vardesc_ ();
9229 type = make_node (RECORD_TYPE);
9231 vardesctype = build_pointer_type (build_pointer_type (vardesctype));
9233 namefield = ffecom_decl_field (type, NULL_TREE, "name",
9235 varsfield = ffecom_decl_field (type, namefield, "vars", vardesctype);
9236 nvarsfield = ffecom_decl_field (type, varsfield, "nvars",
9239 TYPE_FIELDS (type) = namefield;
9242 ggc_add_tree_root (&type, 1);
9248 /* Build Vardesc type. */
9251 ffecom_type_vardesc_ ()
9253 static tree type = NULL_TREE;
9254 static tree namefield, addrfield, dimsfield, typefield;
9256 if (type == NULL_TREE)
9258 type = make_node (RECORD_TYPE);
9260 namefield = ffecom_decl_field (type, NULL_TREE, "name",
9262 addrfield = ffecom_decl_field (type, namefield, "addr",
9264 dimsfield = ffecom_decl_field (type, addrfield, "dims",
9265 ffecom_f2c_ptr_to_ftnlen_type_node);
9266 typefield = ffecom_decl_field (type, dimsfield, "type",
9269 TYPE_FIELDS (type) = namefield;
9272 ggc_add_tree_root (&type, 1);
9279 ffecom_vardesc_ (ffebld expr)
9283 assert (ffebld_op (expr) == FFEBLD_opSYMTER);
9284 s = ffebld_symter (expr);
9286 if (ffesymbol_hook (s).vardesc_tree == NULL_TREE)
9289 tree vardesctype = ffecom_type_vardesc_ ();
9297 static int mynumber = 0;
9299 var = build_decl (VAR_DECL,
9300 ffecom_get_invented_identifier ("__g77_vardesc_%d",
9303 TREE_STATIC (var) = 1;
9304 DECL_INITIAL (var) = error_mark_node;
9306 var = start_decl (var, FALSE);
9308 /* Process inits. */
9310 nameinit = ffecom_build_f2c_string_ ((i = strlen (ffesymbol_text (s)))
9312 ffesymbol_text (s));
9313 TREE_TYPE (nameinit)
9314 = build_type_variant
9317 build_range_type (integer_type_node,
9319 build_int_2 (i, 0))),
9321 TREE_CONSTANT (nameinit) = 1;
9322 TREE_STATIC (nameinit) = 1;
9323 nameinit = ffecom_1 (ADDR_EXPR,
9324 build_pointer_type (TREE_TYPE (nameinit)),
9327 addrinit = ffecom_arg_ptr_to_expr (expr, &typeinit);
9329 dimsinit = ffecom_vardesc_dims_ (s);
9331 if (typeinit == NULL_TREE)
9333 ffeinfoBasictype bt = ffesymbol_basictype (s);
9334 ffeinfoKindtype kt = ffesymbol_kindtype (s);
9335 int tc = ffecom_f2c_typecode (bt, kt);
9338 typeinit = build_int_2 (tc, (tc < 0) ? -1 : 0);
9341 typeinit = ffecom_1 (NEGATE_EXPR, TREE_TYPE (typeinit), typeinit);
9343 varinits = build_tree_list ((field = TYPE_FIELDS (vardesctype)),
9345 TREE_CHAIN (varinits) = build_tree_list ((field = TREE_CHAIN (field)),
9347 TREE_CHAIN (TREE_CHAIN (varinits))
9348 = build_tree_list ((field = TREE_CHAIN (field)), dimsinit);
9349 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (varinits)))
9350 = build_tree_list ((field = TREE_CHAIN (field)), typeinit);
9352 varinits = build (CONSTRUCTOR, vardesctype, NULL_TREE, varinits);
9353 TREE_CONSTANT (varinits) = 1;
9354 TREE_STATIC (varinits) = 1;
9356 finish_decl (var, varinits, FALSE);
9358 var = ffecom_1 (ADDR_EXPR, build_pointer_type (vardesctype), var);
9360 ffesymbol_hook (s).vardesc_tree = var;
9363 return ffesymbol_hook (s).vardesc_tree;
9367 ffecom_vardesc_array_ (ffesymbol s)
9371 tree item = NULL_TREE;
9374 static int mynumber = 0;
9376 for (i = 0, list = NULL_TREE, b = ffesymbol_namelist (s);
9378 b = ffebld_trail (b), ++i)
9382 t = ffecom_vardesc_ (ffebld_head (b));
9384 if (list == NULL_TREE)
9385 list = item = build_tree_list (NULL_TREE, t);
9388 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
9389 item = TREE_CHAIN (item);
9393 item = build_array_type (build_pointer_type (ffecom_type_vardesc_ ()),
9394 build_range_type (integer_type_node,
9396 build_int_2 (i, 0)));
9397 list = build (CONSTRUCTOR, item, NULL_TREE, list);
9398 TREE_CONSTANT (list) = 1;
9399 TREE_STATIC (list) = 1;
9401 var = ffecom_get_invented_identifier ("__g77_vardesc_array_%d", mynumber++);
9402 var = build_decl (VAR_DECL, var, item);
9403 TREE_STATIC (var) = 1;
9404 DECL_INITIAL (var) = error_mark_node;
9405 var = start_decl (var, FALSE);
9406 finish_decl (var, list, FALSE);
9412 ffecom_vardesc_dims_ (ffesymbol s)
9414 if (ffesymbol_dims (s) == NULL)
9415 return convert (ffecom_f2c_ptr_to_ftnlen_type_node,
9423 tree item = NULL_TREE;
9427 tree baseoff = NULL_TREE;
9428 static int mynumber = 0;
9430 numdim = build_int_2 ((int) ffesymbol_rank (s), 0);
9431 TREE_TYPE (numdim) = ffecom_f2c_ftnlen_type_node;
9433 numelem = ffecom_expr (ffesymbol_arraysize (s));
9434 TREE_TYPE (numelem) = ffecom_f2c_ftnlen_type_node;
9437 backlist = NULL_TREE;
9438 for (b = ffesymbol_dims (s), e = ffesymbol_extents (s);
9440 b = ffebld_trail (b), e = ffebld_trail (e))
9446 if (ffebld_trail (b) == NULL)
9450 t = convert (ffecom_f2c_ftnlen_type_node,
9451 ffecom_expr (ffebld_head (e)));
9453 if (list == NULL_TREE)
9454 list = item = build_tree_list (NULL_TREE, t);
9457 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
9458 item = TREE_CHAIN (item);
9462 if (ffebld_left (ffebld_head (b)) == NULL)
9463 low = ffecom_integer_one_node;
9465 low = ffecom_expr (ffebld_left (ffebld_head (b)));
9466 low = convert (ffecom_f2c_ftnlen_type_node, low);
9468 back = build_tree_list (low, t);
9469 TREE_CHAIN (back) = backlist;
9473 for (item = backlist; item != NULL_TREE; item = TREE_CHAIN (item))
9475 if (TREE_VALUE (item) == NULL_TREE)
9476 baseoff = TREE_PURPOSE (item);
9478 baseoff = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
9479 TREE_PURPOSE (item),
9480 ffecom_2 (MULT_EXPR,
9481 ffecom_f2c_ftnlen_type_node,
9486 /* backlist now dead, along with all TREE_PURPOSEs on it. */
9488 baseoff = build_tree_list (NULL_TREE, baseoff);
9489 TREE_CHAIN (baseoff) = list;
9491 numelem = build_tree_list (NULL_TREE, numelem);
9492 TREE_CHAIN (numelem) = baseoff;
9494 numdim = build_tree_list (NULL_TREE, numdim);
9495 TREE_CHAIN (numdim) = numelem;
9497 item = build_array_type (ffecom_f2c_ftnlen_type_node,
9498 build_range_type (integer_type_node,
9501 ((int) ffesymbol_rank (s)
9503 list = build (CONSTRUCTOR, item, NULL_TREE, numdim);
9504 TREE_CONSTANT (list) = 1;
9505 TREE_STATIC (list) = 1;
9507 var = ffecom_get_invented_identifier ("__g77_dims_%d", mynumber++);
9508 var = build_decl (VAR_DECL, var, item);
9509 TREE_STATIC (var) = 1;
9510 DECL_INITIAL (var) = error_mark_node;
9511 var = start_decl (var, FALSE);
9512 finish_decl (var, list, FALSE);
9514 var = ffecom_1 (ADDR_EXPR, build_pointer_type (item), var);
9520 /* Essentially does a "fold (build1 (code, type, node))" while checking
9521 for certain housekeeping things.
9523 NOTE: for building an ADDR_EXPR around a FUNCTION_DECL, use
9524 ffecom_1_fn instead. */
9527 ffecom_1 (enum tree_code code, tree type, tree node)
9531 if ((node == error_mark_node)
9532 || (type == error_mark_node))
9533 return error_mark_node;
9535 if (code == ADDR_EXPR)
9537 if (!ffe_mark_addressable (node))
9538 assert ("can't mark_addressable this node!" == NULL);
9541 switch (ffe_is_emulate_complex () ? code : NOP_EXPR)
9546 item = build (COMPONENT_REF, type, node, TYPE_FIELDS (TREE_TYPE (node)));
9550 item = build (COMPONENT_REF, type, node, TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (node))));
9555 if (TREE_CODE (type) != RECORD_TYPE)
9557 item = build1 (code, type, node);
9560 node = ffecom_stabilize_aggregate_ (node);
9561 realtype = TREE_TYPE (TYPE_FIELDS (type));
9563 ffecom_2 (COMPLEX_EXPR, type,
9564 ffecom_1 (NEGATE_EXPR, realtype,
9565 ffecom_1 (REALPART_EXPR, realtype,
9567 ffecom_1 (NEGATE_EXPR, realtype,
9568 ffecom_1 (IMAGPART_EXPR, realtype,
9573 item = build1 (code, type, node);
9577 if (TREE_SIDE_EFFECTS (node))
9578 TREE_SIDE_EFFECTS (item) = 1;
9579 if (code == ADDR_EXPR && staticp (node))
9580 TREE_CONSTANT (item) = 1;
9581 else if (code == INDIRECT_REF)
9582 TREE_READONLY (item) = TYPE_READONLY (type);
9586 /* Like ffecom_1 (ADDR_EXPR, TREE_TYPE (node), node), except
9587 handles TREE_CODE (node) == FUNCTION_DECL. In particular,
9588 does not set TREE_ADDRESSABLE (because calling an inline
9589 function does not mean the function needs to be separately
9593 ffecom_1_fn (tree node)
9598 if (node == error_mark_node)
9599 return error_mark_node;
9601 type = build_type_variant (TREE_TYPE (node),
9602 TREE_READONLY (node),
9603 TREE_THIS_VOLATILE (node));
9604 item = build1 (ADDR_EXPR,
9605 build_pointer_type (type), node);
9606 if (TREE_SIDE_EFFECTS (node))
9607 TREE_SIDE_EFFECTS (item) = 1;
9609 TREE_CONSTANT (item) = 1;
9613 /* Essentially does a "fold (build (code, type, node1, node2))" while
9614 checking for certain housekeeping things. */
9617 ffecom_2 (enum tree_code code, tree type, tree node1,
9622 if ((node1 == error_mark_node)
9623 || (node2 == error_mark_node)
9624 || (type == error_mark_node))
9625 return error_mark_node;
9627 switch (ffe_is_emulate_complex () ? code : NOP_EXPR)
9629 tree a, b, c, d, realtype;
9632 assert ("no CONJ_EXPR support yet" == NULL);
9633 return error_mark_node;
9636 item = build_tree_list (TYPE_FIELDS (type), node1);
9637 TREE_CHAIN (item) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), node2);
9638 item = build (CONSTRUCTOR, type, NULL_TREE, item);
9642 if (TREE_CODE (type) != RECORD_TYPE)
9644 item = build (code, type, node1, node2);
9647 node1 = ffecom_stabilize_aggregate_ (node1);
9648 node2 = ffecom_stabilize_aggregate_ (node2);
9649 realtype = TREE_TYPE (TYPE_FIELDS (type));
9651 ffecom_2 (COMPLEX_EXPR, type,
9652 ffecom_2 (PLUS_EXPR, realtype,
9653 ffecom_1 (REALPART_EXPR, realtype,
9655 ffecom_1 (REALPART_EXPR, realtype,
9657 ffecom_2 (PLUS_EXPR, realtype,
9658 ffecom_1 (IMAGPART_EXPR, realtype,
9660 ffecom_1 (IMAGPART_EXPR, realtype,
9665 if (TREE_CODE (type) != RECORD_TYPE)
9667 item = build (code, type, node1, node2);
9670 node1 = ffecom_stabilize_aggregate_ (node1);
9671 node2 = ffecom_stabilize_aggregate_ (node2);
9672 realtype = TREE_TYPE (TYPE_FIELDS (type));
9674 ffecom_2 (COMPLEX_EXPR, type,
9675 ffecom_2 (MINUS_EXPR, realtype,
9676 ffecom_1 (REALPART_EXPR, realtype,
9678 ffecom_1 (REALPART_EXPR, realtype,
9680 ffecom_2 (MINUS_EXPR, realtype,
9681 ffecom_1 (IMAGPART_EXPR, realtype,
9683 ffecom_1 (IMAGPART_EXPR, realtype,
9688 if (TREE_CODE (type) != RECORD_TYPE)
9690 item = build (code, type, node1, node2);
9693 node1 = ffecom_stabilize_aggregate_ (node1);
9694 node2 = ffecom_stabilize_aggregate_ (node2);
9695 realtype = TREE_TYPE (TYPE_FIELDS (type));
9696 a = save_expr (ffecom_1 (REALPART_EXPR, realtype,
9698 b = save_expr (ffecom_1 (IMAGPART_EXPR, realtype,
9700 c = save_expr (ffecom_1 (REALPART_EXPR, realtype,
9702 d = save_expr (ffecom_1 (IMAGPART_EXPR, realtype,
9705 ffecom_2 (COMPLEX_EXPR, type,
9706 ffecom_2 (MINUS_EXPR, realtype,
9707 ffecom_2 (MULT_EXPR, realtype,
9710 ffecom_2 (MULT_EXPR, realtype,
9713 ffecom_2 (PLUS_EXPR, realtype,
9714 ffecom_2 (MULT_EXPR, realtype,
9717 ffecom_2 (MULT_EXPR, realtype,
9723 if ((TREE_CODE (node1) != RECORD_TYPE)
9724 && (TREE_CODE (node2) != RECORD_TYPE))
9726 item = build (code, type, node1, node2);
9729 assert (TREE_CODE (node1) == RECORD_TYPE);
9730 assert (TREE_CODE (node2) == RECORD_TYPE);
9731 node1 = ffecom_stabilize_aggregate_ (node1);
9732 node2 = ffecom_stabilize_aggregate_ (node2);
9733 realtype = TREE_TYPE (TYPE_FIELDS (type));
9735 ffecom_2 (TRUTH_ANDIF_EXPR, type,
9736 ffecom_2 (code, type,
9737 ffecom_1 (REALPART_EXPR, realtype,
9739 ffecom_1 (REALPART_EXPR, realtype,
9741 ffecom_2 (code, type,
9742 ffecom_1 (IMAGPART_EXPR, realtype,
9744 ffecom_1 (IMAGPART_EXPR, realtype,
9749 if ((TREE_CODE (node1) != RECORD_TYPE)
9750 && (TREE_CODE (node2) != RECORD_TYPE))
9752 item = build (code, type, node1, node2);
9755 assert (TREE_CODE (node1) == RECORD_TYPE);
9756 assert (TREE_CODE (node2) == RECORD_TYPE);
9757 node1 = ffecom_stabilize_aggregate_ (node1);
9758 node2 = ffecom_stabilize_aggregate_ (node2);
9759 realtype = TREE_TYPE (TYPE_FIELDS (type));
9761 ffecom_2 (TRUTH_ORIF_EXPR, type,
9762 ffecom_2 (code, type,
9763 ffecom_1 (REALPART_EXPR, realtype,
9765 ffecom_1 (REALPART_EXPR, realtype,
9767 ffecom_2 (code, type,
9768 ffecom_1 (IMAGPART_EXPR, realtype,
9770 ffecom_1 (IMAGPART_EXPR, realtype,
9775 item = build (code, type, node1, node2);
9779 if (TREE_SIDE_EFFECTS (node1) || TREE_SIDE_EFFECTS (node2))
9780 TREE_SIDE_EFFECTS (item) = 1;
9784 /* ffecom_2pass_advise_entrypoint -- Advise that there's this entrypoint
9786 ffesymbol s; // the ENTRY point itself
9787 if (ffecom_2pass_advise_entrypoint(s))
9788 // the ENTRY point has been accepted
9790 Does whatever compiler needs to do when it learns about the entrypoint,
9791 like determine the return type of the master function, count the
9792 number of entrypoints, etc. Returns FALSE if the return type is
9793 not compatible with the return type(s) of other entrypoint(s).
9795 NOTE: for every call to this fn that returns TRUE, _do_entrypoint must
9796 later (after _finish_progunit) be called with the same entrypoint(s)
9797 as passed to this fn for which TRUE was returned.
9800 Return FALSE if the return type conflicts with previous entrypoints. */
9803 ffecom_2pass_advise_entrypoint (ffesymbol entry)
9805 ffebld list; /* opITEM. */
9806 ffebld mlist; /* opITEM. */
9807 ffebld plist; /* opITEM. */
9808 ffebld arg; /* ffebld_head(opITEM). */
9809 ffebld item; /* opITEM. */
9810 ffesymbol s; /* ffebld_symter(arg). */
9811 ffeinfoBasictype bt = ffesymbol_basictype (entry);
9812 ffeinfoKindtype kt = ffesymbol_kindtype (entry);
9813 ffetargetCharacterSize size = ffesymbol_size (entry);
9816 if (ffecom_num_entrypoints_ == 0)
9817 { /* First entrypoint, make list of main
9818 arglist's dummies. */
9819 assert (ffecom_primary_entry_ != NULL);
9821 ffecom_master_bt_ = ffesymbol_basictype (ffecom_primary_entry_);
9822 ffecom_master_kt_ = ffesymbol_kindtype (ffecom_primary_entry_);
9823 ffecom_master_size_ = ffesymbol_size (ffecom_primary_entry_);
9825 for (plist = NULL, list = ffesymbol_dummyargs (ffecom_primary_entry_);
9827 list = ffebld_trail (list))
9829 arg = ffebld_head (list);
9830 if (ffebld_op (arg) != FFEBLD_opSYMTER)
9831 continue; /* Alternate return or some such thing. */
9832 item = ffebld_new_item (arg, NULL);
9834 ffecom_master_arglist_ = item;
9836 ffebld_set_trail (plist, item);
9841 /* If necessary, scan entry arglist for alternate returns. Do this scan
9842 apparently redundantly (it's done below to UNIONize the arglists) so
9843 that we don't complain about RETURN 1 if an offending ENTRY is the only
9844 one with an alternate return. */
9846 if (!ffecom_is_altreturning_)
9848 for (list = ffesymbol_dummyargs (entry);
9850 list = ffebld_trail (list))
9852 arg = ffebld_head (list);
9853 if (ffebld_op (arg) == FFEBLD_opSTAR)
9855 ffecom_is_altreturning_ = TRUE;
9861 /* Now check type compatibility. */
9863 switch (ffecom_master_bt_)
9865 case FFEINFO_basictypeNONE:
9866 ok = (bt != FFEINFO_basictypeCHARACTER);
9869 case FFEINFO_basictypeCHARACTER:
9871 = (bt == FFEINFO_basictypeCHARACTER)
9872 && (kt == ffecom_master_kt_)
9873 && (size == ffecom_master_size_);
9876 case FFEINFO_basictypeANY:
9877 return FALSE; /* Just don't bother. */
9880 if (bt == FFEINFO_basictypeCHARACTER)
9886 if ((bt != ffecom_master_bt_) || (kt != ffecom_master_kt_))
9888 ffecom_master_bt_ = FFEINFO_basictypeNONE;
9889 ffecom_master_kt_ = FFEINFO_kindtypeNONE;
9896 ffebad_start (FFEBAD_ENTRY_CONFLICTS);
9897 ffest_ffebad_here_current_stmt (0);
9899 return FALSE; /* Can't handle entrypoint. */
9902 /* Entrypoint type compatible with previous types. */
9904 ++ffecom_num_entrypoints_;
9906 /* Master-arg-list = UNION(Master-arg-list,entry-arg-list). */
9908 for (list = ffesymbol_dummyargs (entry);
9910 list = ffebld_trail (list))
9912 arg = ffebld_head (list);
9913 if (ffebld_op (arg) != FFEBLD_opSYMTER)
9914 continue; /* Alternate return or some such thing. */
9915 s = ffebld_symter (arg);
9916 for (plist = NULL, mlist = ffecom_master_arglist_;
9918 plist = mlist, mlist = ffebld_trail (mlist))
9919 { /* plist points to previous item for easy
9920 appending of arg. */
9921 if (ffebld_symter (ffebld_head (mlist)) == s)
9922 break; /* Already have this arg in the master list. */
9925 continue; /* Already have this arg in the master list. */
9927 /* Append this arg to the master list. */
9929 item = ffebld_new_item (arg, NULL);
9931 ffecom_master_arglist_ = item;
9933 ffebld_set_trail (plist, item);
9939 /* ffecom_2pass_do_entrypoint -- Do compilation of entrypoint
9941 ffesymbol s; // the ENTRY point itself
9942 ffecom_2pass_do_entrypoint(s);
9944 Does whatever compiler needs to do to make the entrypoint actually
9945 happen. Must be called for each entrypoint after
9946 ffecom_finish_progunit is called. */
9949 ffecom_2pass_do_entrypoint (ffesymbol entry)
9951 static int mfn_num = 0;
9954 if (mfn_num != ffecom_num_fns_)
9955 { /* First entrypoint for this program unit. */
9957 mfn_num = ffecom_num_fns_;
9958 ffecom_do_entry_ (ffecom_primary_entry_, 0);
9963 --ffecom_num_entrypoints_;
9965 ffecom_do_entry_ (entry, ent_num);
9968 /* Essentially does a "fold (build (code, type, node1, node2))" while
9969 checking for certain housekeeping things. Always sets
9970 TREE_SIDE_EFFECTS. */
9973 ffecom_2s (enum tree_code code, tree type, tree node1,
9978 if ((node1 == error_mark_node)
9979 || (node2 == error_mark_node)
9980 || (type == error_mark_node))
9981 return error_mark_node;
9983 item = build (code, type, node1, node2);
9984 TREE_SIDE_EFFECTS (item) = 1;
9988 /* Essentially does a "fold (build (code, type, node1, node2, node3))" while
9989 checking for certain housekeeping things. */
9992 ffecom_3 (enum tree_code code, tree type, tree node1,
9993 tree node2, tree node3)
9997 if ((node1 == error_mark_node)
9998 || (node2 == error_mark_node)
9999 || (node3 == error_mark_node)
10000 || (type == error_mark_node))
10001 return error_mark_node;
10003 item = build (code, type, node1, node2, node3);
10004 if (TREE_SIDE_EFFECTS (node1) || TREE_SIDE_EFFECTS (node2)
10005 || (node3 != NULL_TREE && TREE_SIDE_EFFECTS (node3)))
10006 TREE_SIDE_EFFECTS (item) = 1;
10007 return fold (item);
10010 /* Essentially does a "fold (build (code, type, node1, node2, node3))" while
10011 checking for certain housekeeping things. Always sets
10012 TREE_SIDE_EFFECTS. */
10015 ffecom_3s (enum tree_code code, tree type, tree node1,
10016 tree node2, tree node3)
10020 if ((node1 == error_mark_node)
10021 || (node2 == error_mark_node)
10022 || (node3 == error_mark_node)
10023 || (type == error_mark_node))
10024 return error_mark_node;
10026 item = build (code, type, node1, node2, node3);
10027 TREE_SIDE_EFFECTS (item) = 1;
10028 return fold (item);
10031 /* ffecom_arg_expr -- Transform argument expr into gcc tree
10033 See use by ffecom_list_expr.
10035 If expression is NULL, returns an integer zero tree. If it is not
10036 a CHARACTER expression, returns whatever ffecom_expr
10037 returns and sets the length return value to NULL_TREE. Otherwise
10038 generates code to evaluate the character expression, returns the proper
10039 pointer to the result, but does NOT set the length return value to a tree
10040 that specifies the length of the result. (In other words, the length
10041 variable is always set to NULL_TREE, because a length is never passed.)
10044 Don't set returned length, since nobody needs it (yet; someday if
10045 we allow CHARACTER*(*) dummies to statement functions, we'll need
10049 ffecom_arg_expr (ffebld expr, tree *length)
10053 *length = NULL_TREE;
10056 return integer_zero_node;
10058 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10059 return ffecom_expr (expr);
10061 return ffecom_arg_ptr_to_expr (expr, &ign);
10064 /* Transform expression into constant argument-pointer-to-expression tree.
10066 If the expression can be transformed into a argument-pointer-to-expression
10067 tree that is constant, that is done, and the tree returned. Else
10068 NULL_TREE is returned.
10070 That way, a caller can attempt to provide compile-time initialization
10071 of a variable and, if that fails, *then* choose to start a new block
10072 and resort to using temporaries, as appropriate. */
10075 ffecom_arg_ptr_to_const_expr (ffebld expr, tree *length)
10078 return integer_zero_node;
10080 if (ffebld_op (expr) == FFEBLD_opANY)
10083 *length = error_mark_node;
10084 return error_mark_node;
10087 if (ffebld_arity (expr) == 0
10088 && (ffebld_op (expr) != FFEBLD_opSYMTER
10089 || ffebld_where (expr) == FFEINFO_whereCOMMON
10090 || ffebld_where (expr) == FFEINFO_whereGLOBAL
10091 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
10095 t = ffecom_arg_ptr_to_expr (expr, length);
10096 assert (TREE_CONSTANT (t));
10097 assert (! length || TREE_CONSTANT (*length));
10102 && ffebld_size (expr) != FFETARGET_charactersizeNONE)
10103 *length = build_int_2 (ffebld_size (expr), 0);
10105 *length = NULL_TREE;
10109 /* ffecom_arg_ptr_to_expr -- Transform argument expr into gcc tree
10111 See use by ffecom_list_ptr_to_expr.
10113 If expression is NULL, returns an integer zero tree. If it is not
10114 a CHARACTER expression, returns whatever ffecom_ptr_to_expr
10115 returns and sets the length return value to NULL_TREE. Otherwise
10116 generates code to evaluate the character expression, returns the proper
10117 pointer to the result, AND sets the length return value to a tree that
10118 specifies the length of the result.
10120 If the length argument is NULL, this is a slightly special
10121 case of building a FORMAT expression, that is, an expression that
10122 will be used at run time without regard to length. For the current
10123 implementation, which uses the libf2c library, this means it is nice
10124 to append a null byte to the end of the expression, where feasible,
10125 to make sure any diagnostic about the FORMAT string terminates at
10128 For now, treat %REF(char-expr) as the same as char-expr with a NULL
10129 length argument. This might even be seen as a feature, if a null
10130 byte can always be appended. */
10133 ffecom_arg_ptr_to_expr (ffebld expr, tree *length)
10137 ffecomConcatList_ catlist;
10139 if (length != NULL)
10140 *length = NULL_TREE;
10143 return integer_zero_node;
10145 switch (ffebld_op (expr))
10147 case FFEBLD_opPERCENT_VAL:
10148 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10149 return ffecom_expr (ffebld_left (expr));
10154 temp_exp = ffecom_arg_ptr_to_expr (ffebld_left (expr), &temp_length);
10155 if (temp_exp == error_mark_node)
10156 return error_mark_node;
10158 return ffecom_1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (temp_exp)),
10162 case FFEBLD_opPERCENT_REF:
10163 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10164 return ffecom_ptr_to_expr (ffebld_left (expr));
10165 if (length != NULL)
10167 ign_length = NULL_TREE;
10168 length = &ign_length;
10170 expr = ffebld_left (expr);
10173 case FFEBLD_opPERCENT_DESCR:
10174 switch (ffeinfo_basictype (ffebld_info (expr)))
10176 #ifdef PASS_HOLLERITH_BY_DESCRIPTOR
10177 case FFEINFO_basictypeHOLLERITH:
10179 case FFEINFO_basictypeCHARACTER:
10180 break; /* Passed by descriptor anyway. */
10183 item = ffecom_ptr_to_expr (expr);
10184 if (item != error_mark_node)
10185 *length = TYPE_SIZE (TREE_TYPE (TREE_TYPE (item)));
10194 #ifdef PASS_HOLLERITH_BY_DESCRIPTOR
10195 if ((ffeinfo_basictype (ffebld_info (expr)) == FFEINFO_basictypeHOLLERITH)
10196 && (length != NULL))
10197 { /* Pass Hollerith by descriptor. */
10198 ffetargetHollerith h;
10200 assert (ffebld_op (expr) == FFEBLD_opCONTER);
10201 h = ffebld_cu_val_hollerith (ffebld_constant_union
10202 (ffebld_conter (expr)));
10204 = build_int_2 (h.length, 0);
10205 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
10209 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10210 return ffecom_ptr_to_expr (expr);
10212 assert (ffeinfo_kindtype (ffebld_info (expr))
10213 == FFEINFO_kindtypeCHARACTER1);
10215 while (ffebld_op (expr) == FFEBLD_opPAREN)
10216 expr = ffebld_left (expr);
10218 catlist = ffecom_concat_list_new_ (expr, FFETARGET_charactersizeNONE);
10219 switch (ffecom_concat_list_count_ (catlist))
10221 case 0: /* Shouldn't happen, but in case it does... */
10222 if (length != NULL)
10224 *length = ffecom_f2c_ftnlen_zero_node;
10225 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
10227 ffecom_concat_list_kill_ (catlist);
10228 return null_pointer_node;
10230 case 1: /* The (fairly) easy case. */
10231 if (length == NULL)
10232 ffecom_char_args_with_null_ (&item, &ign_length,
10233 ffecom_concat_list_expr_ (catlist, 0));
10235 ffecom_char_args_ (&item, length,
10236 ffecom_concat_list_expr_ (catlist, 0));
10237 ffecom_concat_list_kill_ (catlist);
10238 assert (item != NULL_TREE);
10241 default: /* Must actually concatenate things. */
10246 int count = ffecom_concat_list_count_ (catlist);
10257 ffetargetCharacterSize sz;
10259 sz = ffecom_concat_list_maxlen_ (catlist);
10261 assert (sz != FFETARGET_charactersizeNONE);
10266 = ffecom_push_tempvar (ffecom_f2c_ftnlen_type_node,
10267 FFETARGET_charactersizeNONE, count, TRUE);
10270 = ffecom_push_tempvar (ffecom_f2c_address_type_node,
10271 FFETARGET_charactersizeNONE, count, TRUE);
10272 temporary = ffecom_push_tempvar (char_type_node,
10278 hook = ffebld_nonter_hook (expr);
10280 assert (TREE_CODE (hook) == TREE_VEC);
10281 assert (TREE_VEC_LENGTH (hook) == 3);
10282 length_array = lengths = TREE_VEC_ELT (hook, 0);
10283 item_array = items = TREE_VEC_ELT (hook, 1);
10284 temporary = TREE_VEC_ELT (hook, 2);
10288 known_length = ffecom_f2c_ftnlen_zero_node;
10290 for (i = 0; i < count; ++i)
10293 && (length == NULL))
10294 ffecom_char_args_with_null_ (&citem, &clength,
10295 ffecom_concat_list_expr_ (catlist, i));
10297 ffecom_char_args_ (&citem, &clength,
10298 ffecom_concat_list_expr_ (catlist, i));
10299 if ((citem == error_mark_node)
10300 || (clength == error_mark_node))
10302 ffecom_concat_list_kill_ (catlist);
10303 *length = error_mark_node;
10304 return error_mark_node;
10308 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (items),
10309 ffecom_modify (void_type_node,
10310 ffecom_2 (ARRAY_REF,
10311 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array))),
10313 build_int_2 (i, 0)),
10316 clength = ffecom_save_tree (clength);
10317 if (length != NULL)
10319 = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
10323 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (lengths),
10324 ffecom_modify (void_type_node,
10325 ffecom_2 (ARRAY_REF,
10326 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array))),
10328 build_int_2 (i, 0)),
10333 temporary = ffecom_1 (ADDR_EXPR,
10334 build_pointer_type (TREE_TYPE (temporary)),
10337 item = build_tree_list (NULL_TREE, temporary);
10339 = build_tree_list (NULL_TREE,
10340 ffecom_1 (ADDR_EXPR,
10341 build_pointer_type (TREE_TYPE (items)),
10343 TREE_CHAIN (TREE_CHAIN (item))
10344 = build_tree_list (NULL_TREE,
10345 ffecom_1 (ADDR_EXPR,
10346 build_pointer_type (TREE_TYPE (lengths)),
10348 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item)))
10351 ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
10352 convert (ffecom_f2c_ftnlen_type_node,
10353 build_int_2 (count, 0))));
10354 num = build_int_2 (sz, 0);
10355 TREE_TYPE (num) = ffecom_f2c_ftnlen_type_node;
10356 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item))))
10357 = build_tree_list (NULL_TREE, num);
10359 item = ffecom_call_gfrt (FFECOM_gfrtCAT, item, NULL_TREE);
10360 TREE_SIDE_EFFECTS (item) = 1;
10361 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (temporary),
10365 if (length != NULL)
10366 *length = known_length;
10369 ffecom_concat_list_kill_ (catlist);
10370 assert (item != NULL_TREE);
10374 /* Generate call to run-time function.
10376 The first arg is the GNU Fortran Run-Time function index, the second
10377 arg is the list of arguments to pass to it. Returned is the expression
10378 (WITHOUT TREE_SIDE_EFFECTS set!) that makes the call and returns the
10379 result (which may be void). */
10382 ffecom_call_gfrt (ffecomGfrt ix, tree args, tree hook)
10384 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
10385 ffecom_gfrt_kindtype (ix),
10386 ffe_is_f2c_library () && ffecom_gfrt_complex_[ix],
10387 NULL_TREE, args, NULL_TREE, NULL,
10388 NULL, NULL_TREE, TRUE, hook);
10391 /* Transform constant-union to tree. */
10394 ffecom_constantunion (ffebldConstantUnion *cu, ffeinfoBasictype bt,
10395 ffeinfoKindtype kt, tree tree_type)
10401 case FFEINFO_basictypeINTEGER:
10407 #if FFETARGET_okINTEGER1
10408 case FFEINFO_kindtypeINTEGER1:
10409 val = ffebld_cu_val_integer1 (*cu);
10413 #if FFETARGET_okINTEGER2
10414 case FFEINFO_kindtypeINTEGER2:
10415 val = ffebld_cu_val_integer2 (*cu);
10419 #if FFETARGET_okINTEGER3
10420 case FFEINFO_kindtypeINTEGER3:
10421 val = ffebld_cu_val_integer3 (*cu);
10425 #if FFETARGET_okINTEGER4
10426 case FFEINFO_kindtypeINTEGER4:
10427 val = ffebld_cu_val_integer4 (*cu);
10432 assert ("bad INTEGER constant kind type" == NULL);
10433 /* Fall through. */
10434 case FFEINFO_kindtypeANY:
10435 return error_mark_node;
10437 item = build_int_2 (val, (val < 0) ? -1 : 0);
10438 TREE_TYPE (item) = tree_type;
10442 case FFEINFO_basictypeLOGICAL:
10448 #if FFETARGET_okLOGICAL1
10449 case FFEINFO_kindtypeLOGICAL1:
10450 val = ffebld_cu_val_logical1 (*cu);
10454 #if FFETARGET_okLOGICAL2
10455 case FFEINFO_kindtypeLOGICAL2:
10456 val = ffebld_cu_val_logical2 (*cu);
10460 #if FFETARGET_okLOGICAL3
10461 case FFEINFO_kindtypeLOGICAL3:
10462 val = ffebld_cu_val_logical3 (*cu);
10466 #if FFETARGET_okLOGICAL4
10467 case FFEINFO_kindtypeLOGICAL4:
10468 val = ffebld_cu_val_logical4 (*cu);
10473 assert ("bad LOGICAL constant kind type" == NULL);
10474 /* Fall through. */
10475 case FFEINFO_kindtypeANY:
10476 return error_mark_node;
10478 item = build_int_2 (val, (val < 0) ? -1 : 0);
10479 TREE_TYPE (item) = tree_type;
10483 case FFEINFO_basictypeREAL:
10485 REAL_VALUE_TYPE val;
10489 #if FFETARGET_okREAL1
10490 case FFEINFO_kindtypeREAL1:
10491 val = ffetarget_value_real1 (ffebld_cu_val_real1 (*cu));
10495 #if FFETARGET_okREAL2
10496 case FFEINFO_kindtypeREAL2:
10497 val = ffetarget_value_real2 (ffebld_cu_val_real2 (*cu));
10501 #if FFETARGET_okREAL3
10502 case FFEINFO_kindtypeREAL3:
10503 val = ffetarget_value_real3 (ffebld_cu_val_real3 (*cu));
10507 #if FFETARGET_okREAL4
10508 case FFEINFO_kindtypeREAL4:
10509 val = ffetarget_value_real4 (ffebld_cu_val_real4 (*cu));
10514 assert ("bad REAL constant kind type" == NULL);
10515 /* Fall through. */
10516 case FFEINFO_kindtypeANY:
10517 return error_mark_node;
10519 item = build_real (tree_type, val);
10523 case FFEINFO_basictypeCOMPLEX:
10525 REAL_VALUE_TYPE real;
10526 REAL_VALUE_TYPE imag;
10527 tree el_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
10531 #if FFETARGET_okCOMPLEX1
10532 case FFEINFO_kindtypeREAL1:
10533 real = ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu).real);
10534 imag = ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu).imaginary);
10538 #if FFETARGET_okCOMPLEX2
10539 case FFEINFO_kindtypeREAL2:
10540 real = ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu).real);
10541 imag = ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu).imaginary);
10545 #if FFETARGET_okCOMPLEX3
10546 case FFEINFO_kindtypeREAL3:
10547 real = ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu).real);
10548 imag = ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu).imaginary);
10552 #if FFETARGET_okCOMPLEX4
10553 case FFEINFO_kindtypeREAL4:
10554 real = ffetarget_value_real4 (ffebld_cu_val_complex4 (*cu).real);
10555 imag = ffetarget_value_real4 (ffebld_cu_val_complex4 (*cu).imaginary);
10560 assert ("bad REAL constant kind type" == NULL);
10561 /* Fall through. */
10562 case FFEINFO_kindtypeANY:
10563 return error_mark_node;
10565 item = ffecom_build_complex_constant_ (tree_type,
10566 build_real (el_type, real),
10567 build_real (el_type, imag));
10571 case FFEINFO_basictypeCHARACTER:
10572 { /* Happens only in DATA and similar contexts. */
10573 ffetargetCharacter1 val;
10577 #if FFETARGET_okCHARACTER1
10578 case FFEINFO_kindtypeLOGICAL1:
10579 val = ffebld_cu_val_character1 (*cu);
10584 assert ("bad CHARACTER constant kind type" == NULL);
10585 /* Fall through. */
10586 case FFEINFO_kindtypeANY:
10587 return error_mark_node;
10589 item = build_string (ffetarget_length_character1 (val),
10590 ffetarget_text_character1 (val));
10592 = build_type_variant (build_array_type (char_type_node,
10594 (integer_type_node,
10597 (ffetarget_length_character1
10603 case FFEINFO_basictypeHOLLERITH:
10605 ffetargetHollerith h;
10607 h = ffebld_cu_val_hollerith (*cu);
10609 /* If not at least as wide as default INTEGER, widen it. */
10610 if (h.length >= FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE)
10611 item = build_string (h.length, h.text);
10614 char str[FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE];
10616 memcpy (str, h.text, h.length);
10617 memset (&str[h.length], ' ',
10618 FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE
10620 item = build_string (FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE,
10624 = build_type_variant (build_array_type (char_type_node,
10626 (integer_type_node,
10634 case FFEINFO_basictypeTYPELESS:
10636 ffetargetInteger1 ival;
10637 ffetargetTypeless tless;
10640 tless = ffebld_cu_val_typeless (*cu);
10641 error = ffetarget_convert_integer1_typeless (&ival, tless);
10642 assert (error == FFEBAD);
10644 item = build_int_2 ((int) ival, 0);
10649 assert ("not yet on constant type" == NULL);
10650 /* Fall through. */
10651 case FFEINFO_basictypeANY:
10652 return error_mark_node;
10655 TREE_CONSTANT (item) = 1;
10660 /* Transform expression into constant tree.
10662 If the expression can be transformed into a tree that is constant,
10663 that is done, and the tree returned. Else NULL_TREE is returned.
10665 That way, a caller can attempt to provide compile-time initialization
10666 of a variable and, if that fails, *then* choose to start a new block
10667 and resort to using temporaries, as appropriate. */
10670 ffecom_const_expr (ffebld expr)
10673 return integer_zero_node;
10675 if (ffebld_op (expr) == FFEBLD_opANY)
10676 return error_mark_node;
10678 if (ffebld_arity (expr) == 0
10679 && (ffebld_op (expr) != FFEBLD_opSYMTER
10681 /* ~~Enable once common/equivalence is handled properly? */
10682 || ffebld_where (expr) == FFEINFO_whereCOMMON
10684 || ffebld_where (expr) == FFEINFO_whereGLOBAL
10685 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
10689 t = ffecom_expr (expr);
10690 assert (TREE_CONSTANT (t));
10697 /* Handy way to make a field in a struct/union. */
10700 ffecom_decl_field (tree context, tree prevfield,
10701 const char *name, tree type)
10705 field = build_decl (FIELD_DECL, get_identifier (name), type);
10706 DECL_CONTEXT (field) = context;
10707 DECL_ALIGN (field) = 0;
10708 DECL_USER_ALIGN (field) = 0;
10709 if (prevfield != NULL_TREE)
10710 TREE_CHAIN (prevfield) = field;
10716 ffecom_close_include (FILE *f)
10718 ffecom_close_include_ (f);
10722 ffecom_decode_include_option (char *spec)
10724 return ffecom_decode_include_option_ (spec);
10727 /* End a compound statement (block). */
10730 ffecom_end_compstmt (void)
10732 return bison_rule_compstmt_ ();
10735 /* ffecom_end_transition -- Perform end transition on all symbols
10737 ffecom_end_transition();
10739 Calls ffecom_sym_end_transition for each global and local symbol. */
10742 ffecom_end_transition ()
10746 if (ffe_is_ffedebug ())
10747 fprintf (dmpout, "; end_stmt_transition\n");
10749 ffecom_list_blockdata_ = NULL;
10750 ffecom_list_common_ = NULL;
10752 ffesymbol_drive (ffecom_sym_end_transition);
10753 if (ffe_is_ffedebug ())
10755 ffestorag_report ();
10758 ffecom_start_progunit_ ();
10760 for (item = ffecom_list_blockdata_;
10762 item = ffebld_trail (item))
10769 static int number = 0;
10771 callee = ffebld_head (item);
10772 s = ffebld_symter (callee);
10773 t = ffesymbol_hook (s).decl_tree;
10774 if (t == NULL_TREE)
10776 s = ffecom_sym_transform_ (s);
10777 t = ffesymbol_hook (s).decl_tree;
10780 dt = build_pointer_type (TREE_TYPE (t));
10782 var = build_decl (VAR_DECL,
10783 ffecom_get_invented_identifier ("__g77_forceload_%d",
10786 DECL_EXTERNAL (var) = 0;
10787 TREE_STATIC (var) = 1;
10788 TREE_PUBLIC (var) = 0;
10789 DECL_INITIAL (var) = error_mark_node;
10790 TREE_USED (var) = 1;
10792 var = start_decl (var, FALSE);
10794 t = ffecom_1 (ADDR_EXPR, dt, t);
10796 finish_decl (var, t, FALSE);
10799 /* This handles any COMMON areas that weren't referenced but have, for
10800 example, important initial data. */
10802 for (item = ffecom_list_common_;
10804 item = ffebld_trail (item))
10805 ffecom_transform_common_ (ffebld_symter (ffebld_head (item)));
10807 ffecom_list_common_ = NULL;
10810 /* ffecom_exec_transition -- Perform exec transition on all symbols
10812 ffecom_exec_transition();
10814 Calls ffecom_sym_exec_transition for each global and local symbol.
10815 Make sure error updating not inhibited. */
10818 ffecom_exec_transition ()
10822 if (ffe_is_ffedebug ())
10823 fprintf (dmpout, "; exec_stmt_transition\n");
10825 inhibited = ffebad_inhibit ();
10826 ffebad_set_inhibit (FALSE);
10828 ffesymbol_drive (ffecom_sym_exec_transition); /* Don't retract! */
10829 ffeequiv_exec_transition (); /* Handle all pending EQUIVALENCEs. */
10830 if (ffe_is_ffedebug ())
10832 ffestorag_report ();
10836 ffebad_set_inhibit (TRUE);
10839 /* Handle assignment statement.
10841 Convert dest and source using ffecom_expr, then join them
10842 with an ASSIGN op and pass the whole thing to expand_expr_stmt. */
10845 ffecom_expand_let_stmt (ffebld dest, ffebld source)
10852 if (ffeinfo_basictype (ffebld_info (dest)) != FFEINFO_basictypeCHARACTER)
10857 /* This attempts to replicate the test below, but must not be
10858 true when the test below is false. (Always err on the side
10859 of creating unused temporaries, to avoid ICEs.) */
10860 if (ffebld_op (dest) != FFEBLD_opSYMTER
10861 || ((dest_tree = ffesymbol_hook (ffebld_symter (dest)).decl_tree)
10862 && (TREE_CODE (dest_tree) != VAR_DECL
10863 || TREE_ADDRESSABLE (dest_tree))))
10865 ffecom_prepare_expr_ (source, dest);
10870 ffecom_prepare_expr_ (source, NULL);
10874 ffecom_prepare_expr_w (NULL_TREE, dest);
10876 /* For COMPLEX assignment like C1=C2, if partial overlap is possible,
10877 create a temporary through which the assignment is to take place,
10878 since MODIFY_EXPR doesn't handle partial overlap properly. */
10879 if (ffebld_basictype (dest) == FFEINFO_basictypeCOMPLEX
10880 && ffecom_possible_partial_overlap_ (dest, source))
10882 assign_temp = ffecom_make_tempvar ("complex_let",
10884 [ffebld_basictype (dest)]
10885 [ffebld_kindtype (dest)],
10886 FFETARGET_charactersizeNONE,
10890 assign_temp = NULL_TREE;
10892 ffecom_prepare_end ();
10894 dest_tree = ffecom_expr_w (NULL_TREE, dest);
10895 if (dest_tree == error_mark_node)
10898 if ((TREE_CODE (dest_tree) != VAR_DECL)
10899 || TREE_ADDRESSABLE (dest_tree))
10900 source_tree = ffecom_expr_ (source, dest_tree, dest, &dest_used,
10904 assert (! dest_used);
10906 source_tree = ffecom_expr (source);
10908 if (source_tree == error_mark_node)
10912 expr_tree = source_tree;
10913 else if (assign_temp)
10916 /* The back end understands a conceptual move (evaluate source;
10917 store into dest), so use that, in case it can determine
10918 that it is going to use, say, two registers as temporaries
10919 anyway. So don't use the temp (and someday avoid generating
10920 it, once this code starts triggering regularly). */
10921 expr_tree = ffecom_2s (MOVE_EXPR, void_type_node,
10925 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
10928 expand_expr_stmt (expr_tree);
10929 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
10935 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
10939 expand_expr_stmt (expr_tree);
10943 ffecom_prepare_let_char_ (ffebld_size_known (dest), source);
10944 ffecom_prepare_expr_w (NULL_TREE, dest);
10946 ffecom_prepare_end ();
10948 ffecom_char_args_ (&dest_tree, &dest_length, dest);
10949 ffecom_let_char_ (dest_tree, dest_length, ffebld_size_known (dest),
10953 /* ffecom_expr -- Transform expr into gcc tree
10956 ffebld expr; // FFE expression.
10957 tree = ffecom_expr(expr);
10959 Recursive descent on expr while making corresponding tree nodes and
10960 attaching type info and such. */
10963 ffecom_expr (ffebld expr)
10965 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, FALSE, FALSE);
10968 /* Like ffecom_expr, but return tree usable for assigned GOTO or FORMAT. */
10971 ffecom_expr_assign (ffebld expr)
10973 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, TRUE, FALSE);
10976 /* Like ffecom_expr_rw, but return tree usable for ASSIGN. */
10979 ffecom_expr_assign_w (ffebld expr)
10981 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, TRUE, FALSE);
10984 /* Transform expr for use as into read/write tree and stabilize the
10985 reference. Not for use on CHARACTER expressions.
10987 Recursive descent on expr while making corresponding tree nodes and
10988 attaching type info and such. */
10991 ffecom_expr_rw (tree type, ffebld expr)
10993 assert (expr != NULL);
10994 /* Different target types not yet supported. */
10995 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
10997 return stabilize_reference (ffecom_expr (expr));
11000 /* Transform expr for use as into write tree and stabilize the
11001 reference. Not for use on CHARACTER expressions.
11003 Recursive descent on expr while making corresponding tree nodes and
11004 attaching type info and such. */
11007 ffecom_expr_w (tree type, ffebld expr)
11009 assert (expr != NULL);
11010 /* Different target types not yet supported. */
11011 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
11013 return stabilize_reference (ffecom_expr (expr));
11016 /* Do global stuff. */
11019 ffecom_finish_compile ()
11021 assert (ffecom_outer_function_decl_ == NULL_TREE);
11022 assert (current_function_decl == NULL_TREE);
11024 ffeglobal_drive (ffecom_finish_global_);
11027 /* Public entry point for front end to access finish_decl. */
11030 ffecom_finish_decl (tree decl, tree init, bool is_top_level)
11032 assert (!is_top_level);
11033 finish_decl (decl, init, FALSE);
11036 /* Finish a program unit. */
11039 ffecom_finish_progunit ()
11041 ffecom_end_compstmt ();
11043 ffecom_previous_function_decl_ = current_function_decl;
11044 ffecom_which_entrypoint_decl_ = NULL_TREE;
11046 finish_function (0);
11049 /* Wrapper for get_identifier. pattern is sprintf-like. */
11052 ffecom_get_invented_identifier (const char *pattern, ...)
11058 va_start (ap, pattern);
11059 if (vasprintf (&nam, pattern, ap) == 0)
11062 decl = get_identifier (nam);
11064 IDENTIFIER_INVENTED (decl) = 1;
11069 ffecom_gfrt_basictype (ffecomGfrt gfrt)
11071 assert (gfrt < FFECOM_gfrt);
11073 switch (ffecom_gfrt_type_[gfrt])
11075 case FFECOM_rttypeVOID_:
11076 case FFECOM_rttypeVOIDSTAR_:
11077 return FFEINFO_basictypeNONE;
11079 case FFECOM_rttypeFTNINT_:
11080 return FFEINFO_basictypeINTEGER;
11082 case FFECOM_rttypeINTEGER_:
11083 return FFEINFO_basictypeINTEGER;
11085 case FFECOM_rttypeLONGINT_:
11086 return FFEINFO_basictypeINTEGER;
11088 case FFECOM_rttypeLOGICAL_:
11089 return FFEINFO_basictypeLOGICAL;
11091 case FFECOM_rttypeREAL_F2C_:
11092 case FFECOM_rttypeREAL_GNU_:
11093 return FFEINFO_basictypeREAL;
11095 case FFECOM_rttypeCOMPLEX_F2C_:
11096 case FFECOM_rttypeCOMPLEX_GNU_:
11097 return FFEINFO_basictypeCOMPLEX;
11099 case FFECOM_rttypeDOUBLE_:
11100 case FFECOM_rttypeDOUBLEREAL_:
11101 return FFEINFO_basictypeREAL;
11103 case FFECOM_rttypeDBLCMPLX_F2C_:
11104 case FFECOM_rttypeDBLCMPLX_GNU_:
11105 return FFEINFO_basictypeCOMPLEX;
11107 case FFECOM_rttypeCHARACTER_:
11108 return FFEINFO_basictypeCHARACTER;
11111 return FFEINFO_basictypeANY;
11116 ffecom_gfrt_kindtype (ffecomGfrt gfrt)
11118 assert (gfrt < FFECOM_gfrt);
11120 switch (ffecom_gfrt_type_[gfrt])
11122 case FFECOM_rttypeVOID_:
11123 case FFECOM_rttypeVOIDSTAR_:
11124 return FFEINFO_kindtypeNONE;
11126 case FFECOM_rttypeFTNINT_:
11127 return FFEINFO_kindtypeINTEGER1;
11129 case FFECOM_rttypeINTEGER_:
11130 return FFEINFO_kindtypeINTEGER1;
11132 case FFECOM_rttypeLONGINT_:
11133 return FFEINFO_kindtypeINTEGER4;
11135 case FFECOM_rttypeLOGICAL_:
11136 return FFEINFO_kindtypeLOGICAL1;
11138 case FFECOM_rttypeREAL_F2C_:
11139 case FFECOM_rttypeREAL_GNU_:
11140 return FFEINFO_kindtypeREAL1;
11142 case FFECOM_rttypeCOMPLEX_F2C_:
11143 case FFECOM_rttypeCOMPLEX_GNU_:
11144 return FFEINFO_kindtypeREAL1;
11146 case FFECOM_rttypeDOUBLE_:
11147 case FFECOM_rttypeDOUBLEREAL_:
11148 return FFEINFO_kindtypeREAL2;
11150 case FFECOM_rttypeDBLCMPLX_F2C_:
11151 case FFECOM_rttypeDBLCMPLX_GNU_:
11152 return FFEINFO_kindtypeREAL2;
11154 case FFECOM_rttypeCHARACTER_:
11155 return FFEINFO_kindtypeCHARACTER1;
11158 return FFEINFO_kindtypeANY;
11172 tree double_ftype_double;
11173 tree float_ftype_float;
11174 tree ldouble_ftype_ldouble;
11175 tree ffecom_tree_ptr_to_fun_type_void;
11177 /* This block of code comes from the now-obsolete cktyps.c. It checks
11178 whether the compiler environment is buggy in known ways, some of which
11179 would, if not explicitly checked here, result in subtle bugs in g77. */
11181 if (ffe_is_do_internal_checks ())
11183 static const char names[][12]
11185 {"bar", "bletch", "foo", "foobar"};
11190 name = bsearch ("foo", &names[0], ARRAY_SIZE (names), sizeof (names[0]),
11191 (int (*)(const void *, const void *)) strcmp);
11192 if (name != &names[0][2])
11194 assert ("bsearch doesn't work, #define FFEPROJ_BSEARCH 0 in proj.h"
11199 ul = strtoul ("123456789", NULL, 10);
11200 if (ul != 123456789L)
11202 assert ("strtoul doesn't have enough range, #define FFEPROJ_STRTOUL 0\
11203 in proj.h" == NULL);
11207 fl = atof ("56.789");
11208 if ((fl < 56.788) || (fl > 56.79))
11210 assert ("atof not type double, fix your #include <stdio.h>"
11216 ffecom_outer_function_decl_ = NULL_TREE;
11217 current_function_decl = NULL_TREE;
11218 named_labels = NULL_TREE;
11219 current_binding_level = NULL_BINDING_LEVEL;
11220 free_binding_level = NULL_BINDING_LEVEL;
11221 /* Make the binding_level structure for global names. */
11223 global_binding_level = current_binding_level;
11224 current_binding_level->prep_state = 2;
11226 build_common_tree_nodes (1);
11228 /* Define `int' and `char' first so that dbx will output them first. */
11229 pushdecl (build_decl (TYPE_DECL, get_identifier ("int"),
11230 integer_type_node));
11231 /* CHARACTER*1 is unsigned in ICHAR contexts. */
11232 char_type_node = make_unsigned_type (CHAR_TYPE_SIZE);
11233 pushdecl (build_decl (TYPE_DECL, get_identifier ("char"),
11235 pushdecl (build_decl (TYPE_DECL, get_identifier ("long int"),
11236 long_integer_type_node));
11237 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned int"),
11238 unsigned_type_node));
11239 pushdecl (build_decl (TYPE_DECL, get_identifier ("long unsigned int"),
11240 long_unsigned_type_node));
11241 pushdecl (build_decl (TYPE_DECL, get_identifier ("long long int"),
11242 long_long_integer_type_node));
11243 pushdecl (build_decl (TYPE_DECL, get_identifier ("long long unsigned int"),
11244 long_long_unsigned_type_node));
11245 pushdecl (build_decl (TYPE_DECL, get_identifier ("short int"),
11246 short_integer_type_node));
11247 pushdecl (build_decl (TYPE_DECL, get_identifier ("short unsigned int"),
11248 short_unsigned_type_node));
11250 /* Set the sizetype before we make other types. This *should* be the
11251 first type we create. */
11254 (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE))));
11255 ffecom_typesize_pointer_
11256 = TREE_INT_CST_LOW (TYPE_SIZE (sizetype)) / BITS_PER_UNIT;
11258 build_common_tree_nodes_2 (0);
11260 /* Define both `signed char' and `unsigned char'. */
11261 pushdecl (build_decl (TYPE_DECL, get_identifier ("signed char"),
11262 signed_char_type_node));
11264 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned char"),
11265 unsigned_char_type_node));
11267 pushdecl (build_decl (TYPE_DECL, get_identifier ("float"),
11269 pushdecl (build_decl (TYPE_DECL, get_identifier ("double"),
11270 double_type_node));
11271 pushdecl (build_decl (TYPE_DECL, get_identifier ("long double"),
11272 long_double_type_node));
11274 /* For now, override what build_common_tree_nodes has done. */
11275 complex_integer_type_node = ffecom_make_complex_type_ (integer_type_node);
11276 complex_float_type_node = ffecom_make_complex_type_ (float_type_node);
11277 complex_double_type_node = ffecom_make_complex_type_ (double_type_node);
11278 complex_long_double_type_node
11279 = ffecom_make_complex_type_ (long_double_type_node);
11281 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex int"),
11282 complex_integer_type_node));
11283 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex float"),
11284 complex_float_type_node));
11285 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex double"),
11286 complex_double_type_node));
11287 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex long double"),
11288 complex_long_double_type_node));
11290 pushdecl (build_decl (TYPE_DECL, get_identifier ("void"),
11292 /* We are not going to have real types in C with less than byte alignment,
11293 so we might as well not have any types that claim to have it. */
11294 TYPE_ALIGN (void_type_node) = BITS_PER_UNIT;
11295 TYPE_USER_ALIGN (void_type_node) = 0;
11297 string_type_node = build_pointer_type (char_type_node);
11299 ffecom_tree_fun_type_void
11300 = build_function_type (void_type_node, NULL_TREE);
11302 ffecom_tree_ptr_to_fun_type_void
11303 = build_pointer_type (ffecom_tree_fun_type_void);
11305 endlink = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
11308 = build_function_type (float_type_node,
11309 tree_cons (NULL_TREE, float_type_node, endlink));
11311 double_ftype_double
11312 = build_function_type (double_type_node,
11313 tree_cons (NULL_TREE, double_type_node, endlink));
11315 ldouble_ftype_ldouble
11316 = build_function_type (long_double_type_node,
11317 tree_cons (NULL_TREE, long_double_type_node,
11320 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11321 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11323 ffecom_tree_type[i][j] = NULL_TREE;
11324 ffecom_tree_fun_type[i][j] = NULL_TREE;
11325 ffecom_tree_ptr_to_fun_type[i][j] = NULL_TREE;
11326 ffecom_f2c_typecode_[i][j] = -1;
11329 /* Set up standard g77 types. Note that INTEGER and LOGICAL are set
11330 to size FLOAT_TYPE_SIZE because they have to be the same size as
11331 REAL, which also is FLOAT_TYPE_SIZE, according to the standard.
11332 Compiler options and other such stuff that change the ways these
11333 types are set should not affect this particular setup. */
11335 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER1]
11336 = t = make_signed_type (FLOAT_TYPE_SIZE);
11337 pushdecl (build_decl (TYPE_DECL, get_identifier ("integer"),
11339 type = ffetype_new ();
11341 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER1,
11343 ffetype_set_ams (type,
11344 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11345 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11346 ffetype_set_star (base_type,
11347 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11349 ffetype_set_kind (base_type, 1, type);
11350 ffecom_typesize_integer1_ = ffetype_size (type);
11351 assert (ffetype_size (type) == sizeof (ffetargetInteger1));
11353 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER1]
11354 = t = make_unsigned_type (FLOAT_TYPE_SIZE); /* HOLLERITH means unsigned. */
11355 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned"),
11358 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER2]
11359 = t = make_signed_type (CHAR_TYPE_SIZE);
11360 pushdecl (build_decl (TYPE_DECL, get_identifier ("byte"),
11362 type = ffetype_new ();
11363 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER2,
11365 ffetype_set_ams (type,
11366 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11367 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11368 ffetype_set_star (base_type,
11369 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11371 ffetype_set_kind (base_type, 3, type);
11372 assert (ffetype_size (type) == sizeof (ffetargetInteger2));
11374 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER2]
11375 = t = make_unsigned_type (CHAR_TYPE_SIZE);
11376 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned byte"),
11379 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER3]
11380 = t = make_signed_type (CHAR_TYPE_SIZE * 2);
11381 pushdecl (build_decl (TYPE_DECL, get_identifier ("word"),
11383 type = ffetype_new ();
11384 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER3,
11386 ffetype_set_ams (type,
11387 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11388 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11389 ffetype_set_star (base_type,
11390 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11392 ffetype_set_kind (base_type, 6, type);
11393 assert (ffetype_size (type) == sizeof (ffetargetInteger3));
11395 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER3]
11396 = t = make_unsigned_type (CHAR_TYPE_SIZE * 2);
11397 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned word"),
11400 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER4]
11401 = t = make_signed_type (FLOAT_TYPE_SIZE * 2);
11402 pushdecl (build_decl (TYPE_DECL, get_identifier ("integer4"),
11404 type = ffetype_new ();
11405 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER4,
11407 ffetype_set_ams (type,
11408 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11409 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11410 ffetype_set_star (base_type,
11411 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11413 ffetype_set_kind (base_type, 2, type);
11414 assert (ffetype_size (type) == sizeof (ffetargetInteger4));
11416 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER4]
11417 = t = make_unsigned_type (FLOAT_TYPE_SIZE * 2);
11418 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned4"),
11422 if (ffe_is_do_internal_checks ()
11423 && LONG_TYPE_SIZE != FLOAT_TYPE_SIZE
11424 && LONG_TYPE_SIZE != CHAR_TYPE_SIZE
11425 && LONG_TYPE_SIZE != SHORT_TYPE_SIZE
11426 && LONG_TYPE_SIZE != LONG_LONG_TYPE_SIZE)
11428 fprintf (stderr, "Sorry, no g77 support for LONG_TYPE_SIZE (%d bits) yet.\n",
11433 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL1]
11434 = t = make_signed_type (FLOAT_TYPE_SIZE);
11435 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical"),
11437 type = ffetype_new ();
11439 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL1,
11441 ffetype_set_ams (type,
11442 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11443 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11444 ffetype_set_star (base_type,
11445 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11447 ffetype_set_kind (base_type, 1, type);
11448 assert (ffetype_size (type) == sizeof (ffetargetLogical1));
11450 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL2]
11451 = t = make_signed_type (CHAR_TYPE_SIZE);
11452 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical2"),
11454 type = ffetype_new ();
11455 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL2,
11457 ffetype_set_ams (type,
11458 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11459 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11460 ffetype_set_star (base_type,
11461 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11463 ffetype_set_kind (base_type, 3, type);
11464 assert (ffetype_size (type) == sizeof (ffetargetLogical2));
11466 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL3]
11467 = t = make_signed_type (CHAR_TYPE_SIZE * 2);
11468 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical3"),
11470 type = ffetype_new ();
11471 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL3,
11473 ffetype_set_ams (type,
11474 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11475 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11476 ffetype_set_star (base_type,
11477 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11479 ffetype_set_kind (base_type, 6, type);
11480 assert (ffetype_size (type) == sizeof (ffetargetLogical3));
11482 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL4]
11483 = t = make_signed_type (FLOAT_TYPE_SIZE * 2);
11484 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical4"),
11486 type = ffetype_new ();
11487 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL4,
11489 ffetype_set_ams (type,
11490 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11491 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11492 ffetype_set_star (base_type,
11493 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11495 ffetype_set_kind (base_type, 2, type);
11496 assert (ffetype_size (type) == sizeof (ffetargetLogical4));
11498 ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]
11499 = t = make_node (REAL_TYPE);
11500 TYPE_PRECISION (t) = FLOAT_TYPE_SIZE;
11501 pushdecl (build_decl (TYPE_DECL, get_identifier ("real"),
11504 type = ffetype_new ();
11506 ffeinfo_set_type (FFEINFO_basictypeREAL, FFEINFO_kindtypeREAL1,
11508 ffetype_set_ams (type,
11509 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11510 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11511 ffetype_set_star (base_type,
11512 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11514 ffetype_set_kind (base_type, 1, type);
11515 ffecom_f2c_typecode_[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]
11516 = FFETARGET_f2cTYREAL;
11517 assert (ffetype_size (type) == sizeof (ffetargetReal1));
11519 ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREALDOUBLE]
11520 = t = make_node (REAL_TYPE);
11521 TYPE_PRECISION (t) = FLOAT_TYPE_SIZE * 2; /* Always twice REAL. */
11522 pushdecl (build_decl (TYPE_DECL, get_identifier ("double precision"),
11525 type = ffetype_new ();
11526 ffeinfo_set_type (FFEINFO_basictypeREAL, FFEINFO_kindtypeREALDOUBLE,
11528 ffetype_set_ams (type,
11529 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11530 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11531 ffetype_set_star (base_type,
11532 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11534 ffetype_set_kind (base_type, 2, type);
11535 ffecom_f2c_typecode_[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2]
11536 = FFETARGET_f2cTYDREAL;
11537 assert (ffetype_size (type) == sizeof (ffetargetReal2));
11539 ffecom_tree_type[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL1]
11540 = t = ffecom_make_complex_type_ (ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]);
11541 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex"),
11543 type = ffetype_new ();
11545 ffeinfo_set_type (FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREAL1,
11547 ffetype_set_ams (type,
11548 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11549 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11550 ffetype_set_star (base_type,
11551 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11553 ffetype_set_kind (base_type, 1, type);
11554 ffecom_f2c_typecode_[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL1]
11555 = FFETARGET_f2cTYCOMPLEX;
11556 assert (ffetype_size (type) == sizeof (ffetargetComplex1));
11558 ffecom_tree_type[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREALDOUBLE]
11559 = t = ffecom_make_complex_type_ (ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2]);
11560 pushdecl (build_decl (TYPE_DECL, get_identifier ("double complex"),
11562 type = ffetype_new ();
11563 ffeinfo_set_type (FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREALDOUBLE,
11565 ffetype_set_ams (type,
11566 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11567 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11568 ffetype_set_star (base_type,
11569 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11571 ffetype_set_kind (base_type, 2,
11573 ffecom_f2c_typecode_[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL2]
11574 = FFETARGET_f2cTYDCOMPLEX;
11575 assert (ffetype_size (type) == sizeof (ffetargetComplex2));
11577 /* Make function and ptr-to-function types for non-CHARACTER types. */
11579 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11580 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11582 if ((t = ffecom_tree_type[i][j]) != NULL_TREE)
11584 if (i == FFEINFO_basictypeINTEGER)
11586 /* Figure out the smallest INTEGER type that can hold
11587 a pointer on this machine. */
11588 if (GET_MODE_SIZE (TYPE_MODE (t))
11589 >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
11591 if ((ffecom_pointer_kind_ == FFEINFO_kindtypeNONE)
11592 || (GET_MODE_SIZE (TYPE_MODE (ffecom_tree_type[i][ffecom_pointer_kind_]))
11593 > GET_MODE_SIZE (TYPE_MODE (t))))
11594 ffecom_pointer_kind_ = j;
11597 else if (i == FFEINFO_basictypeCOMPLEX)
11598 t = void_type_node;
11599 /* For f2c compatibility, REAL functions are really
11600 implemented as DOUBLE PRECISION. */
11601 else if ((i == FFEINFO_basictypeREAL)
11602 && (j == FFEINFO_kindtypeREAL1))
11603 t = ffecom_tree_type
11604 [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2];
11606 t = ffecom_tree_fun_type[i][j] = build_function_type (t,
11608 ffecom_tree_ptr_to_fun_type[i][j] = build_pointer_type (t);
11612 /* Set up pointer types. */
11614 if (ffecom_pointer_kind_ == FFEINFO_basictypeNONE)
11615 fatal_error ("no INTEGER type can hold a pointer on this configuration");
11616 else if (0 && ffe_is_do_internal_checks ())
11617 fprintf (stderr, "Pointer type kt=%d\n", ffecom_pointer_kind_);
11618 ffetype_set_kind (ffeinfo_type (FFEINFO_basictypeINTEGER,
11619 FFEINFO_kindtypeINTEGERDEFAULT),
11621 ffeinfo_type (FFEINFO_basictypeINTEGER,
11622 ffecom_pointer_kind_));
11624 if (ffe_is_ugly_assign ())
11625 ffecom_label_kind_ = ffecom_pointer_kind_; /* Require ASSIGN etc to this. */
11627 ffecom_label_kind_ = FFEINFO_kindtypeINTEGERDEFAULT;
11628 if (0 && ffe_is_do_internal_checks ())
11629 fprintf (stderr, "Label type kt=%d\n", ffecom_label_kind_);
11631 ffecom_integer_type_node
11632 = ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER1];
11633 ffecom_integer_zero_node = convert (ffecom_integer_type_node,
11634 integer_zero_node);
11635 ffecom_integer_one_node = convert (ffecom_integer_type_node,
11638 /* Yes, the "FLOAT_TYPE_SIZE" references below are intentional.
11639 Turns out that by TYLONG, runtime/libI77/lio.h really means
11640 "whatever size an ftnint is". For consistency and sanity,
11641 com.h and runtime/f2c.h.in agree that flag, ftnint, and ftlen
11642 all are INTEGER, which we also make out of whatever back-end
11643 integer type is FLOAT_TYPE_SIZE bits wide. This change, from
11644 LONG_TYPE_SIZE, for TYLONG and TYLOGICAL, was necessary to
11645 accommodate machines like the Alpha. Note that this suggests
11646 f2c and libf2c are missing a distinction perhaps needed on
11647 some machines between "int" and "long int". -- burley 0.5.5 950215 */
11649 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, FLOAT_TYPE_SIZE,
11650 FFETARGET_f2cTYLONG);
11651 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, SHORT_TYPE_SIZE,
11652 FFETARGET_f2cTYSHORT);
11653 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, CHAR_TYPE_SIZE,
11654 FFETARGET_f2cTYINT1);
11655 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, LONG_LONG_TYPE_SIZE,
11656 FFETARGET_f2cTYQUAD);
11657 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, FLOAT_TYPE_SIZE,
11658 FFETARGET_f2cTYLOGICAL);
11659 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, SHORT_TYPE_SIZE,
11660 FFETARGET_f2cTYLOGICAL2);
11661 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, CHAR_TYPE_SIZE,
11662 FFETARGET_f2cTYLOGICAL1);
11663 /* ~~~Not really such a type in libf2c, e.g. I/O support? */
11664 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, LONG_LONG_TYPE_SIZE,
11665 FFETARGET_f2cTYQUAD);
11667 /* CHARACTER stuff is all special-cased, so it is not handled in the above
11668 loop. CHARACTER items are built as arrays of unsigned char. */
11670 ffecom_tree_type[FFEINFO_basictypeCHARACTER]
11671 [FFEINFO_kindtypeCHARACTER1] = t = char_type_node;
11672 type = ffetype_new ();
11674 ffeinfo_set_type (FFEINFO_basictypeCHARACTER,
11675 FFEINFO_kindtypeCHARACTER1,
11677 ffetype_set_ams (type,
11678 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11679 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11680 ffetype_set_kind (base_type, 1, type);
11681 assert (ffetype_size (type)
11682 == sizeof (((ffetargetCharacter1) { 0, NULL }).text[0]));
11684 ffecom_tree_fun_type[FFEINFO_basictypeCHARACTER]
11685 [FFEINFO_kindtypeCHARACTER1] = ffecom_tree_fun_type_void;
11686 ffecom_tree_ptr_to_fun_type[FFEINFO_basictypeCHARACTER]
11687 [FFEINFO_kindtypeCHARACTER1]
11688 = ffecom_tree_ptr_to_fun_type_void;
11689 ffecom_f2c_typecode_[FFEINFO_basictypeCHARACTER][FFEINFO_kindtypeCHARACTER1]
11690 = FFETARGET_f2cTYCHAR;
11692 ffecom_f2c_typecode_[FFEINFO_basictypeANY][FFEINFO_kindtypeANY]
11695 /* Make multi-return-value type and fields. */
11697 ffecom_multi_type_node_ = make_node (UNION_TYPE);
11701 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11702 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11706 if (ffecom_tree_type[i][j] == NULL_TREE)
11707 continue; /* Not supported. */
11708 sprintf (&name[0], "bt_%s_kt_%s",
11709 ffeinfo_basictype_string ((ffeinfoBasictype) i),
11710 ffeinfo_kindtype_string ((ffeinfoKindtype) j));
11711 ffecom_multi_fields_[i][j] = build_decl (FIELD_DECL,
11712 get_identifier (name),
11713 ffecom_tree_type[i][j]);
11714 DECL_CONTEXT (ffecom_multi_fields_[i][j])
11715 = ffecom_multi_type_node_;
11716 DECL_ALIGN (ffecom_multi_fields_[i][j]) = 0;
11717 DECL_USER_ALIGN (ffecom_multi_fields_[i][j]) = 0;
11718 TREE_CHAIN (ffecom_multi_fields_[i][j]) = field;
11719 field = ffecom_multi_fields_[i][j];
11722 TYPE_FIELDS (ffecom_multi_type_node_) = field;
11723 layout_type (ffecom_multi_type_node_);
11725 /* Subroutines usually return integer because they might have alternate
11728 ffecom_tree_subr_type
11729 = build_function_type (integer_type_node, NULL_TREE);
11730 ffecom_tree_ptr_to_subr_type
11731 = build_pointer_type (ffecom_tree_subr_type);
11732 ffecom_tree_blockdata_type
11733 = build_function_type (void_type_node, NULL_TREE);
11735 builtin_function ("__builtin_sqrtf", float_ftype_float,
11736 BUILT_IN_SQRTF, BUILT_IN_NORMAL, "sqrtf");
11737 builtin_function ("__builtin_sqrt", double_ftype_double,
11738 BUILT_IN_SQRT, BUILT_IN_NORMAL, "sqrt");
11739 builtin_function ("__builtin_sqrtl", ldouble_ftype_ldouble,
11740 BUILT_IN_SQRTL, BUILT_IN_NORMAL, "sqrtl");
11741 builtin_function ("__builtin_sinf", float_ftype_float,
11742 BUILT_IN_SINF, BUILT_IN_NORMAL, "sinf");
11743 builtin_function ("__builtin_sin", double_ftype_double,
11744 BUILT_IN_SIN, BUILT_IN_NORMAL, "sin");
11745 builtin_function ("__builtin_sinl", ldouble_ftype_ldouble,
11746 BUILT_IN_SINL, BUILT_IN_NORMAL, "sinl");
11747 builtin_function ("__builtin_cosf", float_ftype_float,
11748 BUILT_IN_COSF, BUILT_IN_NORMAL, "cosf");
11749 builtin_function ("__builtin_cos", double_ftype_double,
11750 BUILT_IN_COS, BUILT_IN_NORMAL, "cos");
11751 builtin_function ("__builtin_cosl", ldouble_ftype_ldouble,
11752 BUILT_IN_COSL, BUILT_IN_NORMAL, "cosl");
11754 pedantic_lvalues = FALSE;
11756 ffecom_f2c_make_type_ (&ffecom_f2c_integer_type_node,
11759 ffecom_f2c_make_type_ (&ffecom_f2c_address_type_node,
11762 ffecom_f2c_make_type_ (&ffecom_f2c_real_type_node,
11765 ffecom_f2c_make_type_ (&ffecom_f2c_doublereal_type_node,
11766 FFECOM_f2cDOUBLEREAL,
11768 ffecom_f2c_make_type_ (&ffecom_f2c_complex_type_node,
11771 ffecom_f2c_make_type_ (&ffecom_f2c_doublecomplex_type_node,
11772 FFECOM_f2cDOUBLECOMPLEX,
11774 ffecom_f2c_make_type_ (&ffecom_f2c_longint_type_node,
11777 ffecom_f2c_make_type_ (&ffecom_f2c_logical_type_node,
11780 ffecom_f2c_make_type_ (&ffecom_f2c_flag_type_node,
11783 ffecom_f2c_make_type_ (&ffecom_f2c_ftnlen_type_node,
11786 ffecom_f2c_make_type_ (&ffecom_f2c_ftnint_type_node,
11790 ffecom_f2c_ftnlen_zero_node
11791 = convert (ffecom_f2c_ftnlen_type_node, integer_zero_node);
11793 ffecom_f2c_ftnlen_one_node
11794 = convert (ffecom_f2c_ftnlen_type_node, integer_one_node);
11796 ffecom_f2c_ftnlen_two_node = build_int_2 (2, 0);
11797 TREE_TYPE (ffecom_f2c_ftnlen_two_node) = ffecom_integer_type_node;
11799 ffecom_f2c_ptr_to_ftnlen_type_node
11800 = build_pointer_type (ffecom_f2c_ftnlen_type_node);
11802 ffecom_f2c_ptr_to_ftnint_type_node
11803 = build_pointer_type (ffecom_f2c_ftnint_type_node);
11805 ffecom_f2c_ptr_to_integer_type_node
11806 = build_pointer_type (ffecom_f2c_integer_type_node);
11808 ffecom_f2c_ptr_to_real_type_node
11809 = build_pointer_type (ffecom_f2c_real_type_node);
11811 ffecom_float_zero_ = build_real (float_type_node, dconst0);
11812 ffecom_double_zero_ = build_real (double_type_node, dconst0);
11814 REAL_VALUE_TYPE point_5;
11816 REAL_ARITHMETIC (point_5, RDIV_EXPR, dconst1, dconst2);
11817 ffecom_float_half_ = build_real (float_type_node, point_5);
11818 ffecom_double_half_ = build_real (double_type_node, point_5);
11821 /* Do "extern int xargc;". */
11823 ffecom_tree_xargc_ = build_decl (VAR_DECL,
11824 get_identifier ("f__xargc"),
11825 integer_type_node);
11826 DECL_EXTERNAL (ffecom_tree_xargc_) = 1;
11827 TREE_STATIC (ffecom_tree_xargc_) = 1;
11828 TREE_PUBLIC (ffecom_tree_xargc_) = 1;
11829 ffecom_tree_xargc_ = start_decl (ffecom_tree_xargc_, FALSE);
11830 finish_decl (ffecom_tree_xargc_, NULL_TREE, FALSE);
11832 #if 0 /* This is being fixed, and seems to be working now. */
11833 if ((FLOAT_TYPE_SIZE != 32)
11834 || (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node))) != 32))
11836 warning ("configuration: REAL, INTEGER, and LOGICAL are %d bits wide,",
11837 (int) FLOAT_TYPE_SIZE);
11838 warning ("and pointers are %d bits wide, but g77 doesn't yet work",
11839 (int) TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node))));
11840 warning ("properly unless they all are 32 bits wide");
11841 warning ("Please keep this in mind before you report bugs.");
11845 #if 0 /* Code in ste.c that would crash has been commented out. */
11846 if (TYPE_PRECISION (ffecom_f2c_ftnlen_type_node)
11847 < TYPE_PRECISION (string_type_node))
11848 /* I/O will probably crash. */
11849 warning ("configuration: char * holds %d bits, but ftnlen only %d",
11850 TYPE_PRECISION (string_type_node),
11851 TYPE_PRECISION (ffecom_f2c_ftnlen_type_node));
11854 #if 0 /* ASSIGN-related stuff has been changed to accommodate this. */
11855 if (TYPE_PRECISION (ffecom_integer_type_node)
11856 < TYPE_PRECISION (string_type_node))
11857 /* ASSIGN 10 TO I will crash. */
11858 warning ("configuration: char * holds %d bits, but INTEGER only %d --\n\
11859 ASSIGN statement might fail",
11860 TYPE_PRECISION (string_type_node),
11861 TYPE_PRECISION (ffecom_integer_type_node));
11865 /* ffecom_init_2 -- Initialize
11867 ffecom_init_2(); */
11872 assert (ffecom_outer_function_decl_ == NULL_TREE);
11873 assert (current_function_decl == NULL_TREE);
11874 assert (ffecom_which_entrypoint_decl_ == NULL_TREE);
11876 ffecom_master_arglist_ = NULL;
11878 ffecom_primary_entry_ = NULL;
11879 ffecom_is_altreturning_ = FALSE;
11880 ffecom_func_result_ = NULL_TREE;
11881 ffecom_multi_retval_ = NULL_TREE;
11884 /* ffecom_list_expr -- Transform list of exprs into gcc tree
11887 ffebld expr; // FFE opITEM list.
11888 tree = ffecom_list_expr(expr);
11890 List of actual args is transformed into corresponding gcc backend list. */
11893 ffecom_list_expr (ffebld expr)
11896 tree *plist = &list;
11897 tree trail = NULL_TREE; /* Append char length args here. */
11898 tree *ptrail = &trail;
11901 while (expr != NULL)
11903 tree texpr = ffecom_arg_expr (ffebld_head (expr), &length);
11905 if (texpr == error_mark_node)
11906 return error_mark_node;
11908 *plist = build_tree_list (NULL_TREE, texpr);
11909 plist = &TREE_CHAIN (*plist);
11910 expr = ffebld_trail (expr);
11911 if (length != NULL_TREE)
11913 *ptrail = build_tree_list (NULL_TREE, length);
11914 ptrail = &TREE_CHAIN (*ptrail);
11923 /* ffecom_list_ptr_to_expr -- Transform list of exprs into gcc tree
11926 ffebld expr; // FFE opITEM list.
11927 tree = ffecom_list_ptr_to_expr(expr);
11929 List of actual args is transformed into corresponding gcc backend list for
11930 use in calling an external procedure (vs. a statement function). */
11933 ffecom_list_ptr_to_expr (ffebld expr)
11936 tree *plist = &list;
11937 tree trail = NULL_TREE; /* Append char length args here. */
11938 tree *ptrail = &trail;
11941 while (expr != NULL)
11943 tree texpr = ffecom_arg_ptr_to_expr (ffebld_head (expr), &length);
11945 if (texpr == error_mark_node)
11946 return error_mark_node;
11948 *plist = build_tree_list (NULL_TREE, texpr);
11949 plist = &TREE_CHAIN (*plist);
11950 expr = ffebld_trail (expr);
11951 if (length != NULL_TREE)
11953 *ptrail = build_tree_list (NULL_TREE, length);
11954 ptrail = &TREE_CHAIN (*ptrail);
11963 /* Obtain gcc's LABEL_DECL tree for label. */
11966 ffecom_lookup_label (ffelab label)
11970 if (ffelab_hook (label) == NULL_TREE)
11972 char labelname[16];
11974 switch (ffelab_type (label))
11976 case FFELAB_typeLOOPEND:
11977 case FFELAB_typeNOTLOOP:
11978 case FFELAB_typeENDIF:
11979 sprintf (labelname, "%" ffelabValue_f "u", ffelab_value (label));
11980 glabel = build_decl (LABEL_DECL, get_identifier (labelname),
11982 DECL_CONTEXT (glabel) = current_function_decl;
11983 DECL_MODE (glabel) = VOIDmode;
11986 case FFELAB_typeFORMAT:
11987 glabel = build_decl (VAR_DECL,
11988 ffecom_get_invented_identifier
11989 ("__g77_format_%d", (int) ffelab_value (label)),
11990 build_type_variant (build_array_type
11994 TREE_CONSTANT (glabel) = 1;
11995 TREE_STATIC (glabel) = 1;
11996 DECL_CONTEXT (glabel) = current_function_decl;
11997 DECL_INITIAL (glabel) = NULL;
11998 make_decl_rtl (glabel, NULL);
11999 expand_decl (glabel);
12001 ffecom_save_tree_forever (glabel);
12005 case FFELAB_typeANY:
12006 glabel = error_mark_node;
12010 assert ("bad label type" == NULL);
12014 ffelab_set_hook (label, glabel);
12018 glabel = ffelab_hook (label);
12024 /* Stabilizes the arguments. Don't use this if the lhs and rhs come from
12025 a single source specification (as in the fourth argument of MVBITS).
12026 If the type is NULL_TREE, the type of lhs is used to make the type of
12027 the MODIFY_EXPR. */
12030 ffecom_modify (tree newtype, tree lhs,
12033 if (lhs == error_mark_node || rhs == error_mark_node)
12034 return error_mark_node;
12036 if (newtype == NULL_TREE)
12037 newtype = TREE_TYPE (lhs);
12039 if (TREE_SIDE_EFFECTS (lhs))
12040 lhs = stabilize_reference (lhs);
12042 return ffecom_2s (MODIFY_EXPR, newtype, lhs, rhs);
12045 /* Register source file name. */
12048 ffecom_file (const char *name)
12050 ffecom_file_ (name);
12053 /* ffecom_notify_init_storage -- An aggregate storage is now fully init'ed
12056 ffecom_notify_init_storage(st);
12058 Gets called when all possible units in an aggregate storage area (a LOCAL
12059 with equivalences or a COMMON) have been initialized. The initialization
12060 info either is in ffestorag_init or, if that is NULL,
12061 ffestorag_accretion:
12063 ffestorag_init may contain an opCONTER or opARRTER. opCONTER may occur
12064 even for an array if the array is one element in length!
12066 ffestorag_accretion will contain an opACCTER. It is much like an
12067 opARRTER except it has an ffebit object in it instead of just a size.
12068 The back end can use the info in the ffebit object, if it wants, to
12069 reduce the amount of actual initialization, but in any case it should
12070 kill the ffebit object when done. Also, set accretion to NULL but
12071 init to a non-NULL value.
12073 After performing initialization, DO NOT set init to NULL, because that'll
12074 tell the front end it is ok for more initialization to happen. Instead,
12075 set init to an opANY expression or some such thing that you can use to
12076 tell that you've already initialized the object.
12079 Support two-pass FFE. */
12082 ffecom_notify_init_storage (ffestorag st)
12084 ffebld init; /* The initialization expression. */
12086 if (ffestorag_init (st) == NULL)
12088 init = ffestorag_accretion (st);
12089 assert (init != NULL);
12090 ffestorag_set_accretion (st, NULL);
12091 ffestorag_set_accretes (st, 0);
12092 ffestorag_set_init (st, init);
12096 /* ffecom_notify_init_symbol -- A symbol is now fully init'ed
12099 ffecom_notify_init_symbol(s);
12101 Gets called when all possible units in a symbol (not placed in COMMON
12102 or involved in EQUIVALENCE, unless it as yet has no ffestorag object)
12103 have been initialized. The initialization info either is in
12104 ffesymbol_init or, if that is NULL, ffesymbol_accretion:
12106 ffesymbol_init may contain an opCONTER or opARRTER. opCONTER may occur
12107 even for an array if the array is one element in length!
12109 ffesymbol_accretion will contain an opACCTER. It is much like an
12110 opARRTER except it has an ffebit object in it instead of just a size.
12111 The back end can use the info in the ffebit object, if it wants, to
12112 reduce the amount of actual initialization, but in any case it should
12113 kill the ffebit object when done. Also, set accretion to NULL but
12114 init to a non-NULL value.
12116 After performing initialization, DO NOT set init to NULL, because that'll
12117 tell the front end it is ok for more initialization to happen. Instead,
12118 set init to an opANY expression or some such thing that you can use to
12119 tell that you've already initialized the object.
12122 Support two-pass FFE. */
12125 ffecom_notify_init_symbol (ffesymbol s)
12127 ffebld init; /* The initialization expression. */
12129 if (ffesymbol_storage (s) == NULL)
12130 return; /* Do nothing until COMMON/EQUIVALENCE
12131 possibilities checked. */
12133 if ((ffesymbol_init (s) == NULL)
12134 && ((init = ffesymbol_accretion (s)) != NULL))
12136 ffesymbol_set_accretion (s, NULL);
12137 ffesymbol_set_accretes (s, 0);
12138 ffesymbol_set_init (s, init);
12142 /* ffecom_notify_primary_entry -- Learn which is the primary entry point
12145 ffecom_notify_primary_entry(s);
12147 Gets called when implicit or explicit PROGRAM statement seen or when
12148 FUNCTION, SUBROUTINE, or BLOCK DATA statement seen, with the primary
12149 global symbol that serves as the entry point. */
12152 ffecom_notify_primary_entry (ffesymbol s)
12154 ffecom_primary_entry_ = s;
12155 ffecom_primary_entry_kind_ = ffesymbol_kind (s);
12157 if ((ffecom_primary_entry_kind_ == FFEINFO_kindFUNCTION)
12158 || (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE))
12159 ffecom_primary_entry_is_proc_ = TRUE;
12161 ffecom_primary_entry_is_proc_ = FALSE;
12163 if (!ffe_is_silent ())
12165 if (ffecom_primary_entry_kind_ == FFEINFO_kindPROGRAM)
12166 fprintf (stderr, "%s:\n", ffesymbol_text (s));
12168 fprintf (stderr, " %s:\n", ffesymbol_text (s));
12171 if (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE)
12176 for (list = ffesymbol_dummyargs (s);
12178 list = ffebld_trail (list))
12180 arg = ffebld_head (list);
12181 if (ffebld_op (arg) == FFEBLD_opSTAR)
12183 ffecom_is_altreturning_ = TRUE;
12191 ffecom_open_include (char *name, ffewhereLine l, ffewhereColumn c)
12193 return ffecom_open_include_ (name, l, c);
12196 /* ffecom_ptr_to_expr -- Transform expr into gcc tree with & in front
12199 ffebld expr; // FFE expression.
12200 tree = ffecom_ptr_to_expr(expr);
12202 Like ffecom_expr, but sticks address-of in front of most things. */
12205 ffecom_ptr_to_expr (ffebld expr)
12208 ffeinfoBasictype bt;
12209 ffeinfoKindtype kt;
12212 assert (expr != NULL);
12214 switch (ffebld_op (expr))
12216 case FFEBLD_opSYMTER:
12217 s = ffebld_symter (expr);
12218 if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC)
12222 ix = ffeintrin_gfrt_indirect (ffebld_symter_implementation (expr));
12223 assert (ix != FFECOM_gfrt);
12224 if ((item = ffecom_gfrt_[ix]) == NULL_TREE)
12226 ffecom_make_gfrt_ (ix);
12227 item = ffecom_gfrt_[ix];
12232 item = ffesymbol_hook (s).decl_tree;
12233 if (item == NULL_TREE)
12235 s = ffecom_sym_transform_ (s);
12236 item = ffesymbol_hook (s).decl_tree;
12239 assert (item != NULL);
12240 if (item == error_mark_node)
12242 if (!ffesymbol_hook (s).addr)
12243 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12247 case FFEBLD_opARRAYREF:
12248 return ffecom_arrayref_ (NULL_TREE, expr, 1);
12250 case FFEBLD_opCONTER:
12252 bt = ffeinfo_basictype (ffebld_info (expr));
12253 kt = ffeinfo_kindtype (ffebld_info (expr));
12255 item = ffecom_constantunion (&ffebld_constant_union
12256 (ffebld_conter (expr)), bt, kt,
12257 ffecom_tree_type[bt][kt]);
12258 if (item == error_mark_node)
12259 return error_mark_node;
12260 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12265 return error_mark_node;
12268 bt = ffeinfo_basictype (ffebld_info (expr));
12269 kt = ffeinfo_kindtype (ffebld_info (expr));
12271 item = ffecom_expr (expr);
12272 if (item == error_mark_node)
12273 return error_mark_node;
12275 /* The back end currently optimizes a bit too zealously for us, in that
12276 we fail JCB001 if the following block of code is omitted. It checks
12277 to see if the transformed expression is a symbol or array reference,
12278 and encloses it in a SAVE_EXPR if that is the case. */
12281 if ((TREE_CODE (item) == VAR_DECL)
12282 || (TREE_CODE (item) == PARM_DECL)
12283 || (TREE_CODE (item) == RESULT_DECL)
12284 || (TREE_CODE (item) == INDIRECT_REF)
12285 || (TREE_CODE (item) == ARRAY_REF)
12286 || (TREE_CODE (item) == COMPONENT_REF)
12288 || (TREE_CODE (item) == OFFSET_REF)
12290 || (TREE_CODE (item) == BUFFER_REF)
12291 || (TREE_CODE (item) == REALPART_EXPR)
12292 || (TREE_CODE (item) == IMAGPART_EXPR))
12294 item = ffecom_save_tree (item);
12297 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12302 assert ("fall-through error" == NULL);
12303 return error_mark_node;
12306 /* Obtain a temp var with given data type.
12308 size is FFETARGET_charactersizeNONE for a non-CHARACTER type
12309 or >= 0 for a CHARACTER type.
12311 elements is -1 for a scalar or > 0 for an array of type. */
12314 ffecom_make_tempvar (const char *commentary, tree type,
12315 ffetargetCharacterSize size, int elements)
12318 static int mynumber;
12320 assert (current_binding_level->prep_state < 2);
12322 if (type == error_mark_node)
12323 return error_mark_node;
12325 if (size != FFETARGET_charactersizeNONE)
12326 type = build_array_type (type,
12327 build_range_type (ffecom_f2c_ftnlen_type_node,
12328 ffecom_f2c_ftnlen_one_node,
12329 build_int_2 (size, 0)));
12330 if (elements != -1)
12331 type = build_array_type (type,
12332 build_range_type (integer_type_node,
12334 build_int_2 (elements - 1,
12336 t = build_decl (VAR_DECL,
12337 ffecom_get_invented_identifier ("__g77_%s_%d",
12342 t = start_decl (t, FALSE);
12343 finish_decl (t, NULL_TREE, FALSE);
12348 /* Prepare argument pointer to expression.
12350 Like ffecom_prepare_expr, except for expressions to be evaluated
12351 via ffecom_arg_ptr_to_expr. */
12354 ffecom_prepare_arg_ptr_to_expr (ffebld expr)
12356 /* ~~For now, it seems to be the same thing. */
12357 ffecom_prepare_expr (expr);
12361 /* End of preparations. */
12364 ffecom_prepare_end (void)
12366 int prep_state = current_binding_level->prep_state;
12368 assert (prep_state < 2);
12369 current_binding_level->prep_state = 2;
12371 return (prep_state == 1) ? TRUE : FALSE;
12374 /* Prepare expression.
12376 This is called before any code is generated for the current block.
12377 It scans the expression, declares any temporaries that might be needed
12378 during evaluation of the expression, and stores those temporaries in
12379 the appropriate "hook" fields of the expression. `dest', if not NULL,
12380 specifies the destination that ffecom_expr_ will see, in case that
12381 helps avoid generating unused temporaries.
12383 ~~Improve to avoid allocating unused temporaries by taking `dest'
12384 into account vis-a-vis aliasing requirements of complex/character
12388 ffecom_prepare_expr_ (ffebld expr, ffebld dest UNUSED)
12390 ffeinfoBasictype bt;
12391 ffeinfoKindtype kt;
12392 ffetargetCharacterSize sz;
12393 tree tempvar = NULL_TREE;
12395 assert (current_binding_level->prep_state < 2);
12400 bt = ffeinfo_basictype (ffebld_info (expr));
12401 kt = ffeinfo_kindtype (ffebld_info (expr));
12402 sz = ffeinfo_size (ffebld_info (expr));
12404 /* Generate whatever temporaries are needed to represent the result
12405 of the expression. */
12407 if (bt == FFEINFO_basictypeCHARACTER)
12409 while (ffebld_op (expr) == FFEBLD_opPAREN)
12410 expr = ffebld_left (expr);
12413 switch (ffebld_op (expr))
12416 /* Don't make temps for SYMTER, CONTER, etc. */
12417 if (ffebld_arity (expr) == 0)
12422 case FFEINFO_basictypeCOMPLEX:
12423 if (ffebld_op (expr) == FFEBLD_opFUNCREF)
12427 if (ffebld_op (ffebld_left (expr)) != FFEBLD_opSYMTER)
12430 s = ffebld_symter (ffebld_left (expr));
12431 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT
12432 || (ffesymbol_where (s) != FFEINFO_whereINTRINSIC
12433 && ! ffesymbol_is_f2c (s))
12434 || (ffesymbol_where (s) == FFEINFO_whereINTRINSIC
12435 && ! ffe_is_f2c_library ()))
12438 else if (ffebld_op (expr) == FFEBLD_opPOWER)
12440 /* Requires special treatment. There's no POW_CC function
12441 in libg2c, so POW_ZZ is used, which means we always
12442 need a double-complex temp, not a single-complex. */
12443 kt = FFEINFO_kindtypeREAL2;
12445 else if (ffebld_op (expr) != FFEBLD_opDIVIDE)
12446 /* The other ops don't need temps for complex operands. */
12449 /* ~~~Avoid making temps for some intrinsics, such as AIMAG(C),
12450 REAL(C). See 19990325-0.f, routine `check', for cases. */
12451 tempvar = ffecom_make_tempvar ("complex",
12453 [FFEINFO_basictypeCOMPLEX][kt],
12454 FFETARGET_charactersizeNONE,
12458 case FFEINFO_basictypeCHARACTER:
12459 if (ffebld_op (expr) != FFEBLD_opFUNCREF)
12462 if (sz == FFETARGET_charactersizeNONE)
12463 /* ~~Kludge alert! This should someday be fixed. */
12466 tempvar = ffecom_make_tempvar ("char", char_type_node, sz, -1);
12475 case FFEBLD_opPOWER:
12478 tree rtmp, ltmp, result;
12480 ltype = ffecom_type_expr (ffebld_left (expr));
12481 rtype = ffecom_type_expr (ffebld_right (expr));
12483 rtmp = ffecom_make_tempvar (rtype, FFETARGET_charactersizeNONE, -1);
12484 ltmp = ffecom_make_tempvar (ltype, FFETARGET_charactersizeNONE, -1);
12485 result = ffecom_make_tempvar (ltype, FFETARGET_charactersizeNONE, -1);
12487 tempvar = make_tree_vec (3);
12488 TREE_VEC_ELT (tempvar, 0) = rtmp;
12489 TREE_VEC_ELT (tempvar, 1) = ltmp;
12490 TREE_VEC_ELT (tempvar, 2) = result;
12495 case FFEBLD_opCONCATENATE:
12497 /* This gets special handling, because only one set of temps
12498 is needed for a tree of these -- the tree is treated as
12499 a flattened list of concatenations when generating code. */
12501 ffecomConcatList_ catlist;
12502 tree ltmp, itmp, result;
12506 catlist = ffecom_concat_list_new_ (expr, FFETARGET_charactersizeNONE);
12507 count = ffecom_concat_list_count_ (catlist);
12512 = ffecom_make_tempvar ("concat_len",
12513 ffecom_f2c_ftnlen_type_node,
12514 FFETARGET_charactersizeNONE, count);
12516 = ffecom_make_tempvar ("concat_item",
12517 ffecom_f2c_address_type_node,
12518 FFETARGET_charactersizeNONE, count);
12520 = ffecom_make_tempvar ("concat_res",
12522 ffecom_concat_list_maxlen_ (catlist),
12525 tempvar = make_tree_vec (3);
12526 TREE_VEC_ELT (tempvar, 0) = ltmp;
12527 TREE_VEC_ELT (tempvar, 1) = itmp;
12528 TREE_VEC_ELT (tempvar, 2) = result;
12531 for (i = 0; i < count; ++i)
12532 ffecom_prepare_arg_ptr_to_expr (ffecom_concat_list_expr_ (catlist,
12535 ffecom_concat_list_kill_ (catlist);
12539 ffebld_nonter_set_hook (expr, tempvar);
12540 current_binding_level->prep_state = 1;
12545 case FFEBLD_opCONVERT:
12546 if (bt == FFEINFO_basictypeCHARACTER
12547 && ((ffebld_size_known (ffebld_left (expr))
12548 == FFETARGET_charactersizeNONE)
12549 || (ffebld_size_known (ffebld_left (expr)) >= sz)))
12550 tempvar = ffecom_make_tempvar ("convert", char_type_node, sz, -1);
12556 ffebld_nonter_set_hook (expr, tempvar);
12557 current_binding_level->prep_state = 1;
12560 /* Prepare subexpressions for this expr. */
12562 switch (ffebld_op (expr))
12564 case FFEBLD_opPERCENT_LOC:
12565 ffecom_prepare_ptr_to_expr (ffebld_left (expr));
12568 case FFEBLD_opPERCENT_VAL:
12569 case FFEBLD_opPERCENT_REF:
12570 ffecom_prepare_expr (ffebld_left (expr));
12573 case FFEBLD_opPERCENT_DESCR:
12574 ffecom_prepare_arg_ptr_to_expr (ffebld_left (expr));
12577 case FFEBLD_opITEM:
12583 item = ffebld_trail (item))
12584 if (ffebld_head (item) != NULL)
12585 ffecom_prepare_expr (ffebld_head (item));
12590 /* Need to handle character conversion specially. */
12591 switch (ffebld_arity (expr))
12594 ffecom_prepare_expr (ffebld_left (expr));
12595 ffecom_prepare_expr (ffebld_right (expr));
12599 ffecom_prepare_expr (ffebld_left (expr));
12610 /* Prepare expression for reading and writing.
12612 Like ffecom_prepare_expr, except for expressions to be evaluated
12613 via ffecom_expr_rw. */
12616 ffecom_prepare_expr_rw (tree type, ffebld expr)
12618 /* This is all we support for now. */
12619 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
12621 /* ~~For now, it seems to be the same thing. */
12622 ffecom_prepare_expr (expr);
12626 /* Prepare expression for writing.
12628 Like ffecom_prepare_expr, except for expressions to be evaluated
12629 via ffecom_expr_w. */
12632 ffecom_prepare_expr_w (tree type, ffebld expr)
12634 /* This is all we support for now. */
12635 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
12637 /* ~~For now, it seems to be the same thing. */
12638 ffecom_prepare_expr (expr);
12642 /* Prepare expression for returning.
12644 Like ffecom_prepare_expr, except for expressions to be evaluated
12645 via ffecom_return_expr. */
12648 ffecom_prepare_return_expr (ffebld expr)
12650 assert (current_binding_level->prep_state < 2);
12652 if (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE
12653 && ffecom_is_altreturning_
12655 ffecom_prepare_expr (expr);
12658 /* Prepare pointer to expression.
12660 Like ffecom_prepare_expr, except for expressions to be evaluated
12661 via ffecom_ptr_to_expr. */
12664 ffecom_prepare_ptr_to_expr (ffebld expr)
12666 /* ~~For now, it seems to be the same thing. */
12667 ffecom_prepare_expr (expr);
12671 /* Transform expression into constant pointer-to-expression tree.
12673 If the expression can be transformed into a pointer-to-expression tree
12674 that is constant, that is done, and the tree returned. Else NULL_TREE
12677 That way, a caller can attempt to provide compile-time initialization
12678 of a variable and, if that fails, *then* choose to start a new block
12679 and resort to using temporaries, as appropriate. */
12682 ffecom_ptr_to_const_expr (ffebld expr)
12685 return integer_zero_node;
12687 if (ffebld_op (expr) == FFEBLD_opANY)
12688 return error_mark_node;
12690 if (ffebld_arity (expr) == 0
12691 && (ffebld_op (expr) != FFEBLD_opSYMTER
12692 || ffebld_where (expr) == FFEINFO_whereCOMMON
12693 || ffebld_where (expr) == FFEINFO_whereGLOBAL
12694 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
12698 t = ffecom_ptr_to_expr (expr);
12699 assert (TREE_CONSTANT (t));
12706 /* ffecom_return_expr -- Returns return-value expr given alt return expr
12708 tree rtn; // NULL_TREE means use expand_null_return()
12709 ffebld expr; // NULL if no alt return expr to RETURN stmt
12710 rtn = ffecom_return_expr(expr);
12712 Based on the program unit type and other info (like return function
12713 type, return master function type when alternate ENTRY points,
12714 whether subroutine has any alternate RETURN points, etc), returns the
12715 appropriate expression to be returned to the caller, or NULL_TREE
12716 meaning no return value or the caller expects it to be returned somewhere
12717 else (which is handled by other parts of this module). */
12720 ffecom_return_expr (ffebld expr)
12724 switch (ffecom_primary_entry_kind_)
12726 case FFEINFO_kindPROGRAM:
12727 case FFEINFO_kindBLOCKDATA:
12731 case FFEINFO_kindSUBROUTINE:
12732 if (!ffecom_is_altreturning_)
12733 rtn = NULL_TREE; /* No alt returns, never an expr. */
12734 else if (expr == NULL)
12735 rtn = integer_zero_node;
12737 rtn = ffecom_expr (expr);
12740 case FFEINFO_kindFUNCTION:
12741 if ((ffecom_multi_retval_ != NULL_TREE)
12742 || (ffesymbol_basictype (ffecom_primary_entry_)
12743 == FFEINFO_basictypeCHARACTER)
12744 || ((ffesymbol_basictype (ffecom_primary_entry_)
12745 == FFEINFO_basictypeCOMPLEX)
12746 && (ffecom_num_entrypoints_ == 0)
12747 && ffesymbol_is_f2c (ffecom_primary_entry_)))
12748 { /* Value is returned by direct assignment
12749 into (implicit) dummy. */
12753 rtn = ffecom_func_result_;
12755 /* Spurious error if RETURN happens before first reference! So elide
12756 this code. In particular, for debugging registry, rtn should always
12757 be non-null after all, but TREE_USED won't be set until we encounter
12758 a reference in the code. Perfectly okay (but weird) code that,
12759 e.g., has "GOTO 20;10 RETURN;20 RTN=0;GOTO 10", would result in
12760 this diagnostic for no reason. Have people use -O -Wuninitialized
12761 and leave it to the back end to find obviously weird cases. */
12763 /* Used to "assert(rtn != NULL_TREE);" here, but it's kind of a valid
12764 situation; if the return value has never been referenced, it won't
12765 have a tree under 2pass mode. */
12766 if ((rtn == NULL_TREE)
12767 || !TREE_USED (rtn))
12769 ffebad_start (FFEBAD_RETURN_VALUE_UNSET);
12770 ffebad_here (0, ffesymbol_where_line (ffecom_primary_entry_),
12771 ffesymbol_where_column (ffecom_primary_entry_));
12772 ffebad_string (ffesymbol_text (ffesymbol_funcresult
12773 (ffecom_primary_entry_)));
12780 assert ("bad unit kind" == NULL);
12781 case FFEINFO_kindANY:
12782 rtn = error_mark_node;
12789 /* Do save_expr only if tree is not error_mark_node. */
12792 ffecom_save_tree (tree t)
12794 return save_expr (t);
12797 /* Start a compound statement (block). */
12800 ffecom_start_compstmt (void)
12802 bison_rule_pushlevel_ ();
12805 /* Public entry point for front end to access start_decl. */
12808 ffecom_start_decl (tree decl, bool is_initialized)
12810 DECL_INITIAL (decl) = is_initialized ? error_mark_node : NULL_TREE;
12811 return start_decl (decl, FALSE);
12814 /* ffecom_sym_commit -- Symbol's state being committed to reality
12817 ffecom_sym_commit(s);
12819 Does whatever the backend needs when a symbol is committed after having
12820 been backtrackable for a period of time. */
12823 ffecom_sym_commit (ffesymbol s UNUSED)
12825 assert (!ffesymbol_retractable ());
12828 /* ffecom_sym_end_transition -- Perform end transition on all symbols
12830 ffecom_sym_end_transition();
12832 Does backend-specific stuff and also calls ffest_sym_end_transition
12833 to do the necessary FFE stuff.
12835 Backtracking is never enabled when this fn is called, so don't worry
12839 ffecom_sym_end_transition (ffesymbol s)
12843 assert (!ffesymbol_retractable ());
12845 s = ffest_sym_end_transition (s);
12847 if ((ffesymbol_kind (s) == FFEINFO_kindBLOCKDATA)
12848 && (ffesymbol_where (s) == FFEINFO_whereGLOBAL))
12850 ffecom_list_blockdata_
12851 = ffebld_new_item (ffebld_new_symter (s, FFEINTRIN_genNONE,
12852 FFEINTRIN_specNONE,
12853 FFEINTRIN_impNONE),
12854 ffecom_list_blockdata_);
12857 /* This is where we finally notice that a symbol has partial initialization
12858 and finalize it. */
12860 if (ffesymbol_accretion (s) != NULL)
12862 assert (ffesymbol_init (s) == NULL);
12863 ffecom_notify_init_symbol (s);
12865 else if (((st = ffesymbol_storage (s)) != NULL)
12866 && ((st = ffestorag_parent (st)) != NULL)
12867 && (ffestorag_accretion (st) != NULL))
12869 assert (ffestorag_init (st) == NULL);
12870 ffecom_notify_init_storage (st);
12873 if ((ffesymbol_kind (s) == FFEINFO_kindCOMMON)
12874 && (ffesymbol_where (s) == FFEINFO_whereLOCAL)
12875 && (ffesymbol_storage (s) != NULL))
12877 ffecom_list_common_
12878 = ffebld_new_item (ffebld_new_symter (s, FFEINTRIN_genNONE,
12879 FFEINTRIN_specNONE,
12880 FFEINTRIN_impNONE),
12881 ffecom_list_common_);
12887 /* ffecom_sym_exec_transition -- Perform exec transition on all symbols
12889 ffecom_sym_exec_transition();
12891 Does backend-specific stuff and also calls ffest_sym_exec_transition
12892 to do the necessary FFE stuff.
12894 See the long-winded description in ffecom_sym_learned for info
12895 on handling the situation where backtracking is inhibited. */
12898 ffecom_sym_exec_transition (ffesymbol s)
12900 s = ffest_sym_exec_transition (s);
12905 /* ffecom_sym_learned -- Initial or more info gained on symbol after exec
12908 s = ffecom_sym_learned(s);
12910 Called when a new symbol is seen after the exec transition or when more
12911 info (perhaps) is gained for an UNCERTAIN symbol. The symbol state when
12912 it arrives here is that all its latest info is updated already, so its
12913 state may be UNCERTAIN or UNDERSTOOD, it might already have the hook
12914 field filled in if its gone through here or exec_transition first, and
12917 The backend probably wants to check ffesymbol_retractable() to see if
12918 backtracking is in effect. If so, the FFE's changes to the symbol may
12919 be retracted (undone) or committed (ratified), at which time the
12920 appropriate ffecom_sym_retract or _commit function will be called
12923 If the backend has its own backtracking mechanism, great, use it so that
12924 committal is a simple operation. Though it doesn't make much difference,
12925 I suppose: the reason for tentative symbol evolution in the FFE is to
12926 enable error detection in weird incorrect statements early and to disable
12927 incorrect error detection on a correct statement. The backend is not
12928 likely to introduce any information that'll get involved in these
12929 considerations, so it is probably just fine that the implementation
12930 model for this fn and for _exec_transition is to not do anything
12931 (besides the required FFE stuff) if ffesymbol_retractable() returns TRUE
12932 and instead wait until ffecom_sym_commit is called (which it never
12933 will be as long as we're using ambiguity-detecting statement analysis in
12934 the FFE, which we are initially to shake out the code, but don't depend
12935 on this), otherwise go ahead and do whatever is needed.
12937 In essence, then, when this fn and _exec_transition get called while
12938 backtracking is enabled, a general mechanism would be to flag which (or
12939 both) of these were called (and in what order? neat question as to what
12940 might happen that I'm too lame to think through right now) and then when
12941 _commit is called reproduce the original calling sequence, if any, for
12942 the two fns (at which point backtracking will, of course, be disabled). */
12945 ffecom_sym_learned (ffesymbol s)
12947 ffestorag_exec_layout (s);
12952 /* ffecom_sym_retract -- Symbol's state being retracted from reality
12955 ffecom_sym_retract(s);
12957 Does whatever the backend needs when a symbol is retracted after having
12958 been backtrackable for a period of time. */
12961 ffecom_sym_retract (ffesymbol s UNUSED)
12963 assert (!ffesymbol_retractable ());
12965 #if 0 /* GCC doesn't commit any backtrackable sins,
12966 so nothing needed here. */
12967 switch (ffesymbol_hook (s).state)
12969 case 0: /* nothing happened yet. */
12972 case 1: /* exec transition happened. */
12975 case 2: /* learned happened. */
12978 case 3: /* learned then exec. */
12981 case 4: /* exec then learned. */
12985 assert ("bad hook state" == NULL);
12991 /* Create temporary gcc label. */
12994 ffecom_temp_label ()
12997 static int mynumber = 0;
12999 glabel = build_decl (LABEL_DECL,
13000 ffecom_get_invented_identifier ("__g77_label_%d",
13003 DECL_CONTEXT (glabel) = current_function_decl;
13004 DECL_MODE (glabel) = VOIDmode;
13009 /* Return an expression that is usable as an arg in a conditional context
13010 (IF, DO WHILE, .NOT., and so on).
13012 Use the one provided for the back end as of >2.6.0. */
13015 ffecom_truth_value (tree expr)
13017 return ffe_truthvalue_conversion (expr);
13020 /* Return the inversion of a truth value (the inversion of what
13021 ffecom_truth_value builds).
13023 Apparently invert_truthvalue, which is properly in the back end, is
13024 enough for now, so just use it. */
13027 ffecom_truth_value_invert (tree expr)
13029 return invert_truthvalue (ffecom_truth_value (expr));
13032 /* Return the tree that is the type of the expression, as would be
13033 returned in TREE_TYPE(ffecom_expr(expr)), without otherwise
13034 transforming the expression, generating temporaries, etc. */
13037 ffecom_type_expr (ffebld expr)
13039 ffeinfoBasictype bt;
13040 ffeinfoKindtype kt;
13043 assert (expr != NULL);
13045 bt = ffeinfo_basictype (ffebld_info (expr));
13046 kt = ffeinfo_kindtype (ffebld_info (expr));
13047 tree_type = ffecom_tree_type[bt][kt];
13049 switch (ffebld_op (expr))
13051 case FFEBLD_opCONTER:
13052 case FFEBLD_opSYMTER:
13053 case FFEBLD_opARRAYREF:
13054 case FFEBLD_opUPLUS:
13055 case FFEBLD_opPAREN:
13056 case FFEBLD_opUMINUS:
13058 case FFEBLD_opSUBTRACT:
13059 case FFEBLD_opMULTIPLY:
13060 case FFEBLD_opDIVIDE:
13061 case FFEBLD_opPOWER:
13063 case FFEBLD_opFUNCREF:
13064 case FFEBLD_opSUBRREF:
13068 case FFEBLD_opNEQV:
13070 case FFEBLD_opCONVERT:
13077 case FFEBLD_opPERCENT_LOC:
13080 case FFEBLD_opACCTER:
13081 case FFEBLD_opARRTER:
13082 case FFEBLD_opITEM:
13083 case FFEBLD_opSTAR:
13084 case FFEBLD_opBOUNDS:
13085 case FFEBLD_opREPEAT:
13086 case FFEBLD_opLABTER:
13087 case FFEBLD_opLABTOK:
13088 case FFEBLD_opIMPDO:
13089 case FFEBLD_opCONCATENATE:
13090 case FFEBLD_opSUBSTR:
13092 assert ("bad op for ffecom_type_expr" == NULL);
13093 /* Fall through. */
13095 return error_mark_node;
13099 /* Return PARM_DECL for arg#1 of master fn containing alternate ENTRY points
13101 If the PARM_DECL already exists, return it, else create it. It's an
13102 integer_type_node argument for the master function that implements a
13103 subroutine or function with more than one entrypoint and is bound at
13104 run time with the entrypoint number (0 for SUBROUTINE/FUNCTION, 1 for
13105 first ENTRY statement, and so on). */
13108 ffecom_which_entrypoint_decl ()
13110 assert (ffecom_which_entrypoint_decl_ != NULL_TREE);
13112 return ffecom_which_entrypoint_decl_;
13115 /* The following sections consists of private and public functions
13116 that have the same names and perform roughly the same functions
13117 as counterparts in the C front end. Changes in the C front end
13118 might affect how things should be done here. Only functions
13119 needed by the back end should be public here; the rest should
13120 be private (static in the C sense). Functions needed by other
13121 g77 front-end modules should be accessed by them via public
13122 ffecom_* names, which should themselves call private versions
13123 in this section so the private versions are easy to recognize
13124 when upgrading to a new gcc and finding interesting changes
13127 Functions named after rule "foo:" in c-parse.y are named
13128 "bison_rule_foo_" so they are easy to find. */
13131 bison_rule_pushlevel_ ()
13133 emit_line_note (input_filename, lineno);
13135 clear_last_expr ();
13136 expand_start_bindings (0);
13140 bison_rule_compstmt_ ()
13143 int keep = kept_level_p ();
13145 /* Make the temps go away. */
13147 current_binding_level->names = NULL_TREE;
13149 emit_line_note (input_filename, lineno);
13150 expand_end_bindings (getdecls (), keep, 0);
13151 t = poplevel (keep, 1, 0);
13156 /* Return a definition for a builtin function named NAME and whose data type
13157 is TYPE. TYPE should be a function type with argument types.
13158 FUNCTION_CODE tells later passes how to compile calls to this function.
13159 See tree.h for its possible values.
13161 If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME,
13162 the name to be called if we can't opencode the function. */
13165 builtin_function (const char *name, tree type, int function_code,
13166 enum built_in_class class,
13167 const char *library_name)
13169 tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
13170 DECL_EXTERNAL (decl) = 1;
13171 TREE_PUBLIC (decl) = 1;
13173 SET_DECL_ASSEMBLER_NAME (decl, get_identifier (library_name));
13174 make_decl_rtl (decl, NULL);
13176 DECL_BUILT_IN_CLASS (decl) = class;
13177 DECL_FUNCTION_CODE (decl) = function_code;
13182 /* Handle when a new declaration NEWDECL
13183 has the same name as an old one OLDDECL
13184 in the same binding contour.
13185 Prints an error message if appropriate.
13187 If safely possible, alter OLDDECL to look like NEWDECL, and return 1.
13188 Otherwise, return 0. */
13191 duplicate_decls (tree newdecl, tree olddecl)
13193 int types_match = 1;
13194 int new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL
13195 && DECL_INITIAL (newdecl) != 0);
13196 tree oldtype = TREE_TYPE (olddecl);
13197 tree newtype = TREE_TYPE (newdecl);
13199 if (olddecl == newdecl)
13202 if (TREE_CODE (newtype) == ERROR_MARK
13203 || TREE_CODE (oldtype) == ERROR_MARK)
13206 /* New decl is completely inconsistent with the old one =>
13207 tell caller to replace the old one.
13208 This is always an error except in the case of shadowing a builtin. */
13209 if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
13212 /* For real parm decl following a forward decl,
13213 return 1 so old decl will be reused. */
13214 if (types_match && TREE_CODE (newdecl) == PARM_DECL
13215 && TREE_ASM_WRITTEN (olddecl) && ! TREE_ASM_WRITTEN (newdecl))
13218 /* The new declaration is the same kind of object as the old one.
13219 The declarations may partially match. Print warnings if they don't
13220 match enough. Ultimately, copy most of the information from the new
13221 decl to the old one, and keep using the old one. */
13223 if (TREE_CODE (olddecl) == FUNCTION_DECL
13224 && DECL_BUILT_IN (olddecl))
13226 /* A function declaration for a built-in function. */
13227 if (!TREE_PUBLIC (newdecl))
13229 else if (!types_match)
13231 /* Accept the return type of the new declaration if same modes. */
13232 tree oldreturntype = TREE_TYPE (TREE_TYPE (olddecl));
13233 tree newreturntype = TREE_TYPE (TREE_TYPE (newdecl));
13235 if (TYPE_MODE (oldreturntype) == TYPE_MODE (newreturntype))
13237 /* Function types may be shared, so we can't just modify
13238 the return type of olddecl's function type. */
13240 = build_function_type (newreturntype,
13241 TYPE_ARG_TYPES (TREE_TYPE (olddecl)));
13245 TREE_TYPE (olddecl) = newtype;
13251 else if (TREE_CODE (olddecl) == FUNCTION_DECL
13252 && DECL_SOURCE_LINE (olddecl) == 0)
13254 /* A function declaration for a predeclared function
13255 that isn't actually built in. */
13256 if (!TREE_PUBLIC (newdecl))
13258 else if (!types_match)
13260 /* If the types don't match, preserve volatility indication.
13261 Later on, we will discard everything else about the
13262 default declaration. */
13263 TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
13267 /* Copy all the DECL_... slots specified in the new decl
13268 except for any that we copy here from the old type.
13270 Past this point, we don't change OLDTYPE and NEWTYPE
13271 even if we change the types of NEWDECL and OLDDECL. */
13275 /* Merge the data types specified in the two decls. */
13276 if (TREE_CODE (newdecl) != FUNCTION_DECL || !DECL_BUILT_IN (olddecl))
13277 TREE_TYPE (newdecl)
13278 = TREE_TYPE (olddecl)
13279 = TREE_TYPE (newdecl);
13281 /* Lay the type out, unless already done. */
13282 if (oldtype != TREE_TYPE (newdecl))
13284 if (TREE_TYPE (newdecl) != error_mark_node)
13285 layout_type (TREE_TYPE (newdecl));
13286 if (TREE_CODE (newdecl) != FUNCTION_DECL
13287 && TREE_CODE (newdecl) != TYPE_DECL
13288 && TREE_CODE (newdecl) != CONST_DECL)
13289 layout_decl (newdecl, 0);
13293 /* Since the type is OLDDECL's, make OLDDECL's size go with. */
13294 DECL_SIZE (newdecl) = DECL_SIZE (olddecl);
13295 DECL_SIZE_UNIT (newdecl) = DECL_SIZE_UNIT (olddecl);
13296 if (TREE_CODE (olddecl) != FUNCTION_DECL)
13297 if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl))
13299 DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl);
13300 DECL_USER_ALIGN (newdecl) |= DECL_USER_ALIGN (olddecl);
13304 /* Keep the old rtl since we can safely use it. */
13305 COPY_DECL_RTL (olddecl, newdecl);
13307 /* Merge the type qualifiers. */
13308 if (DECL_BUILT_IN_NONANSI (olddecl) && TREE_THIS_VOLATILE (olddecl)
13309 && !TREE_THIS_VOLATILE (newdecl))
13310 TREE_THIS_VOLATILE (olddecl) = 0;
13311 if (TREE_READONLY (newdecl))
13312 TREE_READONLY (olddecl) = 1;
13313 if (TREE_THIS_VOLATILE (newdecl))
13315 TREE_THIS_VOLATILE (olddecl) = 1;
13316 if (TREE_CODE (newdecl) == VAR_DECL)
13317 make_var_volatile (newdecl);
13320 /* Keep source location of definition rather than declaration.
13321 Likewise, keep decl at outer scope. */
13322 if ((DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0)
13323 || (DECL_CONTEXT (newdecl) != 0 && DECL_CONTEXT (olddecl) == 0))
13325 DECL_SOURCE_LINE (newdecl) = DECL_SOURCE_LINE (olddecl);
13326 DECL_SOURCE_FILE (newdecl) = DECL_SOURCE_FILE (olddecl);
13328 if (DECL_CONTEXT (olddecl) == 0
13329 && TREE_CODE (newdecl) != FUNCTION_DECL)
13330 DECL_CONTEXT (newdecl) = 0;
13333 /* Merge the unused-warning information. */
13334 if (DECL_IN_SYSTEM_HEADER (olddecl))
13335 DECL_IN_SYSTEM_HEADER (newdecl) = 1;
13336 else if (DECL_IN_SYSTEM_HEADER (newdecl))
13337 DECL_IN_SYSTEM_HEADER (olddecl) = 1;
13339 /* Merge the initialization information. */
13340 if (DECL_INITIAL (newdecl) == 0)
13341 DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
13343 /* Merge the section attribute.
13344 We want to issue an error if the sections conflict but that must be
13345 done later in decl_attributes since we are called before attributes
13347 if (DECL_SECTION_NAME (newdecl) == NULL_TREE)
13348 DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl);
13350 if (TREE_CODE (newdecl) == FUNCTION_DECL)
13352 DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl);
13353 DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
13356 /* If cannot merge, then use the new type and qualifiers,
13357 and don't preserve the old rtl. */
13360 TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
13361 TREE_READONLY (olddecl) = TREE_READONLY (newdecl);
13362 TREE_THIS_VOLATILE (olddecl) = TREE_THIS_VOLATILE (newdecl);
13363 TREE_SIDE_EFFECTS (olddecl) = TREE_SIDE_EFFECTS (newdecl);
13366 /* Merge the storage class information. */
13367 /* For functions, static overrides non-static. */
13368 if (TREE_CODE (newdecl) == FUNCTION_DECL)
13370 TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl);
13371 /* This is since we don't automatically
13372 copy the attributes of NEWDECL into OLDDECL. */
13373 TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
13374 /* If this clears `static', clear it in the identifier too. */
13375 if (! TREE_PUBLIC (olddecl))
13376 TREE_PUBLIC (DECL_NAME (olddecl)) = 0;
13378 if (DECL_EXTERNAL (newdecl))
13380 TREE_STATIC (newdecl) = TREE_STATIC (olddecl);
13381 DECL_EXTERNAL (newdecl) = DECL_EXTERNAL (olddecl);
13382 /* An extern decl does not override previous storage class. */
13383 TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
13387 TREE_STATIC (olddecl) = TREE_STATIC (newdecl);
13388 TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
13391 /* If either decl says `inline', this fn is inline,
13392 unless its definition was passed already. */
13393 if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == 0)
13394 DECL_INLINE (olddecl) = 1;
13395 DECL_INLINE (newdecl) = DECL_INLINE (olddecl);
13397 /* Get rid of any built-in function if new arg types don't match it
13398 or if we have a function definition. */
13399 if (TREE_CODE (newdecl) == FUNCTION_DECL
13400 && DECL_BUILT_IN (olddecl)
13401 && (!types_match || new_is_definition))
13403 TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
13404 DECL_BUILT_IN_CLASS (olddecl) = NOT_BUILT_IN;
13407 /* If redeclaring a builtin function, and not a definition,
13409 Also preserve various other info from the definition. */
13410 if (TREE_CODE (newdecl) == FUNCTION_DECL && !new_is_definition)
13412 if (DECL_BUILT_IN (olddecl))
13414 DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl);
13415 DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
13418 DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
13419 DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
13420 DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl);
13421 DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
13424 /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
13425 But preserve olddecl's DECL_UID. */
13427 register unsigned olddecl_uid = DECL_UID (olddecl);
13429 memcpy ((char *) olddecl + sizeof (struct tree_common),
13430 (char *) newdecl + sizeof (struct tree_common),
13431 sizeof (struct tree_decl) - sizeof (struct tree_common));
13432 DECL_UID (olddecl) = olddecl_uid;
13438 /* Finish processing of a declaration;
13439 install its initial value.
13440 If the length of an array type is not known before,
13441 it must be determined now, from the initial value, or it is an error. */
13444 finish_decl (tree decl, tree init, bool is_top_level)
13446 register tree type = TREE_TYPE (decl);
13447 int was_incomplete = (DECL_SIZE (decl) == 0);
13448 bool at_top_level = (current_binding_level == global_binding_level);
13449 bool top_level = is_top_level || at_top_level;
13451 /* Caller should pass TRUE for is_top_level only if we wouldn't be at top
13453 assert (!is_top_level || !at_top_level);
13455 if (TREE_CODE (decl) == PARM_DECL)
13456 assert (init == NULL_TREE);
13457 /* Remember that PARM_DECL doesn't have a DECL_INITIAL field per se -- it
13458 overlaps DECL_ARG_TYPE. */
13459 else if (init == NULL_TREE)
13460 assert (DECL_INITIAL (decl) == NULL_TREE);
13462 assert (DECL_INITIAL (decl) == error_mark_node);
13464 if (init != NULL_TREE)
13466 if (TREE_CODE (decl) != TYPE_DECL)
13467 DECL_INITIAL (decl) = init;
13470 /* typedef foo = bar; store the type of bar as the type of foo. */
13471 TREE_TYPE (decl) = TREE_TYPE (init);
13472 DECL_INITIAL (decl) = init = 0;
13476 /* Deduce size of array from initialization, if not already known */
13478 if (TREE_CODE (type) == ARRAY_TYPE
13479 && TYPE_DOMAIN (type) == 0
13480 && TREE_CODE (decl) != TYPE_DECL)
13482 assert (top_level);
13483 assert (was_incomplete);
13485 layout_decl (decl, 0);
13488 if (TREE_CODE (decl) == VAR_DECL)
13490 if (DECL_SIZE (decl) == NULL_TREE
13491 && TYPE_SIZE (TREE_TYPE (decl)) != NULL_TREE)
13492 layout_decl (decl, 0);
13494 if (DECL_SIZE (decl) == NULL_TREE
13495 && (TREE_STATIC (decl)
13497 /* A static variable with an incomplete type is an error if it is
13498 initialized. Also if it is not file scope. Otherwise, let it
13499 through, but if it is not `extern' then it may cause an error
13501 (DECL_INITIAL (decl) != 0 || DECL_CONTEXT (decl) != 0)
13503 /* An automatic variable with an incomplete type is an error. */
13504 !DECL_EXTERNAL (decl)))
13506 assert ("storage size not known" == NULL);
13510 if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl))
13511 && (DECL_SIZE (decl) != 0)
13512 && (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST))
13514 assert ("storage size not constant" == NULL);
13519 /* Output the assembler code and/or RTL code for variables and functions,
13520 unless the type is an undefined structure or union. If not, it will get
13521 done when the type is completed. */
13523 if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)
13525 rest_of_decl_compilation (decl, NULL,
13526 DECL_CONTEXT (decl) == 0,
13529 if (DECL_CONTEXT (decl) != 0)
13531 /* Recompute the RTL of a local array now if it used to be an
13532 incomplete type. */
13534 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
13536 /* If we used it already as memory, it must stay in memory. */
13537 TREE_ADDRESSABLE (decl) = TREE_USED (decl);
13538 /* If it's still incomplete now, no init will save it. */
13539 if (DECL_SIZE (decl) == 0)
13540 DECL_INITIAL (decl) = 0;
13541 expand_decl (decl);
13543 /* Compute and store the initial value. */
13544 if (TREE_CODE (decl) != FUNCTION_DECL)
13545 expand_decl_init (decl);
13548 else if (TREE_CODE (decl) == TYPE_DECL)
13550 rest_of_decl_compilation (decl, NULL,
13551 DECL_CONTEXT (decl) == 0,
13555 /* At the end of a declaration, throw away any variable type sizes of types
13556 defined inside that declaration. There is no use computing them in the
13557 following function definition. */
13558 if (current_binding_level == global_binding_level)
13559 get_pending_sizes ();
13562 /* Finish up a function declaration and compile that function
13563 all the way to assembler language output. The free the storage
13564 for the function definition.
13566 This is called after parsing the body of the function definition.
13568 NESTED is nonzero if the function being finished is nested in another. */
13571 finish_function (int nested)
13573 register tree fndecl = current_function_decl;
13575 assert (fndecl != NULL_TREE);
13576 if (TREE_CODE (fndecl) != ERROR_MARK)
13579 assert (DECL_CONTEXT (fndecl) != NULL_TREE);
13581 assert (DECL_CONTEXT (fndecl) == NULL_TREE);
13584 /* TREE_READONLY (fndecl) = 1;
13585 This caused &foo to be of type ptr-to-const-function
13586 which then got a warning when stored in a ptr-to-function variable. */
13588 poplevel (1, 0, 1);
13590 if (TREE_CODE (fndecl) != ERROR_MARK)
13592 BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
13594 /* Must mark the RESULT_DECL as being in this function. */
13596 DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;
13598 /* Obey `register' declarations if `setjmp' is called in this fn. */
13599 /* Generate rtl for function exit. */
13600 expand_function_end (input_filename, lineno, 0);
13602 /* If this is a nested function, protect the local variables in the stack
13603 above us from being collected while we're compiling this function. */
13605 ggc_push_context ();
13607 /* Run the optimizers and output the assembler code for this function. */
13608 rest_of_compilation (fndecl);
13610 /* Undo the GC context switch. */
13612 ggc_pop_context ();
13615 if (TREE_CODE (fndecl) != ERROR_MARK
13617 && DECL_SAVED_INSNS (fndecl) == 0)
13619 /* Stop pointing to the local nodes about to be freed. */
13620 /* But DECL_INITIAL must remain nonzero so we know this was an actual
13621 function definition. */
13622 /* For a nested function, this is done in pop_f_function_context. */
13623 /* If rest_of_compilation set this to 0, leave it 0. */
13624 if (DECL_INITIAL (fndecl) != 0)
13625 DECL_INITIAL (fndecl) = error_mark_node;
13626 DECL_ARGUMENTS (fndecl) = 0;
13631 /* Let the error reporting routines know that we're outside a function.
13632 For a nested function, this value is used in pop_c_function_context
13633 and then reset via pop_function_context. */
13634 ffecom_outer_function_decl_ = current_function_decl = NULL;
13638 /* Plug-in replacement for identifying the name of a decl and, for a
13639 function, what we call it in diagnostics. For now, "program unit"
13640 should suffice, since it's a bit of a hassle to figure out which
13641 of several kinds of things it is. Note that it could conceivably
13642 be a statement function, which probably isn't really a program unit
13643 per se, but if that comes up, it should be easy to check (being a
13644 nested function and all). */
13646 static const char *
13647 ffe_printable_name (tree decl, int v)
13649 /* Just to keep GCC quiet about the unused variable.
13650 In theory, differing values of V should produce different
13655 if (TREE_CODE (decl) == ERROR_MARK)
13656 return "erroneous code";
13657 return IDENTIFIER_POINTER (DECL_NAME (decl));
13661 /* g77's function to print out name of current function that caused
13665 ffe_print_error_function (diagnostic_context *context __attribute__((unused)),
13668 static ffeglobal last_g = NULL;
13669 static ffesymbol last_s = NULL;
13674 if ((ffecom_primary_entry_ == NULL)
13675 || (ffesymbol_global (ffecom_primary_entry_) == NULL))
13683 g = ffesymbol_global (ffecom_primary_entry_);
13684 if (ffecom_nested_entry_ == NULL)
13686 s = ffecom_primary_entry_;
13687 kind = _(ffeinfo_kind_message (ffesymbol_kind (s)));
13691 s = ffecom_nested_entry_;
13692 kind = _("In statement function");
13696 if ((last_g != g) || (last_s != s))
13699 fprintf (stderr, "%s: ", file);
13702 fprintf (stderr, _("Outside of any program unit:\n"));
13705 const char *name = ffesymbol_text (s);
13707 fprintf (stderr, "%s `%s':\n", kind, name);
13715 /* Similar to `lookup_name' but look only at current binding level. */
13718 lookup_name_current_level (tree name)
13722 if (current_binding_level == global_binding_level)
13723 return IDENTIFIER_GLOBAL_VALUE (name);
13725 if (IDENTIFIER_LOCAL_VALUE (name) == 0)
13728 for (t = current_binding_level->names; t; t = TREE_CHAIN (t))
13729 if (DECL_NAME (t) == name)
13735 /* Create a new `struct binding_level'. */
13737 static struct binding_level *
13738 make_binding_level ()
13741 return (struct binding_level *) xmalloc (sizeof (struct binding_level));
13744 /* Save and restore the variables in this file and elsewhere
13745 that keep track of the progress of compilation of the current function.
13746 Used for nested functions. */
13750 struct f_function *next;
13752 tree shadowed_labels;
13753 struct binding_level *binding_level;
13756 struct f_function *f_function_chain;
13758 /* Restore the variables used during compilation of a C function. */
13761 pop_f_function_context ()
13763 struct f_function *p = f_function_chain;
13766 /* Bring back all the labels that were shadowed. */
13767 for (link = shadowed_labels; link; link = TREE_CHAIN (link))
13768 if (DECL_NAME (TREE_VALUE (link)) != 0)
13769 IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link)))
13770 = TREE_VALUE (link);
13772 if (current_function_decl != error_mark_node
13773 && DECL_SAVED_INSNS (current_function_decl) == 0)
13775 /* Stop pointing to the local nodes about to be freed. */
13776 /* But DECL_INITIAL must remain nonzero so we know this was an actual
13777 function definition. */
13778 DECL_INITIAL (current_function_decl) = error_mark_node;
13779 DECL_ARGUMENTS (current_function_decl) = 0;
13782 pop_function_context ();
13784 f_function_chain = p->next;
13786 named_labels = p->named_labels;
13787 shadowed_labels = p->shadowed_labels;
13788 current_binding_level = p->binding_level;
13793 /* Save and reinitialize the variables
13794 used during compilation of a C function. */
13797 push_f_function_context ()
13799 struct f_function *p
13800 = (struct f_function *) xmalloc (sizeof (struct f_function));
13802 push_function_context ();
13804 p->next = f_function_chain;
13805 f_function_chain = p;
13807 p->named_labels = named_labels;
13808 p->shadowed_labels = shadowed_labels;
13809 p->binding_level = current_binding_level;
13813 push_parm_decl (tree parm)
13815 int old_immediate_size_expand = immediate_size_expand;
13817 /* Don't try computing parm sizes now -- wait till fn is called. */
13819 immediate_size_expand = 0;
13821 /* Fill in arg stuff. */
13823 DECL_ARG_TYPE (parm) = TREE_TYPE (parm);
13824 DECL_ARG_TYPE_AS_WRITTEN (parm) = TREE_TYPE (parm);
13825 TREE_READONLY (parm) = 1; /* All implementation args are read-only. */
13827 parm = pushdecl (parm);
13829 immediate_size_expand = old_immediate_size_expand;
13831 finish_decl (parm, NULL_TREE, FALSE);
13834 /* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL, if appropriate. */
13837 pushdecl_top_level (x)
13841 register struct binding_level *b = current_binding_level;
13842 register tree f = current_function_decl;
13844 current_binding_level = global_binding_level;
13845 current_function_decl = NULL_TREE;
13847 current_binding_level = b;
13848 current_function_decl = f;
13852 /* Store the list of declarations of the current level.
13853 This is done for the parameter declarations of a function being defined,
13854 after they are modified in the light of any missing parameters. */
13860 return current_binding_level->names = decls;
13863 /* Store the parameter declarations into the current function declaration.
13864 This is called after parsing the parameter declarations, before
13865 digesting the body of the function.
13867 For an old-style definition, modify the function's type
13868 to specify at least the number of arguments. */
13871 store_parm_decls (int is_main_program UNUSED)
13873 register tree fndecl = current_function_decl;
13875 if (fndecl == error_mark_node)
13878 /* This is a chain of PARM_DECLs from old-style parm declarations. */
13879 DECL_ARGUMENTS (fndecl) = storedecls (nreverse (getdecls ()));
13881 /* Initialize the RTL code for the function. */
13883 init_function_start (fndecl, input_filename, lineno);
13885 /* Set up parameters and prepare for return, for the function. */
13887 expand_function_start (fndecl, 0);
13891 start_decl (tree decl, bool is_top_level)
13894 bool at_top_level = (current_binding_level == global_binding_level);
13895 bool top_level = is_top_level || at_top_level;
13897 /* Caller should pass TRUE for is_top_level only if we wouldn't be at top
13899 assert (!is_top_level || !at_top_level);
13901 if (DECL_INITIAL (decl) != NULL_TREE)
13903 assert (DECL_INITIAL (decl) == error_mark_node);
13904 assert (!DECL_EXTERNAL (decl));
13906 else if (top_level)
13907 assert ((TREE_STATIC (decl) == 1) || DECL_EXTERNAL (decl) == 1);
13909 /* For Fortran, we by default put things in .common when possible. */
13910 DECL_COMMON (decl) = 1;
13912 /* Add this decl to the current binding level. TEM may equal DECL or it may
13913 be a previous decl of the same name. */
13915 tem = pushdecl_top_level (decl);
13917 tem = pushdecl (decl);
13919 /* For a local variable, define the RTL now. */
13921 /* But not if this is a duplicate decl and we preserved the rtl from the
13922 previous one (which may or may not happen). */
13923 && !DECL_RTL_SET_P (tem))
13925 if (TYPE_SIZE (TREE_TYPE (tem)) != 0)
13927 else if (TREE_CODE (TREE_TYPE (tem)) == ARRAY_TYPE
13928 && DECL_INITIAL (tem) != 0)
13935 /* Create the FUNCTION_DECL for a function definition.
13936 DECLSPECS and DECLARATOR are the parts of the declaration;
13937 they describe the function's name and the type it returns,
13938 but twisted together in a fashion that parallels the syntax of C.
13940 This function creates a binding context for the function body
13941 as well as setting up the FUNCTION_DECL in current_function_decl.
13943 Returns 1 on success. If the DECLARATOR is not suitable for a function
13944 (it defines a datum instead), we return 0, which tells
13945 ffe_parse_file to report a parse error.
13947 NESTED is nonzero for a function nested within another function. */
13950 start_function (tree name, tree type, int nested, int public)
13954 int old_immediate_size_expand = immediate_size_expand;
13957 shadowed_labels = 0;
13959 /* Don't expand any sizes in the return type of the function. */
13960 immediate_size_expand = 0;
13965 assert (current_function_decl != NULL_TREE);
13966 assert (DECL_CONTEXT (current_function_decl) == NULL_TREE);
13970 assert (current_function_decl == NULL_TREE);
13973 if (TREE_CODE (type) == ERROR_MARK)
13974 decl1 = current_function_decl = error_mark_node;
13977 decl1 = build_decl (FUNCTION_DECL,
13980 TREE_PUBLIC (decl1) = public ? 1 : 0;
13982 DECL_INLINE (decl1) = 1;
13983 TREE_STATIC (decl1) = 1;
13984 DECL_EXTERNAL (decl1) = 0;
13986 announce_function (decl1);
13988 /* Make the init_value nonzero so pushdecl knows this is not tentative.
13989 error_mark_node is replaced below (in poplevel) with the BLOCK. */
13990 DECL_INITIAL (decl1) = error_mark_node;
13992 /* Record the decl so that the function name is defined. If we already have
13993 a decl for this name, and it is a FUNCTION_DECL, use the old decl. */
13995 current_function_decl = pushdecl (decl1);
13999 ffecom_outer_function_decl_ = current_function_decl;
14002 current_binding_level->prep_state = 2;
14004 if (TREE_CODE (current_function_decl) != ERROR_MARK)
14006 make_decl_rtl (current_function_decl, NULL);
14008 restype = TREE_TYPE (TREE_TYPE (current_function_decl));
14009 DECL_RESULT (current_function_decl)
14010 = build_decl (RESULT_DECL, NULL_TREE, restype);
14013 if (!nested && (TREE_CODE (current_function_decl) != ERROR_MARK))
14014 TREE_ADDRESSABLE (current_function_decl) = 1;
14016 immediate_size_expand = old_immediate_size_expand;
14019 /* Here are the public functions the GNU back end needs. */
14022 convert (type, expr)
14025 register tree e = expr;
14026 register enum tree_code code = TREE_CODE (type);
14028 if (type == TREE_TYPE (e)
14029 || TREE_CODE (e) == ERROR_MARK)
14031 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
14032 return fold (build1 (NOP_EXPR, type, e));
14033 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
14034 || code == ERROR_MARK)
14035 return error_mark_node;
14036 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
14038 assert ("void value not ignored as it ought to be" == NULL);
14039 return error_mark_node;
14041 if (code == VOID_TYPE)
14042 return build1 (CONVERT_EXPR, type, e);
14043 if ((code != RECORD_TYPE)
14044 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
14045 e = ffecom_1 (REALPART_EXPR, TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e))),
14047 if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)
14048 return fold (convert_to_integer (type, e));
14049 if (code == POINTER_TYPE)
14050 return fold (convert_to_pointer (type, e));
14051 if (code == REAL_TYPE)
14052 return fold (convert_to_real (type, e));
14053 if (code == COMPLEX_TYPE)
14054 return fold (convert_to_complex (type, e));
14055 if (code == RECORD_TYPE)
14056 return fold (ffecom_convert_to_complex_ (type, e));
14058 assert ("conversion to non-scalar type requested" == NULL);
14059 return error_mark_node;
14062 /* Return the list of declarations of the current level.
14063 Note that this list is in reverse order unless/until
14064 you nreverse it; and when you do nreverse it, you must
14065 store the result back using `storedecls' or you will lose. */
14070 return current_binding_level->names;
14073 /* Nonzero if we are currently in the global binding level. */
14076 global_bindings_p ()
14078 return current_binding_level == global_binding_level;
14081 /* Mark ARG for GC. */
14083 mark_binding_level (void *arg)
14085 struct binding_level *level = *(struct binding_level **) arg;
14089 ggc_mark_tree (level->names);
14090 ggc_mark_tree (level->blocks);
14091 ggc_mark_tree (level->this_block);
14092 level = level->level_chain;
14097 ffecom_init_decl_processing ()
14099 static tree *const tree_roots[] = {
14100 ¤t_function_decl,
14102 &ffecom_tree_fun_type_void,
14103 &ffecom_integer_zero_node,
14104 &ffecom_integer_one_node,
14105 &ffecom_tree_subr_type,
14106 &ffecom_tree_ptr_to_subr_type,
14107 &ffecom_tree_blockdata_type,
14108 &ffecom_tree_xargc_,
14109 &ffecom_f2c_integer_type_node,
14110 &ffecom_f2c_ptr_to_integer_type_node,
14111 &ffecom_f2c_address_type_node,
14112 &ffecom_f2c_real_type_node,
14113 &ffecom_f2c_ptr_to_real_type_node,
14114 &ffecom_f2c_doublereal_type_node,
14115 &ffecom_f2c_complex_type_node,
14116 &ffecom_f2c_doublecomplex_type_node,
14117 &ffecom_f2c_longint_type_node,
14118 &ffecom_f2c_logical_type_node,
14119 &ffecom_f2c_flag_type_node,
14120 &ffecom_f2c_ftnlen_type_node,
14121 &ffecom_f2c_ftnlen_zero_node,
14122 &ffecom_f2c_ftnlen_one_node,
14123 &ffecom_f2c_ftnlen_two_node,
14124 &ffecom_f2c_ptr_to_ftnlen_type_node,
14125 &ffecom_f2c_ftnint_type_node,
14126 &ffecom_f2c_ptr_to_ftnint_type_node,
14127 &ffecom_outer_function_decl_,
14128 &ffecom_previous_function_decl_,
14129 &ffecom_which_entrypoint_decl_,
14130 &ffecom_float_zero_,
14131 &ffecom_float_half_,
14132 &ffecom_double_zero_,
14133 &ffecom_double_half_,
14134 &ffecom_func_result_,
14135 &ffecom_func_length_,
14136 &ffecom_multi_type_node_,
14137 &ffecom_multi_retval_,
14145 /* Record our roots. */
14146 for (i = 0; i < ARRAY_SIZE (tree_roots); i++)
14147 ggc_add_tree_root (tree_roots[i], 1);
14148 ggc_add_tree_root (&ffecom_tree_type[0][0],
14149 FFEINFO_basictype*FFEINFO_kindtype);
14150 ggc_add_tree_root (&ffecom_tree_fun_type[0][0],
14151 FFEINFO_basictype*FFEINFO_kindtype);
14152 ggc_add_tree_root (&ffecom_tree_ptr_to_fun_type[0][0],
14153 FFEINFO_basictype*FFEINFO_kindtype);
14154 ggc_add_tree_root (ffecom_gfrt_, FFECOM_gfrt);
14155 ggc_add_root (¤t_binding_level, 1, sizeof current_binding_level,
14156 mark_binding_level);
14157 ggc_add_root (&free_binding_level, 1, sizeof current_binding_level,
14158 mark_binding_level);
14159 ggc_add_root (&tracker_head, 1, sizeof tracker_head, mark_tracker_head);
14164 /* Delete the node BLOCK from the current binding level.
14165 This is used for the block inside a stmt expr ({...})
14166 so that the block can be reinserted where appropriate. */
14169 delete_block (block)
14173 if (current_binding_level->blocks == block)
14174 current_binding_level->blocks = TREE_CHAIN (block);
14175 for (t = current_binding_level->blocks; t;)
14177 if (TREE_CHAIN (t) == block)
14178 TREE_CHAIN (t) = TREE_CHAIN (block);
14180 t = TREE_CHAIN (t);
14182 TREE_CHAIN (block) = NULL;
14183 /* Clear TREE_USED which is always set by poplevel.
14184 The flag is set again if insert_block is called. */
14185 TREE_USED (block) = 0;
14189 insert_block (block)
14192 TREE_USED (block) = 1;
14193 current_binding_level->blocks
14194 = chainon (current_binding_level->blocks, block);
14197 /* Each front end provides its own. */
14198 static const char *ffe_init PARAMS ((const char *));
14199 static void ffe_finish PARAMS ((void));
14200 static void ffe_init_options PARAMS ((void));
14201 static void ffe_print_identifier PARAMS ((FILE *, tree, int));
14202 static void ffe_mark_tree (tree);
14204 #undef LANG_HOOKS_NAME
14205 #define LANG_HOOKS_NAME "GNU F77"
14206 #undef LANG_HOOKS_INIT
14207 #define LANG_HOOKS_INIT ffe_init
14208 #undef LANG_HOOKS_FINISH
14209 #define LANG_HOOKS_FINISH ffe_finish
14210 #undef LANG_HOOKS_INIT_OPTIONS
14211 #define LANG_HOOKS_INIT_OPTIONS ffe_init_options
14212 #undef LANG_HOOKS_DECODE_OPTION
14213 #define LANG_HOOKS_DECODE_OPTION ffe_decode_option
14214 #undef LANG_HOOKS_PARSE_FILE
14215 #define LANG_HOOKS_PARSE_FILE ffe_parse_file
14216 #undef LANG_HOOKS_MARK_TREE
14217 #define LANG_HOOKS_MARK_TREE ffe_mark_tree
14218 #undef LANG_HOOKS_MARK_ADDRESSABLE
14219 #define LANG_HOOKS_MARK_ADDRESSABLE ffe_mark_addressable
14220 #undef LANG_HOOKS_PRINT_IDENTIFIER
14221 #define LANG_HOOKS_PRINT_IDENTIFIER ffe_print_identifier
14222 #undef LANG_HOOKS_DECL_PRINTABLE_NAME
14223 #define LANG_HOOKS_DECL_PRINTABLE_NAME ffe_printable_name
14224 #undef LANG_HOOKS_PRINT_ERROR_FUNCTION
14225 #define LANG_HOOKS_PRINT_ERROR_FUNCTION ffe_print_error_function
14226 #undef LANG_HOOKS_TRUTHVALUE_CONVERSION
14227 #define LANG_HOOKS_TRUTHVALUE_CONVERSION ffe_truthvalue_conversion
14229 #undef LANG_HOOKS_TYPE_FOR_MODE
14230 #define LANG_HOOKS_TYPE_FOR_MODE ffe_type_for_mode
14231 #undef LANG_HOOKS_TYPE_FOR_SIZE
14232 #define LANG_HOOKS_TYPE_FOR_SIZE ffe_type_for_size
14233 #undef LANG_HOOKS_SIGNED_TYPE
14234 #define LANG_HOOKS_SIGNED_TYPE ffe_signed_type
14235 #undef LANG_HOOKS_UNSIGNED_TYPE
14236 #define LANG_HOOKS_UNSIGNED_TYPE ffe_unsigned_type
14237 #undef LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE
14238 #define LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE ffe_signed_or_unsigned_type
14240 /* We do not wish to use alias-set based aliasing at all. Used in the
14241 extreme (every object with its own set, with equivalences recorded) it
14242 might be helpful, but there are problems when it comes to inlining. We
14243 get on ok with flag_argument_noalias, and alias-set aliasing does
14244 currently limit how stack slots can be reused, which is a lose. */
14245 #undef LANG_HOOKS_GET_ALIAS_SET
14246 #define LANG_HOOKS_GET_ALIAS_SET hook_get_alias_set_0
14248 const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
14250 /* Table indexed by tree code giving a string containing a character
14251 classifying the tree code. Possibilities are
14252 t, d, s, c, r, <, 1, 2 and e. See tree.def for details. */
14254 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
14256 const char tree_code_type[] = {
14257 #include "tree.def"
14261 /* Table indexed by tree code giving number of expression
14262 operands beyond the fixed part of the node structure.
14263 Not used for types or decls. */
14265 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
14267 const unsigned char tree_code_length[] = {
14268 #include "tree.def"
14272 /* Names of tree components.
14273 Used for printing out the tree and error messages. */
14274 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
14276 const char *const tree_code_name[] = {
14277 #include "tree.def"
14281 static const char *
14282 ffe_init (filename)
14283 const char *filename;
14285 /* Open input file. */
14286 if (filename == 0 || !strcmp (filename, "-"))
14289 filename = "stdin";
14292 finput = fopen (filename, "r");
14294 fatal_io_error ("can't open %s", filename);
14296 #ifdef IO_BUFFER_SIZE
14297 setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
14300 ffecom_init_decl_processing ();
14302 /* If the file is output from cpp, it should contain a first line
14303 `# 1 "real-filename"', and the current design of gcc (toplev.c
14304 in particular and the way it sets up information relied on by
14305 INCLUDE) requires that we read this now, and store the
14306 "real-filename" info in master_input_filename. Ask the lexer
14307 to try doing this. */
14308 ffelex_hash_kludge (finput);
14310 /* FIXME: The ffelex_hash_kludge code needs to be cleaned up to
14311 return the new file name. */
14312 if (main_input_filename)
14313 filename = main_input_filename;
14321 ffe_terminate_0 ();
14323 if (ffe_is_ffedebug ())
14324 malloc_pool_display (malloc_pool_image ());
14330 ffe_init_options ()
14332 /* Set default options for Fortran. */
14333 flag_move_all_movables = 1;
14334 flag_reduce_all_givs = 1;
14335 flag_argument_noalias = 2;
14336 flag_merge_constants = 2;
14337 flag_errno_math = 0;
14338 flag_complex_divide_method = 1;
14342 ffe_mark_addressable (exp)
14345 register tree x = exp;
14347 switch (TREE_CODE (x))
14350 case COMPONENT_REF:
14352 x = TREE_OPERAND (x, 0);
14356 TREE_ADDRESSABLE (x) = 1;
14363 if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
14364 && DECL_NONLOCAL (x))
14366 if (TREE_PUBLIC (x))
14368 assert ("address of global register var requested" == NULL);
14371 assert ("address of register variable requested" == NULL);
14373 else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x))
14375 if (TREE_PUBLIC (x))
14377 assert ("address of global register var requested" == NULL);
14380 assert ("address of register var requested" == NULL);
14382 put_var_into_stack (x);
14385 case FUNCTION_DECL:
14386 TREE_ADDRESSABLE (x) = 1;
14387 #if 0 /* poplevel deals with this now. */
14388 if (DECL_CONTEXT (x) == 0)
14389 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (x)) = 1;
14397 /* Exit a binding level.
14398 Pop the level off, and restore the state of the identifier-decl mappings
14399 that were in effect when this level was entered.
14401 If KEEP is nonzero, this level had explicit declarations, so
14402 and create a "block" (a BLOCK node) for the level
14403 to record its declarations and subblocks for symbol table output.
14405 If FUNCTIONBODY is nonzero, this level is the body of a function,
14406 so create a block as if KEEP were set and also clear out all
14409 If REVERSE is nonzero, reverse the order of decls before putting
14410 them into the BLOCK. */
14413 poplevel (keep, reverse, functionbody)
14418 register tree link;
14419 /* The chain of decls was accumulated in reverse order.
14420 Put it into forward order, just for cleanliness. */
14422 tree subblocks = current_binding_level->blocks;
14425 int block_previously_created;
14427 /* Get the decls in the order they were written.
14428 Usually current_binding_level->names is in reverse order.
14429 But parameter decls were previously put in forward order. */
14432 current_binding_level->names
14433 = decls = nreverse (current_binding_level->names);
14435 decls = current_binding_level->names;
14437 /* Output any nested inline functions within this block
14438 if they weren't already output. */
14440 for (decl = decls; decl; decl = TREE_CHAIN (decl))
14441 if (TREE_CODE (decl) == FUNCTION_DECL
14442 && ! TREE_ASM_WRITTEN (decl)
14443 && DECL_INITIAL (decl) != 0
14444 && TREE_ADDRESSABLE (decl))
14446 /* If this decl was copied from a file-scope decl
14447 on account of a block-scope extern decl,
14448 propagate TREE_ADDRESSABLE to the file-scope decl.
14450 DECL_ABSTRACT_ORIGIN can be set to itself if warn_return_type is
14451 true, since then the decl goes through save_for_inline_copying. */
14452 if (DECL_ABSTRACT_ORIGIN (decl) != 0
14453 && DECL_ABSTRACT_ORIGIN (decl) != decl)
14454 TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1;
14455 else if (DECL_SAVED_INSNS (decl) != 0)
14457 push_function_context ();
14458 output_inline_function (decl);
14459 pop_function_context ();
14463 /* If there were any declarations or structure tags in that level,
14464 or if this level is a function body,
14465 create a BLOCK to record them for the life of this function. */
14468 block_previously_created = (current_binding_level->this_block != 0);
14469 if (block_previously_created)
14470 block = current_binding_level->this_block;
14471 else if (keep || functionbody)
14472 block = make_node (BLOCK);
14475 BLOCK_VARS (block) = decls;
14476 BLOCK_SUBBLOCKS (block) = subblocks;
14479 /* In each subblock, record that this is its superior. */
14481 for (link = subblocks; link; link = TREE_CHAIN (link))
14482 BLOCK_SUPERCONTEXT (link) = block;
14484 /* Clear out the meanings of the local variables of this level. */
14486 for (link = decls; link; link = TREE_CHAIN (link))
14488 if (DECL_NAME (link) != 0)
14490 /* If the ident. was used or addressed via a local extern decl,
14491 don't forget that fact. */
14492 if (DECL_EXTERNAL (link))
14494 if (TREE_USED (link))
14495 TREE_USED (DECL_NAME (link)) = 1;
14496 if (TREE_ADDRESSABLE (link))
14497 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (link)) = 1;
14499 IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = 0;
14503 /* If the level being exited is the top level of a function,
14504 check over all the labels, and clear out the current
14505 (function local) meanings of their names. */
14509 /* If this is the top level block of a function,
14510 the vars are the function's parameters.
14511 Don't leave them in the BLOCK because they are
14512 found in the FUNCTION_DECL instead. */
14514 BLOCK_VARS (block) = 0;
14517 /* Pop the current level, and free the structure for reuse. */
14520 register struct binding_level *level = current_binding_level;
14521 current_binding_level = current_binding_level->level_chain;
14523 level->level_chain = free_binding_level;
14524 free_binding_level = level;
14527 /* Dispose of the block that we just made inside some higher level. */
14529 && current_function_decl != error_mark_node)
14530 DECL_INITIAL (current_function_decl) = block;
14533 if (!block_previously_created)
14534 current_binding_level->blocks
14535 = chainon (current_binding_level->blocks, block);
14537 /* If we did not make a block for the level just exited,
14538 any blocks made for inner levels
14539 (since they cannot be recorded as subblocks in that level)
14540 must be carried forward so they will later become subblocks
14541 of something else. */
14542 else if (subblocks)
14543 current_binding_level->blocks
14544 = chainon (current_binding_level->blocks, subblocks);
14547 TREE_USED (block) = 1;
14552 ffe_print_identifier (file, node, indent)
14557 print_node (file, "global", IDENTIFIER_GLOBAL_VALUE (node), indent + 4);
14558 print_node (file, "local", IDENTIFIER_LOCAL_VALUE (node), indent + 4);
14561 /* Record a decl-node X as belonging to the current lexical scope.
14562 Check for errors (such as an incompatible declaration for the same
14563 name already seen in the same scope).
14565 Returns either X or an old decl for the same name.
14566 If an old decl is returned, it may have been smashed
14567 to agree with what X says. */
14574 register tree name = DECL_NAME (x);
14575 register struct binding_level *b = current_binding_level;
14577 if ((TREE_CODE (x) == FUNCTION_DECL)
14578 && (DECL_INITIAL (x) == 0)
14579 && DECL_EXTERNAL (x))
14580 DECL_CONTEXT (x) = NULL_TREE;
14582 DECL_CONTEXT (x) = current_function_decl;
14586 if (IDENTIFIER_INVENTED (name))
14588 DECL_ARTIFICIAL (x) = 1;
14589 DECL_IN_SYSTEM_HEADER (x) = 1;
14592 t = lookup_name_current_level (name);
14594 assert ((t == NULL_TREE) || (DECL_CONTEXT (x) == NULL_TREE));
14596 /* Don't push non-parms onto list for parms until we understand
14597 why we're doing this and whether it works. */
14599 assert ((b == global_binding_level)
14600 || !ffecom_transform_only_dummies_
14601 || TREE_CODE (x) == PARM_DECL);
14603 if ((t != NULL_TREE) && duplicate_decls (x, t))
14606 /* If we are processing a typedef statement, generate a whole new
14607 ..._TYPE node (which will be just an variant of the existing
14608 ..._TYPE node with identical properties) and then install the
14609 TYPE_DECL node generated to represent the typedef name as the
14610 TYPE_NAME of this brand new (duplicate) ..._TYPE node.
14612 The whole point here is to end up with a situation where each and every
14613 ..._TYPE node the compiler creates will be uniquely associated with
14614 AT MOST one node representing a typedef name. This way, even though
14615 the compiler substitutes corresponding ..._TYPE nodes for TYPE_DECL
14616 (i.e. "typedef name") nodes very early on, later parts of the
14617 compiler can always do the reverse translation and get back the
14618 corresponding typedef name. For example, given:
14620 typedef struct S MY_TYPE; MY_TYPE object;
14622 Later parts of the compiler might only know that `object' was of type
14623 `struct S' if it were not for code just below. With this code
14624 however, later parts of the compiler see something like:
14626 struct S' == struct S typedef struct S' MY_TYPE; struct S' object;
14628 And they can then deduce (from the node for type struct S') that the
14629 original object declaration was:
14633 Being able to do this is important for proper support of protoize, and
14634 also for generating precise symbolic debugging information which
14635 takes full account of the programmer's (typedef) vocabulary.
14637 Obviously, we don't want to generate a duplicate ..._TYPE node if the
14638 TYPE_DECL node that we are now processing really represents a
14639 standard built-in type.
14641 Since all standard types are effectively declared at line zero in the
14642 source file, we can easily check to see if we are working on a
14643 standard type by checking the current value of lineno. */
14645 if (TREE_CODE (x) == TYPE_DECL)
14647 if (DECL_SOURCE_LINE (x) == 0)
14649 if (TYPE_NAME (TREE_TYPE (x)) == 0)
14650 TYPE_NAME (TREE_TYPE (x)) = x;
14652 else if (TREE_TYPE (x) != error_mark_node)
14654 tree tt = TREE_TYPE (x);
14656 tt = build_type_copy (tt);
14657 TYPE_NAME (tt) = x;
14658 TREE_TYPE (x) = tt;
14662 /* This name is new in its binding level. Install the new declaration
14664 if (b == global_binding_level)
14665 IDENTIFIER_GLOBAL_VALUE (name) = x;
14667 IDENTIFIER_LOCAL_VALUE (name) = x;
14670 /* Put decls on list in reverse order. We will reverse them later if
14672 TREE_CHAIN (x) = b->names;
14678 /* Nonzero if the current level needs to have a BLOCK made. */
14685 for (decl = current_binding_level->names;
14687 decl = TREE_CHAIN (decl))
14689 if (TREE_USED (decl) || TREE_CODE (decl) != VAR_DECL
14690 || (DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl)))
14691 /* Currently, there aren't supposed to be non-artificial names
14692 at other than the top block for a function -- they're
14693 believed to always be temps. But it's wise to check anyway. */
14699 /* Enter a new binding level.
14700 If TAG_TRANSPARENT is nonzero, do so only for the name space of variables,
14701 not for that of tags. */
14704 pushlevel (tag_transparent)
14705 int tag_transparent;
14707 register struct binding_level *newlevel = NULL_BINDING_LEVEL;
14709 assert (! tag_transparent);
14711 if (current_binding_level == global_binding_level)
14716 /* Reuse or create a struct for this binding level. */
14718 if (free_binding_level)
14720 newlevel = free_binding_level;
14721 free_binding_level = free_binding_level->level_chain;
14725 newlevel = make_binding_level ();
14728 /* Add this level to the front of the chain (stack) of levels that
14731 *newlevel = clear_binding_level;
14732 newlevel->level_chain = current_binding_level;
14733 current_binding_level = newlevel;
14736 /* Set the BLOCK node for the innermost scope
14737 (the one we are currently in). */
14741 register tree block;
14743 current_binding_level->this_block = block;
14744 current_binding_level->names = chainon (current_binding_level->names,
14745 BLOCK_VARS (block));
14746 current_binding_level->blocks = chainon (current_binding_level->blocks,
14747 BLOCK_SUBBLOCKS (block));
14751 ffe_signed_or_unsigned_type (unsignedp, type)
14757 if (! INTEGRAL_TYPE_P (type))
14759 if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node))
14760 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
14761 if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
14762 return unsignedp ? unsigned_type_node : integer_type_node;
14763 if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node))
14764 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
14765 if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node))
14766 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
14767 if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node))
14768 return (unsignedp ? long_long_unsigned_type_node
14769 : long_long_integer_type_node);
14771 type2 = ffe_type_for_size (TYPE_PRECISION (type), unsignedp);
14772 if (type2 == NULL_TREE)
14779 ffe_signed_type (type)
14782 tree type1 = TYPE_MAIN_VARIANT (type);
14783 ffeinfoKindtype kt;
14786 if (type1 == unsigned_char_type_node || type1 == char_type_node)
14787 return signed_char_type_node;
14788 if (type1 == unsigned_type_node)
14789 return integer_type_node;
14790 if (type1 == short_unsigned_type_node)
14791 return short_integer_type_node;
14792 if (type1 == long_unsigned_type_node)
14793 return long_integer_type_node;
14794 if (type1 == long_long_unsigned_type_node)
14795 return long_long_integer_type_node;
14796 #if 0 /* gcc/c-* files only */
14797 if (type1 == unsigned_intDI_type_node)
14798 return intDI_type_node;
14799 if (type1 == unsigned_intSI_type_node)
14800 return intSI_type_node;
14801 if (type1 == unsigned_intHI_type_node)
14802 return intHI_type_node;
14803 if (type1 == unsigned_intQI_type_node)
14804 return intQI_type_node;
14807 type2 = ffe_type_for_size (TYPE_PRECISION (type1), 0);
14808 if (type2 != NULL_TREE)
14811 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
14813 type2 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
14815 if (type1 == type2)
14816 return ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
14822 /* Prepare expr to be an argument of a TRUTH_NOT_EXPR,
14823 or validate its data type for an `if' or `while' statement or ?..: exp.
14825 This preparation consists of taking the ordinary
14826 representation of an expression expr and producing a valid tree
14827 boolean expression describing whether expr is nonzero. We could
14828 simply always do build_binary_op (NE_EXPR, expr, integer_zero_node, 1),
14829 but we optimize comparisons, &&, ||, and !.
14831 The resulting type should always be `integer_type_node'. */
14834 ffe_truthvalue_conversion (expr)
14837 if (TREE_CODE (expr) == ERROR_MARK)
14840 #if 0 /* This appears to be wrong for C++. */
14841 /* These really should return error_mark_node after 2.4 is stable.
14842 But not all callers handle ERROR_MARK properly. */
14843 switch (TREE_CODE (TREE_TYPE (expr)))
14846 error ("struct type value used where scalar is required");
14847 return integer_zero_node;
14850 error ("union type value used where scalar is required");
14851 return integer_zero_node;
14854 error ("array type value used where scalar is required");
14855 return integer_zero_node;
14862 switch (TREE_CODE (expr))
14864 /* It is simpler and generates better code to have only TRUTH_*_EXPR
14865 or comparison expressions as truth values at this level. */
14867 case COMPONENT_REF:
14868 /* A one-bit unsigned bit-field is already acceptable. */
14869 if (1 == TREE_INT_CST_LOW (DECL_SIZE (TREE_OPERAND (expr, 1)))
14870 && TREE_UNSIGNED (TREE_OPERAND (expr, 1)))
14876 /* It is simpler and generates better code to have only TRUTH_*_EXPR
14877 or comparison expressions as truth values at this level. */
14879 if (integer_zerop (TREE_OPERAND (expr, 1)))
14880 return build_unary_op (TRUTH_NOT_EXPR, TREE_OPERAND (expr, 0), 0);
14882 case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
14883 case TRUTH_ANDIF_EXPR:
14884 case TRUTH_ORIF_EXPR:
14885 case TRUTH_AND_EXPR:
14886 case TRUTH_OR_EXPR:
14887 case TRUTH_XOR_EXPR:
14888 TREE_TYPE (expr) = integer_type_node;
14895 return integer_zerop (expr) ? integer_zero_node : integer_one_node;
14898 return real_zerop (expr) ? integer_zero_node : integer_one_node;
14901 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 0)))
14902 return build (COMPOUND_EXPR, integer_type_node,
14903 TREE_OPERAND (expr, 0), integer_one_node);
14905 return integer_one_node;
14908 return ffecom_2 ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))
14909 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
14911 ffe_truthvalue_conversion (TREE_OPERAND (expr, 0)),
14912 ffe_truthvalue_conversion (TREE_OPERAND (expr, 1)));
14918 /* These don't change whether an object is non-zero or zero. */
14919 return ffe_truthvalue_conversion (TREE_OPERAND (expr, 0));
14923 /* These don't change whether an object is zero or non-zero, but
14924 we can't ignore them if their second arg has side-effects. */
14925 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)))
14926 return build (COMPOUND_EXPR, integer_type_node, TREE_OPERAND (expr, 1),
14927 ffe_truthvalue_conversion (TREE_OPERAND (expr, 0)));
14929 return ffe_truthvalue_conversion (TREE_OPERAND (expr, 0));
14932 /* Distribute the conversion into the arms of a COND_EXPR. */
14933 return fold (build (COND_EXPR, integer_type_node, TREE_OPERAND (expr, 0),
14934 ffe_truthvalue_conversion (TREE_OPERAND (expr, 1)),
14935 ffe_truthvalue_conversion (TREE_OPERAND (expr, 2))));
14938 /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
14939 since that affects how `default_conversion' will behave. */
14940 if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE
14941 || TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)
14943 /* fall through... */
14945 /* If this is widening the argument, we can ignore it. */
14946 if (TYPE_PRECISION (TREE_TYPE (expr))
14947 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
14948 return ffe_truthvalue_conversion (TREE_OPERAND (expr, 0));
14952 /* With IEEE arithmetic, x - x may not equal 0, so we can't optimize
14954 if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
14955 && TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE)
14957 /* fall through... */
14959 /* This and MINUS_EXPR can be changed into a comparison of the
14961 if (TREE_TYPE (TREE_OPERAND (expr, 0))
14962 == TREE_TYPE (TREE_OPERAND (expr, 1)))
14963 return ffecom_2 (NE_EXPR, integer_type_node,
14964 TREE_OPERAND (expr, 0),
14965 TREE_OPERAND (expr, 1));
14966 return ffecom_2 (NE_EXPR, integer_type_node,
14967 TREE_OPERAND (expr, 0),
14968 fold (build1 (NOP_EXPR,
14969 TREE_TYPE (TREE_OPERAND (expr, 0)),
14970 TREE_OPERAND (expr, 1))));
14973 if (integer_onep (TREE_OPERAND (expr, 1)))
14978 #if 0 /* No such thing in Fortran. */
14979 if (warn_parentheses && C_EXP_ORIGINAL_CODE (expr) == MODIFY_EXPR)
14980 warning ("suggest parentheses around assignment used as truth value");
14988 if (TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE)
14990 ((TREE_SIDE_EFFECTS (expr)
14991 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
14993 ffe_truthvalue_conversion (ffecom_1 (REALPART_EXPR,
14994 TREE_TYPE (TREE_TYPE (expr)),
14996 ffe_truthvalue_conversion (ffecom_1 (IMAGPART_EXPR,
14997 TREE_TYPE (TREE_TYPE (expr)),
15000 return ffecom_2 (NE_EXPR, integer_type_node,
15002 convert (TREE_TYPE (expr), integer_zero_node));
15006 ffe_type_for_mode (mode, unsignedp)
15007 enum machine_mode mode;
15014 if (mode == TYPE_MODE (integer_type_node))
15015 return unsignedp ? unsigned_type_node : integer_type_node;
15017 if (mode == TYPE_MODE (signed_char_type_node))
15018 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
15020 if (mode == TYPE_MODE (short_integer_type_node))
15021 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
15023 if (mode == TYPE_MODE (long_integer_type_node))
15024 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
15026 if (mode == TYPE_MODE (long_long_integer_type_node))
15027 return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node;
15029 #if HOST_BITS_PER_WIDE_INT >= 64
15030 if (mode == TYPE_MODE (intTI_type_node))
15031 return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
15034 if (mode == TYPE_MODE (float_type_node))
15035 return float_type_node;
15037 if (mode == TYPE_MODE (double_type_node))
15038 return double_type_node;
15040 if (mode == TYPE_MODE (build_pointer_type (char_type_node)))
15041 return build_pointer_type (char_type_node);
15043 if (mode == TYPE_MODE (build_pointer_type (integer_type_node)))
15044 return build_pointer_type (integer_type_node);
15046 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
15047 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
15049 if (((t = ffecom_tree_type[i][j]) != NULL_TREE)
15050 && (mode == TYPE_MODE (t)))
15052 if ((i == FFEINFO_basictypeINTEGER) && unsignedp)
15053 return ffecom_tree_type[FFEINFO_basictypeHOLLERITH][j];
15063 ffe_type_for_size (bits, unsignedp)
15067 ffeinfoKindtype kt;
15070 if (bits == TYPE_PRECISION (integer_type_node))
15071 return unsignedp ? unsigned_type_node : integer_type_node;
15073 if (bits == TYPE_PRECISION (signed_char_type_node))
15074 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
15076 if (bits == TYPE_PRECISION (short_integer_type_node))
15077 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
15079 if (bits == TYPE_PRECISION (long_integer_type_node))
15080 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
15082 if (bits == TYPE_PRECISION (long_long_integer_type_node))
15083 return (unsignedp ? long_long_unsigned_type_node
15084 : long_long_integer_type_node);
15086 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
15088 type_node = ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
15090 if ((type_node != NULL_TREE) && (bits == TYPE_PRECISION (type_node)))
15091 return unsignedp ? ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt]
15099 ffe_unsigned_type (type)
15102 tree type1 = TYPE_MAIN_VARIANT (type);
15103 ffeinfoKindtype kt;
15106 if (type1 == signed_char_type_node || type1 == char_type_node)
15107 return unsigned_char_type_node;
15108 if (type1 == integer_type_node)
15109 return unsigned_type_node;
15110 if (type1 == short_integer_type_node)
15111 return short_unsigned_type_node;
15112 if (type1 == long_integer_type_node)
15113 return long_unsigned_type_node;
15114 if (type1 == long_long_integer_type_node)
15115 return long_long_unsigned_type_node;
15116 #if 0 /* gcc/c-* files only */
15117 if (type1 == intDI_type_node)
15118 return unsigned_intDI_type_node;
15119 if (type1 == intSI_type_node)
15120 return unsigned_intSI_type_node;
15121 if (type1 == intHI_type_node)
15122 return unsigned_intHI_type_node;
15123 if (type1 == intQI_type_node)
15124 return unsigned_intQI_type_node;
15127 type2 = ffe_type_for_size (TYPE_PRECISION (type1), 1);
15128 if (type2 != NULL_TREE)
15131 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
15133 type2 = ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
15135 if (type1 == type2)
15136 return ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
15146 if (TREE_CODE (t) == IDENTIFIER_NODE)
15148 struct lang_identifier *i = (struct lang_identifier *) t;
15149 ggc_mark_tree (IDENTIFIER_GLOBAL_VALUE (i));
15150 ggc_mark_tree (IDENTIFIER_LOCAL_VALUE (i));
15151 ggc_mark_tree (IDENTIFIER_LABEL_VALUE (i));
15153 else if (TYPE_P (t) && TYPE_LANG_SPECIFIC (t))
15154 ggc_mark (TYPE_LANG_SPECIFIC (t));
15157 /* From gcc/cccp.c, the code to handle -I. */
15159 /* Skip leading "./" from a directory name.
15160 This may yield the empty string, which represents the current directory. */
15162 static const char *
15163 skip_redundant_dir_prefix (const char *dir)
15165 while (dir[0] == '.' && dir[1] == '/')
15166 for (dir += 2; *dir == '/'; dir++)
15168 if (dir[0] == '.' && !dir[1])
15173 /* The file_name_map structure holds a mapping of file names for a
15174 particular directory. This mapping is read from the file named
15175 FILE_NAME_MAP_FILE in that directory. Such a file can be used to
15176 map filenames on a file system with severe filename restrictions,
15177 such as DOS. The format of the file name map file is just a series
15178 of lines with two tokens on each line. The first token is the name
15179 to map, and the second token is the actual name to use. */
15181 struct file_name_map
15183 struct file_name_map *map_next;
15188 #define FILE_NAME_MAP_FILE "header.gcc"
15190 /* Current maximum length of directory names in the search path
15191 for include files. (Altered as we get more of them.) */
15193 static int max_include_len = 0;
15195 struct file_name_list
15197 struct file_name_list *next;
15199 /* Mapping of file names for this directory. */
15200 struct file_name_map *name_map;
15201 /* Non-zero if name_map is valid. */
15205 static struct file_name_list *include = NULL; /* First dir to search */
15206 static struct file_name_list *last_include = NULL; /* Last in chain */
15208 /* I/O buffer structure.
15209 The `fname' field is nonzero for source files and #include files
15210 and for the dummy text used for -D and -U.
15211 It is zero for rescanning results of macro expansion
15212 and for expanding macro arguments. */
15213 #define INPUT_STACK_MAX 400
15214 static struct file_buf {
15216 /* Filename specified with #line command. */
15217 const char *nominal_fname;
15218 /* Record where in the search path this file was found.
15219 For #include_next. */
15220 struct file_name_list *dir;
15222 ffewhereColumn column;
15223 } instack[INPUT_STACK_MAX];
15225 static int last_error_tick = 0; /* Incremented each time we print it. */
15226 static int input_file_stack_tick = 0; /* Incremented when status changes. */
15228 /* Current nesting level of input sources.
15229 `instack[indepth]' is the level currently being read. */
15230 static int indepth = -1;
15232 typedef struct file_buf FILE_BUF;
15234 /* Nonzero means -I- has been seen,
15235 so don't look for #include "foo" the source-file directory. */
15236 static int ignore_srcdir;
15238 #ifndef INCLUDE_LEN_FUDGE
15239 #define INCLUDE_LEN_FUDGE 0
15242 static void append_include_chain (struct file_name_list *first,
15243 struct file_name_list *last);
15244 static FILE *open_include_file (char *filename,
15245 struct file_name_list *searchptr);
15246 static void print_containing_files (ffebadSeverity sev);
15247 static char *read_filename_string (int ch, FILE *f);
15248 static struct file_name_map *read_name_map (const char *dirname);
15250 /* Append a chain of `struct file_name_list's
15251 to the end of the main include chain.
15252 FIRST is the beginning of the chain to append, and LAST is the end. */
15255 append_include_chain (first, last)
15256 struct file_name_list *first, *last;
15258 struct file_name_list *dir;
15260 if (!first || !last)
15266 last_include->next = first;
15268 for (dir = first; ; dir = dir->next) {
15269 int len = strlen (dir->fname) + INCLUDE_LEN_FUDGE;
15270 if (len > max_include_len)
15271 max_include_len = len;
15277 last_include = last;
15280 /* Try to open include file FILENAME. SEARCHPTR is the directory
15281 being tried from the include file search path. This function maps
15282 filenames on file systems based on information read by
15286 open_include_file (filename, searchptr)
15288 struct file_name_list *searchptr;
15290 register struct file_name_map *map;
15291 register char *from;
15294 if (searchptr && ! searchptr->got_name_map)
15296 searchptr->name_map = read_name_map (searchptr->fname
15297 ? searchptr->fname : ".");
15298 searchptr->got_name_map = 1;
15301 /* First check the mapping for the directory we are using. */
15302 if (searchptr && searchptr->name_map)
15305 if (searchptr->fname)
15306 from += strlen (searchptr->fname) + 1;
15307 for (map = searchptr->name_map; map; map = map->map_next)
15309 if (! strcmp (map->map_from, from))
15311 /* Found a match. */
15312 return fopen (map->map_to, "r");
15317 /* Try to find a mapping file for the particular directory we are
15318 looking in. Thus #include <sys/types.h> will look up sys/types.h
15319 in /usr/include/header.gcc and look up types.h in
15320 /usr/include/sys/header.gcc. */
15321 p = strrchr (filename, '/');
15322 #ifdef DIR_SEPARATOR
15323 if (! p) p = strrchr (filename, DIR_SEPARATOR);
15325 char *tmp = strrchr (filename, DIR_SEPARATOR);
15326 if (tmp != NULL && tmp > p) p = tmp;
15332 && searchptr->fname
15333 && strlen (searchptr->fname) == (size_t) (p - filename)
15334 && ! strncmp (searchptr->fname, filename, (int) (p - filename)))
15336 /* FILENAME is in SEARCHPTR, which we've already checked. */
15337 return fopen (filename, "r");
15343 map = read_name_map (".");
15347 dir = (char *) xmalloc (p - filename + 1);
15348 memcpy (dir, filename, p - filename);
15349 dir[p - filename] = '\0';
15351 map = read_name_map (dir);
15354 for (; map; map = map->map_next)
15355 if (! strcmp (map->map_from, from))
15356 return fopen (map->map_to, "r");
15358 return fopen (filename, "r");
15361 /* Print the file names and line numbers of the #include
15362 commands which led to the current file. */
15365 print_containing_files (ffebadSeverity sev)
15367 FILE_BUF *ip = NULL;
15373 /* If stack of files hasn't changed since we last printed
15374 this info, don't repeat it. */
15375 if (last_error_tick == input_file_stack_tick)
15378 for (i = indepth; i >= 0; i--)
15379 if (instack[i].fname != NULL) {
15384 /* Give up if we don't find a source file. */
15388 /* Find the other, outer source files. */
15389 for (i--; i >= 0; i--)
15390 if (instack[i].fname != NULL)
15396 str1 = "In file included";
15408 /* xgettext:no-c-format */
15409 ffebad_start_msg ("%A from %B at %0%C", sev);
15410 ffebad_here (0, ip->line, ip->column);
15411 ffebad_string (str1);
15412 ffebad_string (ip->nominal_fname);
15413 ffebad_string (str2);
15417 /* Record we have printed the status as of this time. */
15418 last_error_tick = input_file_stack_tick;
15421 /* Read a space delimited string of unlimited length from a stdio
15425 read_filename_string (ch, f)
15433 set = alloc = xmalloc (len + 1);
15434 if (! ISSPACE (ch))
15437 while ((ch = getc (f)) != EOF && ! ISSPACE (ch))
15439 if (set - alloc == len)
15442 alloc = xrealloc (alloc, len + 1);
15443 set = alloc + len / 2;
15453 /* Read the file name map file for DIRNAME. */
15455 static struct file_name_map *
15456 read_name_map (dirname)
15457 const char *dirname;
15459 /* This structure holds a linked list of file name maps, one per
15461 struct file_name_map_list
15463 struct file_name_map_list *map_list_next;
15464 char *map_list_name;
15465 struct file_name_map *map_list_map;
15467 static struct file_name_map_list *map_list;
15468 register struct file_name_map_list *map_list_ptr;
15472 int separator_needed;
15474 dirname = skip_redundant_dir_prefix (dirname);
15476 for (map_list_ptr = map_list; map_list_ptr;
15477 map_list_ptr = map_list_ptr->map_list_next)
15478 if (! strcmp (map_list_ptr->map_list_name, dirname))
15479 return map_list_ptr->map_list_map;
15481 map_list_ptr = ((struct file_name_map_list *)
15482 xmalloc (sizeof (struct file_name_map_list)));
15483 map_list_ptr->map_list_name = xstrdup (dirname);
15484 map_list_ptr->map_list_map = NULL;
15486 dirlen = strlen (dirname);
15487 separator_needed = dirlen != 0 && dirname[dirlen - 1] != '/';
15488 name = (char *) xmalloc (dirlen + strlen (FILE_NAME_MAP_FILE) + 2);
15489 strcpy (name, dirname);
15490 name[dirlen] = '/';
15491 strcpy (name + dirlen + separator_needed, FILE_NAME_MAP_FILE);
15492 f = fopen (name, "r");
15495 map_list_ptr->map_list_map = NULL;
15500 while ((ch = getc (f)) != EOF)
15503 struct file_name_map *ptr;
15507 from = read_filename_string (ch, f);
15508 while ((ch = getc (f)) != EOF && ISSPACE (ch) && ch != '\n')
15510 to = read_filename_string (ch, f);
15512 ptr = ((struct file_name_map *)
15513 xmalloc (sizeof (struct file_name_map)));
15514 ptr->map_from = from;
15516 /* Make the real filename absolute. */
15521 ptr->map_to = xmalloc (dirlen + strlen (to) + 2);
15522 strcpy (ptr->map_to, dirname);
15523 ptr->map_to[dirlen] = '/';
15524 strcpy (ptr->map_to + dirlen + separator_needed, to);
15528 ptr->map_next = map_list_ptr->map_list_map;
15529 map_list_ptr->map_list_map = ptr;
15531 while ((ch = getc (f)) != '\n')
15538 map_list_ptr->map_list_next = map_list;
15539 map_list = map_list_ptr;
15541 return map_list_ptr->map_list_map;
15545 ffecom_file_ (const char *name)
15549 /* Do partial setup of input buffer for the sake of generating
15550 early #line directives (when -g is in effect). */
15552 fp = &instack[++indepth];
15553 memset ((char *) fp, 0, sizeof (FILE_BUF));
15556 fp->nominal_fname = fp->fname = name;
15560 ffecom_close_include_ (FILE *f)
15565 input_file_stack_tick++;
15567 ffewhere_line_kill (instack[indepth].line);
15568 ffewhere_column_kill (instack[indepth].column);
15572 ffecom_decode_include_option_ (char *spec)
15574 struct file_name_list *dirtmp;
15576 if (! ignore_srcdir && !strcmp (spec, "-"))
15580 dirtmp = (struct file_name_list *)
15581 xmalloc (sizeof (struct file_name_list));
15582 dirtmp->next = 0; /* New one goes on the end */
15583 dirtmp->fname = spec;
15584 dirtmp->got_name_map = 0;
15586 error ("directory name must immediately follow -I");
15588 append_include_chain (dirtmp, dirtmp);
15593 /* Open INCLUDEd file. */
15596 ffecom_open_include_ (char *name, ffewhereLine l, ffewhereColumn c)
15599 size_t flen = strlen (fbeg);
15600 struct file_name_list *search_start = include; /* Chain of dirs to search */
15601 struct file_name_list dsp[1]; /* First in chain, if #include "..." */
15602 struct file_name_list *searchptr = 0;
15603 char *fname; /* Dynamically allocated fname buffer */
15610 dsp[0].fname = NULL;
15612 /* If -I- was specified, don't search current dir, only spec'd ones. */
15613 if (!ignore_srcdir)
15615 for (fp = &instack[indepth]; fp >= instack; fp--)
15621 if ((nam = fp->nominal_fname) != NULL)
15623 /* Found a named file. Figure out dir of the file,
15624 and put it in front of the search list. */
15625 dsp[0].next = search_start;
15626 search_start = dsp;
15628 ep = strrchr (nam, '/');
15629 #ifdef DIR_SEPARATOR
15630 if (ep == NULL) ep = strrchr (nam, DIR_SEPARATOR);
15632 char *tmp = strrchr (nam, DIR_SEPARATOR);
15633 if (tmp != NULL && tmp > ep) ep = tmp;
15637 ep = strrchr (nam, ']');
15638 if (ep == NULL) ep = strrchr (nam, '>');
15639 if (ep == NULL) ep = strrchr (nam, ':');
15640 if (ep != NULL) ep++;
15645 dsp[0].fname = (char *) xmalloc (n + 1);
15646 strncpy (dsp[0].fname, nam, n);
15647 dsp[0].fname[n] = '\0';
15648 if (n + INCLUDE_LEN_FUDGE > max_include_len)
15649 max_include_len = n + INCLUDE_LEN_FUDGE;
15652 dsp[0].fname = NULL; /* Current directory */
15653 dsp[0].got_name_map = 0;
15659 /* Allocate this permanently, because it gets stored in the definitions
15661 fname = xmalloc (max_include_len + flen + 4);
15662 /* + 2 above for slash and terminating null. */
15663 /* + 2 added for '.h' on VMS (to support '#include filename') (NOT USED
15666 /* If specified file name is absolute, just open it. */
15669 #ifdef DIR_SEPARATOR
15670 || *fbeg == DIR_SEPARATOR
15674 strncpy (fname, (char *) fbeg, flen);
15676 f = open_include_file (fname, NULL);
15682 /* Search directory path, trying to open the file.
15683 Copy each filename tried into FNAME. */
15685 for (searchptr = search_start; searchptr; searchptr = searchptr->next)
15687 if (searchptr->fname)
15689 /* The empty string in a search path is ignored.
15690 This makes it possible to turn off entirely
15691 a standard piece of the list. */
15692 if (searchptr->fname[0] == 0)
15694 strcpy (fname, skip_redundant_dir_prefix (searchptr->fname));
15695 if (fname[0] && fname[strlen (fname) - 1] != '/')
15696 strcat (fname, "/");
15697 fname[strlen (fname) + flen] = 0;
15702 strncat (fname, fbeg, flen);
15704 /* Change this 1/2 Unix 1/2 VMS file specification into a
15705 full VMS file specification */
15706 if (searchptr->fname && (searchptr->fname[0] != 0))
15708 /* Fix up the filename */
15709 hack_vms_include_specification (fname);
15713 /* This is a normal VMS filespec, so use it unchanged. */
15714 strncpy (fname, (char *) fbeg, flen);
15716 #if 0 /* Not for g77. */
15717 /* if it's '#include filename', add the missing .h */
15718 if (strchr (fname, '.') == NULL)
15719 strcat (fname, ".h");
15723 f = open_include_file (fname, searchptr);
15725 if (f == NULL && errno == EACCES)
15727 print_containing_files (FFEBAD_severityWARNING);
15728 /* xgettext:no-c-format */
15729 ffebad_start_msg ("At %0, INCLUDE file %A exists, but is not readable",
15730 FFEBAD_severityWARNING);
15731 ffebad_string (fname);
15732 ffebad_here (0, l, c);
15743 /* A file that was not found. */
15745 strncpy (fname, (char *) fbeg, flen);
15747 print_containing_files (ffebad_severity (FFEBAD_OPEN_INCLUDE));
15748 ffebad_start (FFEBAD_OPEN_INCLUDE);
15749 ffebad_here (0, l, c);
15750 ffebad_string (fname);
15754 if (dsp[0].fname != NULL)
15755 free (dsp[0].fname);
15760 if (indepth >= (INPUT_STACK_MAX - 1))
15762 print_containing_files (FFEBAD_severityFATAL);
15763 /* xgettext:no-c-format */
15764 ffebad_start_msg ("At %0, INCLUDE nesting too deep",
15765 FFEBAD_severityFATAL);
15766 ffebad_string (fname);
15767 ffebad_here (0, l, c);
15772 instack[indepth].line = ffewhere_line_use (l);
15773 instack[indepth].column = ffewhere_column_use (c);
15775 fp = &instack[indepth + 1];
15776 memset ((char *) fp, 0, sizeof (FILE_BUF));
15777 fp->nominal_fname = fp->fname = fname;
15778 fp->dir = searchptr;
15781 input_file_stack_tick++;
15786 /**INDENT* (Do not reformat this comment even with -fca option.)
15787 Data-gathering files: Given the source file listed below, compiled with
15788 f2c I obtained the output file listed after that, and from the output
15789 file I derived the above code.
15791 -------- (begin input file to f2c)
15797 double precision D1,D2
15799 call getem(A1,A2,C1,C2,I1,I2,R1,R2,D1,D2)
15826 c FFEINTRIN_impACOS
15827 call fooR(ACOS(R1))
15828 c FFEINTRIN_impAIMAG
15829 call fooR(AIMAG(C1))
15830 c FFEINTRIN_impAINT
15831 call fooR(AINT(R1))
15832 c FFEINTRIN_impALOG
15833 call fooR(ALOG(R1))
15834 c FFEINTRIN_impALOG10
15835 call fooR(ALOG10(R1))
15836 c FFEINTRIN_impAMAX0
15837 call fooR(AMAX0(I1,I2))
15838 c FFEINTRIN_impAMAX1
15839 call fooR(AMAX1(R1,R2))
15840 c FFEINTRIN_impAMIN0
15841 call fooR(AMIN0(I1,I2))
15842 c FFEINTRIN_impAMIN1
15843 call fooR(AMIN1(R1,R2))
15844 c FFEINTRIN_impAMOD
15845 call fooR(AMOD(R1,R2))
15846 c FFEINTRIN_impANINT
15847 call fooR(ANINT(R1))
15848 c FFEINTRIN_impASIN
15849 call fooR(ASIN(R1))
15850 c FFEINTRIN_impATAN
15851 call fooR(ATAN(R1))
15852 c FFEINTRIN_impATAN2
15853 call fooR(ATAN2(R1,R2))
15854 c FFEINTRIN_impCABS
15855 call fooR(CABS(C1))
15856 c FFEINTRIN_impCCOS
15857 call fooC(CCOS(C1))
15858 c FFEINTRIN_impCEXP
15859 call fooC(CEXP(C1))
15860 c FFEINTRIN_impCHAR
15861 call fooA(CHAR(I1))
15862 c FFEINTRIN_impCLOG
15863 call fooC(CLOG(C1))
15864 c FFEINTRIN_impCONJG
15865 call fooC(CONJG(C1))
15868 c FFEINTRIN_impCOSH
15869 call fooR(COSH(R1))
15870 c FFEINTRIN_impCSIN
15871 call fooC(CSIN(C1))
15872 c FFEINTRIN_impCSQRT
15873 call fooC(CSQRT(C1))
15874 c FFEINTRIN_impDABS
15875 call fooD(DABS(D1))
15876 c FFEINTRIN_impDACOS
15877 call fooD(DACOS(D1))
15878 c FFEINTRIN_impDASIN
15879 call fooD(DASIN(D1))
15880 c FFEINTRIN_impDATAN
15881 call fooD(DATAN(D1))
15882 c FFEINTRIN_impDATAN2
15883 call fooD(DATAN2(D1,D2))
15884 c FFEINTRIN_impDCOS
15885 call fooD(DCOS(D1))
15886 c FFEINTRIN_impDCOSH
15887 call fooD(DCOSH(D1))
15888 c FFEINTRIN_impDDIM
15889 call fooD(DDIM(D1,D2))
15890 c FFEINTRIN_impDEXP
15891 call fooD(DEXP(D1))
15893 call fooR(DIM(R1,R2))
15894 c FFEINTRIN_impDINT
15895 call fooD(DINT(D1))
15896 c FFEINTRIN_impDLOG
15897 call fooD(DLOG(D1))
15898 c FFEINTRIN_impDLOG10
15899 call fooD(DLOG10(D1))
15900 c FFEINTRIN_impDMAX1
15901 call fooD(DMAX1(D1,D2))
15902 c FFEINTRIN_impDMIN1
15903 call fooD(DMIN1(D1,D2))
15904 c FFEINTRIN_impDMOD
15905 call fooD(DMOD(D1,D2))
15906 c FFEINTRIN_impDNINT
15907 call fooD(DNINT(D1))
15908 c FFEINTRIN_impDPROD
15909 call fooD(DPROD(R1,R2))
15910 c FFEINTRIN_impDSIGN
15911 call fooD(DSIGN(D1,D2))
15912 c FFEINTRIN_impDSIN
15913 call fooD(DSIN(D1))
15914 c FFEINTRIN_impDSINH
15915 call fooD(DSINH(D1))
15916 c FFEINTRIN_impDSQRT
15917 call fooD(DSQRT(D1))
15918 c FFEINTRIN_impDTAN
15919 call fooD(DTAN(D1))
15920 c FFEINTRIN_impDTANH
15921 call fooD(DTANH(D1))
15924 c FFEINTRIN_impIABS
15925 call fooI(IABS(I1))
15926 c FFEINTRIN_impICHAR
15927 call fooI(ICHAR(A1))
15928 c FFEINTRIN_impIDIM
15929 call fooI(IDIM(I1,I2))
15930 c FFEINTRIN_impIDNINT
15931 call fooI(IDNINT(D1))
15932 c FFEINTRIN_impINDEX
15933 call fooI(INDEX(A1,A2))
15934 c FFEINTRIN_impISIGN
15935 call fooI(ISIGN(I1,I2))
15939 call fooL(LGE(A1,A2))
15941 call fooL(LGT(A1,A2))
15943 call fooL(LLE(A1,A2))
15945 call fooL(LLT(A1,A2))
15946 c FFEINTRIN_impMAX0
15947 call fooI(MAX0(I1,I2))
15948 c FFEINTRIN_impMAX1
15949 call fooI(MAX1(R1,R2))
15950 c FFEINTRIN_impMIN0
15951 call fooI(MIN0(I1,I2))
15952 c FFEINTRIN_impMIN1
15953 call fooI(MIN1(R1,R2))
15955 call fooI(MOD(I1,I2))
15956 c FFEINTRIN_impNINT
15957 call fooI(NINT(R1))
15958 c FFEINTRIN_impSIGN
15959 call fooR(SIGN(R1,R2))
15962 c FFEINTRIN_impSINH
15963 call fooR(SINH(R1))
15964 c FFEINTRIN_impSQRT
15965 call fooR(SQRT(R1))
15968 c FFEINTRIN_impTANH
15969 call fooR(TANH(R1))
15970 c FFEINTRIN_imp_CMPLX_C
15971 call fooC(cmplx(C1,C2))
15972 c FFEINTRIN_imp_CMPLX_D
15973 call fooZ(cmplx(D1,D2))
15974 c FFEINTRIN_imp_CMPLX_I
15975 call fooC(cmplx(I1,I2))
15976 c FFEINTRIN_imp_CMPLX_R
15977 call fooC(cmplx(R1,R2))
15978 c FFEINTRIN_imp_DBLE_C
15979 call fooD(dble(C1))
15980 c FFEINTRIN_imp_DBLE_D
15981 call fooD(dble(D1))
15982 c FFEINTRIN_imp_DBLE_I
15983 call fooD(dble(I1))
15984 c FFEINTRIN_imp_DBLE_R
15985 call fooD(dble(R1))
15986 c FFEINTRIN_imp_INT_C
15988 c FFEINTRIN_imp_INT_D
15990 c FFEINTRIN_imp_INT_I
15992 c FFEINTRIN_imp_INT_R
15994 c FFEINTRIN_imp_REAL_C
15995 call fooR(real(C1))
15996 c FFEINTRIN_imp_REAL_D
15997 call fooR(real(D1))
15998 c FFEINTRIN_imp_REAL_I
15999 call fooR(real(I1))
16000 c FFEINTRIN_imp_REAL_R
16001 call fooR(real(R1))
16003 c FFEINTRIN_imp_INT_D:
16005 c FFEINTRIN_specIDINT
16006 call fooI(IDINT(D1))
16008 c FFEINTRIN_imp_INT_R:
16010 c FFEINTRIN_specIFIX
16011 call fooI(IFIX(R1))
16012 c FFEINTRIN_specINT
16015 c FFEINTRIN_imp_REAL_D:
16017 c FFEINTRIN_specSNGL
16018 call fooR(SNGL(D1))
16020 c FFEINTRIN_imp_REAL_I:
16022 c FFEINTRIN_specFLOAT
16023 call fooR(FLOAT(I1))
16024 c FFEINTRIN_specREAL
16025 call fooR(REAL(I1))
16028 -------- (end input file to f2c)
16030 -------- (begin output from providing above input file as input to:
16031 -------- `f2c | gcc -E -C - | sed -e "s:/[*]*://:g" -e "s:[*]*[/]://:g" \
16032 -------- -e "s:^#.*$::g"')
16034 // -- translated by f2c (version 19950223).
16035 You must link the resulting object file with the libraries:
16036 -lf2c -lm (in that order)
16040 // f2c.h -- Standard Fortran to C header file //
16042 /// barf [ba:rf] 2. "He suggested using FORTRAN, and everybody barfed."
16044 - From The Shogakukan DICTIONARY OF NEW ENGLISH (Second edition) //
16049 // F2C_INTEGER will normally be `int' but would be `long' on 16-bit systems //
16050 // we assume short, float are OK //
16051 typedef long int // long int // integer;
16052 typedef char *address;
16053 typedef short int shortint;
16054 typedef float real;
16055 typedef double doublereal;
16056 typedef struct { real r, i; } complex;
16057 typedef struct { doublereal r, i; } doublecomplex;
16058 typedef long int // long int // logical;
16059 typedef short int shortlogical;
16060 typedef char logical1;
16061 typedef char integer1;
16062 // typedef long long longint; // // system-dependent //
16067 // Extern is for use with -E //
16081 typedef long int // int or long int // flag;
16082 typedef long int // int or long int // ftnlen;
16083 typedef long int // int or long int // ftnint;
16086 //external read, write//
16095 //internal read, write//
16125 //rewind, backspace, endfile//
16137 ftnint *inex; //parameters in standard's order//
16163 union Multitype { // for multiple entry points //
16174 typedef union Multitype Multitype;
16176 typedef long Long; // No longer used; formerly in Namelist //
16178 struct Vardesc { // for Namelist //
16184 typedef struct Vardesc Vardesc;
16191 typedef struct Namelist Namelist;
16200 // procedure parameter types for -A and -C++ //
16205 typedef int // Unknown procedure type // (*U_fp)();
16206 typedef shortint (*J_fp)();
16207 typedef integer (*I_fp)();
16208 typedef real (*R_fp)();
16209 typedef doublereal (*D_fp)(), (*E_fp)();
16210 typedef // Complex // void (*C_fp)();
16211 typedef // Double Complex // void (*Z_fp)();
16212 typedef logical (*L_fp)();
16213 typedef shortlogical (*K_fp)();
16214 typedef // Character // void (*H_fp)();
16215 typedef // Subroutine // int (*S_fp)();
16217 // E_fp is for real functions when -R is not specified //
16218 typedef void C_f; // complex function //
16219 typedef void H_f; // character function //
16220 typedef void Z_f; // double complex function //
16221 typedef doublereal E_f; // real function with -R not specified //
16223 // undef any lower-case symbols that your C compiler predefines, e.g.: //
16226 // (No such symbols should be defined in a strict ANSI C compiler.
16227 We can avoid trouble with f2c-translated code by using
16252 // Main program // MAIN__()
16254 // System generated locals //
16257 doublereal d__1, d__2;
16259 doublecomplex z__1, z__2, z__3;
16263 // Builtin functions //
16266 double pow_ri(), pow_di();
16270 double acos(), r_imag(), r_int(), log(), r_lg10(), r_mod(), r_nint(),
16271 asin(), atan(), atan2(), c_abs();
16272 void c_cos(), c_exp(), c_log(), r_cnjg();
16273 double cos(), cosh();
16274 void c_sin(), c_sqrt();
16275 double d_dim(), exp(), r_dim(), d_int(), d_lg10(), d_mod(), d_nint(),
16276 d_sign(), sin(), sinh(), sqrt(), tan(), tanh();
16277 integer i_dim(), i_dnnt(), i_indx(), i_sign(), i_len();
16278 logical l_ge(), l_gt(), l_le(), l_lt();
16282 // Local variables //
16283 extern // Subroutine // int fooa_(), fooc_(), food_(), fooi_(), foor_(),
16284 fool_(), fooz_(), getem_();
16285 static char a1[10], a2[10];
16286 static complex c1, c2;
16287 static doublereal d1, d2;
16288 static integer i1, i2;
16289 static real r1, r2;
16292 getem_(a1, a2, &c1, &c2, &i1, &i2, &r1, &r2, &d1, &d2, 10L, 10L);
16300 d__1 = (doublereal) i1;
16301 q__1.r = c1.r / d__1, q__1.i = c1.i / d__1;
16311 c_div(&q__1, &c1, &c2);
16313 q__1.r = c1.r / r1, q__1.i = c1.i / r1;
16315 z__1.r = c1.r / d1, z__1.i = c1.i / d1;
16318 i__1 = pow_ii(&i1, &i2);
16320 r__1 = pow_ri(&r1, &i1);
16322 d__1 = pow_di(&d1, &i1);
16324 pow_ci(&q__1, &c1, &i1);
16326 d__1 = (doublereal) r1;
16327 d__2 = (doublereal) r2;
16328 r__1 = pow_dd(&d__1, &d__2);
16330 d__2 = (doublereal) r1;
16331 d__1 = pow_dd(&d__2, &d1);
16333 d__1 = pow_dd(&d1, &d2);
16335 d__2 = (doublereal) r1;
16336 d__1 = pow_dd(&d1, &d__2);
16338 z__2.r = c1.r, z__2.i = c1.i;
16339 z__3.r = c2.r, z__3.i = c2.i;
16340 pow_zz(&z__1, &z__2, &z__3);
16341 q__1.r = z__1.r, q__1.i = z__1.i;
16343 z__2.r = c1.r, z__2.i = c1.i;
16344 z__3.r = r1, z__3.i = 0.;
16345 pow_zz(&z__1, &z__2, &z__3);
16346 q__1.r = z__1.r, q__1.i = z__1.i;
16348 z__2.r = c1.r, z__2.i = c1.i;
16349 z__3.r = d1, z__3.i = 0.;
16350 pow_zz(&z__1, &z__2, &z__3);
16352 // FFEINTRIN_impABS //
16353 r__1 = (doublereal)(( r1 ) >= 0 ? ( r1 ) : -( r1 )) ;
16355 // FFEINTRIN_impACOS //
16358 // FFEINTRIN_impAIMAG //
16359 r__1 = r_imag(&c1);
16361 // FFEINTRIN_impAINT //
16364 // FFEINTRIN_impALOG //
16367 // FFEINTRIN_impALOG10 //
16368 r__1 = r_lg10(&r1);
16370 // FFEINTRIN_impAMAX0 //
16371 r__1 = (real) (( i1 ) >= ( i2 ) ? ( i1 ) : ( i2 )) ;
16373 // FFEINTRIN_impAMAX1 //
16374 r__1 = (doublereal)(( r1 ) >= ( r2 ) ? ( r1 ) : ( r2 )) ;
16376 // FFEINTRIN_impAMIN0 //
16377 r__1 = (real) (( i1 ) <= ( i2 ) ? ( i1 ) : ( i2 )) ;
16379 // FFEINTRIN_impAMIN1 //
16380 r__1 = (doublereal)(( r1 ) <= ( r2 ) ? ( r1 ) : ( r2 )) ;
16382 // FFEINTRIN_impAMOD //
16383 r__1 = r_mod(&r1, &r2);
16385 // FFEINTRIN_impANINT //
16386 r__1 = r_nint(&r1);
16388 // FFEINTRIN_impASIN //
16391 // FFEINTRIN_impATAN //
16394 // FFEINTRIN_impATAN2 //
16395 r__1 = atan2(r1, r2);
16397 // FFEINTRIN_impCABS //
16400 // FFEINTRIN_impCCOS //
16403 // FFEINTRIN_impCEXP //
16406 // FFEINTRIN_impCHAR //
16407 *(unsigned char *)&ch__1[0] = i1;
16409 // FFEINTRIN_impCLOG //
16412 // FFEINTRIN_impCONJG //
16413 r_cnjg(&q__1, &c1);
16415 // FFEINTRIN_impCOS //
16418 // FFEINTRIN_impCOSH //
16421 // FFEINTRIN_impCSIN //
16424 // FFEINTRIN_impCSQRT //
16425 c_sqrt(&q__1, &c1);
16427 // FFEINTRIN_impDABS //
16428 d__1 = (( d1 ) >= 0 ? ( d1 ) : -( d1 )) ;
16430 // FFEINTRIN_impDACOS //
16433 // FFEINTRIN_impDASIN //
16436 // FFEINTRIN_impDATAN //
16439 // FFEINTRIN_impDATAN2 //
16440 d__1 = atan2(d1, d2);
16442 // FFEINTRIN_impDCOS //
16445 // FFEINTRIN_impDCOSH //
16448 // FFEINTRIN_impDDIM //
16449 d__1 = d_dim(&d1, &d2);
16451 // FFEINTRIN_impDEXP //
16454 // FFEINTRIN_impDIM //
16455 r__1 = r_dim(&r1, &r2);
16457 // FFEINTRIN_impDINT //
16460 // FFEINTRIN_impDLOG //
16463 // FFEINTRIN_impDLOG10 //
16464 d__1 = d_lg10(&d1);
16466 // FFEINTRIN_impDMAX1 //
16467 d__1 = (( d1 ) >= ( d2 ) ? ( d1 ) : ( d2 )) ;
16469 // FFEINTRIN_impDMIN1 //
16470 d__1 = (( d1 ) <= ( d2 ) ? ( d1 ) : ( d2 )) ;
16472 // FFEINTRIN_impDMOD //
16473 d__1 = d_mod(&d1, &d2);
16475 // FFEINTRIN_impDNINT //
16476 d__1 = d_nint(&d1);
16478 // FFEINTRIN_impDPROD //
16479 d__1 = (doublereal) r1 * r2;
16481 // FFEINTRIN_impDSIGN //
16482 d__1 = d_sign(&d1, &d2);
16484 // FFEINTRIN_impDSIN //
16487 // FFEINTRIN_impDSINH //
16490 // FFEINTRIN_impDSQRT //
16493 // FFEINTRIN_impDTAN //
16496 // FFEINTRIN_impDTANH //
16499 // FFEINTRIN_impEXP //
16502 // FFEINTRIN_impIABS //
16503 i__1 = (( i1 ) >= 0 ? ( i1 ) : -( i1 )) ;
16505 // FFEINTRIN_impICHAR //
16506 i__1 = *(unsigned char *)a1;
16508 // FFEINTRIN_impIDIM //
16509 i__1 = i_dim(&i1, &i2);
16511 // FFEINTRIN_impIDNINT //
16512 i__1 = i_dnnt(&d1);
16514 // FFEINTRIN_impINDEX //
16515 i__1 = i_indx(a1, a2, 10L, 10L);
16517 // FFEINTRIN_impISIGN //
16518 i__1 = i_sign(&i1, &i2);
16520 // FFEINTRIN_impLEN //
16521 i__1 = i_len(a1, 10L);
16523 // FFEINTRIN_impLGE //
16524 L__1 = l_ge(a1, a2, 10L, 10L);
16526 // FFEINTRIN_impLGT //
16527 L__1 = l_gt(a1, a2, 10L, 10L);
16529 // FFEINTRIN_impLLE //
16530 L__1 = l_le(a1, a2, 10L, 10L);
16532 // FFEINTRIN_impLLT //
16533 L__1 = l_lt(a1, a2, 10L, 10L);
16535 // FFEINTRIN_impMAX0 //
16536 i__1 = (( i1 ) >= ( i2 ) ? ( i1 ) : ( i2 )) ;
16538 // FFEINTRIN_impMAX1 //
16539 i__1 = (integer) (doublereal)(( r1 ) >= ( r2 ) ? ( r1 ) : ( r2 )) ;
16541 // FFEINTRIN_impMIN0 //
16542 i__1 = (( i1 ) <= ( i2 ) ? ( i1 ) : ( i2 )) ;
16544 // FFEINTRIN_impMIN1 //
16545 i__1 = (integer) (doublereal)(( r1 ) <= ( r2 ) ? ( r1 ) : ( r2 )) ;
16547 // FFEINTRIN_impMOD //
16550 // FFEINTRIN_impNINT //
16551 i__1 = i_nint(&r1);
16553 // FFEINTRIN_impSIGN //
16554 r__1 = r_sign(&r1, &r2);
16556 // FFEINTRIN_impSIN //
16559 // FFEINTRIN_impSINH //
16562 // FFEINTRIN_impSQRT //
16565 // FFEINTRIN_impTAN //
16568 // FFEINTRIN_impTANH //
16571 // FFEINTRIN_imp_CMPLX_C //
16574 q__1.r = r__1, q__1.i = r__2;
16576 // FFEINTRIN_imp_CMPLX_D //
16577 z__1.r = d1, z__1.i = d2;
16579 // FFEINTRIN_imp_CMPLX_I //
16582 q__1.r = r__1, q__1.i = r__2;
16584 // FFEINTRIN_imp_CMPLX_R //
16585 q__1.r = r1, q__1.i = r2;
16587 // FFEINTRIN_imp_DBLE_C //
16588 d__1 = (doublereal) c1.r;
16590 // FFEINTRIN_imp_DBLE_D //
16593 // FFEINTRIN_imp_DBLE_I //
16594 d__1 = (doublereal) i1;
16596 // FFEINTRIN_imp_DBLE_R //
16597 d__1 = (doublereal) r1;
16599 // FFEINTRIN_imp_INT_C //
16600 i__1 = (integer) c1.r;
16602 // FFEINTRIN_imp_INT_D //
16603 i__1 = (integer) d1;
16605 // FFEINTRIN_imp_INT_I //
16608 // FFEINTRIN_imp_INT_R //
16609 i__1 = (integer) r1;
16611 // FFEINTRIN_imp_REAL_C //
16614 // FFEINTRIN_imp_REAL_D //
16617 // FFEINTRIN_imp_REAL_I //
16620 // FFEINTRIN_imp_REAL_R //
16624 // FFEINTRIN_imp_INT_D: //
16626 // FFEINTRIN_specIDINT //
16627 i__1 = (integer) d1;
16630 // FFEINTRIN_imp_INT_R: //
16632 // FFEINTRIN_specIFIX //
16633 i__1 = (integer) r1;
16635 // FFEINTRIN_specINT //
16636 i__1 = (integer) r1;
16639 // FFEINTRIN_imp_REAL_D: //
16641 // FFEINTRIN_specSNGL //
16645 // FFEINTRIN_imp_REAL_I: //
16647 // FFEINTRIN_specFLOAT //
16650 // FFEINTRIN_specREAL //
16656 -------- (end output file from f2c)