1 /* com.c -- Implementation File (module.c template V1.0)
2 Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
3 Free Software Foundation, Inc.
4 Contributed by James Craig Burley.
6 This file is part of GNU Fortran.
8 GNU Fortran is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU Fortran is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Fortran; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
27 Contains compiler-specific functions.
32 /* Understanding this module means understanding the interface between
33 the g77 front end and the gcc back end (or, perhaps, some other
34 back end). In here are the functions called by the front end proper
35 to notify whatever back end is in place about certain things, and
36 also the back-end-specific functions. It's a bear to deal with, so
37 lately I've been trying to simplify things, especially with regard
38 to the gcc-back-end-specific stuff.
40 Building expressions generally seems quite easy, but building decls
41 has been challenging and is undergoing revision. gcc has several
44 TYPE_DECL -- a type (int, float, struct, function, etc.)
45 CONST_DECL -- a constant of some type other than function
46 LABEL_DECL -- a variable or a constant?
47 PARM_DECL -- an argument to a function (a variable that is a dummy)
48 RESULT_DECL -- the return value of a function (a variable)
49 VAR_DECL -- other variable (can hold a ptr-to-function, struct, int, etc.)
50 FUNCTION_DECL -- a function (either the actual function or an extern ref)
51 FIELD_DECL -- a field in a struct or union (goes into types)
53 g77 has a set of functions that somewhat parallels the gcc front end
54 when it comes to building decls:
56 Internal Function (one we define, not just declare as extern):
57 if (is_nested) push_f_function_context ();
58 start_function (get_identifier ("function_name"), function_type,
59 is_nested, is_public);
60 // for each arg, build PARM_DECL and call push_parm_decl (decl) with it;
61 store_parm_decls (is_main_program);
62 ffecom_start_compstmt ();
63 // for stmts and decls inside function, do appropriate things;
64 ffecom_end_compstmt ();
65 finish_function (is_nested);
66 if (is_nested) pop_f_function_context ();
71 // fill in external, public, static, &c for decl, and
72 // set DECL_INITIAL to error_mark_node if going to initialize
73 // set is_top_level TRUE only if not at top level and decl
74 // must go in top level (i.e. not within current function decl context)
75 d = start_decl (decl, is_top_level);
76 init = ...; // if have initializer
77 finish_decl (d, init, is_top_level);
89 #include "output.h" /* Must follow tree.h so TREE_CODE is defined! */
92 #include "diagnostic.h"
94 #include "langhooks.h"
95 #include "langhooks-def.h"
98 /* VMS-specific definitions */
101 #define O_RDONLY 0 /* Open arg for Read/Only */
102 #define O_WRONLY 1 /* Open arg for Write/Only */
103 #define read(fd,buf,size) VMS_read (fd,buf,size)
104 #define write(fd,buf,size) VMS_write (fd,buf,size)
105 #define open(fname,mode,prot) VMS_open (fname,mode,prot)
106 #define fopen(fname,mode) VMS_fopen (fname,mode)
107 #define freopen(fname,mode,ofile) VMS_freopen (fname,mode,ofile)
108 #define strncat(dst,src,cnt) VMS_strncat (dst,src,cnt)
109 #define fstat(fd,stbuf) VMS_fstat (fd,stbuf)
110 static int VMS_fstat (), VMS_stat ();
111 static char * VMS_strncat ();
112 static int VMS_read ();
113 static int VMS_write ();
114 static int VMS_open ();
115 static FILE * VMS_fopen ();
116 static FILE * VMS_freopen ();
117 static void hack_vms_include_specification ();
118 typedef struct { unsigned :16, :16, :16; } vms_ino_t;
119 #define ino_t vms_ino_t
120 #define INCLUDE_LEN_FUDGE 10 /* leave room for VMS syntax conversion */
123 #define FFECOM_DETERMINE_TYPES 1 /* for com.h */
140 /* Externals defined here. */
142 /* Stream for reading from the input file. */
145 /* These definitions parallel those in c-decl.c so that code from that
146 module can be used pretty much as is. Much of these defs aren't
147 otherwise used, i.e. by g77 code per se, except some of them are used
148 to build some of them that are. The ones that are global (i.e. not
149 "static") are those that ste.c and such might use (directly
150 or by using com macros that reference them in their definitions). */
152 tree string_type_node;
154 /* The rest of these are inventions for g77, though there might be
155 similar things in the C front end. As they are found, these
156 inventions should be renamed to be canonical. Note that only
157 the ones currently required to be global are so. */
159 static GTY(()) tree ffecom_tree_fun_type_void;
161 tree ffecom_integer_type_node; /* Abbrev for _tree_type[blah][blah]. */
162 tree ffecom_integer_zero_node; /* Like *_*_* with g77's integer type. */
163 tree ffecom_integer_one_node; /* " */
164 tree ffecom_tree_type[FFEINFO_basictype][FFEINFO_kindtype];
166 /* _fun_type things are the f2c-specific versions. For -fno-f2c,
167 just use build_function_type and build_pointer_type on the
168 appropriate _tree_type array element. */
170 static GTY(()) tree ffecom_tree_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
172 ffecom_tree_ptr_to_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
173 static GTY(()) tree ffecom_tree_subr_type;
174 static GTY(()) tree ffecom_tree_ptr_to_subr_type;
175 static GTY(()) tree ffecom_tree_blockdata_type;
177 static GTY(()) tree ffecom_tree_xargc_;
179 ffecomSymbol ffecom_symbol_null_
188 ffeinfoKindtype ffecom_pointer_kind_ = FFEINFO_basictypeNONE;
189 ffeinfoKindtype ffecom_label_kind_ = FFEINFO_basictypeNONE;
191 int ffecom_f2c_typecode_[FFEINFO_basictype][FFEINFO_kindtype];
192 tree ffecom_f2c_integer_type_node;
193 static GTY(()) tree ffecom_f2c_ptr_to_integer_type_node;
194 tree ffecom_f2c_address_type_node;
195 tree ffecom_f2c_real_type_node;
196 static GTY(()) tree ffecom_f2c_ptr_to_real_type_node;
197 tree ffecom_f2c_doublereal_type_node;
198 tree ffecom_f2c_complex_type_node;
199 tree ffecom_f2c_doublecomplex_type_node;
200 tree ffecom_f2c_longint_type_node;
201 tree ffecom_f2c_logical_type_node;
202 tree ffecom_f2c_flag_type_node;
203 tree ffecom_f2c_ftnlen_type_node;
204 tree ffecom_f2c_ftnlen_zero_node;
205 tree ffecom_f2c_ftnlen_one_node;
206 tree ffecom_f2c_ftnlen_two_node;
207 tree ffecom_f2c_ptr_to_ftnlen_type_node;
208 tree ffecom_f2c_ftnint_type_node;
209 tree ffecom_f2c_ptr_to_ftnint_type_node;
211 /* Simple definitions and enumerations. */
213 #ifndef FFECOM_sizeMAXSTACKITEM
214 #define FFECOM_sizeMAXSTACKITEM 32*1024 /* Keep user-declared things
215 larger than this # bytes
216 off stack if possible. */
219 /* For systems that have large enough stacks, they should define
220 this to 0, and here, for ease of use later on, we just undefine
223 #if FFECOM_sizeMAXSTACKITEM == 0
224 #undef FFECOM_sizeMAXSTACKITEM
230 FFECOM_rttypeVOIDSTAR_, /* C's `void *' type. */
231 FFECOM_rttypeFTNINT_, /* f2c's `ftnint' type. */
232 FFECOM_rttypeINTEGER_, /* f2c's `integer' type. */
233 FFECOM_rttypeLONGINT_, /* f2c's `longint' type. */
234 FFECOM_rttypeLOGICAL_, /* f2c's `logical' type. */
235 FFECOM_rttypeREAL_F2C_, /* f2c's `real' returned as `double'. */
236 FFECOM_rttypeREAL_GNU_, /* `real' returned as such. */
237 FFECOM_rttypeCOMPLEX_F2C_, /* f2c's `complex' returned via 1st arg. */
238 FFECOM_rttypeCOMPLEX_GNU_, /* f2c's `complex' returned directly. */
239 FFECOM_rttypeDOUBLE_, /* C's `double' type. */
240 FFECOM_rttypeDOUBLEREAL_, /* f2c's `doublereal' type. */
241 FFECOM_rttypeDBLCMPLX_F2C_, /* f2c's `doublecomplex' returned via 1st arg. */
242 FFECOM_rttypeDBLCMPLX_GNU_, /* f2c's `doublecomplex' returned directly. */
243 FFECOM_rttypeCHARACTER_, /* f2c `char *'/`ftnlen' pair. */
247 /* Internal typedefs. */
249 typedef struct _ffecom_concat_list_ ffecomConcatList_;
251 /* Private include files. */
254 /* Internal structure definitions. */
256 struct _ffecom_concat_list_
261 ffetargetCharacterSize minlen;
262 ffetargetCharacterSize maxlen;
265 /* Static functions (internal). */
267 static tree ffe_type_for_mode (enum machine_mode, int);
268 static tree ffe_type_for_size (unsigned int, int);
269 static tree ffe_unsigned_type (tree);
270 static tree ffe_signed_type (tree);
271 static tree ffe_signed_or_unsigned_type (int, tree);
272 static bool ffe_mark_addressable (tree);
273 static tree ffe_truthvalue_conversion (tree);
274 static void ffecom_init_decl_processing (void);
275 static tree ffecom_arglist_expr_ (const char *argstring, ffebld args);
276 static tree ffecom_widest_expr_type_ (ffebld list);
277 static bool ffecom_overlap_ (tree dest_decl, tree dest_offset,
278 tree dest_size, tree source_tree,
279 ffebld source, bool scalar_arg);
280 static bool ffecom_args_overlapping_ (tree dest_tree, ffebld dest,
281 tree args, tree callee_commons,
283 static tree ffecom_build_f2c_string_ (int i, const char *s);
284 static tree ffecom_call_ (tree fn, ffeinfoKindtype kt,
285 bool is_f2c_complex, tree type,
286 tree args, tree dest_tree,
287 ffebld dest, bool *dest_used,
288 tree callee_commons, bool scalar_args, tree hook);
289 static tree ffecom_call_binop_ (tree fn, ffeinfoKindtype kt,
290 bool is_f2c_complex, tree type,
291 ffebld left, ffebld right,
292 tree dest_tree, ffebld dest,
293 bool *dest_used, tree callee_commons,
294 bool scalar_args, bool ref, tree hook);
295 static void ffecom_char_args_x_ (tree *xitem, tree *length,
296 ffebld expr, bool with_null);
297 static tree ffecom_check_size_overflow_ (ffesymbol s, tree type, bool dummy);
298 static tree ffecom_char_enhance_arg_ (tree *xtype, ffesymbol s);
299 static ffecomConcatList_
300 ffecom_concat_list_gather_ (ffecomConcatList_ catlist,
302 ffetargetCharacterSize max);
303 static void ffecom_concat_list_kill_ (ffecomConcatList_ catlist);
304 static ffecomConcatList_ ffecom_concat_list_new_ (ffebld expr,
305 ffetargetCharacterSize max);
306 static void ffecom_debug_kludge_ (tree aggr, const char *aggr_type,
307 ffesymbol member, tree member_type,
308 ffetargetOffset offset);
309 static void ffecom_do_entry_ (ffesymbol fn, int entrynum);
310 static tree ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest,
311 bool *dest_used, bool assignp, bool widenp);
312 static tree ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree,
313 ffebld dest, bool *dest_used);
314 static tree ffecom_expr_power_integer_ (ffebld expr);
315 static void ffecom_expr_transform_ (ffebld expr);
316 static void ffecom_f2c_make_type_ (tree *type, int tcode, const char *name);
317 static void ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size,
319 static ffeglobal ffecom_finish_global_ (ffeglobal global);
320 static ffesymbol ffecom_finish_symbol_transform_ (ffesymbol s);
321 static tree ffecom_get_appended_identifier_ (char us, const char *text);
322 static tree ffecom_get_external_identifier_ (ffesymbol s);
323 static tree ffecom_get_identifier_ (const char *text);
324 static tree ffecom_gen_sfuncdef_ (ffesymbol s,
327 static const char *ffecom_gfrt_args_ (ffecomGfrt ix);
328 static tree ffecom_gfrt_tree_ (ffecomGfrt ix);
329 static tree ffecom_init_zero_ (tree decl);
330 static tree ffecom_intrinsic_ichar_ (tree tree_type, ffebld arg,
332 static tree ffecom_intrinsic_len_ (ffebld expr);
333 static void ffecom_let_char_ (tree dest_tree,
335 ffetargetCharacterSize dest_size,
337 static void ffecom_make_gfrt_ (ffecomGfrt ix);
338 static void ffecom_member_phase1_ (ffestorag mst, ffestorag st);
339 static void ffecom_member_phase2_ (ffestorag mst, ffestorag st);
340 static void ffecom_prepare_let_char_ (ffetargetCharacterSize dest_size,
342 static void ffecom_push_dummy_decls_ (ffebld dumlist,
344 static void ffecom_start_progunit_ (void);
345 static ffesymbol ffecom_sym_transform_ (ffesymbol s);
346 static ffesymbol ffecom_sym_transform_assign_ (ffesymbol s);
347 static void ffecom_transform_common_ (ffesymbol s);
348 static void ffecom_transform_equiv_ (ffestorag st);
349 static tree ffecom_transform_namelist_ (ffesymbol s);
350 static void ffecom_tree_canonize_ptr_ (tree *decl, tree *offset,
352 static void ffecom_tree_canonize_ref_ (tree *decl, tree *offset,
353 tree *size, tree tree);
354 static tree ffecom_tree_divide_ (tree tree_type, tree left, tree right,
355 tree dest_tree, ffebld dest,
356 bool *dest_used, tree hook);
357 static tree ffecom_type_localvar_ (ffesymbol s,
360 static tree ffecom_type_namelist_ (void);
361 static tree ffecom_type_vardesc_ (void);
362 static tree ffecom_vardesc_ (ffebld expr);
363 static tree ffecom_vardesc_array_ (ffesymbol s);
364 static tree ffecom_vardesc_dims_ (ffesymbol s);
365 static tree ffecom_convert_narrow_ (tree type, tree expr);
366 static tree ffecom_convert_widen_ (tree type, tree expr);
368 /* These are static functions that parallel those found in the C front
369 end and thus have the same names. */
371 static tree bison_rule_compstmt_ (void);
372 static void bison_rule_pushlevel_ (void);
373 static void delete_block (tree block);
374 static int duplicate_decls (tree newdecl, tree olddecl);
375 static void finish_decl (tree decl, tree init, bool is_top_level);
376 static void finish_function (int nested);
377 static const char *ffe_printable_name (tree decl, int v);
378 static void ffe_print_error_function (diagnostic_context *, const char *);
379 static tree lookup_name_current_level (tree name);
380 static struct f_binding_level *make_binding_level (void);
381 static void pop_f_function_context (void);
382 static void push_f_function_context (void);
383 static void push_parm_decl (tree parm);
384 static tree pushdecl_top_level (tree decl);
385 static int kept_level_p (void);
386 static tree storedecls (tree decls);
387 static void store_parm_decls (int is_main_program);
388 static tree start_decl (tree decl, bool is_top_level);
389 static void start_function (tree name, tree type, int nested, int public);
390 static void ffecom_file_ (const char *name);
391 static void ffecom_close_include_ (FILE *f);
392 static FILE *ffecom_open_include_ (char *name, ffewhereLine l,
395 /* Static objects accessed by functions in this module. */
397 static ffesymbol ffecom_primary_entry_ = NULL;
398 static ffesymbol ffecom_nested_entry_ = NULL;
399 static ffeinfoKind ffecom_primary_entry_kind_;
400 static bool ffecom_primary_entry_is_proc_;
401 static GTY(()) tree ffecom_outer_function_decl_;
402 static GTY(()) tree ffecom_previous_function_decl_;
403 static GTY(()) tree ffecom_which_entrypoint_decl_;
404 static GTY(()) tree ffecom_float_zero_;
405 static GTY(()) tree ffecom_float_half_;
406 static GTY(()) tree ffecom_double_zero_;
407 static GTY(()) tree ffecom_double_half_;
408 static GTY(()) tree ffecom_func_result_;/* For functions. */
409 static GTY(()) tree ffecom_func_length_;/* For CHARACTER fns. */
410 static ffebld ffecom_list_blockdata_;
411 static ffebld ffecom_list_common_;
412 static ffebld ffecom_master_arglist_;
413 static ffeinfoBasictype ffecom_master_bt_;
414 static ffeinfoKindtype ffecom_master_kt_;
415 static ffetargetCharacterSize ffecom_master_size_;
416 static int ffecom_num_fns_ = 0;
417 static int ffecom_num_entrypoints_ = 0;
418 static bool ffecom_is_altreturning_ = FALSE;
419 static GTY(()) tree ffecom_multi_type_node_;
420 static GTY(()) tree ffecom_multi_retval_;
422 ffecom_multi_fields_[FFEINFO_basictype][FFEINFO_kindtype];
423 static bool ffecom_member_namelisted_; /* _member_phase1_ namelisted? */
424 static bool ffecom_doing_entry_ = FALSE;
425 static bool ffecom_transform_only_dummies_ = FALSE;
426 static int ffecom_typesize_pointer_;
427 static int ffecom_typesize_integer1_;
429 /* Holds pointer-to-function expressions. */
431 static GTY(()) tree ffecom_gfrt_[FFECOM_gfrt];
433 /* Holds the external names of the functions. */
435 static const char *const ffecom_gfrt_name_[FFECOM_gfrt]
438 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) NAME,
439 #include "com-rt.def"
443 /* Whether the function returns. */
445 static const bool ffecom_gfrt_volatile_[FFECOM_gfrt]
448 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) VOLATILE,
449 #include "com-rt.def"
453 /* Whether the function returns type complex. */
455 static const bool ffecom_gfrt_complex_[FFECOM_gfrt]
458 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) COMPLEX,
459 #include "com-rt.def"
463 /* Whether the function is const
464 (i.e., has no side effects and only depends on its arguments). */
466 static const bool ffecom_gfrt_const_[FFECOM_gfrt]
469 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) CONST,
470 #include "com-rt.def"
474 /* Type code for the function return value. */
476 static const ffecomRttype_ ffecom_gfrt_type_[FFECOM_gfrt]
479 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) TYPE,
480 #include "com-rt.def"
484 /* String of codes for the function's arguments. */
486 static const char *const ffecom_gfrt_argstring_[FFECOM_gfrt]
489 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) ARGS,
490 #include "com-rt.def"
494 /* Internal macros. */
496 /* We let tm.h override the types used here, to handle trivial differences
497 such as the choice of unsigned int or long unsigned int for size_t.
498 When machines start needing nontrivial differences in the size type,
499 it would be best to do something here to figure out automatically
500 from other information what type to use. */
503 #define SIZE_TYPE "long unsigned int"
506 #define ffecom_concat_list_count_(catlist) ((catlist).count)
507 #define ffecom_concat_list_expr_(catlist,i) ((catlist).exprs[(i)])
508 #define ffecom_concat_list_maxlen_(catlist) ((catlist).maxlen)
509 #define ffecom_concat_list_minlen_(catlist) ((catlist).minlen)
511 #define ffecom_char_args_(i,l,e) ffecom_char_args_x_((i),(l),(e),FALSE)
512 #define ffecom_char_args_with_null_(i,l,e) ffecom_char_args_x_((i),(l),(e),TRUE)
514 /* For each binding contour we allocate a binding_level structure
515 * which records the names defined in that contour.
518 * 1) one for each function definition,
519 * where internal declarations of the parameters appear.
521 * The current meaning of a name can be found by searching the levels from
522 * the current one out to the global one.
525 /* Note that the information in the `names' component of the global contour
526 is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */
528 struct f_binding_level GTY(())
530 /* A chain of _DECL nodes for all variables, constants, functions,
531 and typedef types. These are in the reverse of the order supplied.
535 /* For each level (except not the global one),
536 a chain of BLOCK nodes for all the levels
537 that were entered and exited one level down. */
540 /* The BLOCK node for this level, if one has been preallocated.
541 If 0, the BLOCK is allocated (if needed) when the level is popped. */
544 /* The binding level which this one is contained in (inherits from). */
545 struct f_binding_level *level_chain;
547 /* 0: no ffecom_prepare_* functions called at this level yet;
548 1: ffecom_prepare* functions called, except not ffecom_prepare_end;
549 2: ffecom_prepare_end called. */
553 #define NULL_BINDING_LEVEL (struct f_binding_level *) NULL
555 /* The binding level currently in effect. */
557 static GTY(()) struct f_binding_level *current_binding_level;
559 /* A chain of binding_level structures awaiting reuse. */
561 static GTY((deletable (""))) struct f_binding_level *free_binding_level;
563 /* The outermost binding level, for names of file scope.
564 This is created when the compiler is started and exists
565 through the entire run. */
567 static struct f_binding_level *global_binding_level;
569 /* Binding level structures are initialized by copying this one. */
571 static const struct f_binding_level clear_binding_level
573 {NULL, NULL, NULL, NULL_BINDING_LEVEL, 0};
575 /* Language-dependent contents of an identifier. */
577 struct lang_identifier GTY(())
579 struct tree_identifier common;
586 /* Macros for access to language-specific slots in an identifier. */
587 /* Each of these slots contains a DECL node or null. */
589 /* This represents the value which the identifier has in the
590 file-scope namespace. */
591 #define IDENTIFIER_GLOBAL_VALUE(NODE) \
592 (((struct lang_identifier *)(NODE))->global_value)
593 /* This represents the value which the identifier has in the current
595 #define IDENTIFIER_LOCAL_VALUE(NODE) \
596 (((struct lang_identifier *)(NODE))->local_value)
597 /* This represents the value which the identifier has as a label in
598 the current label scope. */
599 #define IDENTIFIER_LABEL_VALUE(NODE) \
600 (((struct lang_identifier *)(NODE))->label_value)
601 /* This is nonzero if the identifier was "made up" by g77 code. */
602 #define IDENTIFIER_INVENTED(NODE) \
603 (((struct lang_identifier *)(NODE))->invented)
605 /* The resulting tree type. */
607 GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
608 chain_next ("(union lang_tree_node *)TREE_CHAIN (&%h.generic)")))
610 union tree_node GTY ((tag ("0"),
611 desc ("tree_node_structure (&%h)")))
613 struct lang_identifier GTY ((tag ("1"))) identifier;
616 /* Fortran doesn't use either of these. */
617 struct lang_decl GTY(())
620 struct lang_type GTY(())
624 /* In identifiers, C uses the following fields in a special way:
625 TREE_PUBLIC to record that there was a previous local extern decl.
626 TREE_USED to record that such a decl was used.
627 TREE_ADDRESSABLE to record that the address of such a decl was used. */
629 /* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function
630 that have names. Here so we can clear out their names' definitions
631 at the end of the function. */
633 static GTY(()) tree named_labels;
635 /* A list of LABEL_DECLs from outer contexts that are currently shadowed. */
637 static GTY(()) tree shadowed_labels;
639 /* Return the subscript expression, modified to do range-checking.
641 `array' is the array to be checked against.
642 `element' is the subscript expression to check.
643 `dim' is the dimension number (starting at 0).
644 `total_dims' is the total number of dimensions (0 for CHARACTER substring).
648 ffecom_subscript_check_ (tree array, tree element, int dim, int total_dims,
649 const char *array_name)
651 tree low = TYPE_MIN_VALUE (TYPE_DOMAIN (array));
652 tree high = TYPE_MAX_VALUE (TYPE_DOMAIN (array));
657 if (element == error_mark_node)
660 if (TREE_TYPE (low) != TREE_TYPE (element))
662 if (TYPE_PRECISION (TREE_TYPE (low))
663 > TYPE_PRECISION (TREE_TYPE (element)))
664 element = convert (TREE_TYPE (low), element);
667 low = convert (TREE_TYPE (element), low);
669 high = convert (TREE_TYPE (element), high);
673 element = ffecom_save_tree (element);
676 /* Special handling for substring range checks. Fortran allows the
677 end subscript < begin subscript, which means that expressions like
678 string(1:0) are valid (and yield a null string). In view of this,
679 enforce two simpler conditions:
680 1) element<=high for end-substring;
681 2) element>=low for start-substring.
682 Run-time character movement will enforce remaining conditions.
684 More complicated checks would be better, but present structure only
685 provides one index element at a time, so it is not possible to
686 enforce a check of both i and j in string(i:j). If it were, the
687 complete set of rules would read,
688 if ( ((j<i) && ((low<=i<=high) || (low<=j<=high))) ||
689 ((low<=i<=high) && (low<=j<=high)) )
695 cond = ffecom_2 (LE_EXPR, integer_type_node, element, high);
697 cond = ffecom_2 (LE_EXPR, integer_type_node, low, element);
701 /* Array reference substring range checking. */
703 cond = ffecom_2 (LE_EXPR, integer_type_node,
708 cond = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
710 ffecom_2 (LE_EXPR, integer_type_node,
728 var = concat (array_name, "[", (dim ? "end" : "start"),
729 "-substring]", NULL);
730 len = strlen (var) + 1;
731 arg1 = build_string (len, var);
736 len = strlen (array_name) + 1;
737 arg1 = build_string (len, array_name);
741 var = xmalloc (strlen (array_name) + 40);
742 sprintf (var, "%s[subscript-%d-of-%d]",
744 dim + 1, total_dims);
745 len = strlen (var) + 1;
746 arg1 = build_string (len, var);
752 = build_type_variant (build_array_type (char_type_node,
756 build_int_2 (len, 0))),
758 TREE_CONSTANT (arg1) = 1;
759 TREE_STATIC (arg1) = 1;
760 arg1 = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg1)),
763 /* s_rnge adds one to the element to print it, so bias against
764 that -- want to print a faithful *subscript* value. */
765 arg2 = convert (ffecom_f2c_ftnint_type_node,
766 ffecom_2 (MINUS_EXPR,
769 convert (TREE_TYPE (element),
772 proc = concat (input_filename, "/",
773 IDENTIFIER_POINTER (DECL_NAME (current_function_decl)),
775 len = strlen (proc) + 1;
776 arg3 = build_string (len, proc);
781 = build_type_variant (build_array_type (char_type_node,
785 build_int_2 (len, 0))),
787 TREE_CONSTANT (arg3) = 1;
788 TREE_STATIC (arg3) = 1;
789 arg3 = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg3)),
792 arg4 = convert (ffecom_f2c_ftnint_type_node,
793 build_int_2 (input_line, 0));
795 arg1 = build_tree_list (NULL_TREE, arg1);
796 arg2 = build_tree_list (NULL_TREE, arg2);
797 arg3 = build_tree_list (NULL_TREE, arg3);
798 arg4 = build_tree_list (NULL_TREE, arg4);
799 TREE_CHAIN (arg3) = arg4;
800 TREE_CHAIN (arg2) = arg3;
801 TREE_CHAIN (arg1) = arg2;
805 die = ffecom_call_gfrt (FFECOM_gfrtRANGE,
807 TREE_SIDE_EFFECTS (die) = 1;
808 die = convert (void_type_node, die);
810 element = ffecom_3 (COND_EXPR,
819 /* Return the computed element of an array reference.
821 `item' is NULL_TREE, or the transformed pointer to the array.
822 `expr' is the original opARRAYREF expression, which is transformed
823 if `item' is NULL_TREE.
824 `want_ptr' is nonzero if a pointer to the element, instead of
825 the element itself, is to be returned. */
828 ffecom_arrayref_ (tree item, ffebld expr, int want_ptr)
830 ffebld dims[FFECOM_dimensionsMAX];
833 int flatten = ffe_is_flatten_arrays ();
839 const char *array_name;
843 if (ffebld_op (ffebld_left (expr)) == FFEBLD_opSYMTER)
844 array_name = ffesymbol_text (ffebld_symter (ffebld_left (expr)));
846 array_name = "[expr?]";
848 /* Build up ARRAY_REFs in reverse order (since we're column major
849 here in Fortran land). */
851 for (i = 0, list = ffebld_right (expr);
853 ++i, list = ffebld_trail (list))
855 dims[i] = ffebld_head (list);
856 type = ffeinfo_type (ffebld_basictype (dims[i]),
857 ffebld_kindtype (dims[i]));
859 && ffecom_typesize_pointer_ > ffecom_typesize_integer1_
860 && ffetype_size (type) > ffecom_typesize_integer1_)
861 /* E.g. ARRAY(INDEX), given INTEGER*8 INDEX, on a system with 64-bit
862 pointers and 32-bit integers. Do the full 64-bit pointer
863 arithmetic, for codes using arrays for nonstandard heap-like
870 need_ptr = want_ptr || flatten;
875 item = ffecom_ptr_to_expr (ffebld_left (expr));
877 item = ffecom_expr (ffebld_left (expr));
879 if (item == error_mark_node)
882 if (ffeinfo_where (ffebld_info (expr)) == FFEINFO_whereFLEETING
883 && ! ffe_mark_addressable (item))
884 return error_mark_node;
887 if (item == error_mark_node)
894 for (--i, array = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item)));
896 --i, array = TYPE_MAIN_VARIANT (TREE_TYPE (array)))
898 min = TYPE_MIN_VALUE (TYPE_DOMAIN (array));
899 element = ffecom_expr_ (dims[i], NULL, NULL, NULL, FALSE, TRUE);
900 if (flag_bounds_check)
901 element = ffecom_subscript_check_ (array, element, i, total_dims,
903 if (element == error_mark_node)
906 /* Widen integral arithmetic as desired while preserving
908 tree_type = TREE_TYPE (element);
909 tree_type_x = tree_type;
911 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
912 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
913 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
915 if (TREE_TYPE (min) != tree_type_x)
916 min = convert (tree_type_x, min);
917 if (TREE_TYPE (element) != tree_type_x)
918 element = convert (tree_type_x, element);
920 item = ffecom_2 (PLUS_EXPR,
921 build_pointer_type (TREE_TYPE (array)),
923 size_binop (MULT_EXPR,
924 size_in_bytes (TREE_TYPE (array)),
926 fold (build (MINUS_EXPR,
932 item = ffecom_1 (INDIRECT_REF,
933 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item))),
943 array = TYPE_MAIN_VARIANT (TREE_TYPE (item));
945 element = ffecom_expr_ (dims[i], NULL, NULL, NULL, FALSE, TRUE);
946 if (flag_bounds_check)
947 element = ffecom_subscript_check_ (array, element, i, total_dims,
949 if (element == error_mark_node)
952 /* Widen integral arithmetic as desired while preserving
954 tree_type = TREE_TYPE (element);
955 tree_type_x = tree_type;
957 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
958 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
959 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
961 element = convert (tree_type_x, element);
963 item = ffecom_2 (ARRAY_REF,
964 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item))),
973 /* This is like gcc's stabilize_reference -- in fact, most of the code
974 comes from that -- but it handles the situation where the reference
975 is going to have its subparts picked at, and it shouldn't change
976 (or trigger extra invocations of functions in the subtrees) due to
977 this. save_expr is a bit overzealous, because we don't need the
978 entire thing calculated and saved like a temp. So, for DECLs, no
979 change is needed, because these are stable aggregates, and ARRAY_REF
980 and such might well be stable too, but for things like calculations,
981 we do need to calculate a snapshot of a value before picking at it. */
984 ffecom_stabilize_aggregate_ (tree ref)
987 enum tree_code code = TREE_CODE (ref);
994 /* No action is needed in this case. */
1000 case FIX_TRUNC_EXPR:
1001 case FIX_FLOOR_EXPR:
1002 case FIX_ROUND_EXPR:
1004 result = build_nt (code, stabilize_reference (TREE_OPERAND (ref, 0)));
1008 result = build_nt (INDIRECT_REF,
1009 stabilize_reference_1 (TREE_OPERAND (ref, 0)));
1013 result = build_nt (COMPONENT_REF,
1014 stabilize_reference (TREE_OPERAND (ref, 0)),
1015 TREE_OPERAND (ref, 1));
1019 result = build_nt (BIT_FIELD_REF,
1020 stabilize_reference (TREE_OPERAND (ref, 0)),
1021 stabilize_reference_1 (TREE_OPERAND (ref, 1)),
1022 stabilize_reference_1 (TREE_OPERAND (ref, 2)));
1026 result = build_nt (ARRAY_REF,
1027 stabilize_reference (TREE_OPERAND (ref, 0)),
1028 stabilize_reference_1 (TREE_OPERAND (ref, 1)));
1032 result = build_nt (COMPOUND_EXPR,
1033 stabilize_reference_1 (TREE_OPERAND (ref, 0)),
1034 stabilize_reference (TREE_OPERAND (ref, 1)));
1042 return save_expr (ref);
1045 return error_mark_node;
1048 TREE_TYPE (result) = TREE_TYPE (ref);
1049 TREE_READONLY (result) = TREE_READONLY (ref);
1050 TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (ref);
1051 TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (ref);
1056 /* A rip-off of gcc's convert.c convert_to_complex function,
1057 reworked to handle complex implemented as C structures
1058 (RECORD_TYPE with two fields, real and imaginary `r' and `i'). */
1061 ffecom_convert_to_complex_ (tree type, tree expr)
1063 register enum tree_code form = TREE_CODE (TREE_TYPE (expr));
1066 assert (TREE_CODE (type) == RECORD_TYPE);
1068 subtype = TREE_TYPE (TYPE_FIELDS (type));
1070 if (form == REAL_TYPE || form == INTEGER_TYPE || form == ENUMERAL_TYPE)
1072 expr = convert (subtype, expr);
1073 return ffecom_2 (COMPLEX_EXPR, type, expr,
1074 convert (subtype, integer_zero_node));
1077 if (form == RECORD_TYPE)
1079 tree elt_type = TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr)));
1080 if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype))
1084 expr = save_expr (expr);
1085 return ffecom_2 (COMPLEX_EXPR,
1088 ffecom_1 (REALPART_EXPR,
1089 TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))),
1092 ffecom_1 (IMAGPART_EXPR,
1093 TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))),
1098 if (form == POINTER_TYPE || form == REFERENCE_TYPE)
1099 error ("pointer value used where a complex was expected");
1101 error ("aggregate value used where a complex was expected");
1103 return ffecom_2 (COMPLEX_EXPR, type,
1104 convert (subtype, integer_zero_node),
1105 convert (subtype, integer_zero_node));
1108 /* Like gcc's convert(), but crashes if widening might happen. */
1111 ffecom_convert_narrow_ (tree type, tree expr)
1113 register tree e = expr;
1114 register enum tree_code code = TREE_CODE (type);
1116 if (type == TREE_TYPE (e)
1117 || TREE_CODE (e) == ERROR_MARK)
1119 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
1120 return fold (build1 (NOP_EXPR, type, e));
1121 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
1122 || code == ERROR_MARK)
1123 return error_mark_node;
1124 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
1126 assert ("void value not ignored as it ought to be" == NULL);
1127 return error_mark_node;
1129 assert (code != VOID_TYPE);
1130 if ((code != RECORD_TYPE)
1131 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
1132 assert ("converting COMPLEX to REAL" == NULL);
1133 assert (code != ENUMERAL_TYPE);
1134 if (code == INTEGER_TYPE)
1136 assert ((TREE_CODE (TREE_TYPE (e)) == INTEGER_TYPE
1137 && TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (e)))
1138 || (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE
1139 && (TYPE_PRECISION (type)
1140 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e))))));
1141 return fold (convert_to_integer (type, e));
1143 if (code == POINTER_TYPE)
1145 assert (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE);
1146 return fold (convert_to_pointer (type, e));
1148 if (code == REAL_TYPE)
1150 assert (TREE_CODE (TREE_TYPE (e)) == REAL_TYPE);
1151 assert (TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (e)));
1152 return fold (convert_to_real (type, e));
1154 if (code == COMPLEX_TYPE)
1156 assert (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE);
1157 assert (TYPE_PRECISION (TREE_TYPE (type)) <= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e))));
1158 return fold (convert_to_complex (type, e));
1160 if (code == RECORD_TYPE)
1162 assert (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE);
1163 /* Check that at least the first field name agrees. */
1164 assert (DECL_NAME (TYPE_FIELDS (type))
1165 == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e))));
1166 assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1167 <= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))));
1168 if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1169 == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))))
1171 return fold (ffecom_convert_to_complex_ (type, e));
1174 assert ("conversion to non-scalar type requested" == NULL);
1175 return error_mark_node;
1178 /* Like gcc's convert(), but crashes if narrowing might happen. */
1181 ffecom_convert_widen_ (tree type, tree expr)
1183 register tree e = expr;
1184 register enum tree_code code = TREE_CODE (type);
1186 if (type == TREE_TYPE (e)
1187 || TREE_CODE (e) == ERROR_MARK)
1189 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
1190 return fold (build1 (NOP_EXPR, type, e));
1191 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
1192 || code == ERROR_MARK)
1193 return error_mark_node;
1194 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
1196 assert ("void value not ignored as it ought to be" == NULL);
1197 return error_mark_node;
1199 assert (code != VOID_TYPE);
1200 if ((code != RECORD_TYPE)
1201 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
1202 assert ("narrowing COMPLEX to REAL" == NULL);
1203 assert (code != ENUMERAL_TYPE);
1204 if (code == INTEGER_TYPE)
1206 assert ((TREE_CODE (TREE_TYPE (e)) == INTEGER_TYPE
1207 && TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (e)))
1208 || (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE
1209 && (TYPE_PRECISION (type)
1210 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e))))));
1211 return fold (convert_to_integer (type, e));
1213 if (code == POINTER_TYPE)
1215 assert (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE);
1216 return fold (convert_to_pointer (type, e));
1218 if (code == REAL_TYPE)
1220 assert (TREE_CODE (TREE_TYPE (e)) == REAL_TYPE);
1221 assert (TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (e)));
1222 return fold (convert_to_real (type, e));
1224 if (code == COMPLEX_TYPE)
1226 assert (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE);
1227 assert (TYPE_PRECISION (TREE_TYPE (type)) >= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e))));
1228 return fold (convert_to_complex (type, e));
1230 if (code == RECORD_TYPE)
1232 assert (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE);
1233 /* Check that at least the first field name agrees. */
1234 assert (DECL_NAME (TYPE_FIELDS (type))
1235 == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e))));
1236 assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1237 >= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))));
1238 if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1239 == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))))
1241 return fold (ffecom_convert_to_complex_ (type, e));
1244 assert ("conversion to non-scalar type requested" == NULL);
1245 return error_mark_node;
1248 /* Handles making a COMPLEX type, either the standard
1249 (but buggy?) gbe way, or the safer (but less elegant?)
1253 ffecom_make_complex_type_ (tree subtype)
1259 if (ffe_is_emulate_complex ())
1261 type = make_node (RECORD_TYPE);
1262 realfield = ffecom_decl_field (type, NULL_TREE, "r", subtype);
1263 imagfield = ffecom_decl_field (type, realfield, "i", subtype);
1264 TYPE_FIELDS (type) = realfield;
1269 type = make_node (COMPLEX_TYPE);
1270 TREE_TYPE (type) = subtype;
1277 /* Chooses either the gbe or the f2c way to build a
1278 complex constant. */
1281 ffecom_build_complex_constant_ (tree type, tree realpart, tree imagpart)
1285 if (ffe_is_emulate_complex ())
1287 bothparts = build_tree_list (TYPE_FIELDS (type), realpart);
1288 TREE_CHAIN (bothparts) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), imagpart);
1289 bothparts = build_constructor (type, bothparts);
1293 bothparts = build_complex (type, realpart, imagpart);
1300 ffecom_arglist_expr_ (const char *c, ffebld expr)
1303 tree *plist = &list;
1304 tree trail = NULL_TREE; /* Append char length args here. */
1305 tree *ptrail = &trail;
1310 tree wanted = NULL_TREE;
1311 static const char zed[] = "0";
1316 while (expr != NULL)
1339 wanted = ffecom_f2c_complex_type_node;
1343 wanted = ffecom_f2c_doublereal_type_node;
1347 wanted = ffecom_f2c_doublecomplex_type_node;
1351 wanted = ffecom_f2c_real_type_node;
1355 wanted = ffecom_f2c_integer_type_node;
1359 wanted = ffecom_f2c_longint_type_node;
1363 assert ("bad argstring code" == NULL);
1369 exprh = ffebld_head (expr);
1373 if ((wanted == NULL_TREE)
1376 (ffecom_tree_type[ffeinfo_basictype (ffebld_info (exprh))]
1377 [ffeinfo_kindtype (ffebld_info (exprh))])
1378 == TYPE_MODE (wanted))))
1380 = build_tree_list (NULL_TREE,
1381 ffecom_arg_ptr_to_expr (exprh,
1385 item = ffecom_arg_expr (exprh, &length);
1386 item = ffecom_convert_widen_ (wanted, item);
1389 item = ffecom_1 (ADDR_EXPR,
1390 build_pointer_type (TREE_TYPE (item)),
1394 = build_tree_list (NULL_TREE,
1398 plist = &TREE_CHAIN (*plist);
1399 expr = ffebld_trail (expr);
1400 if (length != NULL_TREE)
1402 *ptrail = build_tree_list (NULL_TREE, length);
1403 ptrail = &TREE_CHAIN (*ptrail);
1407 /* We've run out of args in the call; if the implementation expects
1408 more, supply null pointers for them, which the implementation can
1409 check to see if an arg was omitted. */
1411 while (*c != '\0' && *c != '0')
1416 assert ("missing arg to run-time routine!" == NULL);
1431 assert ("bad arg string code" == NULL);
1435 = build_tree_list (NULL_TREE,
1437 plist = &TREE_CHAIN (*plist);
1446 ffecom_widest_expr_type_ (ffebld list)
1449 ffebld widest = NULL;
1451 ffetype widest_type = NULL;
1454 for (; list != NULL; list = ffebld_trail (list))
1456 item = ffebld_head (list);
1459 if ((widest != NULL)
1460 && (ffeinfo_basictype (ffebld_info (item))
1461 != ffeinfo_basictype (ffebld_info (widest))))
1463 type = ffeinfo_type (ffeinfo_basictype (ffebld_info (item)),
1464 ffeinfo_kindtype (ffebld_info (item)));
1465 if ((widest == FFEINFO_kindtypeNONE)
1466 || (ffetype_size (type)
1467 > ffetype_size (widest_type)))
1474 assert (widest != NULL);
1475 t = ffecom_tree_type[ffeinfo_basictype (ffebld_info (widest))]
1476 [ffeinfo_kindtype (ffebld_info (widest))];
1477 assert (t != NULL_TREE);
1481 /* Check whether a partial overlap between two expressions is possible.
1483 Can *starting* to write a portion of expr1 change the value
1484 computed (perhaps already, *partially*) by expr2?
1486 Currently, this is a concern only for a COMPLEX expr1. But if it
1487 isn't in COMMON or local EQUIVALENCE, since we don't support
1488 aliasing of arguments, it isn't a concern. */
1491 ffecom_possible_partial_overlap_ (ffebld expr1, ffebld expr2 ATTRIBUTE_UNUSED)
1496 switch (ffebld_op (expr1))
1498 case FFEBLD_opSYMTER:
1499 sym = ffebld_symter (expr1);
1502 case FFEBLD_opARRAYREF:
1503 if (ffebld_op (ffebld_left (expr1)) != FFEBLD_opSYMTER)
1505 sym = ffebld_symter (ffebld_left (expr1));
1512 if (ffesymbol_where (sym) != FFEINFO_whereCOMMON
1513 && (ffesymbol_where (sym) != FFEINFO_whereLOCAL
1514 || ! (st = ffesymbol_storage (sym))
1515 || ! ffestorag_parent (st)))
1518 /* It's in COMMON or local EQUIVALENCE. */
1523 /* Check whether dest and source might overlap. ffebld versions of these
1524 might or might not be passed, will be NULL if not.
1526 The test is really whether source_tree is modifiable and, if modified,
1527 might overlap destination such that the value(s) in the destination might
1528 change before it is finally modified. dest_* are the canonized
1529 destination itself. */
1532 ffecom_overlap_ (tree dest_decl, tree dest_offset, tree dest_size,
1533 tree source_tree, ffebld source UNUSED, bool scalar_arg)
1540 if (source_tree == NULL_TREE)
1543 switch (TREE_CODE (source_tree))
1546 case IDENTIFIER_NODE:
1557 case TRUNC_DIV_EXPR:
1559 case FLOOR_DIV_EXPR:
1560 case ROUND_DIV_EXPR:
1561 case TRUNC_MOD_EXPR:
1563 case FLOOR_MOD_EXPR:
1564 case ROUND_MOD_EXPR:
1566 case EXACT_DIV_EXPR:
1567 case FIX_TRUNC_EXPR:
1569 case FIX_FLOOR_EXPR:
1570 case FIX_ROUND_EXPR:
1584 case BIT_ANDTC_EXPR:
1586 case TRUTH_ANDIF_EXPR:
1587 case TRUTH_ORIF_EXPR:
1588 case TRUTH_AND_EXPR:
1590 case TRUTH_XOR_EXPR:
1591 case TRUTH_NOT_EXPR:
1607 return ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1608 TREE_OPERAND (source_tree, 1), NULL,
1612 return ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1613 TREE_OPERAND (source_tree, 0), NULL,
1618 case NON_LVALUE_EXPR:
1620 if (TREE_CODE (TREE_TYPE (source_tree)) != POINTER_TYPE)
1623 ffecom_tree_canonize_ptr_ (&source_decl, &source_offset,
1625 source_size = TYPE_SIZE (TREE_TYPE (TREE_TYPE (source_tree)));
1630 ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1631 TREE_OPERAND (source_tree, 1), NULL,
1633 || ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1634 TREE_OPERAND (source_tree, 2), NULL,
1639 ffecom_tree_canonize_ref_ (&source_decl, &source_offset,
1641 TREE_OPERAND (source_tree, 0));
1645 if (TREE_CODE (TREE_TYPE (source_tree)) != POINTER_TYPE)
1648 source_decl = source_tree;
1649 source_offset = bitsize_zero_node;
1650 source_size = TYPE_SIZE (TREE_TYPE (TREE_TYPE (source_tree)));
1654 case REFERENCE_EXPR:
1655 case PREDECREMENT_EXPR:
1656 case PREINCREMENT_EXPR:
1657 case POSTDECREMENT_EXPR:
1658 case POSTINCREMENT_EXPR:
1666 /* Come here when source_decl, source_offset, and source_size filled
1667 in appropriately. */
1669 if (source_decl == NULL_TREE)
1670 return FALSE; /* No decl involved, so no overlap. */
1672 if (source_decl != dest_decl)
1673 return FALSE; /* Different decl, no overlap. */
1675 if (TREE_CODE (dest_size) == ERROR_MARK)
1676 return TRUE; /* Assignment into entire assumed-size
1677 array? Shouldn't happen.... */
1679 t = ffecom_2 (LE_EXPR, integer_type_node,
1680 ffecom_2 (PLUS_EXPR, TREE_TYPE (dest_offset),
1682 convert (TREE_TYPE (dest_offset),
1684 convert (TREE_TYPE (dest_offset),
1687 if (integer_onep (t))
1688 return FALSE; /* Destination precedes source. */
1691 || (source_size == NULL_TREE)
1692 || (TREE_CODE (source_size) == ERROR_MARK)
1693 || integer_zerop (source_size))
1694 return TRUE; /* No way to tell if dest follows source. */
1696 t = ffecom_2 (LE_EXPR, integer_type_node,
1697 ffecom_2 (PLUS_EXPR, TREE_TYPE (source_offset),
1699 convert (TREE_TYPE (source_offset),
1701 convert (TREE_TYPE (source_offset),
1704 if (integer_onep (t))
1705 return FALSE; /* Destination follows source. */
1707 return TRUE; /* Destination and source overlap. */
1710 /* Check whether dest might overlap any of a list of arguments or is
1711 in a COMMON area the callee might know about (and thus modify). */
1714 ffecom_args_overlapping_ (tree dest_tree, ffebld dest UNUSED, tree args,
1715 tree callee_commons, bool scalar_args)
1722 ffecom_tree_canonize_ref_ (&dest_decl, &dest_offset, &dest_size,
1725 if (dest_decl == NULL_TREE)
1726 return FALSE; /* Seems unlikely! */
1728 /* If the decl cannot be determined reliably, or if its in COMMON
1729 and the callee isn't known to not futz with COMMON via other
1730 means, overlap might happen. */
1732 if ((TREE_CODE (dest_decl) == ERROR_MARK)
1733 || ((callee_commons != NULL_TREE)
1734 && TREE_PUBLIC (dest_decl)))
1737 for (; args != NULL_TREE; args = TREE_CHAIN (args))
1739 if (((arg = TREE_VALUE (args)) != NULL_TREE)
1740 && ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1741 arg, NULL, scalar_args))
1748 /* Build a string for a variable name as used by NAMELIST. This means that
1749 if we're using the f2c library, we build an uppercase string, since
1753 ffecom_build_f2c_string_ (int i, const char *s)
1755 if (!ffe_is_f2c_library ())
1756 return build_string (i, s);
1765 if (((size_t) i) > ARRAY_SIZE (space))
1766 tmp = malloc_new_ks (malloc_pool_image (), "f2c_string", i);
1770 for (p = s, q = tmp; *p != '\0'; ++p, ++q)
1774 t = build_string (i, tmp);
1776 if (((size_t) i) > ARRAY_SIZE (space))
1777 malloc_kill_ks (malloc_pool_image (), tmp, i);
1783 /* Returns CALL_EXPR or equivalent with given type (pass NULL_TREE for
1784 type to just get whatever the function returns), handling the
1785 f2c value-returning convention, if required, by prepending
1786 to the arglist a pointer to a temporary to receive the return value. */
1789 ffecom_call_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex, tree type,
1790 tree args, tree dest_tree, ffebld dest, bool *dest_used,
1791 tree callee_commons, bool scalar_args, tree hook)
1796 if (dest_used != NULL)
1801 if ((dest_used == NULL)
1803 || (ffeinfo_basictype (ffebld_info (dest))
1804 != FFEINFO_basictypeCOMPLEX)
1805 || (ffeinfo_kindtype (ffebld_info (dest)) != kt)
1806 || ((type != NULL_TREE) && (TREE_TYPE (dest_tree) != type))
1807 || ffecom_args_overlapping_ (dest_tree, dest, args,
1817 tempvar = dest_tree;
1822 = build_tree_list (NULL_TREE,
1823 ffecom_1 (ADDR_EXPR,
1824 build_pointer_type (TREE_TYPE (tempvar)),
1826 TREE_CHAIN (item) = args;
1828 item = ffecom_3s (CALL_EXPR, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), fn,
1831 if (tempvar != dest_tree)
1832 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), item, tempvar);
1835 item = ffecom_3s (CALL_EXPR, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), fn,
1838 if ((type != NULL_TREE) && (TREE_TYPE (item) != type))
1839 item = ffecom_convert_narrow_ (type, item);
1844 /* Given two arguments, transform them and make a call to the given
1845 function via ffecom_call_. */
1848 ffecom_call_binop_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex,
1849 tree type, ffebld left, ffebld right, tree dest_tree,
1850 ffebld dest, bool *dest_used, tree callee_commons,
1851 bool scalar_args, bool ref, tree hook)
1860 /* Pass arguments by reference. */
1861 left_tree = ffecom_arg_ptr_to_expr (left, &left_length);
1862 right_tree = ffecom_arg_ptr_to_expr (right, &right_length);
1866 /* Pass arguments by value. */
1867 left_tree = ffecom_arg_expr (left, &left_length);
1868 right_tree = ffecom_arg_expr (right, &right_length);
1872 left_tree = build_tree_list (NULL_TREE, left_tree);
1873 right_tree = build_tree_list (NULL_TREE, right_tree);
1874 TREE_CHAIN (left_tree) = right_tree;
1876 if (left_length != NULL_TREE)
1878 left_length = build_tree_list (NULL_TREE, left_length);
1879 TREE_CHAIN (right_tree) = left_length;
1882 if (right_length != NULL_TREE)
1884 right_length = build_tree_list (NULL_TREE, right_length);
1885 if (left_length != NULL_TREE)
1886 TREE_CHAIN (left_length) = right_length;
1888 TREE_CHAIN (right_tree) = right_length;
1891 return ffecom_call_ (fn, kt, is_f2c_complex, type, left_tree,
1892 dest_tree, dest, dest_used, callee_commons,
1896 /* Return ptr/length args for char subexpression
1898 Handles CHARACTER-type CONTER, SYMTER, SUBSTR, ARRAYREF, and FUNCREF
1899 subexpressions by constructing the appropriate trees for the ptr-to-
1900 character-text and length-of-character-text arguments in a calling
1903 Note that if with_null is TRUE, and the expression is an opCONTER,
1904 a null byte is appended to the string. */
1907 ffecom_char_args_x_ (tree *xitem, tree *length, ffebld expr, bool with_null)
1911 ffetargetCharacter1 val;
1912 ffetargetCharacterSize newlen;
1914 switch (ffebld_op (expr))
1916 case FFEBLD_opCONTER:
1917 val = ffebld_constant_character1 (ffebld_conter (expr));
1918 newlen = ffetarget_length_character1 (val);
1921 /* Begin FFETARGET-NULL-KLUDGE. */
1925 *length = build_int_2 (newlen, 0);
1926 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
1927 high = build_int_2 (newlen, 0);
1928 TREE_TYPE (high) = ffecom_f2c_ftnlen_type_node;
1929 item = build_string (newlen,
1930 ffetarget_text_character1 (val));
1931 /* End FFETARGET-NULL-KLUDGE. */
1933 = build_type_variant
1937 (ffecom_f2c_ftnlen_type_node,
1938 ffecom_f2c_ftnlen_one_node,
1941 TREE_CONSTANT (item) = 1;
1942 TREE_STATIC (item) = 1;
1943 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
1947 case FFEBLD_opSYMTER:
1949 ffesymbol s = ffebld_symter (expr);
1951 item = ffesymbol_hook (s).decl_tree;
1952 if (item == NULL_TREE)
1954 s = ffecom_sym_transform_ (s);
1955 item = ffesymbol_hook (s).decl_tree;
1957 if (ffesymbol_kind (s) == FFEINFO_kindENTITY)
1959 if (ffesymbol_size (s) == FFETARGET_charactersizeNONE)
1960 *length = ffesymbol_hook (s).length_tree;
1963 *length = build_int_2 (ffesymbol_size (s), 0);
1964 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
1967 else if (item == error_mark_node)
1968 *length = error_mark_node;
1970 /* FFEINFO_kindFUNCTION. */
1971 *length = NULL_TREE;
1972 if (!ffesymbol_hook (s).addr
1973 && (item != error_mark_node))
1974 item = ffecom_1 (ADDR_EXPR,
1975 build_pointer_type (TREE_TYPE (item)),
1980 case FFEBLD_opARRAYREF:
1982 ffecom_char_args_ (&item, length, ffebld_left (expr));
1984 if (item == error_mark_node || *length == error_mark_node)
1986 item = *length = error_mark_node;
1990 item = ffecom_arrayref_ (item, expr, 1);
1994 case FFEBLD_opSUBSTR:
1998 ffebld thing = ffebld_right (expr);
2001 const char *char_name;
2005 assert (ffebld_op (thing) == FFEBLD_opITEM);
2006 start = ffebld_head (thing);
2007 thing = ffebld_trail (thing);
2008 assert (ffebld_trail (thing) == NULL);
2009 end = ffebld_head (thing);
2011 /* Determine name for pretty-printing range-check errors. */
2012 for (left_symter = ffebld_left (expr);
2013 left_symter && ffebld_op (left_symter) == FFEBLD_opARRAYREF;
2014 left_symter = ffebld_left (left_symter))
2016 if (ffebld_op (left_symter) == FFEBLD_opSYMTER)
2017 char_name = ffesymbol_text (ffebld_symter (left_symter));
2019 char_name = "[expr?]";
2021 ffecom_char_args_ (&item, length, ffebld_left (expr));
2023 if (item == error_mark_node || *length == error_mark_node)
2025 item = *length = error_mark_node;
2029 array = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item)));
2031 /* ~~~~Handle INTEGER*8 start/end, a la FFEBLD_opARRAYREF. */
2039 end_tree = ffecom_expr (end);
2040 if (flag_bounds_check)
2041 end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0,
2043 end_tree = convert (ffecom_f2c_ftnlen_type_node,
2046 if (end_tree == error_mark_node)
2048 item = *length = error_mark_node;
2057 start_tree = ffecom_expr (start);
2058 if (flag_bounds_check)
2059 start_tree = ffecom_subscript_check_ (array, start_tree, 0, 0,
2061 start_tree = convert (ffecom_f2c_ftnlen_type_node,
2064 if (start_tree == error_mark_node)
2066 item = *length = error_mark_node;
2070 start_tree = ffecom_save_tree (start_tree);
2072 item = ffecom_2 (PLUS_EXPR, TREE_TYPE (item),
2074 ffecom_2 (MINUS_EXPR,
2075 TREE_TYPE (start_tree),
2077 ffecom_f2c_ftnlen_one_node));
2081 *length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
2082 ffecom_f2c_ftnlen_one_node,
2083 ffecom_2 (MINUS_EXPR,
2084 ffecom_f2c_ftnlen_type_node,
2090 end_tree = ffecom_expr (end);
2091 if (flag_bounds_check)
2092 end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0,
2094 end_tree = convert (ffecom_f2c_ftnlen_type_node,
2097 if (end_tree == error_mark_node)
2099 item = *length = error_mark_node;
2103 *length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
2104 ffecom_f2c_ftnlen_one_node,
2105 ffecom_2 (MINUS_EXPR,
2106 ffecom_f2c_ftnlen_type_node,
2107 end_tree, start_tree));
2113 case FFEBLD_opFUNCREF:
2115 ffesymbol s = ffebld_symter (ffebld_left (expr));
2118 ffetargetCharacterSize size = ffeinfo_size (ffebld_info (expr));
2121 if (size == FFETARGET_charactersizeNONE)
2122 /* ~~Kludge alert! This should someday be fixed. */
2125 *length = build_int_2 (size, 0);
2126 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
2128 if (ffeinfo_where (ffebld_info (ffebld_left (expr)))
2129 == FFEINFO_whereINTRINSIC)
2133 /* Invocation of an intrinsic returning CHARACTER*1. */
2134 item = ffecom_expr_intrinsic_ (expr, NULL_TREE,
2138 ix = ffeintrin_gfrt_direct (ffebld_symter_implementation (ffebld_left (expr)));
2139 assert (ix != FFECOM_gfrt);
2140 item = ffecom_gfrt_tree_ (ix);
2145 item = ffesymbol_hook (s).decl_tree;
2146 if (item == NULL_TREE)
2148 s = ffecom_sym_transform_ (s);
2149 item = ffesymbol_hook (s).decl_tree;
2151 if (item == error_mark_node)
2153 item = *length = error_mark_node;
2157 if (!ffesymbol_hook (s).addr)
2158 item = ffecom_1_fn (item);
2160 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
2213 tempvar = ffebld_nonter_hook (expr);
2215 tempvar = ffecom_1 (ADDR_EXPR,
2216 build_pointer_type (TREE_TYPE (tempvar)),
2219 newlen = build_int_2 (ffebld_size (expr), 0);
2220 TREE_TYPE (newlen) = ffecom_f2c_ftnlen_type_node;
2222 args = build_tree_list (NULL_TREE, tempvar);
2223 TREE_CHAIN (args) = build_tree_list (NULL_TREE, item);
2224 TREE_CHAIN (TREE_CHAIN (args)) = build_tree_list (NULL_TREE, newlen);
2225 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (args)))
2226 = build_tree_list (NULL_TREE, *length);
2228 item = ffecom_call_gfrt (FFECOM_gfrtCOPY, args, NULL_TREE);
2229 TREE_SIDE_EFFECTS (item) = 1;
2230 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), fold (item),
2235 { /* Just truncate the length. */
2236 *length = build_int_2 (ffebld_size (expr), 0);
2237 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
2242 assert ("bad op for single char arg expr" == NULL);
2250 /* Check the size of the type to be sure it doesn't overflow the
2251 "portable" capacities of the compiler back end. `dummy' types
2252 can generally overflow the normal sizes as long as the computations
2253 themselves don't overflow. A particular target of the back end
2254 must still enforce its size requirements, though, and the back
2255 end takes care of this in stor-layout.c. */
2258 ffecom_check_size_overflow_ (ffesymbol s, tree type, bool dummy)
2260 if (TREE_CODE (type) == ERROR_MARK)
2263 if (TYPE_SIZE (type) == NULL_TREE)
2266 if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
2269 /* An array is too large if size is negative or the type_size overflows
2270 or its "upper half" is larger than 3 (which would make the signed
2271 byte size and offset computations overflow). */
2273 if ((tree_int_cst_sgn (TYPE_SIZE (type)) < 0)
2274 || (!dummy && (TREE_INT_CST_HIGH (TYPE_SIZE (type)) > 3
2275 || TREE_OVERFLOW (TYPE_SIZE (type)))))
2277 ffebad_start (FFEBAD_ARRAY_LARGE);
2278 ffebad_string (ffesymbol_text (s));
2279 ffebad_here (0, ffesymbol_where_line (s), ffesymbol_where_column (s));
2282 return error_mark_node;
2288 /* Builds a length argument (PARM_DECL). Also wraps type in an array type
2289 where the dimension info is (1:size) where <size> is ffesymbol_size(s) if
2290 known, length_arg if not known (FFETARGET_charactersizeNONE). */
2293 ffecom_char_enhance_arg_ (tree *xtype, ffesymbol s)
2295 ffetargetCharacterSize sz = ffesymbol_size (s);
2300 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT)
2301 tlen = NULL_TREE; /* A statement function, no length passed. */
2304 if (ffesymbol_where (s) == FFEINFO_whereDUMMY)
2305 tlen = ffecom_get_invented_identifier ("__g77_length_%s",
2306 ffesymbol_text (s));
2308 tlen = ffecom_get_invented_identifier ("__g77_%s", "length");
2309 tlen = build_decl (PARM_DECL, tlen, ffecom_f2c_ftnlen_type_node);
2310 DECL_ARTIFICIAL (tlen) = 1;
2313 if (sz == FFETARGET_charactersizeNONE)
2315 assert (tlen != NULL_TREE);
2316 highval = variable_size (tlen);
2320 highval = build_int_2 (sz, 0);
2321 TREE_TYPE (highval) = ffecom_f2c_ftnlen_type_node;
2324 type = build_array_type (type,
2325 build_range_type (ffecom_f2c_ftnlen_type_node,
2326 ffecom_f2c_ftnlen_one_node,
2333 /* ffecom_concat_list_gather_ -- Gather list of concatenated string exprs
2335 ffecomConcatList_ catlist;
2336 ffebld expr; // expr of CHARACTER basictype.
2337 ffetargetCharacterSize max; // max chars to gather or _...NONE if no max
2338 catlist = ffecom_concat_list_gather_(catlist,expr,max);
2340 Scans expr for character subexpressions, updates and returns catlist
2343 static ffecomConcatList_
2344 ffecom_concat_list_gather_ (ffecomConcatList_ catlist, ffebld expr,
2345 ffetargetCharacterSize max)
2347 ffetargetCharacterSize sz;
2354 if ((max != FFETARGET_charactersizeNONE) && (catlist.minlen >= max))
2355 return catlist; /* Don't append any more items. */
2357 switch (ffebld_op (expr))
2359 case FFEBLD_opCONTER:
2360 case FFEBLD_opSYMTER:
2361 case FFEBLD_opARRAYREF:
2362 case FFEBLD_opFUNCREF:
2363 case FFEBLD_opSUBSTR:
2364 case FFEBLD_opCONVERT: /* Callers should strip this off beforehand
2365 if they don't need to preserve it. */
2366 if (catlist.count == catlist.max)
2367 { /* Make a (larger) list. */
2371 newmax = (catlist.max == 0) ? 8 : catlist.max * 2;
2372 newx = malloc_new_ks (malloc_pool_image (), "catlist",
2373 newmax * sizeof (newx[0]));
2374 if (catlist.max != 0)
2376 memcpy (newx, catlist.exprs, catlist.max * sizeof (newx[0]));
2377 malloc_kill_ks (malloc_pool_image (), catlist.exprs,
2378 catlist.max * sizeof (newx[0]));
2380 catlist.max = newmax;
2381 catlist.exprs = newx;
2383 if ((sz = ffebld_size_known (expr)) != FFETARGET_charactersizeNONE)
2384 catlist.minlen += sz;
2386 ++catlist.minlen; /* Not true for F90; can be 0 length. */
2387 if ((sz = ffebld_size_max (expr)) == FFETARGET_charactersizeNONE)
2388 catlist.maxlen = sz;
2390 catlist.maxlen += sz;
2391 if ((max != FFETARGET_charactersizeNONE) && (catlist.minlen > max))
2392 { /* This item overlaps (or is beyond) the end
2393 of the destination. */
2394 switch (ffebld_op (expr))
2396 case FFEBLD_opCONTER:
2397 case FFEBLD_opSYMTER:
2398 case FFEBLD_opARRAYREF:
2399 case FFEBLD_opFUNCREF:
2400 case FFEBLD_opSUBSTR:
2401 /* ~~Do useful truncations here. */
2405 assert ("op changed or inconsistent switches!" == NULL);
2409 catlist.exprs[catlist.count++] = expr;
2412 case FFEBLD_opPAREN:
2413 expr = ffebld_left (expr);
2414 goto recurse; /* :::::::::::::::::::: */
2416 case FFEBLD_opCONCATENATE:
2417 catlist = ffecom_concat_list_gather_ (catlist, ffebld_left (expr), max);
2418 expr = ffebld_right (expr);
2419 goto recurse; /* :::::::::::::::::::: */
2421 #if 0 /* Breaks passing small actual arg to larger
2422 dummy arg of sfunc */
2423 case FFEBLD_opCONVERT:
2424 expr = ffebld_left (expr);
2426 ffetargetCharacterSize cmax;
2428 cmax = catlist.len + ffebld_size_known (expr);
2430 if ((max == FFETARGET_charactersizeNONE) || (max > cmax))
2433 goto recurse; /* :::::::::::::::::::: */
2440 assert ("bad op in _gather_" == NULL);
2445 /* ffecom_concat_list_kill_ -- Kill list of concatenated string exprs
2447 ffecomConcatList_ catlist;
2448 ffecom_concat_list_kill_(catlist);
2450 Anything allocated within the list info is deallocated. */
2453 ffecom_concat_list_kill_ (ffecomConcatList_ catlist)
2455 if (catlist.max != 0)
2456 malloc_kill_ks (malloc_pool_image (), catlist.exprs,
2457 catlist.max * sizeof (catlist.exprs[0]));
2460 /* Make list of concatenated string exprs.
2462 Returns a flattened list of concatenated subexpressions given a
2463 tree of such expressions. */
2465 static ffecomConcatList_
2466 ffecom_concat_list_new_ (ffebld expr, ffetargetCharacterSize max)
2468 ffecomConcatList_ catlist;
2470 catlist.maxlen = catlist.minlen = catlist.max = catlist.count = 0;
2471 return ffecom_concat_list_gather_ (catlist, expr, max);
2474 /* Provide some kind of useful info on member of aggregate area,
2475 since current g77/gcc technology does not provide debug info
2476 on these members. */
2479 ffecom_debug_kludge_ (tree aggr, const char *aggr_type, ffesymbol member,
2480 tree member_type UNUSED, ffetargetOffset offset)
2490 for (type_id = member_type;
2491 TREE_CODE (type_id) != IDENTIFIER_NODE;
2494 switch (TREE_CODE (type_id))
2498 type_id = TYPE_NAME (type_id);
2503 type_id = TREE_TYPE (type_id);
2507 assert ("no IDENTIFIER_NODE for type!" == NULL);
2508 type_id = error_mark_node;
2514 if (ffecom_transform_only_dummies_
2515 || !ffe_is_debug_kludge ())
2516 return; /* Can't do this yet, maybe later. */
2519 + strlen (aggr_type)
2520 + IDENTIFIER_LENGTH (DECL_NAME (aggr));
2522 + IDENTIFIER_LENGTH (type_id);
2525 if (((size_t) len) >= ARRAY_SIZE (space))
2526 buff = malloc_new_ks (malloc_pool_image (), "debug_kludge", len + 1);
2530 sprintf (&buff[0], "At (%s) `%s' plus %ld bytes",
2532 IDENTIFIER_POINTER (DECL_NAME (aggr)),
2535 value = build_string (len, buff);
2537 = build_type_variant (build_array_type (char_type_node,
2541 build_int_2 (strlen (buff), 0))),
2543 decl = build_decl (VAR_DECL,
2544 ffecom_get_identifier_ (ffesymbol_text (member)),
2546 TREE_CONSTANT (decl) = 1;
2547 TREE_STATIC (decl) = 1;
2548 DECL_INITIAL (decl) = error_mark_node;
2549 DECL_IN_SYSTEM_HEADER (decl) = 1; /* Don't let -Wunused complain. */
2550 decl = start_decl (decl, FALSE);
2551 finish_decl (decl, value, FALSE);
2553 if (buff != &space[0])
2554 malloc_kill_ks (malloc_pool_image (), buff, len + 1);
2557 /* ffecom_do_entry_ -- Do compilation of a particular entrypoint
2559 ffesymbol fn; // the SUBROUTINE, FUNCTION, or ENTRY symbol itself
2560 int i; // entry# for this entrypoint (used by master fn)
2561 ffecom_do_entrypoint_(s,i);
2563 Makes a public entry point that calls our private master fn (already
2567 ffecom_do_entry_ (ffesymbol fn, int entrynum)
2570 tree type; /* Type of function. */
2571 tree multi_retval; /* Var holding return value (union). */
2572 tree result; /* Var holding result. */
2573 ffeinfoBasictype bt;
2577 bool charfunc; /* All entry points return same type
2579 bool cmplxfunc; /* Use f2c way of returning COMPLEX. */
2580 bool multi; /* Master fn has multiple return types. */
2581 bool altreturning = FALSE; /* This entry point has alternate
2583 location_t old_loc = input_location;
2585 input_filename = ffesymbol_where_filename (fn);
2586 input_line = ffesymbol_where_filelinenum (fn);
2588 ffecom_doing_entry_ = TRUE; /* Don't bother with array dimensions. */
2590 switch (ffecom_primary_entry_kind_)
2592 case FFEINFO_kindFUNCTION:
2594 /* Determine actual return type for function. */
2596 gt = FFEGLOBAL_typeFUNC;
2597 bt = ffesymbol_basictype (fn);
2598 kt = ffesymbol_kindtype (fn);
2599 if (bt == FFEINFO_basictypeNONE)
2601 ffeimplic_establish_symbol (fn);
2602 if (ffesymbol_funcresult (fn) != NULL)
2603 ffeimplic_establish_symbol (ffesymbol_funcresult (fn));
2604 bt = ffesymbol_basictype (fn);
2605 kt = ffesymbol_kindtype (fn);
2608 if (bt == FFEINFO_basictypeCHARACTER)
2609 charfunc = TRUE, cmplxfunc = FALSE;
2610 else if ((bt == FFEINFO_basictypeCOMPLEX)
2611 && ffesymbol_is_f2c (fn))
2612 charfunc = FALSE, cmplxfunc = TRUE;
2614 charfunc = cmplxfunc = FALSE;
2617 type = ffecom_tree_fun_type_void;
2618 else if (ffesymbol_is_f2c (fn))
2619 type = ffecom_tree_fun_type[bt][kt];
2621 type = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
2623 if ((type == NULL_TREE)
2624 || (TREE_TYPE (type) == NULL_TREE))
2625 type = ffecom_tree_fun_type_void; /* _sym_exec_transition. */
2627 multi = (ffecom_master_bt_ == FFEINFO_basictypeNONE);
2630 case FFEINFO_kindSUBROUTINE:
2631 gt = FFEGLOBAL_typeSUBR;
2632 bt = FFEINFO_basictypeNONE;
2633 kt = FFEINFO_kindtypeNONE;
2634 if (ffecom_is_altreturning_)
2635 { /* Am _I_ altreturning? */
2636 for (item = ffesymbol_dummyargs (fn);
2638 item = ffebld_trail (item))
2640 if (ffebld_op (ffebld_head (item)) == FFEBLD_opSTAR)
2642 altreturning = TRUE;
2647 type = ffecom_tree_subr_type;
2649 type = ffecom_tree_fun_type_void;
2652 type = ffecom_tree_fun_type_void;
2659 assert ("say what??" == NULL);
2661 case FFEINFO_kindANY:
2662 gt = FFEGLOBAL_typeANY;
2663 bt = FFEINFO_basictypeNONE;
2664 kt = FFEINFO_kindtypeNONE;
2665 type = error_mark_node;
2672 /* build_decl uses the current lineno and input_filename to set the decl
2673 source info. So, I've putzed with ffestd and ffeste code to update that
2674 source info to point to the appropriate statement just before calling
2675 ffecom_do_entrypoint (which calls this fn). */
2677 start_function (ffecom_get_external_identifier_ (fn),
2679 0, /* nested/inline */
2680 1); /* TREE_PUBLIC */
2682 if (((g = ffesymbol_global (fn)) != NULL)
2683 && ((ffeglobal_type (g) == gt)
2684 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
2686 ffeglobal_set_hook (g, current_function_decl);
2689 /* Reset args in master arg list so they get retransitioned. */
2691 for (item = ffecom_master_arglist_;
2693 item = ffebld_trail (item))
2698 arg = ffebld_head (item);
2699 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2700 continue; /* Alternate return or some such thing. */
2701 s = ffebld_symter (arg);
2702 ffesymbol_hook (s).decl_tree = NULL_TREE;
2703 ffesymbol_hook (s).length_tree = NULL_TREE;
2706 /* Build dummy arg list for this entry point. */
2708 if (charfunc || cmplxfunc)
2709 { /* Prepend arg for where result goes. */
2714 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
2716 type = ffecom_tree_type[FFEINFO_basictypeCOMPLEX][kt];
2718 result = ffecom_get_invented_identifier ("__g77_%s", "result");
2720 /* Make length arg _and_ enhance type info for CHAR arg itself. */
2723 length = ffecom_char_enhance_arg_ (&type, fn);
2725 length = NULL_TREE; /* Not ref'd if !charfunc. */
2727 type = build_pointer_type (type);
2728 result = build_decl (PARM_DECL, result, type);
2730 push_parm_decl (result);
2731 ffecom_func_result_ = result;
2735 push_parm_decl (length);
2736 ffecom_func_length_ = length;
2740 result = DECL_RESULT (current_function_decl);
2742 ffecom_push_dummy_decls_ (ffesymbol_dummyargs (fn), FALSE);
2744 store_parm_decls (0);
2746 ffecom_start_compstmt ();
2747 /* Disallow temp vars at this level. */
2748 current_binding_level->prep_state = 2;
2750 /* Make local var to hold return type for multi-type master fn. */
2754 multi_retval = ffecom_get_invented_identifier ("__g77_%s",
2756 multi_retval = build_decl (VAR_DECL, multi_retval,
2757 ffecom_multi_type_node_);
2758 multi_retval = start_decl (multi_retval, FALSE);
2759 finish_decl (multi_retval, NULL_TREE, FALSE);
2762 multi_retval = NULL_TREE; /* Not actually ref'd if !multi. */
2764 /* Here we emit the actual code for the entry point. */
2770 tree arglist = NULL_TREE;
2771 tree *plist = &arglist;
2777 /* Prepare actual arg list based on master arg list. */
2779 for (list = ffecom_master_arglist_;
2781 list = ffebld_trail (list))
2783 arg = ffebld_head (list);
2784 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2786 s = ffebld_symter (arg);
2787 if (ffesymbol_hook (s).decl_tree == NULL_TREE
2788 || ffesymbol_hook (s).decl_tree == error_mark_node)
2789 actarg = null_pointer_node; /* We don't have this arg. */
2791 actarg = ffesymbol_hook (s).decl_tree;
2792 *plist = build_tree_list (NULL_TREE, actarg);
2793 plist = &TREE_CHAIN (*plist);
2796 /* This code appends the length arguments for character
2797 variables/arrays. */
2799 for (list = ffecom_master_arglist_;
2801 list = ffebld_trail (list))
2803 arg = ffebld_head (list);
2804 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2806 s = ffebld_symter (arg);
2807 if (ffesymbol_basictype (s) != FFEINFO_basictypeCHARACTER)
2808 continue; /* Only looking for CHARACTER arguments. */
2809 if (ffesymbol_kind (s) != FFEINFO_kindENTITY)
2810 continue; /* Only looking for variables and arrays. */
2811 if (ffesymbol_hook (s).length_tree == NULL_TREE
2812 || ffesymbol_hook (s).length_tree == error_mark_node)
2813 actarg = ffecom_f2c_ftnlen_zero_node; /* We don't have this arg. */
2815 actarg = ffesymbol_hook (s).length_tree;
2816 *plist = build_tree_list (NULL_TREE, actarg);
2817 plist = &TREE_CHAIN (*plist);
2820 /* Prepend character-value return info to actual arg list. */
2824 prepend = build_tree_list (NULL_TREE, ffecom_func_result_);
2825 TREE_CHAIN (prepend)
2826 = build_tree_list (NULL_TREE, ffecom_func_length_);
2827 TREE_CHAIN (TREE_CHAIN (prepend)) = arglist;
2831 /* Prepend multi-type return value to actual arg list. */
2836 = build_tree_list (NULL_TREE,
2837 ffecom_1 (ADDR_EXPR,
2838 build_pointer_type (TREE_TYPE (multi_retval)),
2840 TREE_CHAIN (prepend) = arglist;
2844 /* Prepend my entry-point number to the actual arg list. */
2846 prepend = build_tree_list (NULL_TREE, build_int_2 (entrynum, 0));
2847 TREE_CHAIN (prepend) = arglist;
2850 /* Build the call to the master function. */
2852 master_fn = ffecom_1_fn (ffecom_previous_function_decl_);
2853 call = ffecom_3s (CALL_EXPR,
2854 TREE_TYPE (TREE_TYPE (TREE_TYPE (master_fn))),
2855 master_fn, arglist, NULL_TREE);
2857 /* Decide whether the master function is a function or subroutine, and
2858 handle the return value for my entry point. */
2860 if (charfunc || ((ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE)
2863 expand_expr_stmt (call);
2864 expand_null_return ();
2866 else if (multi && cmplxfunc)
2868 expand_expr_stmt (call);
2870 = ffecom_1 (INDIRECT_REF,
2871 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result))),
2873 result = ffecom_modify (NULL_TREE, result,
2874 ffecom_2 (COMPONENT_REF, TREE_TYPE (result),
2876 ffecom_multi_fields_[bt][kt]));
2877 expand_expr_stmt (result);
2878 expand_null_return ();
2882 expand_expr_stmt (call);
2884 = ffecom_modify (NULL_TREE, result,
2885 convert (TREE_TYPE (result),
2886 ffecom_2 (COMPONENT_REF,
2887 ffecom_tree_type[bt][kt],
2889 ffecom_multi_fields_[bt][kt])));
2890 expand_return (result);
2895 = ffecom_1 (INDIRECT_REF,
2896 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result))),
2898 result = ffecom_modify (NULL_TREE, result, call);
2899 expand_expr_stmt (result);
2900 expand_null_return ();
2904 result = ffecom_modify (NULL_TREE,
2906 convert (TREE_TYPE (result),
2908 expand_return (result);
2912 ffecom_end_compstmt ();
2914 finish_function (0);
2916 input_location = old_loc;
2918 ffecom_doing_entry_ = FALSE;
2921 /* Transform expr into gcc tree with possible destination
2923 Recursive descent on expr while making corresponding tree nodes and
2924 attaching type info and such. If destination supplied and compatible
2925 with temporary that would be made in certain cases, temporary isn't
2926 made, destination used instead, and dest_used flag set TRUE. */
2929 ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest, bool *dest_used,
2930 bool assignp, bool widenp)
2935 ffeinfoBasictype bt;
2938 tree dt; /* decl_tree for an ffesymbol. */
2939 tree tree_type, tree_type_x;
2942 enum tree_code code;
2944 assert (expr != NULL);
2946 if (dest_used != NULL)
2949 bt = ffeinfo_basictype (ffebld_info (expr));
2950 kt = ffeinfo_kindtype (ffebld_info (expr));
2951 tree_type = ffecom_tree_type[bt][kt];
2953 /* Widen integral arithmetic as desired while preserving signedness. */
2954 tree_type_x = NULL_TREE;
2955 if (widenp && tree_type
2956 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
2957 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
2958 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
2960 switch (ffebld_op (expr))
2962 case FFEBLD_opACCTER:
2965 ffebit bits = ffebld_accter_bits (expr);
2966 ffetargetOffset source_offset = 0;
2967 ffetargetOffset dest_offset = ffebld_accter_pad (expr);
2970 assert (dest_offset == 0
2971 || (bt == FFEINFO_basictypeCHARACTER
2972 && kt == FFEINFO_kindtypeCHARACTER1));
2977 ffebldConstantUnion cu;
2980 ffebldConstantArray ca = ffebld_accter (expr);
2982 ffebit_test (bits, source_offset, &value, &length);
2988 for (i = 0; i < length; ++i)
2990 cu = ffebld_constantarray_get (ca, bt, kt,
2993 t = ffecom_constantunion (&cu, bt, kt, tree_type);
2996 && dest_offset != 0)
2997 purpose = build_int_2 (dest_offset, 0);
2999 purpose = NULL_TREE;
3001 if (list == NULL_TREE)
3002 list = item = build_tree_list (purpose, t);
3005 TREE_CHAIN (item) = build_tree_list (purpose, t);
3006 item = TREE_CHAIN (item);
3010 source_offset += length;
3011 dest_offset += length;
3015 item = build_int_2 ((ffebld_accter_size (expr)
3016 + ffebld_accter_pad (expr)) - 1, 0);
3017 ffebit_kill (ffebld_accter_bits (expr));
3018 TREE_TYPE (item) = ffecom_integer_type_node;
3022 build_range_type (ffecom_integer_type_node,
3023 ffecom_integer_zero_node,
3025 list = build_constructor (item, list);
3026 TREE_CONSTANT (list) = 1;
3027 TREE_STATIC (list) = 1;
3030 case FFEBLD_opARRTER:
3035 if (ffebld_arrter_pad (expr) == 0)
3039 assert (bt == FFEINFO_basictypeCHARACTER
3040 && kt == FFEINFO_kindtypeCHARACTER1);
3042 /* Becomes PURPOSE first time through loop. */
3043 item = build_int_2 (ffebld_arrter_pad (expr), 0);
3046 for (i = 0; i < ffebld_arrter_size (expr); ++i)
3048 ffebldConstantUnion cu
3049 = ffebld_constantarray_get (ffebld_arrter (expr), bt, kt, i);
3051 t = ffecom_constantunion (&cu, bt, kt, tree_type);
3053 if (list == NULL_TREE)
3054 /* Assume item is PURPOSE first time through loop. */
3055 list = item = build_tree_list (item, t);
3058 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
3059 item = TREE_CHAIN (item);
3064 item = build_int_2 ((ffebld_arrter_size (expr)
3065 + ffebld_arrter_pad (expr)) - 1, 0);
3066 TREE_TYPE (item) = ffecom_integer_type_node;
3070 build_range_type (ffecom_integer_type_node,
3071 ffecom_integer_zero_node,
3073 list = build_constructor (item, list);
3074 TREE_CONSTANT (list) = 1;
3075 TREE_STATIC (list) = 1;
3078 case FFEBLD_opCONTER:
3079 assert (ffebld_conter_pad (expr) == 0);
3081 = ffecom_constantunion (&ffebld_constant_union (ffebld_conter (expr)),
3085 case FFEBLD_opSYMTER:
3086 if ((ffebld_symter_generic (expr) != FFEINTRIN_genNONE)
3087 || (ffebld_symter_specific (expr) != FFEINTRIN_specNONE))
3088 return ffecom_ptr_to_expr (expr); /* Same as %REF(intrinsic). */
3089 s = ffebld_symter (expr);
3090 t = ffesymbol_hook (s).decl_tree;
3093 { /* ASSIGN'ed-label expr. */
3094 if (ffe_is_ugly_assign ())
3096 /* User explicitly wants ASSIGN'ed variables to be at the same
3097 memory address as the variables when used in non-ASSIGN
3098 contexts. That can make old, arcane, non-standard code
3099 work, but don't try to do it when a pointer wouldn't fit
3100 in the normal variable (take other approach, and warn,
3105 s = ffecom_sym_transform_ (s);
3106 t = ffesymbol_hook (s).decl_tree;
3107 assert (t != NULL_TREE);
3110 if (t == error_mark_node)
3113 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (t)))
3114 >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
3116 if (ffesymbol_hook (s).addr)
3117 t = ffecom_1 (INDIRECT_REF,
3118 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), t);
3122 if (ffesymbol_hook (s).assign_tree == NULL_TREE)
3124 /* xgettext:no-c-format */
3125 ffebad_start_msg ("ASSIGN'ed label cannot fit into `%A' at %0 -- using wider sibling",
3126 FFEBAD_severityWARNING);
3127 ffebad_string (ffesymbol_text (s));
3128 ffebad_here (0, ffesymbol_where_line (s),
3129 ffesymbol_where_column (s));
3134 /* Don't use the normal variable's tree for ASSIGN, though mark
3135 it as in the system header (housekeeping). Use an explicit,
3136 specially created sibling that is known to be wide enough
3137 to hold pointers to labels. */
3140 && TREE_CODE (t) == VAR_DECL)
3141 DECL_IN_SYSTEM_HEADER (t) = 1; /* Don't let -Wunused complain. */
3143 t = ffesymbol_hook (s).assign_tree;
3146 s = ffecom_sym_transform_assign_ (s);
3147 t = ffesymbol_hook (s).assign_tree;
3148 assert (t != NULL_TREE);
3155 s = ffecom_sym_transform_ (s);
3156 t = ffesymbol_hook (s).decl_tree;
3157 assert (t != NULL_TREE);
3159 if (ffesymbol_hook (s).addr)
3160 t = ffecom_1 (INDIRECT_REF,
3161 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), t);
3165 case FFEBLD_opARRAYREF:
3166 return ffecom_arrayref_ (NULL_TREE, expr, 0);
3168 case FFEBLD_opUPLUS:
3169 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3170 return ffecom_1 (NOP_EXPR, tree_type, left);
3172 case FFEBLD_opPAREN:
3173 /* ~~~Make sure Fortran rules respected here */
3174 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3175 return ffecom_1 (NOP_EXPR, tree_type, left);
3177 case FFEBLD_opUMINUS:
3178 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3181 tree_type = tree_type_x;
3182 left = convert (tree_type, left);
3184 return ffecom_1 (NEGATE_EXPR, tree_type, left);
3187 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3188 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
3191 tree_type = tree_type_x;
3192 left = convert (tree_type, left);
3193 right = convert (tree_type, right);
3195 return ffecom_2 (PLUS_EXPR, tree_type, left, right);
3197 case FFEBLD_opSUBTRACT:
3198 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3199 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
3202 tree_type = tree_type_x;
3203 left = convert (tree_type, left);
3204 right = convert (tree_type, right);
3206 return ffecom_2 (MINUS_EXPR, tree_type, left, right);
3208 case FFEBLD_opMULTIPLY:
3209 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3210 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
3213 tree_type = tree_type_x;
3214 left = convert (tree_type, left);
3215 right = convert (tree_type, right);
3217 return ffecom_2 (MULT_EXPR, tree_type, left, right);
3219 case FFEBLD_opDIVIDE:
3220 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3221 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
3224 tree_type = tree_type_x;
3225 left = convert (tree_type, left);
3226 right = convert (tree_type, right);
3228 return ffecom_tree_divide_ (tree_type, left, right,
3229 dest_tree, dest, dest_used,
3230 ffebld_nonter_hook (expr));
3232 case FFEBLD_opPOWER:
3234 ffebld left = ffebld_left (expr);
3235 ffebld right = ffebld_right (expr);
3237 ffeinfoKindtype rtkt;
3238 ffeinfoKindtype ltkt;
3241 switch (ffeinfo_basictype (ffebld_info (right)))
3244 case FFEINFO_basictypeINTEGER:
3247 item = ffecom_expr_power_integer_ (expr);
3248 if (item != NULL_TREE)
3252 rtkt = FFEINFO_kindtypeINTEGER1;
3253 switch (ffeinfo_basictype (ffebld_info (left)))
3255 case FFEINFO_basictypeINTEGER:
3256 if ((ffeinfo_kindtype (ffebld_info (left))
3257 == FFEINFO_kindtypeINTEGER4)
3258 || (ffeinfo_kindtype (ffebld_info (right))
3259 == FFEINFO_kindtypeINTEGER4))
3261 code = FFECOM_gfrtPOW_QQ;
3262 ltkt = FFEINFO_kindtypeINTEGER4;
3263 rtkt = FFEINFO_kindtypeINTEGER4;
3267 code = FFECOM_gfrtPOW_II;
3268 ltkt = FFEINFO_kindtypeINTEGER1;
3272 case FFEINFO_basictypeREAL:
3273 if (ffeinfo_kindtype (ffebld_info (left))
3274 == FFEINFO_kindtypeREAL1)
3276 code = FFECOM_gfrtPOW_RI;
3277 ltkt = FFEINFO_kindtypeREAL1;
3281 code = FFECOM_gfrtPOW_DI;
3282 ltkt = FFEINFO_kindtypeREAL2;
3286 case FFEINFO_basictypeCOMPLEX:
3287 if (ffeinfo_kindtype (ffebld_info (left))
3288 == FFEINFO_kindtypeREAL1)
3290 code = FFECOM_gfrtPOW_CI; /* Overlapping result okay. */
3291 ltkt = FFEINFO_kindtypeREAL1;
3295 code = FFECOM_gfrtPOW_ZI; /* Overlapping result okay. */
3296 ltkt = FFEINFO_kindtypeREAL2;
3301 assert ("bad pow_*i" == NULL);
3302 code = FFECOM_gfrtPOW_CI; /* Overlapping result okay. */
3303 ltkt = FFEINFO_kindtypeREAL1;
3306 if (ffeinfo_kindtype (ffebld_info (left)) != ltkt)
3307 left = ffeexpr_convert (left, NULL, NULL,
3308 ffeinfo_basictype (ffebld_info (left)),
3310 FFETARGET_charactersizeNONE,
3311 FFEEXPR_contextLET);
3312 if (ffeinfo_kindtype (ffebld_info (right)) != rtkt)
3313 right = ffeexpr_convert (right, NULL, NULL,
3314 FFEINFO_basictypeINTEGER,
3316 FFETARGET_charactersizeNONE,
3317 FFEEXPR_contextLET);
3320 case FFEINFO_basictypeREAL:
3321 if (ffeinfo_kindtype (ffebld_info (left)) == FFEINFO_kindtypeREAL1)
3322 left = ffeexpr_convert (left, NULL, NULL, FFEINFO_basictypeREAL,
3323 FFEINFO_kindtypeREALDOUBLE, 0,
3324 FFETARGET_charactersizeNONE,
3325 FFEEXPR_contextLET);
3326 if (ffeinfo_kindtype (ffebld_info (right))
3327 == FFEINFO_kindtypeREAL1)
3328 right = ffeexpr_convert (right, NULL, NULL,
3329 FFEINFO_basictypeREAL,
3330 FFEINFO_kindtypeREALDOUBLE, 0,
3331 FFETARGET_charactersizeNONE,
3332 FFEEXPR_contextLET);
3333 /* We used to call FFECOM_gfrtPOW_DD here,
3334 which passes arguments by reference. */
3335 code = FFECOM_gfrtL_POW;
3336 /* Pass arguments by value. */
3340 case FFEINFO_basictypeCOMPLEX:
3341 if (ffeinfo_kindtype (ffebld_info (left)) == FFEINFO_kindtypeREAL1)
3342 left = ffeexpr_convert (left, NULL, NULL,
3343 FFEINFO_basictypeCOMPLEX,
3344 FFEINFO_kindtypeREALDOUBLE, 0,
3345 FFETARGET_charactersizeNONE,
3346 FFEEXPR_contextLET);
3347 if (ffeinfo_kindtype (ffebld_info (right))
3348 == FFEINFO_kindtypeREAL1)
3349 right = ffeexpr_convert (right, NULL, NULL,
3350 FFEINFO_basictypeCOMPLEX,
3351 FFEINFO_kindtypeREALDOUBLE, 0,
3352 FFETARGET_charactersizeNONE,
3353 FFEEXPR_contextLET);
3354 code = FFECOM_gfrtPOW_ZZ; /* Overlapping result okay. */
3355 ref = TRUE; /* Pass arguments by reference. */
3359 assert ("bad pow_x*" == NULL);
3360 code = FFECOM_gfrtPOW_II;
3363 return ffecom_call_binop_ (ffecom_gfrt_tree_ (code),
3364 ffecom_gfrt_kindtype (code),
3365 (ffe_is_f2c_library ()
3366 && ffecom_gfrt_complex_[code]),
3367 tree_type, left, right,
3368 dest_tree, dest, dest_used,
3369 NULL_TREE, FALSE, ref,
3370 ffebld_nonter_hook (expr));
3376 case FFEINFO_basictypeLOGICAL:
3377 item = ffecom_truth_value_invert (ffecom_expr (ffebld_left (expr)));
3378 return convert (tree_type, item);
3380 case FFEINFO_basictypeINTEGER:
3381 return ffecom_1 (BIT_NOT_EXPR, tree_type,
3382 ffecom_expr (ffebld_left (expr)));
3385 assert ("NOT bad basictype" == NULL);
3387 case FFEINFO_basictypeANY:
3388 return error_mark_node;
3392 case FFEBLD_opFUNCREF:
3393 assert (ffeinfo_basictype (ffebld_info (expr))
3394 != FFEINFO_basictypeCHARACTER);
3396 case FFEBLD_opSUBRREF:
3397 if (ffeinfo_where (ffebld_info (ffebld_left (expr)))
3398 == FFEINFO_whereINTRINSIC)
3399 { /* Invocation of an intrinsic. */
3400 item = ffecom_expr_intrinsic_ (expr, dest_tree, dest,
3404 s = ffebld_symter (ffebld_left (expr));
3405 dt = ffesymbol_hook (s).decl_tree;
3406 if (dt == NULL_TREE)
3408 s = ffecom_sym_transform_ (s);
3409 dt = ffesymbol_hook (s).decl_tree;
3411 if (dt == error_mark_node)
3414 if (ffesymbol_hook (s).addr)
3417 item = ffecom_1_fn (dt);
3419 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT)
3420 args = ffecom_list_expr (ffebld_right (expr));
3422 args = ffecom_list_ptr_to_expr (ffebld_right (expr));
3424 if (args == error_mark_node)
3425 return error_mark_node;
3427 item = ffecom_call_ (item, kt,
3428 ffesymbol_is_f2c (s)
3429 && (bt == FFEINFO_basictypeCOMPLEX)
3430 && (ffesymbol_where (s)
3431 != FFEINFO_whereCONSTANT),
3434 dest_tree, dest, dest_used,
3435 error_mark_node, FALSE,
3436 ffebld_nonter_hook (expr));
3437 TREE_SIDE_EFFECTS (item) = 1;
3443 case FFEINFO_basictypeLOGICAL:
3445 = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
3446 ffecom_truth_value (ffecom_expr (ffebld_left (expr))),
3447 ffecom_truth_value (ffecom_expr (ffebld_right (expr))));
3448 return convert (tree_type, item);
3450 case FFEINFO_basictypeINTEGER:
3451 return ffecom_2 (BIT_AND_EXPR, tree_type,
3452 ffecom_expr (ffebld_left (expr)),
3453 ffecom_expr (ffebld_right (expr)));
3456 assert ("AND bad basictype" == NULL);
3458 case FFEINFO_basictypeANY:
3459 return error_mark_node;
3466 case FFEINFO_basictypeLOGICAL:
3468 = ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
3469 ffecom_truth_value (ffecom_expr (ffebld_left (expr))),
3470 ffecom_truth_value (ffecom_expr (ffebld_right (expr))));
3471 return convert (tree_type, item);
3473 case FFEINFO_basictypeINTEGER:
3474 return ffecom_2 (BIT_IOR_EXPR, tree_type,
3475 ffecom_expr (ffebld_left (expr)),
3476 ffecom_expr (ffebld_right (expr)));
3479 assert ("OR bad basictype" == NULL);
3481 case FFEINFO_basictypeANY:
3482 return error_mark_node;
3490 case FFEINFO_basictypeLOGICAL:
3492 = ffecom_2 (NE_EXPR, integer_type_node,
3493 ffecom_expr (ffebld_left (expr)),
3494 ffecom_expr (ffebld_right (expr)));
3495 return convert (tree_type, ffecom_truth_value (item));
3497 case FFEINFO_basictypeINTEGER:
3498 return ffecom_2 (BIT_XOR_EXPR, tree_type,
3499 ffecom_expr (ffebld_left (expr)),
3500 ffecom_expr (ffebld_right (expr)));
3503 assert ("XOR/NEQV bad basictype" == NULL);
3505 case FFEINFO_basictypeANY:
3506 return error_mark_node;
3513 case FFEINFO_basictypeLOGICAL:
3515 = ffecom_2 (EQ_EXPR, integer_type_node,
3516 ffecom_expr (ffebld_left (expr)),
3517 ffecom_expr (ffebld_right (expr)));
3518 return convert (tree_type, ffecom_truth_value (item));
3520 case FFEINFO_basictypeINTEGER:
3522 ffecom_1 (BIT_NOT_EXPR, tree_type,
3523 ffecom_2 (BIT_XOR_EXPR, tree_type,
3524 ffecom_expr (ffebld_left (expr)),
3525 ffecom_expr (ffebld_right (expr))));
3528 assert ("EQV bad basictype" == NULL);
3530 case FFEINFO_basictypeANY:
3531 return error_mark_node;
3535 case FFEBLD_opCONVERT:
3536 if (ffebld_op (ffebld_left (expr)) == FFEBLD_opANY)
3537 return error_mark_node;
3541 case FFEINFO_basictypeLOGICAL:
3542 case FFEINFO_basictypeINTEGER:
3543 case FFEINFO_basictypeREAL:
3544 return convert (tree_type, ffecom_expr (ffebld_left (expr)));
3546 case FFEINFO_basictypeCOMPLEX:
3547 switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr))))
3549 case FFEINFO_basictypeINTEGER:
3550 case FFEINFO_basictypeLOGICAL:
3551 case FFEINFO_basictypeREAL:
3552 item = ffecom_expr (ffebld_left (expr));
3553 if (item == error_mark_node)
3554 return error_mark_node;
3555 /* convert() takes care of converting to the subtype first,
3556 at least in gcc-2.7.2. */
3557 item = convert (tree_type, item);
3560 case FFEINFO_basictypeCOMPLEX:
3561 return convert (tree_type, ffecom_expr (ffebld_left (expr)));
3564 assert ("CONVERT COMPLEX bad basictype" == NULL);
3566 case FFEINFO_basictypeANY:
3567 return error_mark_node;
3572 assert ("CONVERT bad basictype" == NULL);
3574 case FFEINFO_basictypeANY:
3575 return error_mark_node;
3581 goto relational; /* :::::::::::::::::::: */
3585 goto relational; /* :::::::::::::::::::: */
3589 goto relational; /* :::::::::::::::::::: */
3593 goto relational; /* :::::::::::::::::::: */
3597 goto relational; /* :::::::::::::::::::: */
3602 relational: /* :::::::::::::::::::: */
3603 switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr))))
3605 case FFEINFO_basictypeLOGICAL:
3606 case FFEINFO_basictypeINTEGER:
3607 case FFEINFO_basictypeREAL:
3608 item = ffecom_2 (code, integer_type_node,
3609 ffecom_expr (ffebld_left (expr)),
3610 ffecom_expr (ffebld_right (expr)));
3611 return convert (tree_type, item);
3613 case FFEINFO_basictypeCOMPLEX:
3614 assert (code == EQ_EXPR || code == NE_EXPR);
3617 tree arg1 = ffecom_expr (ffebld_left (expr));
3618 tree arg2 = ffecom_expr (ffebld_right (expr));
3620 if (arg1 == error_mark_node || arg2 == error_mark_node)
3621 return error_mark_node;
3623 arg1 = ffecom_save_tree (arg1);
3624 arg2 = ffecom_save_tree (arg2);
3626 if (TREE_CODE (TREE_TYPE (arg1)) == COMPLEX_TYPE)
3628 real_type = TREE_TYPE (TREE_TYPE (arg1));
3629 assert (real_type == TREE_TYPE (TREE_TYPE (arg2)));
3633 real_type = TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg1)));
3634 assert (real_type == TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg2))));
3638 = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
3639 ffecom_2 (EQ_EXPR, integer_type_node,
3640 ffecom_1 (REALPART_EXPR, real_type, arg1),
3641 ffecom_1 (REALPART_EXPR, real_type, arg2)),
3642 ffecom_2 (EQ_EXPR, integer_type_node,
3643 ffecom_1 (IMAGPART_EXPR, real_type, arg1),
3644 ffecom_1 (IMAGPART_EXPR, real_type,
3646 if (code == EQ_EXPR)
3647 item = ffecom_truth_value (item);
3649 item = ffecom_truth_value_invert (item);
3650 return convert (tree_type, item);
3653 case FFEINFO_basictypeCHARACTER:
3655 ffebld left = ffebld_left (expr);
3656 ffebld right = ffebld_right (expr);
3662 /* f2c run-time functions do the implicit blank-padding for us,
3663 so we don't usually have to implement blank-padding ourselves.
3664 (The exception is when we pass an argument to a separately
3665 compiled statement function -- if we know the arg is not the
3666 same length as the dummy, we must truncate or extend it. If
3667 we "inline" statement functions, that necessity goes away as
3670 Strip off the CONVERT operators that blank-pad. (Truncation by
3671 CONVERT shouldn't happen here, but it can happen in
3674 while (ffebld_op (left) == FFEBLD_opCONVERT)
3675 left = ffebld_left (left);
3676 while (ffebld_op (right) == FFEBLD_opCONVERT)
3677 right = ffebld_left (right);
3679 left_tree = ffecom_arg_ptr_to_expr (left, &left_length);
3680 right_tree = ffecom_arg_ptr_to_expr (right, &right_length);
3682 if (left_tree == error_mark_node || left_length == error_mark_node
3683 || right_tree == error_mark_node
3684 || right_length == error_mark_node)
3685 return error_mark_node;
3687 if ((ffebld_size_known (left) == 1)
3688 && (ffebld_size_known (right) == 1))
3691 = ffecom_1 (INDIRECT_REF,
3692 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree))),
3695 = ffecom_1 (INDIRECT_REF,
3696 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree))),
3700 = ffecom_2 (code, integer_type_node,
3701 ffecom_2 (ARRAY_REF,
3702 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree))),
3705 ffecom_2 (ARRAY_REF,
3706 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree))),
3712 item = build_tree_list (NULL_TREE, left_tree);
3713 TREE_CHAIN (item) = build_tree_list (NULL_TREE, right_tree);
3714 TREE_CHAIN (TREE_CHAIN (item)) = build_tree_list (NULL_TREE,
3716 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item)))
3717 = build_tree_list (NULL_TREE, right_length);
3718 item = ffecom_call_gfrt (FFECOM_gfrtCMP, item, NULL_TREE);
3719 item = ffecom_2 (code, integer_type_node,
3721 convert (TREE_TYPE (item),
3722 integer_zero_node));
3724 item = convert (tree_type, item);
3730 assert ("relational bad basictype" == NULL);
3732 case FFEINFO_basictypeANY:
3733 return error_mark_node;
3737 case FFEBLD_opPERCENT_LOC:
3738 item = ffecom_arg_ptr_to_expr (ffebld_left (expr), &list);
3739 return convert (tree_type, item);
3741 case FFEBLD_opPERCENT_VAL:
3742 item = ffecom_arg_expr (ffebld_left (expr), &list);
3743 return convert (tree_type, item);
3747 case FFEBLD_opBOUNDS:
3748 case FFEBLD_opREPEAT:
3749 case FFEBLD_opLABTER:
3750 case FFEBLD_opLABTOK:
3751 case FFEBLD_opIMPDO:
3752 case FFEBLD_opCONCATENATE:
3753 case FFEBLD_opSUBSTR:
3755 assert ("bad op" == NULL);
3758 return error_mark_node;
3762 assert ("didn't think anything got here anymore!!" == NULL);
3764 switch (ffebld_arity (expr))
3767 TREE_OPERAND (item, 0) = ffecom_expr (ffebld_left (expr));
3768 TREE_OPERAND (item, 1) = ffecom_expr (ffebld_right (expr));
3769 if (TREE_OPERAND (item, 0) == error_mark_node
3770 || TREE_OPERAND (item, 1) == error_mark_node)
3771 return error_mark_node;
3775 TREE_OPERAND (item, 0) = ffecom_expr (ffebld_left (expr));
3776 if (TREE_OPERAND (item, 0) == error_mark_node)
3777 return error_mark_node;
3788 /* Returns the tree that does the intrinsic invocation.
3790 Note: this function applies only to intrinsics returning
3791 CHARACTER*1 or non-CHARACTER results, and to intrinsic
3795 ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree, ffebld dest,
3799 tree saved_expr1; /* For those who need it. */
3800 tree saved_expr2; /* For those who need it. */
3801 ffeinfoBasictype bt;
3805 tree real_type; /* REAL type corresponding to COMPLEX. */
3807 ffebld list = ffebld_right (expr); /* List of (some) args. */
3808 ffebld arg1; /* For handy reference. */
3811 ffeintrinImp codegen_imp;
3814 assert (ffebld_op (ffebld_left (expr)) == FFEBLD_opSYMTER);
3816 if (dest_used != NULL)
3819 bt = ffeinfo_basictype (ffebld_info (expr));
3820 kt = ffeinfo_kindtype (ffebld_info (expr));
3821 tree_type = ffecom_tree_type[bt][kt];
3825 arg1 = ffebld_head (list);
3826 if (arg1 != NULL && ffebld_op (arg1) == FFEBLD_opANY)
3827 return error_mark_node;
3828 if ((list = ffebld_trail (list)) != NULL)
3830 arg2 = ffebld_head (list);
3831 if (arg2 != NULL && ffebld_op (arg2) == FFEBLD_opANY)
3832 return error_mark_node;
3833 if ((list = ffebld_trail (list)) != NULL)
3835 arg3 = ffebld_head (list);
3836 if (arg3 != NULL && ffebld_op (arg3) == FFEBLD_opANY)
3837 return error_mark_node;
3846 arg1 = arg2 = arg3 = NULL;
3848 /* <list> ends up at the opITEM of the 3rd arg, or NULL if there are < 3
3849 args. This is used by the MAX/MIN expansions. */
3852 arg1_type = ffecom_tree_type
3853 [ffeinfo_basictype (ffebld_info (arg1))]
3854 [ffeinfo_kindtype (ffebld_info (arg1))];
3856 arg1_type = NULL_TREE; /* Really not needed, but might catch bugs
3859 /* There are several ways for each of the cases in the following switch
3860 statements to exit (from simplest to use to most complicated):
3862 break; (when expr_tree == NULL)
3864 A standard call is made to the specific intrinsic just as if it had been
3865 passed in as a dummy procedure and called as any old procedure. This
3866 method can produce slower code but in some cases it's the easiest way for
3867 now. However, if a (presumably faster) direct call is available,
3868 that is used, so this is the easiest way in many more cases now.
3870 gfrt = FFECOM_gfrtWHATEVER;
3873 gfrt contains the gfrt index of a library function to call, passing the
3874 argument(s) by value rather than by reference. Used when a more
3875 careful choice of library function is needed than that provided
3876 by the vanilla `break;'.
3880 The expr_tree has been completely set up and is ready to be returned
3881 as is. No further actions are taken. Use this when the tree is not
3882 in the simple form for one of the arity_n labels. */
3884 /* For info on how the switch statement cases were written, see the files
3885 enclosed in comments below the switch statement. */
3887 codegen_imp = ffebld_symter_implementation (ffebld_left (expr));
3888 gfrt = ffeintrin_gfrt_direct (codegen_imp);
3889 if (gfrt == FFECOM_gfrt)
3890 gfrt = ffeintrin_gfrt_indirect (codegen_imp);
3892 switch (codegen_imp)
3894 case FFEINTRIN_impABS:
3895 case FFEINTRIN_impCABS:
3896 case FFEINTRIN_impCDABS:
3897 case FFEINTRIN_impDABS:
3898 case FFEINTRIN_impIABS:
3899 if (ffeinfo_basictype (ffebld_info (arg1))
3900 == FFEINFO_basictypeCOMPLEX)
3902 if (kt == FFEINFO_kindtypeREAL1)
3903 gfrt = FFECOM_gfrtCABS;
3904 else if (kt == FFEINFO_kindtypeREAL2)
3905 gfrt = FFECOM_gfrtCDABS;
3908 return ffecom_1 (ABS_EXPR, tree_type,
3909 convert (tree_type, ffecom_expr (arg1)));
3911 case FFEINTRIN_impACOS:
3912 case FFEINTRIN_impDACOS:
3915 case FFEINTRIN_impAIMAG:
3916 case FFEINTRIN_impDIMAG:
3917 case FFEINTRIN_impIMAGPART:
3918 if (TREE_CODE (arg1_type) == COMPLEX_TYPE)
3919 arg1_type = TREE_TYPE (arg1_type);
3921 arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type));
3925 ffecom_1 (IMAGPART_EXPR, arg1_type,
3926 ffecom_expr (arg1)));
3928 case FFEINTRIN_impAINT:
3929 case FFEINTRIN_impDINT:
3931 /* ~~Someday implement FIX_TRUNC_EXPR yielding same type as arg. */
3932 return ffecom_1 (FIX_TRUNC_EXPR, tree_type, ffecom_expr (arg1));
3933 #else /* in the meantime, must use floor to avoid range problems with ints */
3934 /* r__1 = r1 >= 0 ? floor(r1) : -floor(-r1); */
3935 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
3938 ffecom_3 (COND_EXPR, double_type_node,
3940 (ffecom_2 (GE_EXPR, integer_type_node,
3943 ffecom_float_zero_))),
3944 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
3945 build_tree_list (NULL_TREE,
3946 convert (double_type_node,
3949 ffecom_1 (NEGATE_EXPR, double_type_node,
3950 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
3951 build_tree_list (NULL_TREE,
3952 convert (double_type_node,
3953 ffecom_1 (NEGATE_EXPR,
3961 case FFEINTRIN_impANINT:
3962 case FFEINTRIN_impDNINT:
3963 #if 0 /* This way of doing it won't handle real
3964 numbers of large magnitudes. */
3965 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
3966 expr_tree = convert (tree_type,
3967 convert (integer_type_node,
3968 ffecom_3 (COND_EXPR, tree_type,
3973 ffecom_float_zero_)),
3974 ffecom_2 (PLUS_EXPR,
3977 ffecom_float_half_),
3978 ffecom_2 (MINUS_EXPR,
3981 ffecom_float_half_))));
3983 #else /* So we instead call floor. */
3984 /* r__1 = r1 >= 0 ? floor(r1 + .5) : -floor(.5 - r1) */
3985 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
3988 ffecom_3 (COND_EXPR, double_type_node,
3990 (ffecom_2 (GE_EXPR, integer_type_node,
3993 ffecom_float_zero_))),
3994 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
3995 build_tree_list (NULL_TREE,
3996 convert (double_type_node,
3997 ffecom_2 (PLUS_EXPR,
4001 ffecom_float_half_)))),
4003 ffecom_1 (NEGATE_EXPR, double_type_node,
4004 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
4005 build_tree_list (NULL_TREE,
4006 convert (double_type_node,
4007 ffecom_2 (MINUS_EXPR,
4010 ffecom_float_half_),
4017 case FFEINTRIN_impASIN:
4018 case FFEINTRIN_impDASIN:
4019 case FFEINTRIN_impATAN:
4020 case FFEINTRIN_impDATAN:
4021 case FFEINTRIN_impATAN2:
4022 case FFEINTRIN_impDATAN2:
4025 case FFEINTRIN_impCHAR:
4026 case FFEINTRIN_impACHAR:
4027 tempvar = ffebld_nonter_hook (expr);
4030 tree tmv = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (tempvar)));
4032 expr_tree = ffecom_modify (tmv,
4033 ffecom_2 (ARRAY_REF, tmv, tempvar,
4035 convert (tmv, ffecom_expr (arg1)));
4037 expr_tree = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar),
4040 expr_tree = ffecom_1 (ADDR_EXPR,
4041 build_pointer_type (TREE_TYPE (expr_tree)),
4045 case FFEINTRIN_impCMPLX:
4046 case FFEINTRIN_impDCMPLX:
4049 convert (tree_type, ffecom_expr (arg1));
4051 real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
4053 ffecom_2 (COMPLEX_EXPR, tree_type,
4054 convert (real_type, ffecom_expr (arg1)),
4056 ffecom_expr (arg2)));
4058 case FFEINTRIN_impCOMPLEX:
4060 ffecom_2 (COMPLEX_EXPR, tree_type,
4062 ffecom_expr (arg2));
4064 case FFEINTRIN_impCONJG:
4065 case FFEINTRIN_impDCONJG:
4069 real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
4070 arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4072 ffecom_2 (COMPLEX_EXPR, tree_type,
4073 ffecom_1 (REALPART_EXPR, real_type, arg1_tree),
4074 ffecom_1 (NEGATE_EXPR, real_type,
4075 ffecom_1 (IMAGPART_EXPR, real_type, arg1_tree)));
4078 case FFEINTRIN_impCOS:
4079 case FFEINTRIN_impCCOS:
4080 case FFEINTRIN_impCDCOS:
4081 case FFEINTRIN_impDCOS:
4082 if (bt == FFEINFO_basictypeCOMPLEX)
4084 if (kt == FFEINFO_kindtypeREAL1)
4085 gfrt = FFECOM_gfrtCCOS; /* Overlapping result okay. */
4086 else if (kt == FFEINFO_kindtypeREAL2)
4087 gfrt = FFECOM_gfrtCDCOS; /* Overlapping result okay. */
4091 case FFEINTRIN_impCOSH:
4092 case FFEINTRIN_impDCOSH:
4095 case FFEINTRIN_impDBLE:
4096 case FFEINTRIN_impDFLOAT:
4097 case FFEINTRIN_impDREAL:
4098 case FFEINTRIN_impFLOAT:
4099 case FFEINTRIN_impIDINT:
4100 case FFEINTRIN_impIFIX:
4101 case FFEINTRIN_impINT2:
4102 case FFEINTRIN_impINT8:
4103 case FFEINTRIN_impINT:
4104 case FFEINTRIN_impLONG:
4105 case FFEINTRIN_impREAL:
4106 case FFEINTRIN_impSHORT:
4107 case FFEINTRIN_impSNGL:
4108 return convert (tree_type, ffecom_expr (arg1));
4110 case FFEINTRIN_impDIM:
4111 case FFEINTRIN_impDDIM:
4112 case FFEINTRIN_impIDIM:
4113 saved_expr1 = ffecom_save_tree (convert (tree_type,
4114 ffecom_expr (arg1)));
4115 saved_expr2 = ffecom_save_tree (convert (tree_type,
4116 ffecom_expr (arg2)));
4118 ffecom_3 (COND_EXPR, tree_type,
4120 (ffecom_2 (GT_EXPR, integer_type_node,
4123 ffecom_2 (MINUS_EXPR, tree_type,
4126 convert (tree_type, ffecom_float_zero_));
4128 case FFEINTRIN_impDPROD:
4130 ffecom_2 (MULT_EXPR, tree_type,
4131 convert (tree_type, ffecom_expr (arg1)),
4132 convert (tree_type, ffecom_expr (arg2)));
4134 case FFEINTRIN_impEXP:
4135 case FFEINTRIN_impCDEXP:
4136 case FFEINTRIN_impCEXP:
4137 case FFEINTRIN_impDEXP:
4138 if (bt == FFEINFO_basictypeCOMPLEX)
4140 if (kt == FFEINFO_kindtypeREAL1)
4141 gfrt = FFECOM_gfrtCEXP; /* Overlapping result okay. */
4142 else if (kt == FFEINFO_kindtypeREAL2)
4143 gfrt = FFECOM_gfrtCDEXP; /* Overlapping result okay. */
4147 case FFEINTRIN_impICHAR:
4148 case FFEINTRIN_impIACHAR:
4149 #if 0 /* The simple approach. */
4150 ffecom_char_args_ (&expr_tree, &saved_expr1 /* Ignored */ , arg1);
4152 = ffecom_1 (INDIRECT_REF,
4153 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
4156 = ffecom_2 (ARRAY_REF,
4157 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
4160 return convert (tree_type, expr_tree);
4161 #else /* The more interesting (and more optimal) approach. */
4162 expr_tree = ffecom_intrinsic_ichar_ (tree_type, arg1, &saved_expr1);
4163 expr_tree = ffecom_3 (COND_EXPR, tree_type,
4166 convert (tree_type, integer_zero_node));
4170 case FFEINTRIN_impINDEX:
4173 case FFEINTRIN_impLEN:
4175 break; /* The simple approach. */
4177 return ffecom_intrinsic_len_ (arg1); /* The more optimal approach. */
4180 case FFEINTRIN_impLGE:
4181 case FFEINTRIN_impLGT:
4182 case FFEINTRIN_impLLE:
4183 case FFEINTRIN_impLLT:
4186 case FFEINTRIN_impLOG:
4187 case FFEINTRIN_impALOG:
4188 case FFEINTRIN_impCDLOG:
4189 case FFEINTRIN_impCLOG:
4190 case FFEINTRIN_impDLOG:
4191 if (bt == FFEINFO_basictypeCOMPLEX)
4193 if (kt == FFEINFO_kindtypeREAL1)
4194 gfrt = FFECOM_gfrtCLOG; /* Overlapping result okay. */
4195 else if (kt == FFEINFO_kindtypeREAL2)
4196 gfrt = FFECOM_gfrtCDLOG; /* Overlapping result okay. */
4200 case FFEINTRIN_impLOG10:
4201 case FFEINTRIN_impALOG10:
4202 case FFEINTRIN_impDLOG10:
4203 if (gfrt != FFECOM_gfrt)
4204 break; /* Already picked one, stick with it. */
4206 if (kt == FFEINFO_kindtypeREAL1)
4207 /* We used to call FFECOM_gfrtALOG10 here. */
4208 gfrt = FFECOM_gfrtL_LOG10;
4209 else if (kt == FFEINFO_kindtypeREAL2)
4210 /* We used to call FFECOM_gfrtDLOG10 here. */
4211 gfrt = FFECOM_gfrtL_LOG10;
4214 case FFEINTRIN_impMAX:
4215 case FFEINTRIN_impAMAX0:
4216 case FFEINTRIN_impAMAX1:
4217 case FFEINTRIN_impDMAX1:
4218 case FFEINTRIN_impMAX0:
4219 case FFEINTRIN_impMAX1:
4220 if (bt != ffeinfo_basictype (ffebld_info (arg1)))
4221 arg1_type = ffecom_widest_expr_type_ (ffebld_right (expr));
4223 arg1_type = tree_type;
4224 expr_tree = ffecom_2 (MAX_EXPR, arg1_type,
4225 convert (arg1_type, ffecom_expr (arg1)),
4226 convert (arg1_type, ffecom_expr (arg2)));
4227 for (; list != NULL; list = ffebld_trail (list))
4229 if ((ffebld_head (list) == NULL)
4230 || (ffebld_op (ffebld_head (list)) == FFEBLD_opANY))
4232 expr_tree = ffecom_2 (MAX_EXPR, arg1_type,
4235 ffecom_expr (ffebld_head (list))));
4237 return convert (tree_type, expr_tree);
4239 case FFEINTRIN_impMIN:
4240 case FFEINTRIN_impAMIN0:
4241 case FFEINTRIN_impAMIN1:
4242 case FFEINTRIN_impDMIN1:
4243 case FFEINTRIN_impMIN0:
4244 case FFEINTRIN_impMIN1:
4245 if (bt != ffeinfo_basictype (ffebld_info (arg1)))
4246 arg1_type = ffecom_widest_expr_type_ (ffebld_right (expr));
4248 arg1_type = tree_type;
4249 expr_tree = ffecom_2 (MIN_EXPR, arg1_type,
4250 convert (arg1_type, ffecom_expr (arg1)),
4251 convert (arg1_type, ffecom_expr (arg2)));
4252 for (; list != NULL; list = ffebld_trail (list))
4254 if ((ffebld_head (list) == NULL)
4255 || (ffebld_op (ffebld_head (list)) == FFEBLD_opANY))
4257 expr_tree = ffecom_2 (MIN_EXPR, arg1_type,
4260 ffecom_expr (ffebld_head (list))));
4262 return convert (tree_type, expr_tree);
4264 case FFEINTRIN_impMOD:
4265 case FFEINTRIN_impAMOD:
4266 case FFEINTRIN_impDMOD:
4267 if (bt != FFEINFO_basictypeREAL)
4268 return ffecom_2 (TRUNC_MOD_EXPR, tree_type,
4269 convert (tree_type, ffecom_expr (arg1)),
4270 convert (tree_type, ffecom_expr (arg2)));
4272 if (kt == FFEINFO_kindtypeREAL1)
4273 /* We used to call FFECOM_gfrtAMOD here. */
4274 gfrt = FFECOM_gfrtL_FMOD;
4275 else if (kt == FFEINFO_kindtypeREAL2)
4276 /* We used to call FFECOM_gfrtDMOD here. */
4277 gfrt = FFECOM_gfrtL_FMOD;
4280 case FFEINTRIN_impNINT:
4281 case FFEINTRIN_impIDNINT:
4283 /* ~~Ideally FIX_ROUND_EXPR would be implemented, but it ain't yet. */
4284 return ffecom_1 (FIX_ROUND_EXPR, tree_type, ffecom_expr (arg1));
4286 /* i__1 = r1 >= 0 ? floor(r1 + .5) : -floor(.5 - r1); */
4287 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
4289 convert (ffecom_integer_type_node,
4290 ffecom_3 (COND_EXPR, arg1_type,
4292 (ffecom_2 (GE_EXPR, integer_type_node,
4295 ffecom_float_zero_))),
4296 ffecom_2 (PLUS_EXPR, arg1_type,
4299 ffecom_float_half_)),
4300 ffecom_2 (MINUS_EXPR, arg1_type,
4303 ffecom_float_half_))));
4306 case FFEINTRIN_impSIGN:
4307 case FFEINTRIN_impDSIGN:
4308 case FFEINTRIN_impISIGN:
4310 tree arg2_tree = ffecom_expr (arg2);
4314 (ffecom_1 (ABS_EXPR, tree_type,
4316 ffecom_expr (arg1))));
4318 = ffecom_3 (COND_EXPR, tree_type,
4320 (ffecom_2 (GE_EXPR, integer_type_node,
4322 convert (TREE_TYPE (arg2_tree),
4323 integer_zero_node))),
4325 ffecom_1 (NEGATE_EXPR, tree_type, saved_expr1));
4326 /* Make sure SAVE_EXPRs get referenced early enough. */
4328 = ffecom_2 (COMPOUND_EXPR, tree_type,
4329 convert (void_type_node, saved_expr1),
4334 case FFEINTRIN_impSIN:
4335 case FFEINTRIN_impCDSIN:
4336 case FFEINTRIN_impCSIN:
4337 case FFEINTRIN_impDSIN:
4338 if (bt == FFEINFO_basictypeCOMPLEX)
4340 if (kt == FFEINFO_kindtypeREAL1)
4341 gfrt = FFECOM_gfrtCSIN; /* Overlapping result okay. */
4342 else if (kt == FFEINFO_kindtypeREAL2)
4343 gfrt = FFECOM_gfrtCDSIN; /* Overlapping result okay. */
4347 case FFEINTRIN_impSINH:
4348 case FFEINTRIN_impDSINH:
4351 case FFEINTRIN_impSQRT:
4352 case FFEINTRIN_impCDSQRT:
4353 case FFEINTRIN_impCSQRT:
4354 case FFEINTRIN_impDSQRT:
4355 if (bt == FFEINFO_basictypeCOMPLEX)
4357 if (kt == FFEINFO_kindtypeREAL1)
4358 gfrt = FFECOM_gfrtCSQRT; /* Overlapping result okay. */
4359 else if (kt == FFEINFO_kindtypeREAL2)
4360 gfrt = FFECOM_gfrtCDSQRT; /* Overlapping result okay. */
4364 case FFEINTRIN_impTAN:
4365 case FFEINTRIN_impDTAN:
4366 case FFEINTRIN_impTANH:
4367 case FFEINTRIN_impDTANH:
4370 case FFEINTRIN_impREALPART:
4371 if (TREE_CODE (arg1_type) == COMPLEX_TYPE)
4372 arg1_type = TREE_TYPE (arg1_type);
4374 arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type));
4378 ffecom_1 (REALPART_EXPR, arg1_type,
4379 ffecom_expr (arg1)));
4381 case FFEINTRIN_impIAND:
4382 case FFEINTRIN_impAND:
4383 return ffecom_2 (BIT_AND_EXPR, tree_type,
4385 ffecom_expr (arg1)),
4387 ffecom_expr (arg2)));
4389 case FFEINTRIN_impIOR:
4390 case FFEINTRIN_impOR:
4391 return ffecom_2 (BIT_IOR_EXPR, tree_type,
4393 ffecom_expr (arg1)),
4395 ffecom_expr (arg2)));
4397 case FFEINTRIN_impIEOR:
4398 case FFEINTRIN_impXOR:
4399 return ffecom_2 (BIT_XOR_EXPR, tree_type,
4401 ffecom_expr (arg1)),
4403 ffecom_expr (arg2)));
4405 case FFEINTRIN_impLSHIFT:
4406 return ffecom_2 (LSHIFT_EXPR, tree_type,
4408 convert (integer_type_node,
4409 ffecom_expr (arg2)));
4411 case FFEINTRIN_impRSHIFT:
4412 return ffecom_2 (RSHIFT_EXPR, tree_type,
4414 convert (integer_type_node,
4415 ffecom_expr (arg2)));
4417 case FFEINTRIN_impNOT:
4418 return ffecom_1 (BIT_NOT_EXPR, tree_type, ffecom_expr (arg1));
4420 case FFEINTRIN_impBIT_SIZE:
4421 return convert (tree_type, TYPE_SIZE (arg1_type));
4423 case FFEINTRIN_impBTEST:
4425 ffetargetLogical1 target_true;
4426 ffetargetLogical1 target_false;
4430 ffetarget_logical1 (&target_true, TRUE);
4431 ffetarget_logical1 (&target_false, FALSE);
4432 if (target_true == 1)
4433 true_tree = convert (tree_type, integer_one_node);
4435 true_tree = convert (tree_type, build_int_2 (target_true, 0));
4436 if (target_false == 0)
4437 false_tree = convert (tree_type, integer_zero_node);
4439 false_tree = convert (tree_type, build_int_2 (target_false, 0));
4442 ffecom_3 (COND_EXPR, tree_type,
4444 (ffecom_2 (EQ_EXPR, integer_type_node,
4445 ffecom_2 (BIT_AND_EXPR, arg1_type,
4447 ffecom_2 (LSHIFT_EXPR, arg1_type,
4450 convert (integer_type_node,
4451 ffecom_expr (arg2)))),
4453 integer_zero_node))),
4458 case FFEINTRIN_impIBCLR:
4460 ffecom_2 (BIT_AND_EXPR, tree_type,
4462 ffecom_1 (BIT_NOT_EXPR, tree_type,
4463 ffecom_2 (LSHIFT_EXPR, tree_type,
4466 convert (integer_type_node,
4467 ffecom_expr (arg2)))));
4469 case FFEINTRIN_impIBITS:
4471 tree arg3_tree = ffecom_save_tree (convert (integer_type_node,
4472 ffecom_expr (arg3)));
4474 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4477 = ffecom_2 (BIT_AND_EXPR, tree_type,
4478 ffecom_2 (RSHIFT_EXPR, tree_type,
4480 convert (integer_type_node,
4481 ffecom_expr (arg2))),
4483 ffecom_2 (RSHIFT_EXPR, uns_type,
4484 ffecom_1 (BIT_NOT_EXPR,
4487 integer_zero_node)),
4488 ffecom_2 (MINUS_EXPR,
4490 TYPE_SIZE (uns_type),
4492 /* Fix up, because the RSHIFT_EXPR above can't shift over TYPE_SIZE. */
4494 = ffecom_3 (COND_EXPR, tree_type,
4496 (ffecom_2 (NE_EXPR, integer_type_node,
4498 integer_zero_node)),
4500 convert (tree_type, integer_zero_node));
4504 case FFEINTRIN_impIBSET:
4506 ffecom_2 (BIT_IOR_EXPR, tree_type,
4508 ffecom_2 (LSHIFT_EXPR, tree_type,
4509 convert (tree_type, integer_one_node),
4510 convert (integer_type_node,
4511 ffecom_expr (arg2))));
4513 case FFEINTRIN_impISHFT:
4515 tree arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4516 tree arg2_tree = ffecom_save_tree (convert (integer_type_node,
4517 ffecom_expr (arg2)));
4519 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4522 = ffecom_3 (COND_EXPR, tree_type,
4524 (ffecom_2 (GE_EXPR, integer_type_node,
4526 integer_zero_node)),
4527 ffecom_2 (LSHIFT_EXPR, tree_type,
4531 ffecom_2 (RSHIFT_EXPR, uns_type,
4532 convert (uns_type, arg1_tree),
4533 ffecom_1 (NEGATE_EXPR,
4536 /* Fix up, because {L|R}SHIFT_EXPR don't go over TYPE_SIZE bounds. */
4538 = ffecom_3 (COND_EXPR, tree_type,
4540 (ffecom_2 (NE_EXPR, integer_type_node,
4544 TYPE_SIZE (uns_type))),
4546 convert (tree_type, integer_zero_node));
4547 /* Make sure SAVE_EXPRs get referenced early enough. */
4549 = ffecom_2 (COMPOUND_EXPR, tree_type,
4550 convert (void_type_node, arg1_tree),
4551 ffecom_2 (COMPOUND_EXPR, tree_type,
4552 convert (void_type_node, arg2_tree),
4557 case FFEINTRIN_impISHFTC:
4559 tree arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4560 tree arg2_tree = ffecom_save_tree (convert (integer_type_node,
4561 ffecom_expr (arg2)));
4562 tree arg3_tree = (arg3 == NULL) ? TYPE_SIZE (tree_type)
4563 : ffecom_save_tree (convert (integer_type_node, ffecom_expr (arg3)));
4569 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4572 = ffecom_2 (LSHIFT_EXPR, tree_type,
4573 ffecom_1 (BIT_NOT_EXPR, tree_type,
4574 convert (tree_type, integer_zero_node)),
4576 /* Fix up, because LSHIFT_EXPR above can't shift over TYPE_SIZE. */
4578 = ffecom_3 (COND_EXPR, tree_type,
4580 (ffecom_2 (NE_EXPR, integer_type_node,
4582 TYPE_SIZE (uns_type))),
4584 convert (tree_type, integer_zero_node));
4585 mask_arg1 = ffecom_save_tree (mask_arg1);
4587 = ffecom_2 (BIT_AND_EXPR, tree_type,
4589 ffecom_1 (BIT_NOT_EXPR, tree_type,
4591 masked_arg1 = ffecom_save_tree (masked_arg1);
4593 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4595 ffecom_2 (RSHIFT_EXPR, uns_type,
4596 convert (uns_type, masked_arg1),
4597 ffecom_1 (NEGATE_EXPR,
4600 ffecom_2 (LSHIFT_EXPR, tree_type,
4602 ffecom_2 (PLUS_EXPR, integer_type_node,
4606 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4607 ffecom_2 (LSHIFT_EXPR, tree_type,
4611 ffecom_2 (RSHIFT_EXPR, uns_type,
4612 convert (uns_type, masked_arg1),
4613 ffecom_2 (MINUS_EXPR,
4618 = ffecom_3 (COND_EXPR, tree_type,
4620 (ffecom_2 (LT_EXPR, integer_type_node,
4622 integer_zero_node)),
4626 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4627 ffecom_2 (BIT_AND_EXPR, tree_type,
4630 ffecom_2 (BIT_AND_EXPR, tree_type,
4631 ffecom_1 (BIT_NOT_EXPR, tree_type,
4635 = ffecom_3 (COND_EXPR, tree_type,
4637 (ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
4638 ffecom_2 (EQ_EXPR, integer_type_node,
4643 ffecom_2 (EQ_EXPR, integer_type_node,
4645 integer_zero_node))),
4648 /* Make sure SAVE_EXPRs get referenced early enough. */
4650 = ffecom_2 (COMPOUND_EXPR, tree_type,
4651 convert (void_type_node, arg1_tree),
4652 ffecom_2 (COMPOUND_EXPR, tree_type,
4653 convert (void_type_node, arg2_tree),
4654 ffecom_2 (COMPOUND_EXPR, tree_type,
4655 convert (void_type_node,
4657 ffecom_2 (COMPOUND_EXPR, tree_type,
4658 convert (void_type_node,
4662 = ffecom_2 (COMPOUND_EXPR, tree_type,
4663 convert (void_type_node,
4669 case FFEINTRIN_impLOC:
4671 tree arg1_tree = ffecom_expr (arg1);
4674 = convert (tree_type,
4675 ffecom_1 (ADDR_EXPR,
4676 build_pointer_type (TREE_TYPE (arg1_tree)),
4681 case FFEINTRIN_impMVBITS:
4686 ffebld arg4 = ffebld_head (ffebld_trail (list));
4689 ffebld arg5 = ffebld_head (ffebld_trail (ffebld_trail (list)));
4693 tree arg5_plus_arg3;
4695 arg2_tree = convert (integer_type_node,
4696 ffecom_expr (arg2));
4697 arg3_tree = ffecom_save_tree (convert (integer_type_node,
4698 ffecom_expr (arg3)));
4699 arg4_tree = ffecom_expr_rw (NULL_TREE, arg4);
4700 arg4_type = TREE_TYPE (arg4_tree);
4702 arg1_tree = ffecom_save_tree (convert (arg4_type,
4703 ffecom_expr (arg1)));
4705 arg5_tree = ffecom_save_tree (convert (integer_type_node,
4706 ffecom_expr (arg5)));
4709 = ffecom_2 (LSHIFT_EXPR, arg4_type,
4710 ffecom_2 (BIT_AND_EXPR, arg4_type,
4711 ffecom_2 (RSHIFT_EXPR, arg4_type,
4714 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4715 ffecom_2 (LSHIFT_EXPR, arg4_type,
4716 ffecom_1 (BIT_NOT_EXPR,
4720 integer_zero_node)),
4724 = ffecom_save_tree (ffecom_2 (PLUS_EXPR, arg4_type,
4728 = ffecom_2 (LSHIFT_EXPR, arg4_type,
4729 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4731 integer_zero_node)),
4733 /* Fix up, because LSHIFT_EXPR above can't shift over TYPE_SIZE. */
4735 = ffecom_3 (COND_EXPR, arg4_type,
4737 (ffecom_2 (NE_EXPR, integer_type_node,
4739 convert (TREE_TYPE (arg5_plus_arg3),
4740 TYPE_SIZE (arg4_type)))),
4742 convert (arg4_type, integer_zero_node));
4744 = ffecom_2 (BIT_AND_EXPR, arg4_type,
4746 ffecom_2 (BIT_IOR_EXPR, arg4_type,
4748 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4749 ffecom_2 (LSHIFT_EXPR, arg4_type,
4750 ffecom_1 (BIT_NOT_EXPR,
4754 integer_zero_node)),
4757 = ffecom_2 (BIT_IOR_EXPR, arg4_type,
4760 /* Fix up (twice), because LSHIFT_EXPR above
4761 can't shift over TYPE_SIZE. */
4763 = ffecom_3 (COND_EXPR, arg4_type,
4765 (ffecom_2 (NE_EXPR, integer_type_node,
4767 convert (TREE_TYPE (arg3_tree),
4768 integer_zero_node))),
4772 = ffecom_3 (COND_EXPR, arg4_type,
4774 (ffecom_2 (NE_EXPR, integer_type_node,
4776 convert (TREE_TYPE (arg3_tree),
4777 TYPE_SIZE (arg4_type)))),
4781 = ffecom_2s (MODIFY_EXPR, void_type_node,
4784 /* Make sure SAVE_EXPRs get referenced early enough. */
4786 = ffecom_2 (COMPOUND_EXPR, void_type_node,
4788 ffecom_2 (COMPOUND_EXPR, void_type_node,
4790 ffecom_2 (COMPOUND_EXPR, void_type_node,
4792 ffecom_2 (COMPOUND_EXPR, void_type_node,
4796 = ffecom_2 (COMPOUND_EXPR, void_type_node,
4803 case FFEINTRIN_impDERF:
4804 case FFEINTRIN_impERF:
4805 case FFEINTRIN_impDERFC:
4806 case FFEINTRIN_impERFC:
4809 case FFEINTRIN_impIARGC:
4810 /* extern int xargc; i__1 = xargc - 1; */
4811 expr_tree = ffecom_2 (MINUS_EXPR, TREE_TYPE (ffecom_tree_xargc_),
4813 convert (TREE_TYPE (ffecom_tree_xargc_),
4817 case FFEINTRIN_impSIGNAL_func:
4818 case FFEINTRIN_impSIGNAL_subr:
4824 arg1_tree = convert (ffecom_f2c_integer_type_node,
4825 ffecom_expr (arg1));
4826 arg1_tree = ffecom_1 (ADDR_EXPR,
4827 build_pointer_type (TREE_TYPE (arg1_tree)),
4830 /* Pass procedure as a pointer to it, anything else by value. */
4831 if (ffeinfo_kind (ffebld_info (arg2)) == FFEINFO_kindENTITY)
4832 arg2_tree = convert (integer_type_node, ffecom_expr (arg2));
4834 arg2_tree = ffecom_ptr_to_expr (arg2);
4835 arg2_tree = convert (TREE_TYPE (null_pointer_node),
4839 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
4841 arg3_tree = NULL_TREE;
4843 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4844 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
4845 TREE_CHAIN (arg1_tree) = arg2_tree;
4848 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4849 ffecom_gfrt_kindtype (gfrt),
4851 ((codegen_imp == FFEINTRIN_impSIGNAL_subr) ?
4855 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4856 ffebld_nonter_hook (expr));
4858 if (arg3_tree != NULL_TREE)
4860 = ffecom_modify (NULL_TREE, arg3_tree,
4861 convert (TREE_TYPE (arg3_tree),
4866 case FFEINTRIN_impALARM:
4872 arg1_tree = convert (ffecom_f2c_integer_type_node,
4873 ffecom_expr (arg1));
4874 arg1_tree = ffecom_1 (ADDR_EXPR,
4875 build_pointer_type (TREE_TYPE (arg1_tree)),
4878 /* Pass procedure as a pointer to it, anything else by value. */
4879 if (ffeinfo_kind (ffebld_info (arg2)) == FFEINFO_kindENTITY)
4880 arg2_tree = convert (integer_type_node, ffecom_expr (arg2));
4882 arg2_tree = ffecom_ptr_to_expr (arg2);
4883 arg2_tree = convert (TREE_TYPE (null_pointer_node),
4887 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
4889 arg3_tree = NULL_TREE;
4891 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4892 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
4893 TREE_CHAIN (arg1_tree) = arg2_tree;
4896 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4897 ffecom_gfrt_kindtype (gfrt),
4901 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4902 ffebld_nonter_hook (expr));
4904 if (arg3_tree != NULL_TREE)
4906 = ffecom_modify (NULL_TREE, arg3_tree,
4907 convert (TREE_TYPE (arg3_tree),
4912 case FFEINTRIN_impCHDIR_subr:
4913 case FFEINTRIN_impFDATE_subr:
4914 case FFEINTRIN_impFGET_subr:
4915 case FFEINTRIN_impFPUT_subr:
4916 case FFEINTRIN_impGETCWD_subr:
4917 case FFEINTRIN_impHOSTNM_subr:
4918 case FFEINTRIN_impSYSTEM_subr:
4919 case FFEINTRIN_impUNLINK_subr:
4921 tree arg1_len = integer_zero_node;
4925 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
4928 arg2_tree = ffecom_expr_w (NULL_TREE, arg2);
4930 arg2_tree = NULL_TREE;
4932 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4933 arg1_len = build_tree_list (NULL_TREE, arg1_len);
4934 TREE_CHAIN (arg1_tree) = arg1_len;
4937 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4938 ffecom_gfrt_kindtype (gfrt),
4942 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4943 ffebld_nonter_hook (expr));
4945 if (arg2_tree != NULL_TREE)
4947 = ffecom_modify (NULL_TREE, arg2_tree,
4948 convert (TREE_TYPE (arg2_tree),
4953 case FFEINTRIN_impEXIT:
4957 expr_tree = build_tree_list (NULL_TREE,
4958 ffecom_1 (ADDR_EXPR,
4960 (ffecom_integer_type_node),
4961 integer_zero_node));
4964 ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4965 ffecom_gfrt_kindtype (gfrt),
4969 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4970 ffebld_nonter_hook (expr));
4972 case FFEINTRIN_impFLUSH:
4974 gfrt = FFECOM_gfrtFLUSH;
4976 gfrt = FFECOM_gfrtFLUSH1;
4979 case FFEINTRIN_impCHMOD_subr:
4980 case FFEINTRIN_impLINK_subr:
4981 case FFEINTRIN_impRENAME_subr:
4982 case FFEINTRIN_impSYMLNK_subr:
4984 tree arg1_len = integer_zero_node;
4986 tree arg2_len = integer_zero_node;
4990 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
4991 arg2_tree = ffecom_arg_ptr_to_expr (arg2, &arg2_len);
4993 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
4995 arg3_tree = NULL_TREE;
4997 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4998 arg1_len = build_tree_list (NULL_TREE, arg1_len);
4999 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5000 arg2_len = build_tree_list (NULL_TREE, arg2_len);
5001 TREE_CHAIN (arg1_tree) = arg2_tree;
5002 TREE_CHAIN (arg2_tree) = arg1_len;
5003 TREE_CHAIN (arg1_len) = arg2_len;
5004 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5005 ffecom_gfrt_kindtype (gfrt),
5009 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5010 ffebld_nonter_hook (expr));
5011 if (arg3_tree != NULL_TREE)
5012 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5013 convert (TREE_TYPE (arg3_tree),
5018 case FFEINTRIN_impLSTAT_subr:
5019 case FFEINTRIN_impSTAT_subr:
5021 tree arg1_len = integer_zero_node;
5026 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
5028 arg2_tree = ffecom_ptr_to_expr (arg2);
5031 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5033 arg3_tree = NULL_TREE;
5035 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5036 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5037 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5038 TREE_CHAIN (arg1_tree) = arg2_tree;
5039 TREE_CHAIN (arg2_tree) = arg1_len;
5040 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5041 ffecom_gfrt_kindtype (gfrt),
5045 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5046 ffebld_nonter_hook (expr));
5047 if (arg3_tree != NULL_TREE)
5048 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5049 convert (TREE_TYPE (arg3_tree),
5054 case FFEINTRIN_impFGETC_subr:
5055 case FFEINTRIN_impFPUTC_subr:
5059 tree arg2_len = integer_zero_node;
5062 arg1_tree = convert (ffecom_f2c_integer_type_node,
5063 ffecom_expr (arg1));
5064 arg1_tree = ffecom_1 (ADDR_EXPR,
5065 build_pointer_type (TREE_TYPE (arg1_tree)),
5068 arg2_tree = ffecom_arg_ptr_to_expr (arg2, &arg2_len);
5070 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5072 arg3_tree = NULL_TREE;
5074 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5075 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5076 arg2_len = build_tree_list (NULL_TREE, arg2_len);
5077 TREE_CHAIN (arg1_tree) = arg2_tree;
5078 TREE_CHAIN (arg2_tree) = arg2_len;
5080 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5081 ffecom_gfrt_kindtype (gfrt),
5085 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5086 ffebld_nonter_hook (expr));
5087 if (arg3_tree != NULL_TREE)
5088 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5089 convert (TREE_TYPE (arg3_tree),
5094 case FFEINTRIN_impFSTAT_subr:
5100 arg1_tree = convert (ffecom_f2c_integer_type_node,
5101 ffecom_expr (arg1));
5102 arg1_tree = ffecom_1 (ADDR_EXPR,
5103 build_pointer_type (TREE_TYPE (arg1_tree)),
5106 arg2_tree = convert (ffecom_f2c_ptr_to_integer_type_node,
5107 ffecom_ptr_to_expr (arg2));
5110 arg3_tree = NULL_TREE;
5112 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5114 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5115 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5116 TREE_CHAIN (arg1_tree) = arg2_tree;
5117 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5118 ffecom_gfrt_kindtype (gfrt),
5122 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5123 ffebld_nonter_hook (expr));
5124 if (arg3_tree != NULL_TREE) {
5125 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5126 convert (TREE_TYPE (arg3_tree),
5132 case FFEINTRIN_impKILL_subr:
5138 arg1_tree = convert (ffecom_f2c_integer_type_node,
5139 ffecom_expr (arg1));
5140 arg1_tree = ffecom_1 (ADDR_EXPR,
5141 build_pointer_type (TREE_TYPE (arg1_tree)),
5144 arg2_tree = convert (ffecom_f2c_integer_type_node,
5145 ffecom_expr (arg2));
5146 arg2_tree = ffecom_1 (ADDR_EXPR,
5147 build_pointer_type (TREE_TYPE (arg2_tree)),
5151 arg3_tree = NULL_TREE;
5153 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5155 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5156 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5157 TREE_CHAIN (arg1_tree) = arg2_tree;
5158 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5159 ffecom_gfrt_kindtype (gfrt),
5163 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5164 ffebld_nonter_hook (expr));
5165 if (arg3_tree != NULL_TREE) {
5166 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5167 convert (TREE_TYPE (arg3_tree),
5173 case FFEINTRIN_impCTIME_subr:
5174 case FFEINTRIN_impTTYNAM_subr:
5176 tree arg1_len = integer_zero_node;
5180 arg1_tree = ffecom_arg_ptr_to_expr (arg2, &arg1_len);
5182 arg2_tree = convert (((codegen_imp == FFEINTRIN_impCTIME_subr) ?
5183 ffecom_f2c_longint_type_node :
5184 ffecom_f2c_integer_type_node),
5185 ffecom_expr (arg1));
5186 arg2_tree = ffecom_1 (ADDR_EXPR,
5187 build_pointer_type (TREE_TYPE (arg2_tree)),
5190 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5191 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5192 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5193 TREE_CHAIN (arg1_len) = arg2_tree;
5194 TREE_CHAIN (arg1_tree) = arg1_len;
5197 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5198 ffecom_gfrt_kindtype (gfrt),
5202 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5203 ffebld_nonter_hook (expr));
5204 TREE_SIDE_EFFECTS (expr_tree) = 1;
5208 case FFEINTRIN_impIRAND:
5209 case FFEINTRIN_impRAND:
5210 /* Arg defaults to 0 (normal random case) */
5215 arg1_tree = ffecom_integer_zero_node;
5217 arg1_tree = ffecom_expr (arg1);
5218 arg1_tree = convert (ffecom_f2c_integer_type_node,
5220 arg1_tree = ffecom_1 (ADDR_EXPR,
5221 build_pointer_type (TREE_TYPE (arg1_tree)),
5223 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5225 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5226 ffecom_gfrt_kindtype (gfrt),
5228 ((codegen_imp == FFEINTRIN_impIRAND) ?
5229 ffecom_f2c_integer_type_node :
5230 ffecom_f2c_real_type_node),
5232 dest_tree, dest, dest_used,
5234 ffebld_nonter_hook (expr));
5238 case FFEINTRIN_impFTELL_subr:
5239 case FFEINTRIN_impUMASK_subr:
5244 arg1_tree = convert (ffecom_f2c_integer_type_node,
5245 ffecom_expr (arg1));
5246 arg1_tree = ffecom_1 (ADDR_EXPR,
5247 build_pointer_type (TREE_TYPE (arg1_tree)),
5251 arg2_tree = NULL_TREE;
5253 arg2_tree = ffecom_expr_w (NULL_TREE, arg2);
5255 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5256 ffecom_gfrt_kindtype (gfrt),
5259 build_tree_list (NULL_TREE, arg1_tree),
5260 NULL_TREE, NULL, NULL, NULL_TREE,
5262 ffebld_nonter_hook (expr));
5263 if (arg2_tree != NULL_TREE) {
5264 expr_tree = ffecom_modify (NULL_TREE, arg2_tree,
5265 convert (TREE_TYPE (arg2_tree),
5271 case FFEINTRIN_impCPU_TIME:
5272 case FFEINTRIN_impSECOND_subr:
5276 arg1_tree = ffecom_expr_w (NULL_TREE, arg1);
5279 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5280 ffecom_gfrt_kindtype (gfrt),
5284 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5285 ffebld_nonter_hook (expr));
5288 = ffecom_modify (NULL_TREE, arg1_tree,
5289 convert (TREE_TYPE (arg1_tree),
5294 case FFEINTRIN_impDTIME_subr:
5295 case FFEINTRIN_impETIME_subr:
5300 result_tree = ffecom_expr_w (NULL_TREE, arg2);
5302 arg1_tree = ffecom_ptr_to_expr (arg1);
5304 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5305 ffecom_gfrt_kindtype (gfrt),
5308 build_tree_list (NULL_TREE, arg1_tree),
5309 NULL_TREE, NULL, NULL, NULL_TREE,
5311 ffebld_nonter_hook (expr));
5312 expr_tree = ffecom_modify (NULL_TREE, result_tree,
5313 convert (TREE_TYPE (result_tree),
5318 /* Straightforward calls of libf2c routines: */
5319 case FFEINTRIN_impABORT:
5320 case FFEINTRIN_impACCESS:
5321 case FFEINTRIN_impBESJ0:
5322 case FFEINTRIN_impBESJ1:
5323 case FFEINTRIN_impBESJN:
5324 case FFEINTRIN_impBESY0:
5325 case FFEINTRIN_impBESY1:
5326 case FFEINTRIN_impBESYN:
5327 case FFEINTRIN_impCHDIR_func:
5328 case FFEINTRIN_impCHMOD_func:
5329 case FFEINTRIN_impDATE:
5330 case FFEINTRIN_impDATE_AND_TIME:
5331 case FFEINTRIN_impDBESJ0:
5332 case FFEINTRIN_impDBESJ1:
5333 case FFEINTRIN_impDBESJN:
5334 case FFEINTRIN_impDBESY0:
5335 case FFEINTRIN_impDBESY1:
5336 case FFEINTRIN_impDBESYN:
5337 case FFEINTRIN_impDTIME_func:
5338 case FFEINTRIN_impETIME_func:
5339 case FFEINTRIN_impFGETC_func:
5340 case FFEINTRIN_impFGET_func:
5341 case FFEINTRIN_impFNUM:
5342 case FFEINTRIN_impFPUTC_func:
5343 case FFEINTRIN_impFPUT_func:
5344 case FFEINTRIN_impFSEEK:
5345 case FFEINTRIN_impFSTAT_func:
5346 case FFEINTRIN_impFTELL_func:
5347 case FFEINTRIN_impGERROR:
5348 case FFEINTRIN_impGETARG:
5349 case FFEINTRIN_impGETCWD_func:
5350 case FFEINTRIN_impGETENV:
5351 case FFEINTRIN_impGETGID:
5352 case FFEINTRIN_impGETLOG:
5353 case FFEINTRIN_impGETPID:
5354 case FFEINTRIN_impGETUID:
5355 case FFEINTRIN_impGMTIME:
5356 case FFEINTRIN_impHOSTNM_func:
5357 case FFEINTRIN_impIDATE_unix:
5358 case FFEINTRIN_impIDATE_vxt:
5359 case FFEINTRIN_impIERRNO:
5360 case FFEINTRIN_impISATTY:
5361 case FFEINTRIN_impITIME:
5362 case FFEINTRIN_impKILL_func:
5363 case FFEINTRIN_impLINK_func:
5364 case FFEINTRIN_impLNBLNK:
5365 case FFEINTRIN_impLSTAT_func:
5366 case FFEINTRIN_impLTIME:
5367 case FFEINTRIN_impMCLOCK8:
5368 case FFEINTRIN_impMCLOCK:
5369 case FFEINTRIN_impPERROR:
5370 case FFEINTRIN_impRENAME_func:
5371 case FFEINTRIN_impSECNDS:
5372 case FFEINTRIN_impSECOND_func:
5373 case FFEINTRIN_impSLEEP:
5374 case FFEINTRIN_impSRAND:
5375 case FFEINTRIN_impSTAT_func:
5376 case FFEINTRIN_impSYMLNK_func:
5377 case FFEINTRIN_impSYSTEM_CLOCK:
5378 case FFEINTRIN_impSYSTEM_func:
5379 case FFEINTRIN_impTIME8:
5380 case FFEINTRIN_impTIME_unix:
5381 case FFEINTRIN_impTIME_vxt:
5382 case FFEINTRIN_impUMASK_func:
5383 case FFEINTRIN_impUNLINK_func:
5386 case FFEINTRIN_impCTIME_func: /* CHARACTER functions not handled here. */
5387 case FFEINTRIN_impFDATE_func: /* CHARACTER functions not handled here. */
5388 case FFEINTRIN_impTTYNAM_func: /* CHARACTER functions not handled here. */
5389 case FFEINTRIN_impNONE:
5390 case FFEINTRIN_imp: /* Hush up gcc warning. */
5391 fprintf (stderr, "No %s implementation.\n",
5392 ffeintrin_name_implementation (ffebld_symter_implementation (ffebld_left (expr))));
5393 assert ("unimplemented intrinsic" == NULL);
5394 return error_mark_node;
5397 assert (gfrt != FFECOM_gfrt); /* Must have an implementation! */
5399 expr_tree = ffecom_arglist_expr_ (ffecom_gfrt_args_ (gfrt),
5400 ffebld_right (expr));
5402 return ffecom_call_ (ffecom_gfrt_tree_ (gfrt), ffecom_gfrt_kindtype (gfrt),
5403 (ffe_is_f2c_library () && ffecom_gfrt_complex_[gfrt]),
5405 expr_tree, dest_tree, dest, dest_used,
5407 ffebld_nonter_hook (expr));
5409 /* See bottom of this file for f2c transforms used to determine
5410 many of the above implementations. The info seems to confuse
5411 Emacs's C mode indentation, which is why it's been moved to
5412 the bottom of this source file. */
5415 /* For power (exponentiation) where right-hand operand is type INTEGER,
5416 generate in-line code to do it the fast way (which, if the operand
5417 is a constant, might just mean a series of multiplies). */
5420 ffecom_expr_power_integer_ (ffebld expr)
5422 tree l = ffecom_expr (ffebld_left (expr));
5423 tree r = ffecom_expr (ffebld_right (expr));
5424 tree ltype = TREE_TYPE (l);
5425 tree rtype = TREE_TYPE (r);
5426 tree result = NULL_TREE;
5428 if (l == error_mark_node
5429 || r == error_mark_node)
5430 return error_mark_node;
5432 if (TREE_CODE (r) == INTEGER_CST)
5434 int sgn = tree_int_cst_sgn (r);
5437 return convert (ltype, integer_one_node);
5439 if ((TREE_CODE (ltype) == INTEGER_TYPE)
5442 /* Reciprocal of integer is either 0, -1, or 1, so after
5443 calculating that (which we leave to the back end to do
5444 or not do optimally), don't bother with any multiplying. */
5446 result = ffecom_tree_divide_ (ltype,
5447 convert (ltype, integer_one_node),
5449 NULL_TREE, NULL, NULL, NULL_TREE);
5450 r = ffecom_1 (NEGATE_EXPR,
5453 if ((TREE_INT_CST_LOW (r) & 1) == 0)
5454 result = ffecom_1 (ABS_EXPR, rtype,
5458 /* Generate appropriate series of multiplies, preceded
5459 by divide if the exponent is negative. */
5465 l = ffecom_tree_divide_ (ltype,
5466 convert (ltype, integer_one_node),
5468 NULL_TREE, NULL, NULL,
5469 ffebld_nonter_hook (expr));
5470 r = ffecom_1 (NEGATE_EXPR, rtype, r);
5471 assert (TREE_CODE (r) == INTEGER_CST);
5473 if (tree_int_cst_sgn (r) < 0)
5474 { /* The "most negative" number. */
5475 r = ffecom_1 (NEGATE_EXPR, rtype,
5476 ffecom_2 (RSHIFT_EXPR, rtype,
5480 l = ffecom_2 (MULT_EXPR, ltype,
5488 if (TREE_INT_CST_LOW (r) & 1)
5490 if (result == NULL_TREE)
5493 result = ffecom_2 (MULT_EXPR, ltype,
5498 r = ffecom_2 (RSHIFT_EXPR, rtype,
5501 if (integer_zerop (r))
5503 assert (TREE_CODE (r) == INTEGER_CST);
5506 l = ffecom_2 (MULT_EXPR, ltype,
5513 /* Though rhs isn't a constant, in-line code cannot be expanded
5514 while transforming dummies
5515 because the back end cannot be easily convinced to generate
5516 stores (MODIFY_EXPR), handle temporaries, and so on before
5517 all the appropriate rtx's have been generated for things like
5518 dummy args referenced in rhs -- which doesn't happen until
5519 store_parm_decls() is called (expand_function_start, I believe,
5520 does the actual rtx-stuffing of PARM_DECLs).
5522 So, in this case, let the caller generate the call to the
5523 run-time-library function to evaluate the power for us. */
5525 if (ffecom_transform_only_dummies_)
5528 /* Right-hand operand not a constant, expand in-line code to figure
5529 out how to do the multiplies, &c.
5531 The returned expression is expressed this way in GNU C, where l and
5534 ({ typeof (r) rtmp = r;
5535 typeof (l) ltmp = l;
5542 if ((basetypeof (l) == basetypeof (int))
5545 result = ((typeof (l)) 1) / ltmp;
5546 if ((ltmp < 0) && (((-rtmp) & 1) == 0))
5552 if ((basetypeof (l) != basetypeof (int))
5555 ltmp = ((typeof (l)) 1) / ltmp;
5559 rtmp = -(rtmp >> 1);
5567 if ((rtmp >>= 1) == 0)
5576 Note that some of the above is compile-time collapsable, such as
5577 the first part of the if statements that checks the base type of
5578 l against int. The if statements are phrased that way to suggest
5579 an easy way to generate the if/else constructs here, knowing that
5580 the back end should (and probably does) eliminate the resulting
5581 dead code (either the int case or the non-int case), something
5582 it couldn't do without the redundant phrasing, requiring explicit
5583 dead-code elimination here, which would be kind of difficult to
5590 tree basetypeof_l_is_int;
5595 = build_int_2 ((TREE_CODE (ltype) == INTEGER_TYPE), 0);
5597 se = expand_start_stmt_expr (/*has_scope=*/1);
5599 ffecom_start_compstmt ();
5601 rtmp = ffecom_make_tempvar ("power_r", rtype,
5602 FFETARGET_charactersizeNONE, -1);
5603 ltmp = ffecom_make_tempvar ("power_l", ltype,
5604 FFETARGET_charactersizeNONE, -1);
5605 result = ffecom_make_tempvar ("power_res", ltype,
5606 FFETARGET_charactersizeNONE, -1);
5607 if (TREE_CODE (ltype) == COMPLEX_TYPE
5608 || TREE_CODE (ltype) == RECORD_TYPE)
5609 divide = ffecom_make_tempvar ("power_div", ltype,
5610 FFETARGET_charactersizeNONE, -1);
5614 expand_expr_stmt (ffecom_modify (void_type_node,
5617 expand_expr_stmt (ffecom_modify (void_type_node,
5620 expand_start_cond (ffecom_truth_value
5621 (ffecom_2 (EQ_EXPR, integer_type_node,
5623 convert (rtype, integer_zero_node))),
5625 expand_expr_stmt (ffecom_modify (void_type_node,
5627 convert (ltype, integer_one_node)));
5628 expand_start_else ();
5629 if (! integer_zerop (basetypeof_l_is_int))
5631 expand_start_cond (ffecom_2 (LT_EXPR, integer_type_node,
5634 integer_zero_node)),
5636 expand_expr_stmt (ffecom_modify (void_type_node,
5640 convert (ltype, integer_one_node),
5642 NULL_TREE, NULL, NULL,
5644 expand_start_cond (ffecom_truth_value
5645 (ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
5646 ffecom_2 (LT_EXPR, integer_type_node,
5649 integer_zero_node)),
5650 ffecom_2 (EQ_EXPR, integer_type_node,
5651 ffecom_2 (BIT_AND_EXPR,
5653 ffecom_1 (NEGATE_EXPR,
5659 integer_zero_node)))),
5661 expand_expr_stmt (ffecom_modify (void_type_node,
5663 ffecom_1 (NEGATE_EXPR,
5667 expand_start_else ();
5669 expand_expr_stmt (ffecom_modify (void_type_node,
5671 convert (ltype, integer_one_node)));
5672 expand_start_cond (ffecom_truth_value
5673 (ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
5674 ffecom_truth_value_invert
5675 (basetypeof_l_is_int),
5676 ffecom_2 (LT_EXPR, integer_type_node,
5679 integer_zero_node)))),
5681 expand_expr_stmt (ffecom_modify (void_type_node,
5685 convert (ltype, integer_one_node),
5687 NULL_TREE, NULL, NULL,
5689 expand_expr_stmt (ffecom_modify (void_type_node,
5691 ffecom_1 (NEGATE_EXPR, rtype,
5693 expand_start_cond (ffecom_truth_value
5694 (ffecom_2 (LT_EXPR, integer_type_node,
5696 convert (rtype, integer_zero_node))),
5698 expand_expr_stmt (ffecom_modify (void_type_node,
5700 ffecom_1 (NEGATE_EXPR, rtype,
5701 ffecom_2 (RSHIFT_EXPR,
5704 integer_one_node))));
5705 expand_expr_stmt (ffecom_modify (void_type_node,
5707 ffecom_2 (MULT_EXPR, ltype,
5712 expand_start_loop (1);
5713 expand_start_cond (ffecom_truth_value
5714 (ffecom_2 (BIT_AND_EXPR, rtype,
5716 convert (rtype, integer_one_node))),
5718 expand_expr_stmt (ffecom_modify (void_type_node,
5720 ffecom_2 (MULT_EXPR, ltype,
5724 expand_exit_loop_if_false (NULL,
5726 (ffecom_modify (rtype,
5728 ffecom_2 (RSHIFT_EXPR,
5731 integer_one_node))));
5732 expand_expr_stmt (ffecom_modify (void_type_node,
5734 ffecom_2 (MULT_EXPR, ltype,
5739 if (!integer_zerop (basetypeof_l_is_int))
5741 expand_expr_stmt (result);
5743 t = ffecom_end_compstmt ();
5745 result = expand_end_stmt_expr (se);
5747 /* This code comes from c-parse.in, after its expand_end_stmt_expr. */
5749 if (TREE_CODE (t) == BLOCK)
5751 /* Make a BIND_EXPR for the BLOCK already made. */
5752 result = build (BIND_EXPR, TREE_TYPE (result),
5753 NULL_TREE, result, t);
5754 /* Remove the block from the tree at this point.
5755 It gets put back at the proper place
5756 when the BIND_EXPR is expanded. */
5766 /* ffecom_expr_transform_ -- Transform symbols in expr
5768 ffebld expr; // FFE expression.
5769 ffecom_expr_transform_ (expr);
5771 Recursive descent on expr while transforming any untransformed SYMTERs. */
5774 ffecom_expr_transform_ (ffebld expr)
5784 switch (ffebld_op (expr))
5786 case FFEBLD_opSYMTER:
5787 s = ffebld_symter (expr);
5788 t = ffesymbol_hook (s).decl_tree;
5789 if ((t == NULL_TREE)
5790 && ((ffesymbol_kind (s) != FFEINFO_kindNONE)
5791 || ((ffesymbol_where (s) != FFEINFO_whereNONE)
5792 && (ffesymbol_where (s) != FFEINFO_whereINTRINSIC))))
5794 s = ffecom_sym_transform_ (s);
5795 t = ffesymbol_hook (s).decl_tree; /* Sfunc expr non-dummy,
5798 break; /* Ok if (t == NULL) here. */
5801 ffecom_expr_transform_ (ffebld_head (expr));
5802 expr = ffebld_trail (expr);
5803 goto tail_recurse; /* :::::::::::::::::::: */
5809 switch (ffebld_arity (expr))
5812 ffecom_expr_transform_ (ffebld_left (expr));
5813 expr = ffebld_right (expr);
5814 goto tail_recurse; /* :::::::::::::::::::: */
5817 expr = ffebld_left (expr);
5818 goto tail_recurse; /* :::::::::::::::::::: */
5827 /* Make a type based on info in live f2c.h file. */
5830 ffecom_f2c_make_type_ (tree *type, int tcode, const char *name)
5834 case FFECOM_f2ccodeCHAR:
5835 *type = make_signed_type (CHAR_TYPE_SIZE);
5838 case FFECOM_f2ccodeSHORT:
5839 *type = make_signed_type (SHORT_TYPE_SIZE);
5842 case FFECOM_f2ccodeINT:
5843 *type = make_signed_type (INT_TYPE_SIZE);
5846 case FFECOM_f2ccodeLONG:
5847 *type = make_signed_type (LONG_TYPE_SIZE);
5850 case FFECOM_f2ccodeLONGLONG:
5851 *type = make_signed_type (LONG_LONG_TYPE_SIZE);
5854 case FFECOM_f2ccodeCHARPTR:
5855 *type = build_pointer_type (DEFAULT_SIGNED_CHAR
5856 ? signed_char_type_node
5857 : unsigned_char_type_node);
5860 case FFECOM_f2ccodeFLOAT:
5861 *type = make_node (REAL_TYPE);
5862 TYPE_PRECISION (*type) = FLOAT_TYPE_SIZE;
5863 layout_type (*type);
5866 case FFECOM_f2ccodeDOUBLE:
5867 *type = make_node (REAL_TYPE);
5868 TYPE_PRECISION (*type) = DOUBLE_TYPE_SIZE;
5869 layout_type (*type);
5872 case FFECOM_f2ccodeLONGDOUBLE:
5873 *type = make_node (REAL_TYPE);
5874 TYPE_PRECISION (*type) = LONG_DOUBLE_TYPE_SIZE;
5875 layout_type (*type);
5878 case FFECOM_f2ccodeTWOREALS:
5879 *type = ffecom_make_complex_type_ (ffecom_f2c_real_type_node);
5882 case FFECOM_f2ccodeTWODOUBLEREALS:
5883 *type = ffecom_make_complex_type_ (ffecom_f2c_doublereal_type_node);
5887 assert ("unexpected FFECOM_f2ccodeXYZZY!" == NULL);
5888 *type = error_mark_node;
5892 pushdecl (build_decl (TYPE_DECL,
5893 ffecom_get_invented_identifier ("__g77_f2c_%s", name),
5897 /* Set the f2c list-directed-I/O code for whatever (integral) type has the
5901 ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size, int code)
5906 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
5907 if ((t = ffecom_tree_type[bt][j]) != NULL_TREE
5908 && compare_tree_int (TYPE_SIZE (t), size) == 0)
5910 assert (code != -1);
5911 ffecom_f2c_typecode_[bt][j] = code;
5916 /* Finish up globals after doing all program units in file
5918 Need to handle only uninitialized COMMON areas. */
5921 ffecom_finish_global_ (ffeglobal global)
5927 if (ffeglobal_type (global) != FFEGLOBAL_typeCOMMON)
5930 if (ffeglobal_common_init (global))
5933 cbt = ffeglobal_hook (global);
5934 if ((cbt == NULL_TREE)
5935 || !ffeglobal_common_have_size (global))
5936 return global; /* No need to make common, never ref'd. */
5938 DECL_EXTERNAL (cbt) = 0;
5940 /* Give the array a size now. */
5942 size = build_int_2 ((ffeglobal_common_size (global)
5943 + ffeglobal_common_pad (global)) - 1,
5946 cbtype = TREE_TYPE (cbt);
5947 TYPE_DOMAIN (cbtype) = build_range_type (integer_type_node,
5950 if (!TREE_TYPE (size))
5951 TREE_TYPE (size) = TYPE_DOMAIN (cbtype);
5952 layout_type (cbtype);
5954 cbt = start_decl (cbt, FALSE);
5955 assert (cbt == ffeglobal_hook (global));
5957 finish_decl (cbt, NULL_TREE, FALSE);
5962 /* Finish up any untransformed symbols. */
5965 ffecom_finish_symbol_transform_ (ffesymbol s)
5967 if ((s == NULL) || (TREE_CODE (current_function_decl) == ERROR_MARK))
5970 /* It's easy to know to transform an untransformed symbol, to make sure
5971 we put out debugging info for it. But COMMON variables, unlike
5972 EQUIVALENCE ones, aren't given declarations in addition to the
5973 tree expressions that specify offsets, because COMMON variables
5974 can be referenced in the outer scope where only dummy arguments
5975 (PARM_DECLs) should really be seen. To be safe, just don't do any
5976 VAR_DECLs for COMMON variables when we transform them for real
5977 use, and therefore we do all the VAR_DECL creating here. */
5979 if (ffesymbol_hook (s).decl_tree == NULL_TREE)
5981 if (ffesymbol_kind (s) != FFEINFO_kindNONE
5982 || (ffesymbol_where (s) != FFEINFO_whereNONE
5983 && ffesymbol_where (s) != FFEINFO_whereINTRINSIC
5984 && ffesymbol_where (s) != FFEINFO_whereDUMMY))
5985 /* Not transformed, and not CHARACTER*(*), and not a dummy
5986 argument, which can happen only if the entry point names
5987 it "rides in on" are all invalidated for other reasons. */
5988 s = ffecom_sym_transform_ (s);
5991 if ((ffesymbol_where (s) == FFEINFO_whereCOMMON)
5992 && (ffesymbol_hook (s).decl_tree != error_mark_node))
5994 /* This isn't working, at least for dbxout. The .s file looks
5995 okay to me (burley), but in gdb 4.9 at least, the variables
5996 appear to reside somewhere outside of the common area, so
5997 it doesn't make sense to mislead anyone by generating the info
5998 on those variables until this is fixed. NOTE: Same problem
5999 with EQUIVALENCE, sadly...see similar #if later. */
6000 ffecom_member_phase2_ (ffesymbol_storage (ffesymbol_common (s)),
6001 ffesymbol_storage (s));
6007 /* Append underscore(s) to name before calling get_identifier. "us"
6008 is nonzero if the name already contains an underscore and thus
6009 needs two underscores appended. */
6012 ffecom_get_appended_identifier_ (char us, const char *name)
6018 newname = xmalloc ((i = strlen (name)) + 1
6019 + ffe_is_underscoring ()
6021 memcpy (newname, name, i);
6023 newname[i + us] = '_';
6024 newname[i + 1 + us] = '\0';
6025 id = get_identifier (newname);
6032 /* Decide whether to append underscore to name before calling
6036 ffecom_get_external_identifier_ (ffesymbol s)
6039 const char *name = ffesymbol_text (s);
6041 /* If name is a built-in name, just return it as is. */
6043 if (!ffe_is_underscoring ()
6044 || (strcmp (name, FFETARGET_nameBLANK_COMMON) == 0)
6045 || (strcmp (name, FFETARGET_nameUNNAMED_MAIN) == 0)
6046 || (strcmp (name, FFETARGET_nameUNNAMED_BLOCK_DATA) == 0))
6047 return get_identifier (name);
6049 us = ffe_is_second_underscore ()
6050 ? (strchr (name, '_') != NULL)
6053 return ffecom_get_appended_identifier_ (us, name);
6056 /* Decide whether to append underscore to internal name before calling
6059 This is for non-external, top-function-context names only. Transform
6060 identifier so it doesn't conflict with the transformed result
6061 of using a _different_ external name. E.g. if "CALL FOO" is
6062 transformed into "FOO_();", then the variable in "FOO_ = 3"
6063 must be transformed into something that does not conflict, since
6064 these two things should be independent.
6066 The transformation is as follows. If the name does not contain
6067 an underscore, there is no possible conflict, so just return.
6068 If the name does contain an underscore, then transform it just
6069 like we transform an external identifier. */
6072 ffecom_get_identifier_ (const char *name)
6074 /* If name does not contain an underscore, just return it as is. */
6076 if (!ffe_is_underscoring ()
6077 || (strchr (name, '_') == NULL))
6078 return get_identifier (name);
6080 return ffecom_get_appended_identifier_ (ffe_is_second_underscore (),
6084 /* ffecom_gen_sfuncdef_ -- Generate definition of statement function
6087 ffesymbol s; // kindFUNCTION, whereIMMEDIATE.
6088 t = ffecom_gen_sfuncdef_(s,ffesymbol_basictype(s),
6089 ffesymbol_kindtype(s));
6091 Call after setting up containing function and getting trees for all
6095 ffecom_gen_sfuncdef_ (ffesymbol s, ffeinfoBasictype bt, ffeinfoKindtype kt)
6097 ffebld expr = ffesymbol_sfexpr (s);
6101 bool charfunc = (bt == FFEINFO_basictypeCHARACTER);
6102 static bool recurse = FALSE;
6103 location_t old_loc = input_location;
6105 ffecom_nested_entry_ = s;
6107 /* For now, we don't have a handy pointer to where the sfunc is actually
6108 defined, though that should be easy to add to an ffesymbol. (The
6109 token/where info available might well point to the place where the type
6110 of the sfunc is declared, especially if that precedes the place where
6111 the sfunc itself is defined, which is typically the case.) We should
6112 put out a null pointer rather than point somewhere wrong, but I want to
6113 see how it works at this point. */
6115 input_filename = ffesymbol_where_filename (s);
6116 input_line = ffesymbol_where_filelinenum (s);
6118 /* Pretransform the expression so any newly discovered things belong to the
6119 outer program unit, not to the statement function. */
6121 ffecom_expr_transform_ (expr);
6123 /* Make sure no recursive invocation of this fn (a specific case of failing
6124 to pretransform an sfunc's expression, i.e. where its expression
6125 references another untransformed sfunc) happens. */
6130 push_f_function_context ();
6133 type = void_type_node;
6136 type = ffecom_tree_type[bt][kt];
6137 if (type == NULL_TREE)
6138 type = integer_type_node; /* _sym_exec_transition reports
6142 start_function (ffecom_get_identifier_ (ffesymbol_text (s)),
6143 build_function_type (type, NULL_TREE),
6144 1, /* nested/inline */
6145 0); /* TREE_PUBLIC */
6147 /* We don't worry about COMPLEX return values here, because this is
6148 entirely internal to our code, and gcc has the ability to return COMPLEX
6149 directly as a value. */
6152 { /* Prepend arg for where result goes. */
6155 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
6157 result = ffecom_get_invented_identifier ("__g77_%s", "result");
6159 ffecom_char_enhance_arg_ (&type, s); /* Ignore returned length. */
6161 type = build_pointer_type (type);
6162 result = build_decl (PARM_DECL, result, type);
6164 push_parm_decl (result);
6167 result = NULL_TREE; /* Not ref'd if !charfunc. */
6169 ffecom_push_dummy_decls_ (ffesymbol_dummyargs (s), TRUE);
6171 store_parm_decls (0);
6173 ffecom_start_compstmt ();
6179 ffetargetCharacterSize sz = ffesymbol_size (s);
6182 result_length = build_int_2 (sz, 0);
6183 TREE_TYPE (result_length) = ffecom_f2c_ftnlen_type_node;
6185 ffecom_prepare_let_char_ (sz, expr);
6187 ffecom_prepare_end ();
6189 ffecom_let_char_ (result, result_length, sz, expr);
6190 expand_null_return ();
6194 ffecom_prepare_expr (expr);
6196 ffecom_prepare_end ();
6198 expand_return (ffecom_modify (NULL_TREE,
6199 DECL_RESULT (current_function_decl),
6200 ffecom_expr (expr)));
6204 ffecom_end_compstmt ();
6206 func = current_function_decl;
6207 finish_function (1);
6209 pop_f_function_context ();
6213 input_location = old_loc;
6215 ffecom_nested_entry_ = NULL;
6221 ffecom_gfrt_args_ (ffecomGfrt ix)
6223 return ffecom_gfrt_argstring_[ix];
6227 ffecom_gfrt_tree_ (ffecomGfrt ix)
6229 if (ffecom_gfrt_[ix] == NULL_TREE)
6230 ffecom_make_gfrt_ (ix);
6232 return ffecom_1 (ADDR_EXPR,
6233 build_pointer_type (TREE_TYPE (ffecom_gfrt_[ix])),
6237 /* Return initialize-to-zero expression for this VAR_DECL. */
6239 /* A somewhat evil way to prevent the garbage collector
6240 from collecting 'tree' structures. */
6241 #define NUM_TRACKED_CHUNK 63
6242 struct tree_ggc_tracker GTY(())
6244 struct tree_ggc_tracker *next;
6245 tree trees[NUM_TRACKED_CHUNK];
6247 static GTY(()) struct tree_ggc_tracker *tracker_head;
6250 ffecom_save_tree_forever (tree t)
6253 if (tracker_head != NULL)
6254 for (i = 0; i < NUM_TRACKED_CHUNK; i++)
6255 if (tracker_head->trees[i] == NULL)
6257 tracker_head->trees[i] = t;
6262 /* Need to allocate a new block. */
6263 struct tree_ggc_tracker *old_head = tracker_head;
6265 tracker_head = ggc_alloc (sizeof (*tracker_head));
6266 tracker_head->next = old_head;
6267 tracker_head->trees[0] = t;
6268 for (i = 1; i < NUM_TRACKED_CHUNK; i++)
6269 tracker_head->trees[i] = NULL;
6274 ffecom_init_zero_ (tree decl)
6277 int incremental = TREE_STATIC (decl);
6278 tree type = TREE_TYPE (decl);
6282 make_decl_rtl (decl, NULL);
6283 assemble_variable (decl, TREE_PUBLIC (decl) ? 1 : 0, 0, 1);
6286 if ((TREE_CODE (type) != ARRAY_TYPE)
6287 && (TREE_CODE (type) != RECORD_TYPE)
6288 && (TREE_CODE (type) != UNION_TYPE)
6290 init = convert (type, integer_zero_node);
6291 else if (!incremental)
6293 init = build_constructor (type, NULL_TREE);
6294 TREE_CONSTANT (init) = 1;
6295 TREE_STATIC (init) = 1;
6299 assemble_zeros (int_size_in_bytes (type));
6300 init = error_mark_node;
6307 ffecom_intrinsic_ichar_ (tree tree_type, ffebld arg, tree *maybe_tree)
6312 switch (ffebld_op (arg))
6314 case FFEBLD_opCONTER: /* For F90, check 0-length. */
6315 if (ffetarget_length_character1
6316 (ffebld_constant_character1
6317 (ffebld_conter (arg))) == 0)
6319 *maybe_tree = integer_zero_node;
6320 return convert (tree_type, integer_zero_node);
6323 *maybe_tree = integer_one_node;
6324 expr_tree = build_int_2 (*ffetarget_text_character1
6325 (ffebld_constant_character1
6326 (ffebld_conter (arg))),
6328 TREE_TYPE (expr_tree) = tree_type;
6331 case FFEBLD_opSYMTER:
6332 case FFEBLD_opARRAYREF:
6333 case FFEBLD_opFUNCREF:
6334 case FFEBLD_opSUBSTR:
6335 ffecom_char_args_ (&expr_tree, &length_tree, arg);
6337 if ((expr_tree == error_mark_node)
6338 || (length_tree == error_mark_node))
6340 *maybe_tree = error_mark_node;
6341 return error_mark_node;
6344 if (integer_zerop (length_tree))
6346 *maybe_tree = integer_zero_node;
6347 return convert (tree_type, integer_zero_node);
6351 = ffecom_1 (INDIRECT_REF,
6352 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
6355 = ffecom_2 (ARRAY_REF,
6356 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
6359 expr_tree = convert (tree_type, expr_tree);
6361 if (TREE_CODE (length_tree) == INTEGER_CST)
6362 *maybe_tree = integer_one_node;
6363 else /* Must check length at run time. */
6365 = ffecom_truth_value
6366 (ffecom_2 (GT_EXPR, integer_type_node,
6368 ffecom_f2c_ftnlen_zero_node));
6371 case FFEBLD_opPAREN:
6372 case FFEBLD_opCONVERT:
6373 if (ffeinfo_size (ffebld_info (arg)) == 0)
6375 *maybe_tree = integer_zero_node;
6376 return convert (tree_type, integer_zero_node);
6378 return ffecom_intrinsic_ichar_ (tree_type, ffebld_left (arg),
6381 case FFEBLD_opCONCATENATE:
6388 expr_left = ffecom_intrinsic_ichar_ (tree_type, ffebld_left (arg),
6390 expr_right = ffecom_intrinsic_ichar_ (tree_type, ffebld_right (arg),
6392 *maybe_tree = ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
6395 expr_tree = ffecom_3 (COND_EXPR, tree_type,
6403 assert ("bad op in ICHAR" == NULL);
6404 return error_mark_node;
6408 /* ffecom_intrinsic_len_ -- Return length info for char arg (LEN())
6412 length_arg = ffecom_intrinsic_len_ (expr);
6414 Handles CHARACTER-type CONTER, SYMTER, SUBSTR, ARRAYREF, and FUNCREF
6415 subexpressions by constructing the appropriate tree for the
6416 length-of-character-text argument in a calling sequence. */
6419 ffecom_intrinsic_len_ (ffebld expr)
6421 ffetargetCharacter1 val;
6424 switch (ffebld_op (expr))
6426 case FFEBLD_opCONTER:
6427 val = ffebld_constant_character1 (ffebld_conter (expr));
6428 length = build_int_2 (ffetarget_length_character1 (val), 0);
6429 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6432 case FFEBLD_opSYMTER:
6434 ffesymbol s = ffebld_symter (expr);
6437 item = ffesymbol_hook (s).decl_tree;
6438 if (item == NULL_TREE)
6440 s = ffecom_sym_transform_ (s);
6441 item = ffesymbol_hook (s).decl_tree;
6443 if (ffesymbol_kind (s) == FFEINFO_kindENTITY)
6445 if (ffesymbol_size (s) == FFETARGET_charactersizeNONE)
6446 length = ffesymbol_hook (s).length_tree;
6449 length = build_int_2 (ffesymbol_size (s), 0);
6450 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6453 else if (item == error_mark_node)
6454 length = error_mark_node;
6455 else /* FFEINFO_kindFUNCTION: */
6460 case FFEBLD_opARRAYREF:
6461 length = ffecom_intrinsic_len_ (ffebld_left (expr));
6464 case FFEBLD_opSUBSTR:
6468 ffebld thing = ffebld_right (expr);
6472 assert (ffebld_op (thing) == FFEBLD_opITEM);
6473 start = ffebld_head (thing);
6474 thing = ffebld_trail (thing);
6475 assert (ffebld_trail (thing) == NULL);
6476 end = ffebld_head (thing);
6478 length = ffecom_intrinsic_len_ (ffebld_left (expr));
6480 if (length == error_mark_node)
6489 length = convert (ffecom_f2c_ftnlen_type_node,
6495 start_tree = convert (ffecom_f2c_ftnlen_type_node,
6496 ffecom_expr (start));
6498 if (start_tree == error_mark_node)
6500 length = error_mark_node;
6506 length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6507 ffecom_f2c_ftnlen_one_node,
6508 ffecom_2 (MINUS_EXPR,
6509 ffecom_f2c_ftnlen_type_node,
6515 end_tree = convert (ffecom_f2c_ftnlen_type_node,
6518 if (end_tree == error_mark_node)
6520 length = error_mark_node;
6524 length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6525 ffecom_f2c_ftnlen_one_node,
6526 ffecom_2 (MINUS_EXPR,
6527 ffecom_f2c_ftnlen_type_node,
6528 end_tree, start_tree));
6534 case FFEBLD_opCONCATENATE:
6536 = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6537 ffecom_intrinsic_len_ (ffebld_left (expr)),
6538 ffecom_intrinsic_len_ (ffebld_right (expr)));
6541 case FFEBLD_opFUNCREF:
6542 case FFEBLD_opCONVERT:
6543 length = build_int_2 (ffebld_size (expr), 0);
6544 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6548 assert ("bad op for single char arg expr" == NULL);
6549 length = ffecom_f2c_ftnlen_zero_node;
6553 assert (length != NULL_TREE);
6558 /* Handle CHARACTER assignments.
6560 Generates code to do the assignment. Used by ordinary assignment
6561 statement handler ffecom_let_stmt and by statement-function
6562 handler to generate code for a statement function. */
6565 ffecom_let_char_ (tree dest_tree, tree dest_length,
6566 ffetargetCharacterSize dest_size, ffebld source)
6568 ffecomConcatList_ catlist;
6573 if ((dest_tree == error_mark_node)
6574 || (dest_length == error_mark_node))
6577 assert (dest_tree != NULL_TREE);
6578 assert (dest_length != NULL_TREE);
6580 /* Source might be an opCONVERT, which just means it is a different size
6581 than the destination. Since the underlying implementation here handles
6582 that (directly or via the s_copy or s_cat run-time-library functions),
6583 we don't need the "convenience" of an opCONVERT that tells us to
6584 truncate or blank-pad, particularly since the resulting implementation
6585 would probably be slower than otherwise. */
6587 while (ffebld_op (source) == FFEBLD_opCONVERT)
6588 source = ffebld_left (source);
6590 catlist = ffecom_concat_list_new_ (source, dest_size);
6591 switch (ffecom_concat_list_count_ (catlist))
6593 case 0: /* Shouldn't happen, but in case it does... */
6594 ffecom_concat_list_kill_ (catlist);
6595 source_tree = null_pointer_node;
6596 source_length = ffecom_f2c_ftnlen_zero_node;
6597 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6598 TREE_CHAIN (expr_tree) = build_tree_list (NULL_TREE, source_tree);
6599 TREE_CHAIN (TREE_CHAIN (expr_tree))
6600 = build_tree_list (NULL_TREE, dest_length);
6601 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6602 = build_tree_list (NULL_TREE, source_length);
6604 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCOPY, expr_tree, NULL_TREE);
6605 TREE_SIDE_EFFECTS (expr_tree) = 1;
6607 expand_expr_stmt (expr_tree);
6611 case 1: /* The (fairly) easy case. */
6612 ffecom_char_args_ (&source_tree, &source_length,
6613 ffecom_concat_list_expr_ (catlist, 0));
6614 ffecom_concat_list_kill_ (catlist);
6615 assert (source_tree != NULL_TREE);
6616 assert (source_length != NULL_TREE);
6618 if ((source_tree == error_mark_node)
6619 || (source_length == error_mark_node))
6625 = ffecom_1 (INDIRECT_REF,
6626 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6630 = ffecom_2 (ARRAY_REF,
6631 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6636 = ffecom_1 (INDIRECT_REF,
6637 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6641 = ffecom_2 (ARRAY_REF,
6642 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6647 expr_tree = ffecom_modify (void_type_node, dest_tree, source_tree);
6649 expand_expr_stmt (expr_tree);
6654 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6655 TREE_CHAIN (expr_tree) = build_tree_list (NULL_TREE, source_tree);
6656 TREE_CHAIN (TREE_CHAIN (expr_tree))
6657 = build_tree_list (NULL_TREE, dest_length);
6658 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6659 = build_tree_list (NULL_TREE, source_length);
6661 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCOPY, expr_tree, NULL_TREE);
6662 TREE_SIDE_EFFECTS (expr_tree) = 1;
6664 expand_expr_stmt (expr_tree);
6668 default: /* Must actually concatenate things. */
6672 /* Heavy-duty concatenation. */
6675 int count = ffecom_concat_list_count_ (catlist);
6687 hook = ffebld_nonter_hook (source);
6689 assert (TREE_CODE (hook) == TREE_VEC);
6690 assert (TREE_VEC_LENGTH (hook) == 2);
6691 length_array = lengths = TREE_VEC_ELT (hook, 0);
6692 item_array = items = TREE_VEC_ELT (hook, 1);
6695 for (i = 0; i < count; ++i)
6697 ffecom_char_args_ (&citem, &clength,
6698 ffecom_concat_list_expr_ (catlist, i));
6699 if ((citem == error_mark_node)
6700 || (clength == error_mark_node))
6702 ffecom_concat_list_kill_ (catlist);
6707 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (items),
6708 ffecom_modify (void_type_node,
6709 ffecom_2 (ARRAY_REF,
6710 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array))),
6712 build_int_2 (i, 0)),
6716 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (lengths),
6717 ffecom_modify (void_type_node,
6718 ffecom_2 (ARRAY_REF,
6719 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array))),
6721 build_int_2 (i, 0)),
6726 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6727 TREE_CHAIN (expr_tree)
6728 = build_tree_list (NULL_TREE,
6729 ffecom_1 (ADDR_EXPR,
6730 build_pointer_type (TREE_TYPE (items)),
6732 TREE_CHAIN (TREE_CHAIN (expr_tree))
6733 = build_tree_list (NULL_TREE,
6734 ffecom_1 (ADDR_EXPR,
6735 build_pointer_type (TREE_TYPE (lengths)),
6737 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6740 ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
6741 convert (ffecom_f2c_ftnlen_type_node,
6742 build_int_2 (count, 0))));
6743 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree))))
6744 = build_tree_list (NULL_TREE, dest_length);
6746 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCAT, expr_tree, NULL_TREE);
6747 TREE_SIDE_EFFECTS (expr_tree) = 1;
6749 expand_expr_stmt (expr_tree);
6752 ffecom_concat_list_kill_ (catlist);
6755 /* ffecom_make_gfrt_ -- Make initial info for run-time routine
6758 ffecom_make_gfrt_(ix);
6760 Assumes gfrt_[ix] is NULL_TREE, and replaces it with the FUNCTION_DECL
6761 for the indicated run-time routine (ix). */
6764 ffecom_make_gfrt_ (ffecomGfrt ix)
6769 switch (ffecom_gfrt_type_[ix])
6771 case FFECOM_rttypeVOID_:
6772 ttype = void_type_node;
6775 case FFECOM_rttypeVOIDSTAR_:
6776 ttype = TREE_TYPE (null_pointer_node); /* `void *'. */
6779 case FFECOM_rttypeFTNINT_:
6780 ttype = ffecom_f2c_ftnint_type_node;
6783 case FFECOM_rttypeINTEGER_:
6784 ttype = ffecom_f2c_integer_type_node;
6787 case FFECOM_rttypeLONGINT_:
6788 ttype = ffecom_f2c_longint_type_node;
6791 case FFECOM_rttypeLOGICAL_:
6792 ttype = ffecom_f2c_logical_type_node;
6795 case FFECOM_rttypeREAL_F2C_:
6796 ttype = double_type_node;
6799 case FFECOM_rttypeREAL_GNU_:
6800 ttype = float_type_node;
6803 case FFECOM_rttypeCOMPLEX_F2C_:
6804 ttype = void_type_node;
6807 case FFECOM_rttypeCOMPLEX_GNU_:
6808 ttype = ffecom_f2c_complex_type_node;
6811 case FFECOM_rttypeDOUBLE_:
6812 ttype = double_type_node;
6815 case FFECOM_rttypeDOUBLEREAL_:
6816 ttype = ffecom_f2c_doublereal_type_node;
6819 case FFECOM_rttypeDBLCMPLX_F2C_:
6820 ttype = void_type_node;
6823 case FFECOM_rttypeDBLCMPLX_GNU_:
6824 ttype = ffecom_f2c_doublecomplex_type_node;
6827 case FFECOM_rttypeCHARACTER_:
6828 ttype = void_type_node;
6833 assert ("bad rttype" == NULL);
6837 ttype = build_function_type (ttype, NULL_TREE);
6838 t = build_decl (FUNCTION_DECL,
6839 get_identifier (ffecom_gfrt_name_[ix]),
6841 DECL_EXTERNAL (t) = 1;
6842 TREE_READONLY (t) = ffecom_gfrt_const_[ix] ? 1 : 0;
6843 TREE_PUBLIC (t) = 1;
6844 TREE_THIS_VOLATILE (t) = ffecom_gfrt_volatile_[ix] ? 1 : 0;
6846 /* Sanity check: A function that's const cannot be volatile. */
6848 assert (ffecom_gfrt_const_[ix] ? !ffecom_gfrt_volatile_[ix] : 1);
6850 /* Sanity check: A function that's const cannot return complex. */
6852 assert (ffecom_gfrt_const_[ix] ? !ffecom_gfrt_complex_[ix] : 1);
6854 t = start_decl (t, TRUE);
6856 finish_decl (t, NULL_TREE, TRUE);
6858 ffecom_gfrt_[ix] = t;
6861 /* Phase 1 pass over each member of a COMMON/EQUIVALENCE group. */
6864 ffecom_member_phase1_ (ffestorag mst UNUSED, ffestorag st)
6866 ffesymbol s = ffestorag_symbol (st);
6868 if (ffesymbol_namelisted (s))
6869 ffecom_member_namelisted_ = TRUE;
6872 /* Phase 2 pass over each member of a COMMON/EQUIVALENCE group. Declare
6873 the member so debugger will see it. Otherwise nobody should be
6874 referencing the member. */
6877 ffecom_member_phase2_ (ffestorag mst, ffestorag st)
6885 || ((mt = ffestorag_hook (mst)) == NULL)
6886 || (mt == error_mark_node))
6890 || ((s = ffestorag_symbol (st)) == NULL))
6893 type = ffecom_type_localvar_ (s,
6894 ffesymbol_basictype (s),
6895 ffesymbol_kindtype (s));
6896 if (type == error_mark_node)
6899 t = build_decl (VAR_DECL,
6900 ffecom_get_identifier_ (ffesymbol_text (s)),
6903 TREE_STATIC (t) = TREE_STATIC (mt);
6904 DECL_INITIAL (t) = NULL_TREE;
6905 TREE_ASM_WRITTEN (t) = 1;
6909 gen_rtx (MEM, TYPE_MODE (type),
6910 plus_constant (XEXP (DECL_RTL (mt), 0),
6911 ffestorag_modulo (mst)
6912 + ffestorag_offset (st)
6913 - ffestorag_offset (mst))));
6915 t = start_decl (t, FALSE);
6917 finish_decl (t, NULL_TREE, FALSE);
6920 /* Prepare source expression for assignment into a destination perhaps known
6921 to be of a specific size. */
6924 ffecom_prepare_let_char_ (ffetargetCharacterSize dest_size, ffebld source)
6926 ffecomConcatList_ catlist;
6931 tree tempvar = NULL_TREE;
6933 while (ffebld_op (source) == FFEBLD_opCONVERT)
6934 source = ffebld_left (source);
6936 catlist = ffecom_concat_list_new_ (source, dest_size);
6937 count = ffecom_concat_list_count_ (catlist);
6942 = ffecom_make_tempvar ("let_char_len", ffecom_f2c_ftnlen_type_node,
6943 FFETARGET_charactersizeNONE, count);
6945 = ffecom_make_tempvar ("let_char_item", ffecom_f2c_address_type_node,
6946 FFETARGET_charactersizeNONE, count);
6948 tempvar = make_tree_vec (2);
6949 TREE_VEC_ELT (tempvar, 0) = ltmp;
6950 TREE_VEC_ELT (tempvar, 1) = itmp;
6953 for (i = 0; i < count; ++i)
6954 ffecom_prepare_arg_ptr_to_expr (ffecom_concat_list_expr_ (catlist, i));
6956 ffecom_concat_list_kill_ (catlist);
6960 ffebld_nonter_set_hook (source, tempvar);
6961 current_binding_level->prep_state = 1;
6965 /* ffecom_push_dummy_decls_ -- Transform dummy args, push parm decls in order
6967 Ignores STAR (alternate-return) dummies. All other get exec-transitioned
6968 (which generates their trees) and then their trees get push_parm_decl'd.
6970 The second arg is TRUE if the dummies are for a statement function, in
6971 which case lengths are not pushed for character arguments (since they are
6972 always known by both the caller and the callee, though the code allows
6973 for someday permitting CHAR*(*) stmtfunc dummies). */
6976 ffecom_push_dummy_decls_ (ffebld dummy_list, bool stmtfunc)
6983 ffecom_transform_only_dummies_ = TRUE;
6985 /* First push the parms corresponding to actual dummy "contents". */
6987 for (dumlist = dummy_list; dumlist != NULL; dumlist = ffebld_trail (dumlist))
6989 dummy = ffebld_head (dumlist);
6990 switch (ffebld_op (dummy))
6994 continue; /* Forget alternate returns. */
6999 assert (ffebld_op (dummy) == FFEBLD_opSYMTER);
7000 s = ffebld_symter (dummy);
7001 parm = ffesymbol_hook (s).decl_tree;
7002 if (parm == NULL_TREE)
7004 s = ffecom_sym_transform_ (s);
7005 parm = ffesymbol_hook (s).decl_tree;
7006 assert (parm != NULL_TREE);
7008 if (parm != error_mark_node)
7009 push_parm_decl (parm);
7012 /* Then, for CHARACTER dummies, push the parms giving their lengths. */
7014 for (dumlist = dummy_list; dumlist != NULL; dumlist = ffebld_trail (dumlist))
7016 dummy = ffebld_head (dumlist);
7017 switch (ffebld_op (dummy))
7021 continue; /* Forget alternate returns, they mean
7027 s = ffebld_symter (dummy);
7028 if (ffesymbol_basictype (s) != FFEINFO_basictypeCHARACTER)
7029 continue; /* Only looking for CHARACTER arguments. */
7030 if (stmtfunc && (ffesymbol_size (s) != FFETARGET_charactersizeNONE))
7031 continue; /* Stmtfunc arg with known size needs no
7033 if (ffesymbol_kind (s) != FFEINFO_kindENTITY)
7034 continue; /* Only looking for variables and arrays. */
7035 parm = ffesymbol_hook (s).length_tree;
7036 assert (parm != NULL_TREE);
7037 if (parm != error_mark_node)
7038 push_parm_decl (parm);
7041 ffecom_transform_only_dummies_ = FALSE;
7044 /* ffecom_start_progunit_ -- Beginning of program unit
7046 Does GNU back end stuff necessary to teach it about the start of its
7047 equivalent of a Fortran program unit. */
7050 ffecom_start_progunit_ (void)
7052 ffesymbol fn = ffecom_primary_entry_;
7054 tree id; /* Identifier (name) of function. */
7055 tree type; /* Type of function. */
7056 tree result; /* Result of function. */
7057 ffeinfoBasictype bt;
7061 ffeglobalType egt = FFEGLOBAL_type;
7064 bool altentries = (ffecom_num_entrypoints_ != 0);
7067 && (ffecom_primary_entry_kind_ == FFEINFO_kindFUNCTION)
7068 && (ffecom_master_bt_ == FFEINFO_basictypeNONE);
7069 bool main_program = FALSE;
7070 location_t old_loc = input_location;
7072 assert (fn != NULL);
7073 assert (ffesymbol_hook (fn).decl_tree == NULL_TREE);
7075 input_filename = ffesymbol_where_filename (fn);
7076 input_line = ffesymbol_where_filelinenum (fn);
7078 switch (ffecom_primary_entry_kind_)
7080 case FFEINFO_kindPROGRAM:
7081 main_program = TRUE;
7082 gt = FFEGLOBAL_typeMAIN;
7083 bt = FFEINFO_basictypeNONE;
7084 kt = FFEINFO_kindtypeNONE;
7085 type = ffecom_tree_fun_type_void;
7090 case FFEINFO_kindBLOCKDATA:
7091 gt = FFEGLOBAL_typeBDATA;
7092 bt = FFEINFO_basictypeNONE;
7093 kt = FFEINFO_kindtypeNONE;
7094 type = ffecom_tree_fun_type_void;
7099 case FFEINFO_kindFUNCTION:
7100 gt = FFEGLOBAL_typeFUNC;
7101 egt = FFEGLOBAL_typeEXT;
7102 bt = ffesymbol_basictype (fn);
7103 kt = ffesymbol_kindtype (fn);
7104 if (bt == FFEINFO_basictypeNONE)
7106 ffeimplic_establish_symbol (fn);
7107 if (ffesymbol_funcresult (fn) != NULL)
7108 ffeimplic_establish_symbol (ffesymbol_funcresult (fn));
7109 bt = ffesymbol_basictype (fn);
7110 kt = ffesymbol_kindtype (fn);
7114 charfunc = cmplxfunc = FALSE;
7115 else if (bt == FFEINFO_basictypeCHARACTER)
7116 charfunc = TRUE, cmplxfunc = FALSE;
7117 else if ((bt == FFEINFO_basictypeCOMPLEX)
7118 && ffesymbol_is_f2c (fn)
7120 charfunc = FALSE, cmplxfunc = TRUE;
7122 charfunc = cmplxfunc = FALSE;
7124 if (multi || charfunc)
7125 type = ffecom_tree_fun_type_void;
7126 else if (ffesymbol_is_f2c (fn) && !altentries)
7127 type = ffecom_tree_fun_type[bt][kt];
7129 type = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
7131 if ((type == NULL_TREE)
7132 || (TREE_TYPE (type) == NULL_TREE))
7133 type = ffecom_tree_fun_type_void; /* _sym_exec_transition. */
7136 case FFEINFO_kindSUBROUTINE:
7137 gt = FFEGLOBAL_typeSUBR;
7138 egt = FFEGLOBAL_typeEXT;
7139 bt = FFEINFO_basictypeNONE;
7140 kt = FFEINFO_kindtypeNONE;
7141 if (ffecom_is_altreturning_)
7142 type = ffecom_tree_subr_type;
7144 type = ffecom_tree_fun_type_void;
7150 assert ("say what??" == NULL);
7152 case FFEINFO_kindANY:
7153 gt = FFEGLOBAL_typeANY;
7154 bt = FFEINFO_basictypeNONE;
7155 kt = FFEINFO_kindtypeNONE;
7156 type = error_mark_node;
7164 id = ffecom_get_invented_identifier ("__g77_masterfun_%s",
7165 ffesymbol_text (fn));
7167 #if FFETARGET_isENFORCED_MAIN
7168 else if (main_program)
7169 id = get_identifier (FFETARGET_nameENFORCED_MAIN_NAME);
7172 id = ffecom_get_external_identifier_ (fn);
7176 0, /* nested/inline */
7177 !altentries); /* TREE_PUBLIC */
7179 TREE_USED (current_function_decl) = 1; /* Avoid spurious warning if altentries. */
7182 && ((g = ffesymbol_global (fn)) != NULL)
7183 && ((ffeglobal_type (g) == gt)
7184 || (ffeglobal_type (g) == egt)))
7186 ffeglobal_set_hook (g, current_function_decl);
7189 /* Arg handling needs exec-transitioned ffesymbols to work with. But
7190 exec-transitioning needs current_function_decl to be filled in. So we
7191 do these things in two phases. */
7194 { /* 1st arg identifies which entrypoint. */
7195 ffecom_which_entrypoint_decl_
7196 = build_decl (PARM_DECL,
7197 ffecom_get_invented_identifier ("__g77_%s",
7198 "which_entrypoint"),
7200 push_parm_decl (ffecom_which_entrypoint_decl_);
7206 { /* Arg for result (return value). */
7211 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
7213 type = ffecom_tree_type[FFEINFO_basictypeCOMPLEX][kt];
7215 type = ffecom_multi_type_node_;
7217 result = ffecom_get_invented_identifier ("__g77_%s", "result");
7219 /* Make length arg _and_ enhance type info for CHAR arg itself. */
7222 length = ffecom_char_enhance_arg_ (&type, fn);
7224 length = NULL_TREE; /* Not ref'd if !charfunc. */
7226 type = build_pointer_type (type);
7227 result = build_decl (PARM_DECL, result, type);
7229 push_parm_decl (result);
7231 ffecom_multi_retval_ = result;
7233 ffecom_func_result_ = result;
7237 push_parm_decl (length);
7238 ffecom_func_length_ = length;
7242 if (ffecom_primary_entry_is_proc_)
7245 arglist = ffecom_master_arglist_;
7247 arglist = ffesymbol_dummyargs (fn);
7248 ffecom_push_dummy_decls_ (arglist, FALSE);
7251 if (TREE_CODE (current_function_decl) != ERROR_MARK)
7252 store_parm_decls (main_program ? 1 : 0);
7254 ffecom_start_compstmt ();
7255 /* Disallow temp vars at this level. */
7256 current_binding_level->prep_state = 2;
7258 input_location = old_loc;
7260 /* This handles any symbols still untransformed, in case -g specified.
7261 This used to be done in ffecom_finish_progunit, but it turns out to
7262 be necessary to do it here so that statement functions are
7263 expanded before code. But don't bother for BLOCK DATA. */
7265 if (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA)
7266 ffesymbol_drive (ffecom_finish_symbol_transform_);
7269 /* ffecom_sym_transform_ -- Transform FFE sym into backend sym
7272 ffecom_sym_transform_(s);
7274 The ffesymbol_hook info for s is updated with appropriate backend info
7278 ffecom_sym_transform_ (ffesymbol s)
7280 tree t; /* Transformed thingy. */
7281 tree tlen; /* Length if CHAR*(*). */
7282 bool addr; /* Is t the address of the thingy? */
7283 ffeinfoBasictype bt;
7286 location_t old_loc = input_location;
7288 /* Must ensure special ASSIGN variables are declared at top of outermost
7289 block, else they'll end up in the innermost block when their first
7290 ASSIGN is seen, which leaves them out of scope when they're the
7291 subject of a GOTO or I/O statement.
7293 We make this variable even if -fugly-assign. Just let it go unused,
7294 in case it turns out there are cases where we really want to use this
7295 variable anyway (e.g. ASSIGN to INTEGER*2 variable). */
7297 if (! ffecom_transform_only_dummies_
7298 && ffesymbol_assigned (s)
7299 && ! ffesymbol_hook (s).assign_tree)
7300 s = ffecom_sym_transform_assign_ (s);
7302 if (ffesymbol_sfdummyparent (s) == NULL)
7304 input_filename = ffesymbol_where_filename (s);
7305 input_line = ffesymbol_where_filelinenum (s);
7309 ffesymbol sf = ffesymbol_sfdummyparent (s);
7311 input_filename = ffesymbol_where_filename (sf);
7312 input_line = ffesymbol_where_filelinenum (sf);
7315 bt = ffeinfo_basictype (ffebld_info (s));
7316 kt = ffeinfo_kindtype (ffebld_info (s));
7322 switch (ffesymbol_kind (s))
7324 case FFEINFO_kindNONE:
7325 switch (ffesymbol_where (s))
7327 case FFEINFO_whereDUMMY: /* Subroutine or function. */
7328 assert (ffecom_transform_only_dummies_);
7330 /* Before 0.4, this could be ENTITY/DUMMY, but see
7331 ffestu_sym_end_transition -- no longer true (in particular, if
7332 it could be an ENTITY, it _will_ be made one, so that
7333 possibility won't come through here). So we never make length
7334 arg for CHARACTER type. */
7336 t = build_decl (PARM_DECL,
7337 ffecom_get_identifier_ (ffesymbol_text (s)),
7338 ffecom_tree_ptr_to_subr_type);
7339 DECL_ARTIFICIAL (t) = 1;
7343 case FFEINFO_whereGLOBAL: /* Subroutine or function. */
7344 assert (!ffecom_transform_only_dummies_);
7346 if (((g = ffesymbol_global (s)) != NULL)
7347 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
7348 || (ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
7349 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
7350 && (ffeglobal_hook (g) != NULL_TREE)
7351 && ffe_is_globals ())
7353 t = ffeglobal_hook (g);
7357 t = build_decl (FUNCTION_DECL,
7358 ffecom_get_external_identifier_ (s),
7359 ffecom_tree_subr_type); /* Assume subr. */
7360 DECL_EXTERNAL (t) = 1;
7361 TREE_PUBLIC (t) = 1;
7363 t = start_decl (t, FALSE);
7364 finish_decl (t, NULL_TREE, FALSE);
7367 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
7368 || (ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
7369 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
7370 ffeglobal_set_hook (g, t);
7372 ffecom_save_tree_forever (t);
7377 assert ("NONE where unexpected" == NULL);
7379 case FFEINFO_whereANY:
7384 case FFEINFO_kindENTITY:
7385 switch (ffeinfo_where (ffesymbol_info (s)))
7388 case FFEINFO_whereCONSTANT:
7389 /* ~~Debugging info needed? */
7390 assert (!ffecom_transform_only_dummies_);
7391 t = error_mark_node; /* Shouldn't ever see this in expr. */
7394 case FFEINFO_whereLOCAL:
7395 assert (!ffecom_transform_only_dummies_);
7398 ffestorag st = ffesymbol_storage (s);
7401 type = ffecom_type_localvar_ (s, bt, kt);
7403 if (type == error_mark_node)
7405 t = error_mark_node;
7410 && (ffestorag_size (st) == 0))
7412 t = error_mark_node;
7417 && (ffestorag_parent (st) != NULL))
7418 { /* Child of EQUIVALENCE parent. */
7421 ffetargetOffset offset;
7423 est = ffestorag_parent (st);
7424 ffecom_transform_equiv_ (est);
7426 et = ffestorag_hook (est);
7427 assert (et != NULL_TREE);
7429 if (! TREE_STATIC (et))
7430 put_var_into_stack (et, /*rescan=*/true);
7432 offset = ffestorag_modulo (est)
7433 + ffestorag_offset (ffesymbol_storage (s))
7434 - ffestorag_offset (est);
7436 ffecom_debug_kludge_ (et, "EQUIVALENCE", s, type, offset);
7438 /* (t_type *) (((char *) &et) + offset) */
7440 t = convert (string_type_node, /* (char *) */
7441 ffecom_1 (ADDR_EXPR,
7442 build_pointer_type (TREE_TYPE (et)),
7444 t = ffecom_2 (PLUS_EXPR, TREE_TYPE (t),
7446 build_int_2 (offset, 0));
7447 t = convert (build_pointer_type (type),
7449 TREE_CONSTANT (t) = staticp (et);
7456 bool init = ffesymbol_is_init (s);
7458 t = build_decl (VAR_DECL,
7459 ffecom_get_identifier_ (ffesymbol_text (s)),
7463 || ffesymbol_namelisted (s)
7464 #ifdef FFECOM_sizeMAXSTACKITEM
7466 && (ffestorag_size (st) > FFECOM_sizeMAXSTACKITEM))
7468 || ((ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
7469 && (ffecom_primary_entry_kind_
7470 != FFEINFO_kindBLOCKDATA)
7471 && (ffesymbol_is_save (s) || ffe_is_saveall ())))
7472 TREE_STATIC (t) = !ffesymbol_attr (s, FFESYMBOL_attrADJUSTABLE);
7474 TREE_STATIC (t) = 0; /* No need to make static. */
7476 if (init || ffe_is_init_local_zero ())
7477 DECL_INITIAL (t) = error_mark_node;
7479 /* Keep -Wunused from complaining about var if it
7480 is used as sfunc arg or DATA implied-DO. */
7481 if (ffesymbol_attrs (s) & FFESYMBOL_attrsSFARG)
7482 DECL_IN_SYSTEM_HEADER (t) = 1;
7484 t = start_decl (t, FALSE);
7488 if (ffesymbol_init (s) != NULL)
7489 initexpr = ffecom_expr (ffesymbol_init (s));
7491 initexpr = ffecom_init_zero_ (t);
7493 else if (ffe_is_init_local_zero ())
7494 initexpr = ffecom_init_zero_ (t);
7496 initexpr = NULL_TREE; /* Not ref'd if !init. */
7498 finish_decl (t, initexpr, FALSE);
7500 if (st != NULL && DECL_SIZE (t) != error_mark_node)
7502 assert (TREE_CODE (DECL_SIZE_UNIT (t)) == INTEGER_CST);
7503 assert (0 == compare_tree_int (DECL_SIZE_UNIT (t),
7504 ffestorag_size (st)));
7510 case FFEINFO_whereRESULT:
7511 assert (!ffecom_transform_only_dummies_);
7513 if (bt == FFEINFO_basictypeCHARACTER)
7514 { /* Result is already in list of dummies, use
7516 t = ffecom_func_result_;
7517 tlen = ffecom_func_length_;
7521 if ((ffecom_num_entrypoints_ == 0)
7522 && (bt == FFEINFO_basictypeCOMPLEX)
7523 && (ffesymbol_is_f2c (ffecom_primary_entry_)))
7524 { /* Result is already in list of dummies, use
7526 t = ffecom_func_result_;
7530 if (ffecom_func_result_ != NULL_TREE)
7532 t = ffecom_func_result_;
7535 if ((ffecom_num_entrypoints_ != 0)
7536 && (ffecom_master_bt_ == FFEINFO_basictypeNONE))
7538 assert (ffecom_multi_retval_ != NULL_TREE);
7539 t = ffecom_1 (INDIRECT_REF, ffecom_multi_type_node_,
7540 ffecom_multi_retval_);
7541 t = ffecom_2 (COMPONENT_REF, ffecom_tree_type[bt][kt],
7542 t, ffecom_multi_fields_[bt][kt]);
7547 t = build_decl (VAR_DECL,
7548 ffecom_get_identifier_ (ffesymbol_text (s)),
7549 ffecom_tree_type[bt][kt]);
7550 TREE_STATIC (t) = 0; /* Put result on stack. */
7551 t = start_decl (t, FALSE);
7552 finish_decl (t, NULL_TREE, FALSE);
7554 ffecom_func_result_ = t;
7558 case FFEINFO_whereDUMMY:
7566 bool adjustable = FALSE; /* Conditionally adjustable? */
7568 type = ffecom_tree_type[bt][kt];
7569 if (ffesymbol_sfdummyparent (s) != NULL)
7571 if (current_function_decl == ffecom_outer_function_decl_)
7572 { /* Exec transition before sfunc
7573 context; get it later. */
7576 t = ffecom_get_identifier_ (ffesymbol_text
7577 (ffesymbol_sfdummyparent (s)));
7580 t = ffecom_get_identifier_ (ffesymbol_text (s));
7582 assert (ffecom_transform_only_dummies_);
7584 old_sizes = get_pending_sizes ();
7585 put_pending_sizes (old_sizes);
7587 if (bt == FFEINFO_basictypeCHARACTER)
7588 tlen = ffecom_char_enhance_arg_ (&type, s);
7589 type = ffecom_check_size_overflow_ (s, type, TRUE);
7591 for (dl = ffesymbol_dims (s); dl != NULL; dl = ffebld_trail (dl))
7593 if (type == error_mark_node)
7596 dim = ffebld_head (dl);
7597 assert (ffebld_op (dim) == FFEBLD_opBOUNDS);
7598 if ((ffebld_left (dim) == NULL) || ffecom_doing_entry_)
7599 low = ffecom_integer_one_node;
7601 low = ffecom_expr (ffebld_left (dim));
7602 assert (ffebld_right (dim) != NULL);
7603 if ((ffebld_op (ffebld_right (dim)) == FFEBLD_opSTAR)
7604 || ffecom_doing_entry_)
7606 /* Used to just do high=low. But for ffecom_tree_
7607 canonize_ref_, it probably is important to correctly
7608 assess the size. E.g. given COMPLEX C(*),CFUNC and
7609 C(2)=CFUNC(C), overlap can happen, while it can't
7610 for, say, C(1)=CFUNC(C(2)). */
7611 /* Even more recently used to set to INT_MAX, but that
7612 broke when some overflow checking went into the back
7613 end. Now we just leave the upper bound unspecified. */
7617 high = ffecom_expr (ffebld_right (dim));
7619 /* Determine whether array is conditionally adjustable,
7620 to decide whether back-end magic is needed.
7622 Normally the front end uses the back-end function
7623 variable_size to wrap SAVE_EXPR's around expressions
7624 affecting the size/shape of an array so that the
7625 size/shape info doesn't change during execution
7626 of the compiled code even though variables and
7627 functions referenced in those expressions might.
7629 variable_size also makes sure those saved expressions
7630 get evaluated immediately upon entry to the
7631 compiled procedure -- the front end normally doesn't
7632 have to worry about that.
7634 However, there is a problem with this that affects
7635 g77's implementation of entry points, and that is
7636 that it is _not_ true that each invocation of the
7637 compiled procedure is permitted to evaluate
7638 array size/shape info -- because it is possible
7639 that, for some invocations, that info is invalid (in
7640 which case it is "promised" -- i.e. a violation of
7641 the Fortran standard -- that the compiled code
7642 won't reference the array or its size/shape
7643 during that particular invocation).
7645 To phrase this in C terms, consider this gcc function:
7647 void foo (int *n, float (*a)[*n])
7649 // a is "pointer to array ...", fyi.
7652 Suppose that, for some invocations, it is permitted
7653 for a caller of foo to do this:
7657 Now the _written_ code for foo can take such a call
7658 into account by either testing explicitly for whether
7659 (a == NULL) || (n == NULL) -- presumably it is
7660 not permitted to reference *a in various fashions
7661 if (n == NULL) I suppose -- or it can avoid it by
7662 looking at other info (other arguments, static/global
7665 However, this won't work in gcc 2.5.8 because it'll
7666 automatically emit the code to save the "*n"
7667 expression, which'll yield a NULL dereference for
7668 the "foo (NULL, NULL)" call, something the code
7669 for foo cannot prevent.
7671 g77 definitely needs to avoid executing such
7672 code anytime the pointer to the adjustable array
7673 is NULL, because even if its bounds expressions
7674 don't have any references to possible "absent"
7675 variables like "*n" -- say all variable references
7676 are to COMMON variables, i.e. global (though in C,
7677 local static could actually make sense) -- the
7678 expressions could yield other run-time problems
7679 for allowably "dead" values in those variables.
7681 For example, let's consider a more complicated
7687 void foo (float (*a)[i/j])
7692 The above is (essentially) quite valid for Fortran
7693 but, again, for a call like "foo (NULL);", it is
7694 permitted for i and j to be undefined when the
7695 call is made. If j happened to be zero, for
7696 example, emitting the code to evaluate "i/j"
7697 could result in a run-time error.
7699 Offhand, though I don't have my F77 or F90
7700 standards handy, it might even be valid for a
7701 bounds expression to contain a function reference,
7702 in which case I doubt it is permitted for an
7703 implementation to invoke that function in the
7704 Fortran case involved here (invocation of an
7705 alternate ENTRY point that doesn't have the adjustable
7706 array as one of its arguments).
7708 So, the code that the compiler would normally emit
7709 to preevaluate the size/shape info for an
7710 adjustable array _must not_ be executed at run time
7711 in certain cases. Specifically, for Fortran,
7712 the case is when the pointer to the adjustable
7713 array == NULL. (For gnu-ish C, it might be nice
7714 for the source code itself to specify an expression
7715 that, if TRUE, inhibits execution of the code. Or
7716 reverse the sense for elegance.)
7718 (Note that g77 could use a different test than NULL,
7719 actually, since it happens to always pass an
7720 integer to the called function that specifies which
7721 entry point is being invoked. Hmm, this might
7722 solve the next problem.)
7724 One way a user could, I suppose, write "foo" so
7725 it works is to insert COND_EXPR's for the
7726 size/shape info so the dangerous stuff isn't
7727 actually done, as in:
7729 void foo (int *n, float (*a)[(a == NULL) ? 0 : *n])
7734 The next problem is that the front end needs to
7735 be able to tell the back end about the array's
7736 decl _before_ it tells it about the conditional
7737 expression to inhibit evaluation of size/shape info,
7740 To solve this, the front end needs to be able
7741 to give the back end the expression to inhibit
7742 generation of the preevaluation code _after_
7743 it makes the decl for the adjustable array.
7745 Until then, the above example using the COND_EXPR
7746 doesn't pass muster with gcc because the "(a == NULL)"
7747 part has a reference to "a", which is still
7748 undefined at that point.
7750 g77 will therefore use a different mechanism in the
7754 && ((TREE_CODE (low) != INTEGER_CST)
7755 || (high && TREE_CODE (high) != INTEGER_CST)))
7758 #if 0 /* Old approach -- see below. */
7759 if (TREE_CODE (low) != INTEGER_CST)
7760 low = ffecom_3 (COND_EXPR, integer_type_node,
7761 ffecom_adjarray_passed_ (s),
7763 ffecom_integer_zero_node);
7765 if (high && TREE_CODE (high) != INTEGER_CST)
7766 high = ffecom_3 (COND_EXPR, integer_type_node,
7767 ffecom_adjarray_passed_ (s),
7769 ffecom_integer_zero_node);
7772 /* ~~~gcc/stor-layout.c (layout_type) should do this,
7773 probably. Fixes 950302-1.f. */
7775 if (TREE_CODE (low) != INTEGER_CST)
7776 low = variable_size (low);
7778 /* ~~~Similarly, this fixes dumb0.f. The C front end
7779 does this, which is why dumb0.c would work. */
7781 if (high && TREE_CODE (high) != INTEGER_CST)
7782 high = variable_size (high);
7787 build_range_type (ffecom_integer_type_node,
7789 type = ffecom_check_size_overflow_ (s, type, TRUE);
7792 if (type == error_mark_node)
7794 t = error_mark_node;
7798 if ((ffesymbol_sfdummyparent (s) == NULL)
7799 || (ffesymbol_basictype (s) == FFEINFO_basictypeCHARACTER))
7801 type = build_pointer_type (type);
7805 t = build_decl (PARM_DECL, t, type);
7806 DECL_ARTIFICIAL (t) = 1;
7808 /* If this arg is present in every entry point's list of
7809 dummy args, then we're done. */
7811 if (ffesymbol_numentries (s)
7812 == (ffecom_num_entrypoints_ + 1))
7817 /* If variable_size in stor-layout has been called during
7818 the above, then get_pending_sizes should have the
7819 yet-to-be-evaluated saved expressions pending.
7820 Make the whole lot of them get emitted, conditionally
7821 on whether the array decl ("t" above) is not NULL. */
7824 tree sizes = get_pending_sizes ();
7829 tem = TREE_CHAIN (tem))
7831 tree temv = TREE_VALUE (tem);
7837 = ffecom_2 (COMPOUND_EXPR,
7846 = ffecom_3 (COND_EXPR,
7853 convert (TREE_TYPE (sizes),
7854 integer_zero_node));
7855 sizes = ffecom_save_tree (sizes);
7858 = tree_cons (NULL_TREE, sizes, tem);
7862 put_pending_sizes (sizes);
7868 && (ffesymbol_numentries (s)
7869 != ffecom_num_entrypoints_ + 1))
7871 = ffecom_2 (NE_EXPR, integer_type_node,
7877 && (ffesymbol_numentries (s)
7878 != ffecom_num_entrypoints_ + 1))
7880 ffebad_start (FFEBAD_MISSING_ADJARRAY_UNSUPPORTED);
7881 ffebad_here (0, ffesymbol_where_line (s),
7882 ffesymbol_where_column (s));
7883 ffebad_string (ffesymbol_text (s));
7892 case FFEINFO_whereCOMMON:
7897 ffestorag st = ffesymbol_storage (s);
7900 cs = ffesymbol_common (s); /* The COMMON area itself. */
7901 if (st != NULL) /* Else not laid out. */
7903 ffecom_transform_common_ (cs);
7904 st = ffesymbol_storage (s);
7907 type = ffecom_type_localvar_ (s, bt, kt);
7909 cg = ffesymbol_global (cs); /* The global COMMON info. */
7911 || (ffeglobal_type (cg) != FFEGLOBAL_typeCOMMON))
7914 ct = ffeglobal_hook (cg); /* The common area's tree. */
7916 if ((ct == NULL_TREE)
7918 || (type == error_mark_node))
7919 t = error_mark_node;
7922 ffetargetOffset offset;
7925 cst = ffestorag_parent (st);
7926 assert (cst == ffesymbol_storage (cs));
7928 offset = ffestorag_modulo (cst)
7929 + ffestorag_offset (st)
7930 - ffestorag_offset (cst);
7932 ffecom_debug_kludge_ (ct, "COMMON", s, type, offset);
7934 /* (t_type *) (((char *) &ct) + offset) */
7936 t = convert (string_type_node, /* (char *) */
7937 ffecom_1 (ADDR_EXPR,
7938 build_pointer_type (TREE_TYPE (ct)),
7940 t = ffecom_2 (PLUS_EXPR, TREE_TYPE (t),
7942 build_int_2 (offset, 0));
7943 t = convert (build_pointer_type (type),
7945 TREE_CONSTANT (t) = 1;
7952 case FFEINFO_whereIMMEDIATE:
7953 case FFEINFO_whereGLOBAL:
7954 case FFEINFO_whereFLEETING:
7955 case FFEINFO_whereFLEETING_CADDR:
7956 case FFEINFO_whereFLEETING_IADDR:
7957 case FFEINFO_whereINTRINSIC:
7958 case FFEINFO_whereCONSTANT_SUBOBJECT:
7960 assert ("ENTITY where unheard of" == NULL);
7962 case FFEINFO_whereANY:
7963 t = error_mark_node;
7968 case FFEINFO_kindFUNCTION:
7969 switch (ffeinfo_where (ffesymbol_info (s)))
7971 case FFEINFO_whereLOCAL: /* Me. */
7972 assert (!ffecom_transform_only_dummies_);
7973 t = current_function_decl;
7976 case FFEINFO_whereGLOBAL:
7977 assert (!ffecom_transform_only_dummies_);
7979 if (((g = ffesymbol_global (s)) != NULL)
7980 && ((ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
7981 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
7982 && (ffeglobal_hook (g) != NULL_TREE)
7983 && ffe_is_globals ())
7985 t = ffeglobal_hook (g);
7989 if (ffesymbol_is_f2c (s)
7990 && (ffesymbol_where (s) != FFEINFO_whereCONSTANT))
7991 t = ffecom_tree_fun_type[bt][kt];
7993 t = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
7995 t = build_decl (FUNCTION_DECL,
7996 ffecom_get_external_identifier_ (s),
7998 DECL_EXTERNAL (t) = 1;
7999 TREE_PUBLIC (t) = 1;
8001 t = start_decl (t, FALSE);
8002 finish_decl (t, NULL_TREE, FALSE);
8005 && ((ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
8006 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
8007 ffeglobal_set_hook (g, t);
8009 ffecom_save_tree_forever (t);
8013 case FFEINFO_whereDUMMY:
8014 assert (ffecom_transform_only_dummies_);
8016 if (ffesymbol_is_f2c (s)
8017 && (ffesymbol_where (s) != FFEINFO_whereCONSTANT))
8018 t = ffecom_tree_ptr_to_fun_type[bt][kt];
8020 t = build_pointer_type
8021 (build_function_type (ffecom_tree_type[bt][kt], NULL_TREE));
8023 t = build_decl (PARM_DECL,
8024 ffecom_get_identifier_ (ffesymbol_text (s)),
8026 DECL_ARTIFICIAL (t) = 1;
8030 case FFEINFO_whereCONSTANT: /* Statement function. */
8031 assert (!ffecom_transform_only_dummies_);
8032 t = ffecom_gen_sfuncdef_ (s, bt, kt);
8035 case FFEINFO_whereINTRINSIC:
8036 assert (!ffecom_transform_only_dummies_);
8037 break; /* Let actual references generate their
8041 assert ("FUNCTION where unheard of" == NULL);
8043 case FFEINFO_whereANY:
8044 t = error_mark_node;
8049 case FFEINFO_kindSUBROUTINE:
8050 switch (ffeinfo_where (ffesymbol_info (s)))
8052 case FFEINFO_whereLOCAL: /* Me. */
8053 assert (!ffecom_transform_only_dummies_);
8054 t = current_function_decl;
8057 case FFEINFO_whereGLOBAL:
8058 assert (!ffecom_transform_only_dummies_);
8060 if (((g = ffesymbol_global (s)) != NULL)
8061 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
8062 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
8063 && (ffeglobal_hook (g) != NULL_TREE)
8064 && ffe_is_globals ())
8066 t = ffeglobal_hook (g);
8070 t = build_decl (FUNCTION_DECL,
8071 ffecom_get_external_identifier_ (s),
8072 ffecom_tree_subr_type);
8073 DECL_EXTERNAL (t) = 1;
8074 TREE_PUBLIC (t) = 1;
8076 t = start_decl (t, ffe_is_globals ());
8077 finish_decl (t, NULL_TREE, ffe_is_globals ());
8080 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
8081 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
8082 ffeglobal_set_hook (g, t);
8084 ffecom_save_tree_forever (t);
8088 case FFEINFO_whereDUMMY:
8089 assert (ffecom_transform_only_dummies_);
8091 t = build_decl (PARM_DECL,
8092 ffecom_get_identifier_ (ffesymbol_text (s)),
8093 ffecom_tree_ptr_to_subr_type);
8094 DECL_ARTIFICIAL (t) = 1;
8098 case FFEINFO_whereINTRINSIC:
8099 assert (!ffecom_transform_only_dummies_);
8100 break; /* Let actual references generate their
8104 assert ("SUBROUTINE where unheard of" == NULL);
8106 case FFEINFO_whereANY:
8107 t = error_mark_node;
8112 case FFEINFO_kindPROGRAM:
8113 switch (ffeinfo_where (ffesymbol_info (s)))
8115 case FFEINFO_whereLOCAL: /* Me. */
8116 assert (!ffecom_transform_only_dummies_);
8117 t = current_function_decl;
8120 case FFEINFO_whereCOMMON:
8121 case FFEINFO_whereDUMMY:
8122 case FFEINFO_whereGLOBAL:
8123 case FFEINFO_whereRESULT:
8124 case FFEINFO_whereFLEETING:
8125 case FFEINFO_whereFLEETING_CADDR:
8126 case FFEINFO_whereFLEETING_IADDR:
8127 case FFEINFO_whereIMMEDIATE:
8128 case FFEINFO_whereINTRINSIC:
8129 case FFEINFO_whereCONSTANT:
8130 case FFEINFO_whereCONSTANT_SUBOBJECT:
8132 assert ("PROGRAM where unheard of" == NULL);
8134 case FFEINFO_whereANY:
8135 t = error_mark_node;
8140 case FFEINFO_kindBLOCKDATA:
8141 switch (ffeinfo_where (ffesymbol_info (s)))
8143 case FFEINFO_whereLOCAL: /* Me. */
8144 assert (!ffecom_transform_only_dummies_);
8145 t = current_function_decl;
8148 case FFEINFO_whereGLOBAL:
8149 assert (!ffecom_transform_only_dummies_);
8151 t = build_decl (FUNCTION_DECL,
8152 ffecom_get_external_identifier_ (s),
8153 ffecom_tree_blockdata_type);
8154 DECL_EXTERNAL (t) = 1;
8155 TREE_PUBLIC (t) = 1;
8157 t = start_decl (t, FALSE);
8158 finish_decl (t, NULL_TREE, FALSE);
8160 ffecom_save_tree_forever (t);
8164 case FFEINFO_whereCOMMON:
8165 case FFEINFO_whereDUMMY:
8166 case FFEINFO_whereRESULT:
8167 case FFEINFO_whereFLEETING:
8168 case FFEINFO_whereFLEETING_CADDR:
8169 case FFEINFO_whereFLEETING_IADDR:
8170 case FFEINFO_whereIMMEDIATE:
8171 case FFEINFO_whereINTRINSIC:
8172 case FFEINFO_whereCONSTANT:
8173 case FFEINFO_whereCONSTANT_SUBOBJECT:
8175 assert ("BLOCKDATA where unheard of" == NULL);
8177 case FFEINFO_whereANY:
8178 t = error_mark_node;
8183 case FFEINFO_kindCOMMON:
8184 switch (ffeinfo_where (ffesymbol_info (s)))
8186 case FFEINFO_whereLOCAL:
8187 assert (!ffecom_transform_only_dummies_);
8188 ffecom_transform_common_ (s);
8191 case FFEINFO_whereNONE:
8192 case FFEINFO_whereCOMMON:
8193 case FFEINFO_whereDUMMY:
8194 case FFEINFO_whereGLOBAL:
8195 case FFEINFO_whereRESULT:
8196 case FFEINFO_whereFLEETING:
8197 case FFEINFO_whereFLEETING_CADDR:
8198 case FFEINFO_whereFLEETING_IADDR:
8199 case FFEINFO_whereIMMEDIATE:
8200 case FFEINFO_whereINTRINSIC:
8201 case FFEINFO_whereCONSTANT:
8202 case FFEINFO_whereCONSTANT_SUBOBJECT:
8204 assert ("COMMON where unheard of" == NULL);
8206 case FFEINFO_whereANY:
8207 t = error_mark_node;
8212 case FFEINFO_kindCONSTRUCT:
8213 switch (ffeinfo_where (ffesymbol_info (s)))
8215 case FFEINFO_whereLOCAL:
8216 assert (!ffecom_transform_only_dummies_);
8219 case FFEINFO_whereNONE:
8220 case FFEINFO_whereCOMMON:
8221 case FFEINFO_whereDUMMY:
8222 case FFEINFO_whereGLOBAL:
8223 case FFEINFO_whereRESULT:
8224 case FFEINFO_whereFLEETING:
8225 case FFEINFO_whereFLEETING_CADDR:
8226 case FFEINFO_whereFLEETING_IADDR:
8227 case FFEINFO_whereIMMEDIATE:
8228 case FFEINFO_whereINTRINSIC:
8229 case FFEINFO_whereCONSTANT:
8230 case FFEINFO_whereCONSTANT_SUBOBJECT:
8232 assert ("CONSTRUCT where unheard of" == NULL);
8234 case FFEINFO_whereANY:
8235 t = error_mark_node;
8240 case FFEINFO_kindNAMELIST:
8241 switch (ffeinfo_where (ffesymbol_info (s)))
8243 case FFEINFO_whereLOCAL:
8244 assert (!ffecom_transform_only_dummies_);
8245 t = ffecom_transform_namelist_ (s);
8248 case FFEINFO_whereNONE:
8249 case FFEINFO_whereCOMMON:
8250 case FFEINFO_whereDUMMY:
8251 case FFEINFO_whereGLOBAL:
8252 case FFEINFO_whereRESULT:
8253 case FFEINFO_whereFLEETING:
8254 case FFEINFO_whereFLEETING_CADDR:
8255 case FFEINFO_whereFLEETING_IADDR:
8256 case FFEINFO_whereIMMEDIATE:
8257 case FFEINFO_whereINTRINSIC:
8258 case FFEINFO_whereCONSTANT:
8259 case FFEINFO_whereCONSTANT_SUBOBJECT:
8261 assert ("NAMELIST where unheard of" == NULL);
8263 case FFEINFO_whereANY:
8264 t = error_mark_node;
8270 assert ("kind unheard of" == NULL);
8272 case FFEINFO_kindANY:
8273 t = error_mark_node;
8277 ffesymbol_hook (s).decl_tree = t;
8278 ffesymbol_hook (s).length_tree = tlen;
8279 ffesymbol_hook (s).addr = addr;
8281 input_location = old_loc;
8286 /* Transform into ASSIGNable symbol.
8288 Symbol has already been transformed, but for whatever reason, the
8289 resulting decl_tree has been deemed not usable for an ASSIGN target.
8290 (E.g. it isn't wide enough to hold a pointer.) So, here we invent
8291 another local symbol of type void * and stuff that in the assign_tree
8292 argument. The F77/F90 standards allow this implementation. */
8295 ffecom_sym_transform_assign_ (ffesymbol s)
8297 tree t; /* Transformed thingy. */
8298 location_t old_loc = input_location;
8300 if (ffesymbol_sfdummyparent (s) == NULL)
8302 input_filename = ffesymbol_where_filename (s);
8303 input_line = ffesymbol_where_filelinenum (s);
8307 ffesymbol sf = ffesymbol_sfdummyparent (s);
8309 input_filename = ffesymbol_where_filename (sf);
8310 input_line = ffesymbol_where_filelinenum (sf);
8313 assert (!ffecom_transform_only_dummies_);
8315 t = build_decl (VAR_DECL,
8316 ffecom_get_invented_identifier ("__g77_ASSIGN_%s",
8317 ffesymbol_text (s)),
8318 TREE_TYPE (null_pointer_node));
8320 switch (ffesymbol_where (s))
8322 case FFEINFO_whereLOCAL:
8323 /* Unlike for regular vars, SAVE status is easy to determine for
8324 ASSIGNed vars, since there's no initialization, there's no
8325 effective storage association (so "SAVE J" does not apply to
8326 K even given "EQUIVALENCE (J,K)"), there's no size issue
8327 to worry about, etc. */
8328 if ((ffesymbol_is_save (s) || ffe_is_saveall ())
8329 && (ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
8330 && (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA))
8331 TREE_STATIC (t) = 1; /* SAVEd in proc, make static. */
8333 TREE_STATIC (t) = 0; /* No need to make static. */
8336 case FFEINFO_whereCOMMON:
8337 TREE_STATIC (t) = 1; /* Assume COMMONs always SAVEd. */
8340 case FFEINFO_whereDUMMY:
8341 /* Note that twinning a DUMMY means the caller won't see
8342 the ASSIGNed value. But both F77 and F90 allow implementations
8343 to do this, i.e. disallow Fortran code that would try and
8344 take advantage of actually putting a label into a variable
8345 via a dummy argument (or any other storage association, for
8347 TREE_STATIC (t) = 0;
8351 TREE_STATIC (t) = 0;
8355 t = start_decl (t, FALSE);
8356 finish_decl (t, NULL_TREE, FALSE);
8358 ffesymbol_hook (s).assign_tree = t;
8360 input_location = old_loc;
8365 /* Implement COMMON area in back end.
8367 Because COMMON-based variables can be referenced in the dimension
8368 expressions of dummy (adjustable) arrays, and because dummies
8369 (in the gcc back end) need to be put in the outer binding level
8370 of a function (which has two binding levels, the outer holding
8371 the dummies and the inner holding the other vars), special care
8372 must be taken to handle COMMON areas.
8374 The current strategy is basically to always tell the back end about
8375 the COMMON area as a top-level external reference to just a block
8376 of storage of the master type of that area (e.g. integer, real,
8377 character, whatever -- not a structure). As a distinct action,
8378 if initial values are provided, tell the back end about the area
8379 as a top-level non-external (initialized) area and remember not to
8380 allow further initialization or expansion of the area. Meanwhile,
8381 if no initialization happens at all, tell the back end about
8382 the largest size we've seen declared so the space does get reserved.
8383 (This function doesn't handle all that stuff, but it does some
8384 of the important things.)
8386 Meanwhile, for COMMON variables themselves, just keep creating
8387 references like *((float *) (&common_area + offset)) each time
8388 we reference the variable. In other words, don't make a VAR_DECL
8389 or any kind of component reference (like we used to do before 0.4),
8390 though we might do that as well just for debugging purposes (and
8391 stuff the rtl with the appropriate offset expression). */
8394 ffecom_transform_common_ (ffesymbol s)
8396 ffestorag st = ffesymbol_storage (s);
8397 ffeglobal g = ffesymbol_global (s);
8402 bool is_init = ffestorag_is_init (st);
8404 assert (st != NULL);
8407 || (ffeglobal_type (g) != FFEGLOBAL_typeCOMMON))
8410 /* First update the size of the area in global terms. */
8412 ffeglobal_size_common (s, ffestorag_size (st));
8414 if (!ffeglobal_common_init (g))
8415 is_init = FALSE; /* No explicit init, don't let erroneous joins init. */
8417 cbt = ffeglobal_hook (g);
8419 /* If we already have declared this common block for a previous program
8420 unit, and either we already initialized it or we don't have new
8421 initialization for it, just return what we have without changing it. */
8423 if ((cbt != NULL_TREE)
8425 || !DECL_EXTERNAL (cbt)))
8427 if (st->hook == NULL) ffestorag_set_hook (st, cbt);
8431 /* Process inits. */
8435 if (ffestorag_init (st) != NULL)
8439 /* Set the padding for the expression, so ffecom_expr
8440 knows to insert that many zeros. */
8441 switch (ffebld_op (sexp = ffestorag_init (st)))
8443 case FFEBLD_opCONTER:
8444 ffebld_conter_set_pad (sexp, ffestorag_modulo (st));
8447 case FFEBLD_opARRTER:
8448 ffebld_arrter_set_pad (sexp, ffestorag_modulo (st));
8451 case FFEBLD_opACCTER:
8452 ffebld_accter_set_pad (sexp, ffestorag_modulo (st));
8456 assert ("bad op for cmn init (pad)" == NULL);
8460 init = ffecom_expr (sexp);
8461 if (init == error_mark_node)
8462 { /* Hopefully the back end complained! */
8464 if (cbt != NULL_TREE)
8469 init = error_mark_node;
8474 /* cbtype must be permanently allocated! */
8476 /* Allocate the MAX of the areas so far, seen filewide. */
8477 high = build_int_2 ((ffeglobal_common_size (g)
8478 + ffeglobal_common_pad (g)) - 1, 0);
8479 TREE_TYPE (high) = ffecom_integer_type_node;
8482 cbtype = build_array_type (char_type_node,
8483 build_range_type (integer_type_node,
8487 cbtype = build_array_type (char_type_node, NULL_TREE);
8489 if (cbt == NULL_TREE)
8492 = build_decl (VAR_DECL,
8493 ffecom_get_external_identifier_ (s),
8495 TREE_STATIC (cbt) = 1;
8496 TREE_PUBLIC (cbt) = 1;
8501 TREE_TYPE (cbt) = cbtype;
8503 DECL_EXTERNAL (cbt) = init ? 0 : 1;
8504 DECL_INITIAL (cbt) = init ? error_mark_node : NULL_TREE;
8506 cbt = start_decl (cbt, TRUE);
8507 if (ffeglobal_hook (g) != NULL)
8508 assert (cbt == ffeglobal_hook (g));
8510 assert (!init || !DECL_EXTERNAL (cbt));
8512 /* Make sure that any type can live in COMMON and be referenced
8513 without getting a bus error. We could pick the most restrictive
8514 alignment of all entities actually placed in the COMMON, but
8515 this seems easy enough. */
8517 DECL_ALIGN (cbt) = BIGGEST_ALIGNMENT;
8518 DECL_USER_ALIGN (cbt) = 0;
8520 if (is_init && (ffestorag_init (st) == NULL))
8521 init = ffecom_init_zero_ (cbt);
8523 finish_decl (cbt, init, TRUE);
8526 ffestorag_set_init (st, ffebld_new_any ());
8530 assert (DECL_SIZE_UNIT (cbt) != NULL_TREE);
8531 assert (TREE_CODE (DECL_SIZE_UNIT (cbt)) == INTEGER_CST);
8532 assert (0 == compare_tree_int (DECL_SIZE_UNIT (cbt),
8533 (ffeglobal_common_size (g)
8534 + ffeglobal_common_pad (g))));
8537 ffeglobal_set_hook (g, cbt);
8539 ffestorag_set_hook (st, cbt);
8541 ffecom_save_tree_forever (cbt);
8544 /* Make master area for local EQUIVALENCE. */
8547 ffecom_transform_equiv_ (ffestorag eqst)
8553 bool is_init = ffestorag_is_init (eqst);
8555 assert (eqst != NULL);
8557 eqt = ffestorag_hook (eqst);
8559 if (eqt != NULL_TREE)
8562 /* Process inits. */
8566 if (ffestorag_init (eqst) != NULL)
8570 /* Set the padding for the expression, so ffecom_expr
8571 knows to insert that many zeros. */
8572 switch (ffebld_op (sexp = ffestorag_init (eqst)))
8574 case FFEBLD_opCONTER:
8575 ffebld_conter_set_pad (sexp, ffestorag_modulo (eqst));
8578 case FFEBLD_opARRTER:
8579 ffebld_arrter_set_pad (sexp, ffestorag_modulo (eqst));
8582 case FFEBLD_opACCTER:
8583 ffebld_accter_set_pad (sexp, ffestorag_modulo (eqst));
8587 assert ("bad op for eqv init (pad)" == NULL);
8591 init = ffecom_expr (sexp);
8592 if (init == error_mark_node)
8593 init = NULL_TREE; /* Hopefully the back end complained! */
8596 init = error_mark_node;
8598 else if (ffe_is_init_local_zero ())
8599 init = error_mark_node;
8603 ffecom_member_namelisted_ = FALSE;
8604 ffestorag_drive (ffestorag_list_equivs (eqst),
8605 &ffecom_member_phase1_,
8608 high = build_int_2 ((ffestorag_size (eqst)
8609 + ffestorag_modulo (eqst)) - 1, 0);
8610 TREE_TYPE (high) = ffecom_integer_type_node;
8612 eqtype = build_array_type (char_type_node,
8613 build_range_type (ffecom_integer_type_node,
8614 ffecom_integer_zero_node,
8617 eqt = build_decl (VAR_DECL,
8618 ffecom_get_invented_identifier ("__g77_equiv_%s",
8620 (ffestorag_symbol (eqst))),
8622 DECL_EXTERNAL (eqt) = 0;
8624 || ffecom_member_namelisted_
8625 #ifdef FFECOM_sizeMAXSTACKITEM
8626 || (ffestorag_size (eqst) > FFECOM_sizeMAXSTACKITEM)
8628 || ((ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
8629 && (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA)
8630 && (ffestorag_is_save (eqst) || ffe_is_saveall ())))
8631 TREE_STATIC (eqt) = 1;
8633 TREE_STATIC (eqt) = 0;
8634 TREE_PUBLIC (eqt) = 0;
8635 TREE_ADDRESSABLE (eqt) = 1; /* Ensure non-register allocation */
8636 DECL_CONTEXT (eqt) = current_function_decl;
8638 DECL_INITIAL (eqt) = error_mark_node;
8640 DECL_INITIAL (eqt) = NULL_TREE;
8642 eqt = start_decl (eqt, FALSE);
8644 /* Make sure that any type can live in EQUIVALENCE and be referenced
8645 without getting a bus error. We could pick the most restrictive
8646 alignment of all entities actually placed in the EQUIVALENCE, but
8647 this seems easy enough. */
8649 DECL_ALIGN (eqt) = BIGGEST_ALIGNMENT;
8650 DECL_USER_ALIGN (eqt) = 0;
8652 if ((!is_init && ffe_is_init_local_zero ())
8653 || (is_init && (ffestorag_init (eqst) == NULL)))
8654 init = ffecom_init_zero_ (eqt);
8656 finish_decl (eqt, init, FALSE);
8659 ffestorag_set_init (eqst, ffebld_new_any ());
8662 assert (TREE_CODE (DECL_SIZE_UNIT (eqt)) == INTEGER_CST);
8663 assert (0 == compare_tree_int (DECL_SIZE_UNIT (eqt),
8664 (ffestorag_size (eqst)
8665 + ffestorag_modulo (eqst))));
8668 ffestorag_set_hook (eqst, eqt);
8670 ffestorag_drive (ffestorag_list_equivs (eqst),
8671 &ffecom_member_phase2_,
8675 /* Implement NAMELIST in back end. See f2c/format.c for more info. */
8678 ffecom_transform_namelist_ (ffesymbol s)
8681 tree nmltype = ffecom_type_namelist_ ();
8689 static int mynumber = 0;
8691 nmlt = build_decl (VAR_DECL,
8692 ffecom_get_invented_identifier ("__g77_namelist_%d",
8695 TREE_STATIC (nmlt) = 1;
8696 DECL_INITIAL (nmlt) = error_mark_node;
8698 nmlt = start_decl (nmlt, FALSE);
8700 /* Process inits. */
8702 i = strlen (ffesymbol_text (s));
8704 high = build_int_2 (i, 0);
8705 TREE_TYPE (high) = ffecom_f2c_ftnlen_type_node;
8707 nameinit = ffecom_build_f2c_string_ (i + 1,
8708 ffesymbol_text (s));
8709 TREE_TYPE (nameinit)
8710 = build_type_variant
8713 build_range_type (ffecom_f2c_ftnlen_type_node,
8714 ffecom_f2c_ftnlen_one_node,
8717 TREE_CONSTANT (nameinit) = 1;
8718 TREE_STATIC (nameinit) = 1;
8719 nameinit = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (nameinit)),
8722 varsinit = ffecom_vardesc_array_ (s);
8723 varsinit = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (varsinit)),
8725 TREE_CONSTANT (varsinit) = 1;
8726 TREE_STATIC (varsinit) = 1;
8731 for (i = 0, b = ffesymbol_namelist (s); b != NULL; b = ffebld_trail (b))
8734 nvarsinit = build_int_2 (i, 0);
8735 TREE_TYPE (nvarsinit) = integer_type_node;
8736 TREE_CONSTANT (nvarsinit) = 1;
8737 TREE_STATIC (nvarsinit) = 1;
8739 nmlinits = build_tree_list ((field = TYPE_FIELDS (nmltype)), nameinit);
8740 TREE_CHAIN (nmlinits) = build_tree_list ((field = TREE_CHAIN (field)),
8742 TREE_CHAIN (TREE_CHAIN (nmlinits))
8743 = build_tree_list ((field = TREE_CHAIN (field)), nvarsinit);
8745 nmlinits = build_constructor (nmltype, nmlinits);
8746 TREE_CONSTANT (nmlinits) = 1;
8747 TREE_STATIC (nmlinits) = 1;
8749 finish_decl (nmlt, nmlinits, FALSE);
8751 nmlt = ffecom_1 (ADDR_EXPR, build_pointer_type (nmltype), nmlt);
8756 /* A subroutine of ffecom_tree_canonize_ref_. The incoming tree is
8757 analyzed on the assumption it is calculating a pointer to be
8758 indirected through. It must return the proper decl and offset,
8759 taking into account different units of measurements for offsets. */
8762 ffecom_tree_canonize_ptr_ (tree *decl, tree *offset, tree t)
8764 switch (TREE_CODE (t))
8768 case NON_LVALUE_EXPR:
8769 ffecom_tree_canonize_ptr_ (decl, offset, TREE_OPERAND (t, 0));
8773 ffecom_tree_canonize_ptr_ (decl, offset, TREE_OPERAND (t, 0));
8774 if ((*decl == NULL_TREE)
8775 || (*decl == error_mark_node))
8778 if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST)
8780 /* An offset into COMMON. */
8781 *offset = fold (build (PLUS_EXPR, TREE_TYPE (*offset),
8782 *offset, TREE_OPERAND (t, 1)));
8783 /* Convert offset (presumably in bytes) into canonical units
8784 (presumably bits). */
8785 *offset = size_binop (MULT_EXPR,
8786 convert (bitsizetype, *offset),
8787 TYPE_SIZE (TREE_TYPE (TREE_TYPE (t))));
8790 /* Not a COMMON reference, so an unrecognized pattern. */
8791 *decl = error_mark_node;
8796 *offset = bitsize_zero_node;
8800 if (TREE_CODE (TREE_OPERAND (t, 0)) == VAR_DECL)
8802 /* A reference to COMMON. */
8803 *decl = TREE_OPERAND (t, 0);
8804 *offset = bitsize_zero_node;
8809 /* Not a COMMON reference, so an unrecognized pattern. */
8810 *decl = error_mark_node;
8815 /* Given a tree that is possibly intended for use as an lvalue, return
8816 information representing a canonical view of that tree as a decl, an
8817 offset into that decl, and a size for the lvalue.
8819 If there's no applicable decl, NULL_TREE is returned for the decl,
8820 and the other fields are left undefined.
8822 If the tree doesn't fit the recognizable forms, an ERROR_MARK node
8823 is returned for the decl, and the other fields are left undefined.
8825 Otherwise, the decl returned currently is either a VAR_DECL or a
8828 The offset returned is always valid, but of course not necessarily
8829 a constant, and not necessarily converted into the appropriate
8830 type, leaving that up to the caller (so as to avoid that overhead
8831 if the decls being looked at are different anyway).
8833 If the size cannot be determined (e.g. an adjustable array),
8834 an ERROR_MARK node is returned for the size. Otherwise, the
8835 size returned is valid, not necessarily a constant, and not
8836 necessarily converted into the appropriate type as with the
8839 Note that the offset and size expressions are expressed in the
8840 base storage units (usually bits) rather than in the units of
8841 the type of the decl, because two decls with different types
8842 might overlap but with apparently non-overlapping array offsets,
8843 whereas converting the array offsets to consistant offsets will
8844 reveal the overlap. */
8847 ffecom_tree_canonize_ref_ (tree *decl, tree *offset, tree *size, tree t)
8849 /* The default path is to report a nonexistant decl. */
8855 switch (TREE_CODE (t))
8858 case IDENTIFIER_NODE:
8867 case TRUNC_DIV_EXPR:
8869 case FLOOR_DIV_EXPR:
8870 case ROUND_DIV_EXPR:
8871 case TRUNC_MOD_EXPR:
8873 case FLOOR_MOD_EXPR:
8874 case ROUND_MOD_EXPR:
8876 case EXACT_DIV_EXPR:
8877 case FIX_TRUNC_EXPR:
8879 case FIX_FLOOR_EXPR:
8880 case FIX_ROUND_EXPR:
8894 case BIT_ANDTC_EXPR:
8896 case TRUTH_ANDIF_EXPR:
8897 case TRUTH_ORIF_EXPR:
8898 case TRUTH_AND_EXPR:
8900 case TRUTH_XOR_EXPR:
8901 case TRUTH_NOT_EXPR:
8921 *offset = bitsize_zero_node;
8922 *size = TYPE_SIZE (TREE_TYPE (t));
8927 tree array = TREE_OPERAND (t, 0);
8928 tree element = TREE_OPERAND (t, 1);
8931 if ((array == NULL_TREE)
8932 || (element == NULL_TREE))
8934 *decl = error_mark_node;
8938 ffecom_tree_canonize_ref_ (decl, &init_offset, size,
8940 if ((*decl == NULL_TREE)
8941 || (*decl == error_mark_node))
8944 /* Calculate ((element - base) * NBBY) + init_offset. */
8945 *offset = fold (build (MINUS_EXPR, TREE_TYPE (element),
8947 TYPE_MIN_VALUE (TYPE_DOMAIN
8948 (TREE_TYPE (array)))));
8950 *offset = size_binop (MULT_EXPR,
8951 convert (bitsizetype, *offset),
8952 TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))));
8954 *offset = size_binop (PLUS_EXPR, init_offset, *offset);
8956 *size = TYPE_SIZE (TREE_TYPE (t));
8962 /* Most of this code is to handle references to COMMON. And so
8963 far that is useful only for calling library functions, since
8964 external (user) functions might reference common areas. But
8965 even calling an external function, it's worthwhile to decode
8966 COMMON references because if not storing into COMMON, we don't
8967 want COMMON-based arguments to gratuitously force use of a
8970 *size = TYPE_SIZE (TREE_TYPE (t));
8972 ffecom_tree_canonize_ptr_ (decl, offset,
8973 TREE_OPERAND (t, 0));
8980 case NON_LVALUE_EXPR:
8983 case COND_EXPR: /* More cases than we can handle. */
8985 case REFERENCE_EXPR:
8986 case PREDECREMENT_EXPR:
8987 case PREINCREMENT_EXPR:
8988 case POSTDECREMENT_EXPR:
8989 case POSTINCREMENT_EXPR:
8992 *decl = error_mark_node;
8997 /* Do divide operation appropriate to type of operands. */
9000 ffecom_tree_divide_ (tree tree_type, tree left, tree right, tree dest_tree,
9001 ffebld dest, bool *dest_used, tree hook)
9003 if ((left == error_mark_node)
9004 || (right == error_mark_node))
9005 return error_mark_node;
9007 switch (TREE_CODE (tree_type))
9010 return ffecom_2 (TRUNC_DIV_EXPR, tree_type,
9015 if (! optimize_size)
9016 return ffecom_2 (RDIV_EXPR, tree_type,
9022 if (TREE_TYPE (tree_type)
9023 == ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1])
9024 ix = FFECOM_gfrtDIV_CC; /* Overlapping result okay. */
9026 ix = FFECOM_gfrtDIV_ZZ; /* Overlapping result okay. */
9028 left = ffecom_1 (ADDR_EXPR,
9029 build_pointer_type (TREE_TYPE (left)),
9031 left = build_tree_list (NULL_TREE, left);
9032 right = ffecom_1 (ADDR_EXPR,
9033 build_pointer_type (TREE_TYPE (right)),
9035 right = build_tree_list (NULL_TREE, right);
9036 TREE_CHAIN (left) = right;
9038 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
9039 ffecom_gfrt_kindtype (ix),
9040 ffe_is_f2c_library (),
9043 dest_tree, dest, dest_used,
9044 NULL_TREE, TRUE, hook);
9052 if (TREE_TYPE (TYPE_FIELDS (tree_type))
9053 == ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1])
9054 ix = FFECOM_gfrtDIV_CC; /* Overlapping result okay. */
9056 ix = FFECOM_gfrtDIV_ZZ; /* Overlapping result okay. */
9058 left = ffecom_1 (ADDR_EXPR,
9059 build_pointer_type (TREE_TYPE (left)),
9061 left = build_tree_list (NULL_TREE, left);
9062 right = ffecom_1 (ADDR_EXPR,
9063 build_pointer_type (TREE_TYPE (right)),
9065 right = build_tree_list (NULL_TREE, right);
9066 TREE_CHAIN (left) = right;
9068 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
9069 ffecom_gfrt_kindtype (ix),
9070 ffe_is_f2c_library (),
9073 dest_tree, dest, dest_used,
9074 NULL_TREE, TRUE, hook);
9079 return ffecom_2 (RDIV_EXPR, tree_type,
9085 /* Build type info for non-dummy variable. */
9088 ffecom_type_localvar_ (ffesymbol s, ffeinfoBasictype bt, ffeinfoKindtype kt)
9096 type = ffecom_tree_type[bt][kt];
9097 if (bt == FFEINFO_basictypeCHARACTER)
9099 hight = build_int_2 (ffesymbol_size (s), 0);
9100 TREE_TYPE (hight) = ffecom_f2c_ftnlen_type_node;
9105 build_range_type (ffecom_f2c_ftnlen_type_node,
9106 ffecom_f2c_ftnlen_one_node,
9108 type = ffecom_check_size_overflow_ (s, type, FALSE);
9111 for (dl = ffesymbol_dims (s); dl != NULL; dl = ffebld_trail (dl))
9113 if (type == error_mark_node)
9116 dim = ffebld_head (dl);
9117 assert (ffebld_op (dim) == FFEBLD_opBOUNDS);
9119 if (ffebld_left (dim) == NULL)
9120 lowt = integer_one_node;
9122 lowt = ffecom_expr (ffebld_left (dim));
9124 if (TREE_CODE (lowt) != INTEGER_CST)
9125 lowt = variable_size (lowt);
9127 assert (ffebld_right (dim) != NULL);
9128 hight = ffecom_expr (ffebld_right (dim));
9130 if (TREE_CODE (hight) != INTEGER_CST)
9131 hight = variable_size (hight);
9133 type = build_array_type (type,
9134 build_range_type (ffecom_integer_type_node,
9136 type = ffecom_check_size_overflow_ (s, type, FALSE);
9142 /* Build Namelist type. */
9144 static GTY(()) tree ffecom_type_namelist_var;
9146 ffecom_type_namelist_ (void)
9148 if (ffecom_type_namelist_var == NULL_TREE)
9150 tree namefield, varsfield, nvarsfield, vardesctype, type;
9152 vardesctype = ffecom_type_vardesc_ ();
9154 type = make_node (RECORD_TYPE);
9156 vardesctype = build_pointer_type (build_pointer_type (vardesctype));
9158 namefield = ffecom_decl_field (type, NULL_TREE, "name",
9160 varsfield = ffecom_decl_field (type, namefield, "vars", vardesctype);
9161 nvarsfield = ffecom_decl_field (type, varsfield, "nvars",
9164 TYPE_FIELDS (type) = namefield;
9167 ffecom_type_namelist_var = type;
9170 return ffecom_type_namelist_var;
9173 /* Build Vardesc type. */
9175 static GTY(()) tree ffecom_type_vardesc_var;
9177 ffecom_type_vardesc_ (void)
9179 if (ffecom_type_vardesc_var == NULL_TREE)
9181 tree namefield, addrfield, dimsfield, typefield, type;
9182 type = make_node (RECORD_TYPE);
9184 namefield = ffecom_decl_field (type, NULL_TREE, "name",
9186 addrfield = ffecom_decl_field (type, namefield, "addr",
9188 dimsfield = ffecom_decl_field (type, addrfield, "dims",
9189 ffecom_f2c_ptr_to_ftnlen_type_node);
9190 typefield = ffecom_decl_field (type, dimsfield, "type",
9193 TYPE_FIELDS (type) = namefield;
9196 ffecom_type_vardesc_var = type;
9199 return ffecom_type_vardesc_var;
9203 ffecom_vardesc_ (ffebld expr)
9207 assert (ffebld_op (expr) == FFEBLD_opSYMTER);
9208 s = ffebld_symter (expr);
9210 if (ffesymbol_hook (s).vardesc_tree == NULL_TREE)
9213 tree vardesctype = ffecom_type_vardesc_ ();
9221 static int mynumber = 0;
9223 var = build_decl (VAR_DECL,
9224 ffecom_get_invented_identifier ("__g77_vardesc_%d",
9227 TREE_STATIC (var) = 1;
9228 DECL_INITIAL (var) = error_mark_node;
9230 var = start_decl (var, FALSE);
9232 /* Process inits. */
9234 nameinit = ffecom_build_f2c_string_ ((i = strlen (ffesymbol_text (s)))
9236 ffesymbol_text (s));
9237 TREE_TYPE (nameinit)
9238 = build_type_variant
9241 build_range_type (integer_type_node,
9243 build_int_2 (i, 0))),
9245 TREE_CONSTANT (nameinit) = 1;
9246 TREE_STATIC (nameinit) = 1;
9247 nameinit = ffecom_1 (ADDR_EXPR,
9248 build_pointer_type (TREE_TYPE (nameinit)),
9251 addrinit = ffecom_arg_ptr_to_expr (expr, &typeinit);
9253 dimsinit = ffecom_vardesc_dims_ (s);
9255 if (typeinit == NULL_TREE)
9257 ffeinfoBasictype bt = ffesymbol_basictype (s);
9258 ffeinfoKindtype kt = ffesymbol_kindtype (s);
9259 int tc = ffecom_f2c_typecode (bt, kt);
9262 typeinit = build_int_2 (tc, (tc < 0) ? -1 : 0);
9265 typeinit = ffecom_1 (NEGATE_EXPR, TREE_TYPE (typeinit), typeinit);
9267 varinits = build_tree_list ((field = TYPE_FIELDS (vardesctype)),
9269 TREE_CHAIN (varinits) = build_tree_list ((field = TREE_CHAIN (field)),
9271 TREE_CHAIN (TREE_CHAIN (varinits))
9272 = build_tree_list ((field = TREE_CHAIN (field)), dimsinit);
9273 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (varinits)))
9274 = build_tree_list ((field = TREE_CHAIN (field)), typeinit);
9276 varinits = build_constructor (vardesctype, varinits);
9277 TREE_CONSTANT (varinits) = 1;
9278 TREE_STATIC (varinits) = 1;
9280 finish_decl (var, varinits, FALSE);
9282 var = ffecom_1 (ADDR_EXPR, build_pointer_type (vardesctype), var);
9284 ffesymbol_hook (s).vardesc_tree = var;
9287 return ffesymbol_hook (s).vardesc_tree;
9291 ffecom_vardesc_array_ (ffesymbol s)
9295 tree item = NULL_TREE;
9298 static int mynumber = 0;
9300 for (i = 0, list = NULL_TREE, b = ffesymbol_namelist (s);
9302 b = ffebld_trail (b), ++i)
9306 t = ffecom_vardesc_ (ffebld_head (b));
9308 if (list == NULL_TREE)
9309 list = item = build_tree_list (NULL_TREE, t);
9312 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
9313 item = TREE_CHAIN (item);
9317 item = build_array_type (build_pointer_type (ffecom_type_vardesc_ ()),
9318 build_range_type (integer_type_node,
9320 build_int_2 (i, 0)));
9321 list = build_constructor (item, list);
9322 TREE_CONSTANT (list) = 1;
9323 TREE_STATIC (list) = 1;
9325 var = ffecom_get_invented_identifier ("__g77_vardesc_array_%d", mynumber++);
9326 var = build_decl (VAR_DECL, var, item);
9327 TREE_STATIC (var) = 1;
9328 DECL_INITIAL (var) = error_mark_node;
9329 var = start_decl (var, FALSE);
9330 finish_decl (var, list, FALSE);
9336 ffecom_vardesc_dims_ (ffesymbol s)
9338 if (ffesymbol_dims (s) == NULL)
9339 return convert (ffecom_f2c_ptr_to_ftnlen_type_node,
9347 tree item = NULL_TREE;
9351 tree baseoff = NULL_TREE;
9352 static int mynumber = 0;
9354 numdim = build_int_2 ((int) ffesymbol_rank (s), 0);
9355 TREE_TYPE (numdim) = ffecom_f2c_ftnlen_type_node;
9357 numelem = ffecom_expr (ffesymbol_arraysize (s));
9358 TREE_TYPE (numelem) = ffecom_f2c_ftnlen_type_node;
9361 backlist = NULL_TREE;
9362 for (b = ffesymbol_dims (s), e = ffesymbol_extents (s);
9364 b = ffebld_trail (b), e = ffebld_trail (e))
9370 if (ffebld_trail (b) == NULL)
9374 t = convert (ffecom_f2c_ftnlen_type_node,
9375 ffecom_expr (ffebld_head (e)));
9377 if (list == NULL_TREE)
9378 list = item = build_tree_list (NULL_TREE, t);
9381 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
9382 item = TREE_CHAIN (item);
9386 if (ffebld_left (ffebld_head (b)) == NULL)
9387 low = ffecom_integer_one_node;
9389 low = ffecom_expr (ffebld_left (ffebld_head (b)));
9390 low = convert (ffecom_f2c_ftnlen_type_node, low);
9392 back = build_tree_list (low, t);
9393 TREE_CHAIN (back) = backlist;
9397 for (item = backlist; item != NULL_TREE; item = TREE_CHAIN (item))
9399 if (TREE_VALUE (item) == NULL_TREE)
9400 baseoff = TREE_PURPOSE (item);
9402 baseoff = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
9403 TREE_PURPOSE (item),
9404 ffecom_2 (MULT_EXPR,
9405 ffecom_f2c_ftnlen_type_node,
9410 /* backlist now dead, along with all TREE_PURPOSEs on it. */
9412 baseoff = build_tree_list (NULL_TREE, baseoff);
9413 TREE_CHAIN (baseoff) = list;
9415 numelem = build_tree_list (NULL_TREE, numelem);
9416 TREE_CHAIN (numelem) = baseoff;
9418 numdim = build_tree_list (NULL_TREE, numdim);
9419 TREE_CHAIN (numdim) = numelem;
9421 item = build_array_type (ffecom_f2c_ftnlen_type_node,
9422 build_range_type (integer_type_node,
9425 ((int) ffesymbol_rank (s)
9427 list = build_constructor (item, numdim);
9428 TREE_CONSTANT (list) = 1;
9429 TREE_STATIC (list) = 1;
9431 var = ffecom_get_invented_identifier ("__g77_dims_%d", mynumber++);
9432 var = build_decl (VAR_DECL, var, item);
9433 TREE_STATIC (var) = 1;
9434 DECL_INITIAL (var) = error_mark_node;
9435 var = start_decl (var, FALSE);
9436 finish_decl (var, list, FALSE);
9438 var = ffecom_1 (ADDR_EXPR, build_pointer_type (item), var);
9444 /* Essentially does a "fold (build1 (code, type, node))" while checking
9445 for certain housekeeping things.
9447 NOTE: for building an ADDR_EXPR around a FUNCTION_DECL, use
9448 ffecom_1_fn instead. */
9451 ffecom_1 (enum tree_code code, tree type, tree node)
9455 if ((node == error_mark_node)
9456 || (type == error_mark_node))
9457 return error_mark_node;
9459 if (code == ADDR_EXPR)
9461 if (!ffe_mark_addressable (node))
9462 assert ("can't mark_addressable this node!" == NULL);
9465 switch (ffe_is_emulate_complex () ? code : NOP_EXPR)
9470 item = build (COMPONENT_REF, type, node, TYPE_FIELDS (TREE_TYPE (node)));
9474 item = build (COMPONENT_REF, type, node, TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (node))));
9479 if (TREE_CODE (type) != RECORD_TYPE)
9481 item = build1 (code, type, node);
9484 node = ffecom_stabilize_aggregate_ (node);
9485 realtype = TREE_TYPE (TYPE_FIELDS (type));
9487 ffecom_2 (COMPLEX_EXPR, type,
9488 ffecom_1 (NEGATE_EXPR, realtype,
9489 ffecom_1 (REALPART_EXPR, realtype,
9491 ffecom_1 (NEGATE_EXPR, realtype,
9492 ffecom_1 (IMAGPART_EXPR, realtype,
9497 item = build1 (code, type, node);
9501 if (TREE_SIDE_EFFECTS (node))
9502 TREE_SIDE_EFFECTS (item) = 1;
9503 if (code == ADDR_EXPR && staticp (node))
9504 TREE_CONSTANT (item) = 1;
9505 else if (code == INDIRECT_REF)
9506 TREE_READONLY (item) = TYPE_READONLY (type);
9510 /* Like ffecom_1 (ADDR_EXPR, TREE_TYPE (node), node), except
9511 handles TREE_CODE (node) == FUNCTION_DECL. In particular,
9512 does not set TREE_ADDRESSABLE (because calling an inline
9513 function does not mean the function needs to be separately
9517 ffecom_1_fn (tree node)
9522 if (node == error_mark_node)
9523 return error_mark_node;
9525 type = build_type_variant (TREE_TYPE (node),
9526 TREE_READONLY (node),
9527 TREE_THIS_VOLATILE (node));
9528 item = build1 (ADDR_EXPR,
9529 build_pointer_type (type), node);
9530 if (TREE_SIDE_EFFECTS (node))
9531 TREE_SIDE_EFFECTS (item) = 1;
9533 TREE_CONSTANT (item) = 1;
9537 /* Essentially does a "fold (build (code, type, node1, node2))" while
9538 checking for certain housekeeping things. */
9541 ffecom_2 (enum tree_code code, tree type, tree node1, tree node2)
9545 if ((node1 == error_mark_node)
9546 || (node2 == error_mark_node)
9547 || (type == error_mark_node))
9548 return error_mark_node;
9550 switch (ffe_is_emulate_complex () ? code : NOP_EXPR)
9552 tree a, b, c, d, realtype;
9555 assert ("no CONJ_EXPR support yet" == NULL);
9556 return error_mark_node;
9559 item = build_tree_list (TYPE_FIELDS (type), node1);
9560 TREE_CHAIN (item) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), node2);
9561 item = build_constructor (type, item);
9565 if (TREE_CODE (type) != RECORD_TYPE)
9567 item = build (code, type, node1, node2);
9570 node1 = ffecom_stabilize_aggregate_ (node1);
9571 node2 = ffecom_stabilize_aggregate_ (node2);
9572 realtype = TREE_TYPE (TYPE_FIELDS (type));
9574 ffecom_2 (COMPLEX_EXPR, type,
9575 ffecom_2 (PLUS_EXPR, realtype,
9576 ffecom_1 (REALPART_EXPR, realtype,
9578 ffecom_1 (REALPART_EXPR, realtype,
9580 ffecom_2 (PLUS_EXPR, realtype,
9581 ffecom_1 (IMAGPART_EXPR, realtype,
9583 ffecom_1 (IMAGPART_EXPR, realtype,
9588 if (TREE_CODE (type) != RECORD_TYPE)
9590 item = build (code, type, node1, node2);
9593 node1 = ffecom_stabilize_aggregate_ (node1);
9594 node2 = ffecom_stabilize_aggregate_ (node2);
9595 realtype = TREE_TYPE (TYPE_FIELDS (type));
9597 ffecom_2 (COMPLEX_EXPR, type,
9598 ffecom_2 (MINUS_EXPR, realtype,
9599 ffecom_1 (REALPART_EXPR, realtype,
9601 ffecom_1 (REALPART_EXPR, realtype,
9603 ffecom_2 (MINUS_EXPR, realtype,
9604 ffecom_1 (IMAGPART_EXPR, realtype,
9606 ffecom_1 (IMAGPART_EXPR, realtype,
9611 if (TREE_CODE (type) != RECORD_TYPE)
9613 item = build (code, type, node1, node2);
9616 node1 = ffecom_stabilize_aggregate_ (node1);
9617 node2 = ffecom_stabilize_aggregate_ (node2);
9618 realtype = TREE_TYPE (TYPE_FIELDS (type));
9619 a = save_expr (ffecom_1 (REALPART_EXPR, realtype,
9621 b = save_expr (ffecom_1 (IMAGPART_EXPR, realtype,
9623 c = save_expr (ffecom_1 (REALPART_EXPR, realtype,
9625 d = save_expr (ffecom_1 (IMAGPART_EXPR, realtype,
9628 ffecom_2 (COMPLEX_EXPR, type,
9629 ffecom_2 (MINUS_EXPR, realtype,
9630 ffecom_2 (MULT_EXPR, realtype,
9633 ffecom_2 (MULT_EXPR, realtype,
9636 ffecom_2 (PLUS_EXPR, realtype,
9637 ffecom_2 (MULT_EXPR, realtype,
9640 ffecom_2 (MULT_EXPR, realtype,
9646 if ((TREE_CODE (node1) != RECORD_TYPE)
9647 && (TREE_CODE (node2) != RECORD_TYPE))
9649 item = build (code, type, node1, node2);
9652 assert (TREE_CODE (node1) == RECORD_TYPE);
9653 assert (TREE_CODE (node2) == RECORD_TYPE);
9654 node1 = ffecom_stabilize_aggregate_ (node1);
9655 node2 = ffecom_stabilize_aggregate_ (node2);
9656 realtype = TREE_TYPE (TYPE_FIELDS (type));
9658 ffecom_2 (TRUTH_ANDIF_EXPR, type,
9659 ffecom_2 (code, type,
9660 ffecom_1 (REALPART_EXPR, realtype,
9662 ffecom_1 (REALPART_EXPR, realtype,
9664 ffecom_2 (code, type,
9665 ffecom_1 (IMAGPART_EXPR, realtype,
9667 ffecom_1 (IMAGPART_EXPR, realtype,
9672 if ((TREE_CODE (node1) != RECORD_TYPE)
9673 && (TREE_CODE (node2) != RECORD_TYPE))
9675 item = build (code, type, node1, node2);
9678 assert (TREE_CODE (node1) == RECORD_TYPE);
9679 assert (TREE_CODE (node2) == RECORD_TYPE);
9680 node1 = ffecom_stabilize_aggregate_ (node1);
9681 node2 = ffecom_stabilize_aggregate_ (node2);
9682 realtype = TREE_TYPE (TYPE_FIELDS (type));
9684 ffecom_2 (TRUTH_ORIF_EXPR, type,
9685 ffecom_2 (code, type,
9686 ffecom_1 (REALPART_EXPR, realtype,
9688 ffecom_1 (REALPART_EXPR, realtype,
9690 ffecom_2 (code, type,
9691 ffecom_1 (IMAGPART_EXPR, realtype,
9693 ffecom_1 (IMAGPART_EXPR, realtype,
9698 item = build (code, type, node1, node2);
9702 if (TREE_SIDE_EFFECTS (node1) || TREE_SIDE_EFFECTS (node2))
9703 TREE_SIDE_EFFECTS (item) = 1;
9707 /* ffecom_2pass_advise_entrypoint -- Advise that there's this entrypoint
9709 ffesymbol s; // the ENTRY point itself
9710 if (ffecom_2pass_advise_entrypoint(s))
9711 // the ENTRY point has been accepted
9713 Does whatever compiler needs to do when it learns about the entrypoint,
9714 like determine the return type of the master function, count the
9715 number of entrypoints, etc. Returns FALSE if the return type is
9716 not compatible with the return type(s) of other entrypoint(s).
9718 NOTE: for every call to this fn that returns TRUE, _do_entrypoint must
9719 later (after _finish_progunit) be called with the same entrypoint(s)
9720 as passed to this fn for which TRUE was returned.
9723 Return FALSE if the return type conflicts with previous entrypoints. */
9726 ffecom_2pass_advise_entrypoint (ffesymbol entry)
9728 ffebld list; /* opITEM. */
9729 ffebld mlist; /* opITEM. */
9730 ffebld plist; /* opITEM. */
9731 ffebld arg; /* ffebld_head(opITEM). */
9732 ffebld item; /* opITEM. */
9733 ffesymbol s; /* ffebld_symter(arg). */
9734 ffeinfoBasictype bt = ffesymbol_basictype (entry);
9735 ffeinfoKindtype kt = ffesymbol_kindtype (entry);
9736 ffetargetCharacterSize size = ffesymbol_size (entry);
9739 if (ffecom_num_entrypoints_ == 0)
9740 { /* First entrypoint, make list of main
9741 arglist's dummies. */
9742 assert (ffecom_primary_entry_ != NULL);
9744 ffecom_master_bt_ = ffesymbol_basictype (ffecom_primary_entry_);
9745 ffecom_master_kt_ = ffesymbol_kindtype (ffecom_primary_entry_);
9746 ffecom_master_size_ = ffesymbol_size (ffecom_primary_entry_);
9748 for (plist = NULL, list = ffesymbol_dummyargs (ffecom_primary_entry_);
9750 list = ffebld_trail (list))
9752 arg = ffebld_head (list);
9753 if (ffebld_op (arg) != FFEBLD_opSYMTER)
9754 continue; /* Alternate return or some such thing. */
9755 item = ffebld_new_item (arg, NULL);
9757 ffecom_master_arglist_ = item;
9759 ffebld_set_trail (plist, item);
9764 /* If necessary, scan entry arglist for alternate returns. Do this scan
9765 apparently redundantly (it's done below to UNIONize the arglists) so
9766 that we don't complain about RETURN 1 if an offending ENTRY is the only
9767 one with an alternate return. */
9769 if (!ffecom_is_altreturning_)
9771 for (list = ffesymbol_dummyargs (entry);
9773 list = ffebld_trail (list))
9775 arg = ffebld_head (list);
9776 if (ffebld_op (arg) == FFEBLD_opSTAR)
9778 ffecom_is_altreturning_ = TRUE;
9784 /* Now check type compatibility. */
9786 switch (ffecom_master_bt_)
9788 case FFEINFO_basictypeNONE:
9789 ok = (bt != FFEINFO_basictypeCHARACTER);
9792 case FFEINFO_basictypeCHARACTER:
9794 = (bt == FFEINFO_basictypeCHARACTER)
9795 && (kt == ffecom_master_kt_)
9796 && (size == ffecom_master_size_);
9799 case FFEINFO_basictypeANY:
9800 return FALSE; /* Just don't bother. */
9803 if (bt == FFEINFO_basictypeCHARACTER)
9809 if ((bt != ffecom_master_bt_) || (kt != ffecom_master_kt_))
9811 ffecom_master_bt_ = FFEINFO_basictypeNONE;
9812 ffecom_master_kt_ = FFEINFO_kindtypeNONE;
9819 ffebad_start (FFEBAD_ENTRY_CONFLICTS);
9820 ffest_ffebad_here_current_stmt (0);
9822 return FALSE; /* Can't handle entrypoint. */
9825 /* Entrypoint type compatible with previous types. */
9827 ++ffecom_num_entrypoints_;
9829 /* Master-arg-list = UNION(Master-arg-list,entry-arg-list). */
9831 for (list = ffesymbol_dummyargs (entry);
9833 list = ffebld_trail (list))
9835 arg = ffebld_head (list);
9836 if (ffebld_op (arg) != FFEBLD_opSYMTER)
9837 continue; /* Alternate return or some such thing. */
9838 s = ffebld_symter (arg);
9839 for (plist = NULL, mlist = ffecom_master_arglist_;
9841 plist = mlist, mlist = ffebld_trail (mlist))
9842 { /* plist points to previous item for easy
9843 appending of arg. */
9844 if (ffebld_symter (ffebld_head (mlist)) == s)
9845 break; /* Already have this arg in the master list. */
9848 continue; /* Already have this arg in the master list. */
9850 /* Append this arg to the master list. */
9852 item = ffebld_new_item (arg, NULL);
9854 ffecom_master_arglist_ = item;
9856 ffebld_set_trail (plist, item);
9862 /* ffecom_2pass_do_entrypoint -- Do compilation of entrypoint
9864 ffesymbol s; // the ENTRY point itself
9865 ffecom_2pass_do_entrypoint(s);
9867 Does whatever compiler needs to do to make the entrypoint actually
9868 happen. Must be called for each entrypoint after
9869 ffecom_finish_progunit is called. */
9872 ffecom_2pass_do_entrypoint (ffesymbol entry)
9874 static int mfn_num = 0;
9877 if (mfn_num != ffecom_num_fns_)
9878 { /* First entrypoint for this program unit. */
9880 mfn_num = ffecom_num_fns_;
9881 ffecom_do_entry_ (ffecom_primary_entry_, 0);
9886 --ffecom_num_entrypoints_;
9888 ffecom_do_entry_ (entry, ent_num);
9891 /* Essentially does a "fold (build (code, type, node1, node2))" while
9892 checking for certain housekeeping things. Always sets
9893 TREE_SIDE_EFFECTS. */
9896 ffecom_2s (enum tree_code code, tree type, tree node1, tree node2)
9900 if ((node1 == error_mark_node)
9901 || (node2 == error_mark_node)
9902 || (type == error_mark_node))
9903 return error_mark_node;
9905 item = build (code, type, node1, node2);
9906 TREE_SIDE_EFFECTS (item) = 1;
9910 /* Essentially does a "fold (build (code, type, node1, node2, node3))" while
9911 checking for certain housekeeping things. */
9914 ffecom_3 (enum tree_code code, tree type, tree node1, tree node2, tree node3)
9918 if ((node1 == error_mark_node)
9919 || (node2 == error_mark_node)
9920 || (node3 == error_mark_node)
9921 || (type == error_mark_node))
9922 return error_mark_node;
9924 item = build (code, type, node1, node2, node3);
9925 if (TREE_SIDE_EFFECTS (node1) || TREE_SIDE_EFFECTS (node2)
9926 || (node3 != NULL_TREE && TREE_SIDE_EFFECTS (node3)))
9927 TREE_SIDE_EFFECTS (item) = 1;
9931 /* Essentially does a "fold (build (code, type, node1, node2, node3))" while
9932 checking for certain housekeeping things. Always sets
9933 TREE_SIDE_EFFECTS. */
9936 ffecom_3s (enum tree_code code, tree type, tree node1, tree node2, tree node3)
9940 if ((node1 == error_mark_node)
9941 || (node2 == error_mark_node)
9942 || (node3 == error_mark_node)
9943 || (type == error_mark_node))
9944 return error_mark_node;
9946 item = build (code, type, node1, node2, node3);
9947 TREE_SIDE_EFFECTS (item) = 1;
9951 /* ffecom_arg_expr -- Transform argument expr into gcc tree
9953 See use by ffecom_list_expr.
9955 If expression is NULL, returns an integer zero tree. If it is not
9956 a CHARACTER expression, returns whatever ffecom_expr
9957 returns and sets the length return value to NULL_TREE. Otherwise
9958 generates code to evaluate the character expression, returns the proper
9959 pointer to the result, but does NOT set the length return value to a tree
9960 that specifies the length of the result. (In other words, the length
9961 variable is always set to NULL_TREE, because a length is never passed.)
9964 Don't set returned length, since nobody needs it (yet; someday if
9965 we allow CHARACTER*(*) dummies to statement functions, we'll need
9969 ffecom_arg_expr (ffebld expr, tree *length)
9973 *length = NULL_TREE;
9976 return integer_zero_node;
9978 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
9979 return ffecom_expr (expr);
9981 return ffecom_arg_ptr_to_expr (expr, &ign);
9984 /* Transform expression into constant argument-pointer-to-expression tree.
9986 If the expression can be transformed into a argument-pointer-to-expression
9987 tree that is constant, that is done, and the tree returned. Else
9988 NULL_TREE is returned.
9990 That way, a caller can attempt to provide compile-time initialization
9991 of a variable and, if that fails, *then* choose to start a new block
9992 and resort to using temporaries, as appropriate. */
9995 ffecom_arg_ptr_to_const_expr (ffebld expr, tree *length)
9998 return integer_zero_node;
10000 if (ffebld_op (expr) == FFEBLD_opANY)
10003 *length = error_mark_node;
10004 return error_mark_node;
10007 if (ffebld_arity (expr) == 0
10008 && (ffebld_op (expr) != FFEBLD_opSYMTER
10009 || ffebld_where (expr) == FFEINFO_whereCOMMON
10010 || ffebld_where (expr) == FFEINFO_whereGLOBAL
10011 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
10015 t = ffecom_arg_ptr_to_expr (expr, length);
10016 assert (TREE_CONSTANT (t));
10017 assert (! length || TREE_CONSTANT (*length));
10022 && ffebld_size (expr) != FFETARGET_charactersizeNONE)
10023 *length = build_int_2 (ffebld_size (expr), 0);
10025 *length = NULL_TREE;
10029 /* ffecom_arg_ptr_to_expr -- Transform argument expr into gcc tree
10031 See use by ffecom_list_ptr_to_expr.
10033 If expression is NULL, returns an integer zero tree. If it is not
10034 a CHARACTER expression, returns whatever ffecom_ptr_to_expr
10035 returns and sets the length return value to NULL_TREE. Otherwise
10036 generates code to evaluate the character expression, returns the proper
10037 pointer to the result, AND sets the length return value to a tree that
10038 specifies the length of the result.
10040 If the length argument is NULL, this is a slightly special
10041 case of building a FORMAT expression, that is, an expression that
10042 will be used at run time without regard to length. For the current
10043 implementation, which uses the libf2c library, this means it is nice
10044 to append a null byte to the end of the expression, where feasible,
10045 to make sure any diagnostic about the FORMAT string terminates at
10048 For now, treat %REF(char-expr) as the same as char-expr with a NULL
10049 length argument. This might even be seen as a feature, if a null
10050 byte can always be appended. */
10053 ffecom_arg_ptr_to_expr (ffebld expr, tree *length)
10057 ffecomConcatList_ catlist;
10059 if (length != NULL)
10060 *length = NULL_TREE;
10063 return integer_zero_node;
10065 switch (ffebld_op (expr))
10067 case FFEBLD_opPERCENT_VAL:
10068 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10069 return ffecom_expr (ffebld_left (expr));
10074 temp_exp = ffecom_arg_ptr_to_expr (ffebld_left (expr), &temp_length);
10075 if (temp_exp == error_mark_node)
10076 return error_mark_node;
10078 return ffecom_1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (temp_exp)),
10082 case FFEBLD_opPERCENT_REF:
10083 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10084 return ffecom_ptr_to_expr (ffebld_left (expr));
10085 if (length != NULL)
10087 ign_length = NULL_TREE;
10088 length = &ign_length;
10090 expr = ffebld_left (expr);
10093 case FFEBLD_opPERCENT_DESCR:
10094 switch (ffeinfo_basictype (ffebld_info (expr)))
10096 case FFEINFO_basictypeCHARACTER:
10097 break; /* Passed by descriptor anyway. */
10100 item = ffecom_ptr_to_expr (expr);
10101 if (item != error_mark_node)
10102 *length = TYPE_SIZE (TREE_TYPE (TREE_TYPE (item)));
10111 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10112 return ffecom_ptr_to_expr (expr);
10114 assert (ffeinfo_kindtype (ffebld_info (expr))
10115 == FFEINFO_kindtypeCHARACTER1);
10117 while (ffebld_op (expr) == FFEBLD_opPAREN)
10118 expr = ffebld_left (expr);
10120 catlist = ffecom_concat_list_new_ (expr, FFETARGET_charactersizeNONE);
10121 switch (ffecom_concat_list_count_ (catlist))
10123 case 0: /* Shouldn't happen, but in case it does... */
10124 if (length != NULL)
10126 *length = ffecom_f2c_ftnlen_zero_node;
10127 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
10129 ffecom_concat_list_kill_ (catlist);
10130 return null_pointer_node;
10132 case 1: /* The (fairly) easy case. */
10133 if (length == NULL)
10134 ffecom_char_args_with_null_ (&item, &ign_length,
10135 ffecom_concat_list_expr_ (catlist, 0));
10137 ffecom_char_args_ (&item, length,
10138 ffecom_concat_list_expr_ (catlist, 0));
10139 ffecom_concat_list_kill_ (catlist);
10140 assert (item != NULL_TREE);
10143 default: /* Must actually concatenate things. */
10148 int count = ffecom_concat_list_count_ (catlist);
10159 ffetargetCharacterSize sz;
10161 sz = ffecom_concat_list_maxlen_ (catlist);
10163 assert (sz != FFETARGET_charactersizeNONE);
10168 hook = ffebld_nonter_hook (expr);
10170 assert (TREE_CODE (hook) == TREE_VEC);
10171 assert (TREE_VEC_LENGTH (hook) == 3);
10172 length_array = lengths = TREE_VEC_ELT (hook, 0);
10173 item_array = items = TREE_VEC_ELT (hook, 1);
10174 temporary = TREE_VEC_ELT (hook, 2);
10177 known_length = ffecom_f2c_ftnlen_zero_node;
10179 for (i = 0; i < count; ++i)
10182 && (length == NULL))
10183 ffecom_char_args_with_null_ (&citem, &clength,
10184 ffecom_concat_list_expr_ (catlist, i));
10186 ffecom_char_args_ (&citem, &clength,
10187 ffecom_concat_list_expr_ (catlist, i));
10188 if ((citem == error_mark_node)
10189 || (clength == error_mark_node))
10191 ffecom_concat_list_kill_ (catlist);
10192 *length = error_mark_node;
10193 return error_mark_node;
10197 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (items),
10198 ffecom_modify (void_type_node,
10199 ffecom_2 (ARRAY_REF,
10200 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array))),
10202 build_int_2 (i, 0)),
10205 clength = ffecom_save_tree (clength);
10206 if (length != NULL)
10208 = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
10212 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (lengths),
10213 ffecom_modify (void_type_node,
10214 ffecom_2 (ARRAY_REF,
10215 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array))),
10217 build_int_2 (i, 0)),
10222 temporary = ffecom_1 (ADDR_EXPR,
10223 build_pointer_type (TREE_TYPE (temporary)),
10226 item = build_tree_list (NULL_TREE, temporary);
10228 = build_tree_list (NULL_TREE,
10229 ffecom_1 (ADDR_EXPR,
10230 build_pointer_type (TREE_TYPE (items)),
10232 TREE_CHAIN (TREE_CHAIN (item))
10233 = build_tree_list (NULL_TREE,
10234 ffecom_1 (ADDR_EXPR,
10235 build_pointer_type (TREE_TYPE (lengths)),
10237 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item)))
10240 ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
10241 convert (ffecom_f2c_ftnlen_type_node,
10242 build_int_2 (count, 0))));
10243 num = build_int_2 (sz, 0);
10244 TREE_TYPE (num) = ffecom_f2c_ftnlen_type_node;
10245 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item))))
10246 = build_tree_list (NULL_TREE, num);
10248 item = ffecom_call_gfrt (FFECOM_gfrtCAT, item, NULL_TREE);
10249 TREE_SIDE_EFFECTS (item) = 1;
10250 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (temporary),
10254 if (length != NULL)
10255 *length = known_length;
10258 ffecom_concat_list_kill_ (catlist);
10259 assert (item != NULL_TREE);
10263 /* Generate call to run-time function.
10265 The first arg is the GNU Fortran Run-Time function index, the second
10266 arg is the list of arguments to pass to it. Returned is the expression
10267 (WITHOUT TREE_SIDE_EFFECTS set!) that makes the call and returns the
10268 result (which may be void). */
10271 ffecom_call_gfrt (ffecomGfrt ix, tree args, tree hook)
10273 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
10274 ffecom_gfrt_kindtype (ix),
10275 ffe_is_f2c_library () && ffecom_gfrt_complex_[ix],
10276 NULL_TREE, args, NULL_TREE, NULL,
10277 NULL, NULL_TREE, TRUE, hook);
10280 /* Transform constant-union to tree. */
10283 ffecom_constantunion (ffebldConstantUnion *cu, ffeinfoBasictype bt,
10284 ffeinfoKindtype kt, tree tree_type)
10290 case FFEINFO_basictypeINTEGER:
10292 HOST_WIDE_INT hi, lo;
10296 #if FFETARGET_okINTEGER1
10297 case FFEINFO_kindtypeINTEGER1:
10298 lo = ffebld_cu_val_integer1 (*cu);
10299 hi = (lo < 0) ? -1 : 0;
10303 #if FFETARGET_okINTEGER2
10304 case FFEINFO_kindtypeINTEGER2:
10305 lo = ffebld_cu_val_integer2 (*cu);
10306 hi = (lo < 0) ? -1 : 0;
10310 #if FFETARGET_okINTEGER3
10311 case FFEINFO_kindtypeINTEGER3:
10312 lo = ffebld_cu_val_integer3 (*cu);
10313 hi = (lo < 0) ? -1 : 0;
10317 #if FFETARGET_okINTEGER4
10318 case FFEINFO_kindtypeINTEGER4:
10319 #if HOST_BITS_PER_LONGLONG > HOST_BITS_PER_WIDE_INT
10321 long long int big = ffebld_cu_val_integer4 (*cu);
10322 hi = (HOST_WIDE_INT) (big >> HOST_BITS_PER_WIDE_INT);
10323 lo = (HOST_WIDE_INT) big;
10326 lo = ffebld_cu_val_integer4 (*cu);
10327 hi = (lo < 0) ? -1 : 0;
10333 assert ("bad INTEGER constant kind type" == NULL);
10334 /* Fall through. */
10335 case FFEINFO_kindtypeANY:
10336 return error_mark_node;
10338 item = build_int_2 (lo, hi);
10339 TREE_TYPE (item) = tree_type;
10343 case FFEINFO_basictypeLOGICAL:
10349 #if FFETARGET_okLOGICAL1
10350 case FFEINFO_kindtypeLOGICAL1:
10351 val = ffebld_cu_val_logical1 (*cu);
10355 #if FFETARGET_okLOGICAL2
10356 case FFEINFO_kindtypeLOGICAL2:
10357 val = ffebld_cu_val_logical2 (*cu);
10361 #if FFETARGET_okLOGICAL3
10362 case FFEINFO_kindtypeLOGICAL3:
10363 val = ffebld_cu_val_logical3 (*cu);
10367 #if FFETARGET_okLOGICAL4
10368 case FFEINFO_kindtypeLOGICAL4:
10369 val = ffebld_cu_val_logical4 (*cu);
10374 assert ("bad LOGICAL constant kind type" == NULL);
10375 /* Fall through. */
10376 case FFEINFO_kindtypeANY:
10377 return error_mark_node;
10379 item = build_int_2 (val, (val < 0) ? -1 : 0);
10380 TREE_TYPE (item) = tree_type;
10384 case FFEINFO_basictypeREAL:
10386 REAL_VALUE_TYPE val;
10390 #if FFETARGET_okREAL1
10391 case FFEINFO_kindtypeREAL1:
10392 val = ffetarget_value_real1 (ffebld_cu_val_real1 (*cu));
10396 #if FFETARGET_okREAL2
10397 case FFEINFO_kindtypeREAL2:
10398 val = ffetarget_value_real2 (ffebld_cu_val_real2 (*cu));
10402 #if FFETARGET_okREAL3
10403 case FFEINFO_kindtypeREAL3:
10404 val = ffetarget_value_real3 (ffebld_cu_val_real3 (*cu));
10409 assert ("bad REAL constant kind type" == NULL);
10410 /* Fall through. */
10411 case FFEINFO_kindtypeANY:
10412 return error_mark_node;
10414 item = build_real (tree_type, val);
10418 case FFEINFO_basictypeCOMPLEX:
10420 REAL_VALUE_TYPE real;
10421 REAL_VALUE_TYPE imag;
10422 tree el_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
10426 #if FFETARGET_okCOMPLEX1
10427 case FFEINFO_kindtypeREAL1:
10428 real = ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu).real);
10429 imag = ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu).imaginary);
10433 #if FFETARGET_okCOMPLEX2
10434 case FFEINFO_kindtypeREAL2:
10435 real = ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu).real);
10436 imag = ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu).imaginary);
10440 #if FFETARGET_okCOMPLEX3
10441 case FFEINFO_kindtypeREAL3:
10442 real = ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu).real);
10443 imag = ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu).imaginary);
10448 assert ("bad REAL constant kind type" == NULL);
10449 /* Fall through. */
10450 case FFEINFO_kindtypeANY:
10451 return error_mark_node;
10453 item = ffecom_build_complex_constant_ (tree_type,
10454 build_real (el_type, real),
10455 build_real (el_type, imag));
10459 case FFEINFO_basictypeCHARACTER:
10460 { /* Happens only in DATA and similar contexts. */
10461 ffetargetCharacter1 val;
10465 #if FFETARGET_okCHARACTER1
10466 case FFEINFO_kindtypeLOGICAL1:
10467 val = ffebld_cu_val_character1 (*cu);
10472 assert ("bad CHARACTER constant kind type" == NULL);
10473 /* Fall through. */
10474 case FFEINFO_kindtypeANY:
10475 return error_mark_node;
10477 item = build_string (ffetarget_length_character1 (val),
10478 ffetarget_text_character1 (val));
10480 = build_type_variant (build_array_type (char_type_node,
10482 (integer_type_node,
10485 (ffetarget_length_character1
10491 case FFEINFO_basictypeHOLLERITH:
10493 ffetargetHollerith h;
10495 h = ffebld_cu_val_hollerith (*cu);
10497 /* If not at least as wide as default INTEGER, widen it. */
10498 if (h.length >= FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE)
10499 item = build_string (h.length, h.text);
10502 char str[FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE];
10504 memcpy (str, h.text, h.length);
10505 memset (&str[h.length], ' ',
10506 FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE
10508 item = build_string (FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE,
10512 = build_type_variant (build_array_type (char_type_node,
10514 (integer_type_node,
10522 case FFEINFO_basictypeTYPELESS:
10524 ffetargetInteger1 ival;
10525 ffetargetTypeless tless;
10528 tless = ffebld_cu_val_typeless (*cu);
10529 error = ffetarget_convert_integer1_typeless (&ival, tless);
10530 assert (error == FFEBAD);
10532 item = build_int_2 ((int) ival, 0);
10537 assert ("not yet on constant type" == NULL);
10538 /* Fall through. */
10539 case FFEINFO_basictypeANY:
10540 return error_mark_node;
10543 TREE_CONSTANT (item) = 1;
10548 /* Transform constant-union to tree, with the type known. */
10551 ffecom_constantunion_with_type (ffebldConstantUnion *cu, tree tree_type,
10560 #if FFETARGET_okINTEGER1
10561 case FFEBLD_constINTEGER1:
10562 val = ffebld_cu_val_integer1 (*cu);
10563 item = build_int_2 (val, (val < 0) ? -1 : 0);
10566 #if FFETARGET_okINTEGER2
10567 case FFEBLD_constINTEGER2:
10568 val = ffebld_cu_val_integer2 (*cu);
10569 item = build_int_2 (val, (val < 0) ? -1 : 0);
10572 #if FFETARGET_okINTEGER3
10573 case FFEBLD_constINTEGER3:
10574 val = ffebld_cu_val_integer3 (*cu);
10575 item = build_int_2 (val, (val < 0) ? -1 : 0);
10578 #if FFETARGET_okINTEGER4
10579 case FFEBLD_constINTEGER4:
10580 #if HOST_BITS_PER_LONGLONG > HOST_BITS_PER_WIDE_INT
10582 long long int big = ffebld_cu_val_integer4 (*cu);
10583 item = build_int_2 ((HOST_WIDE_INT) big,
10585 (big >> HOST_BITS_PER_WIDE_INT));
10588 val = ffebld_cu_val_integer4 (*cu);
10589 item = build_int_2 (val, (val < 0) ? -1 : 0);
10593 #if FFETARGET_okLOGICAL1
10594 case FFEBLD_constLOGICAL1:
10595 val = ffebld_cu_val_logical1 (*cu);
10596 item = build_int_2 (val, (val < 0) ? -1 : 0);
10599 #if FFETARGET_okLOGICAL2
10600 case FFEBLD_constLOGICAL2:
10601 val = ffebld_cu_val_logical2 (*cu);
10602 item = build_int_2 (val, (val < 0) ? -1 : 0);
10605 #if FFETARGET_okLOGICAL3
10606 case FFEBLD_constLOGICAL3:
10607 val = ffebld_cu_val_logical3 (*cu);
10608 item = build_int_2 (val, (val < 0) ? -1 : 0);
10611 #if FFETARGET_okLOGICAL4
10612 case FFEBLD_constLOGICAL4:
10613 val = ffebld_cu_val_logical4 (*cu);
10614 item = build_int_2 (val, (val < 0) ? -1 : 0);
10618 assert ("constant type not supported"==NULL);
10619 return error_mark_node;
10623 TREE_TYPE (item) = tree_type;
10625 TREE_CONSTANT (item) = 1;
10629 /* Transform expression into constant tree.
10631 If the expression can be transformed into a tree that is constant,
10632 that is done, and the tree returned. Else NULL_TREE is returned.
10634 That way, a caller can attempt to provide compile-time initialization
10635 of a variable and, if that fails, *then* choose to start a new block
10636 and resort to using temporaries, as appropriate. */
10639 ffecom_const_expr (ffebld expr)
10642 return integer_zero_node;
10644 if (ffebld_op (expr) == FFEBLD_opANY)
10645 return error_mark_node;
10647 if (ffebld_arity (expr) == 0
10648 && (ffebld_op (expr) != FFEBLD_opSYMTER
10649 || ffebld_where (expr) == FFEINFO_whereGLOBAL
10650 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
10654 t = ffecom_expr (expr);
10655 assert (TREE_CONSTANT (t));
10662 /* Handy way to make a field in a struct/union. */
10665 ffecom_decl_field (tree context, tree prevfield, const char *name, tree type)
10669 field = build_decl (FIELD_DECL, get_identifier (name), type);
10670 DECL_CONTEXT (field) = context;
10671 DECL_ALIGN (field) = 0;
10672 DECL_USER_ALIGN (field) = 0;
10673 if (prevfield != NULL_TREE)
10674 TREE_CHAIN (prevfield) = field;
10680 ffecom_close_include (FILE *f)
10682 ffecom_close_include_ (f);
10685 /* End a compound statement (block). */
10688 ffecom_end_compstmt (void)
10690 return bison_rule_compstmt_ ();
10693 /* ffecom_end_transition -- Perform end transition on all symbols
10695 ffecom_end_transition();
10697 Calls ffecom_sym_end_transition for each global and local symbol. */
10700 ffecom_end_transition (void)
10704 if (ffe_is_ffedebug ())
10705 fprintf (dmpout, "; end_stmt_transition\n");
10707 ffecom_list_blockdata_ = NULL;
10708 ffecom_list_common_ = NULL;
10710 ffesymbol_drive (ffecom_sym_end_transition);
10711 if (ffe_is_ffedebug ())
10713 ffestorag_report ();
10716 ffecom_start_progunit_ ();
10718 for (item = ffecom_list_blockdata_;
10720 item = ffebld_trail (item))
10727 static int number = 0;
10729 callee = ffebld_head (item);
10730 s = ffebld_symter (callee);
10731 t = ffesymbol_hook (s).decl_tree;
10732 if (t == NULL_TREE)
10734 s = ffecom_sym_transform_ (s);
10735 t = ffesymbol_hook (s).decl_tree;
10738 dt = build_pointer_type (TREE_TYPE (t));
10740 var = build_decl (VAR_DECL,
10741 ffecom_get_invented_identifier ("__g77_forceload_%d",
10744 DECL_EXTERNAL (var) = 0;
10745 TREE_STATIC (var) = 1;
10746 TREE_PUBLIC (var) = 0;
10747 DECL_INITIAL (var) = error_mark_node;
10748 TREE_USED (var) = 1;
10750 var = start_decl (var, FALSE);
10752 t = ffecom_1 (ADDR_EXPR, dt, t);
10754 finish_decl (var, t, FALSE);
10757 /* This handles any COMMON areas that weren't referenced but have, for
10758 example, important initial data. */
10760 for (item = ffecom_list_common_;
10762 item = ffebld_trail (item))
10763 ffecom_transform_common_ (ffebld_symter (ffebld_head (item)));
10765 ffecom_list_common_ = NULL;
10768 /* ffecom_exec_transition -- Perform exec transition on all symbols
10770 ffecom_exec_transition();
10772 Calls ffecom_sym_exec_transition for each global and local symbol.
10773 Make sure error updating not inhibited. */
10776 ffecom_exec_transition (void)
10780 if (ffe_is_ffedebug ())
10781 fprintf (dmpout, "; exec_stmt_transition\n");
10783 inhibited = ffebad_inhibit ();
10784 ffebad_set_inhibit (FALSE);
10786 ffesymbol_drive (ffecom_sym_exec_transition); /* Don't retract! */
10787 ffeequiv_exec_transition (); /* Handle all pending EQUIVALENCEs. */
10788 if (ffe_is_ffedebug ())
10790 ffestorag_report ();
10794 ffebad_set_inhibit (TRUE);
10797 /* Handle assignment statement.
10799 Convert dest and source using ffecom_expr, then join them
10800 with an ASSIGN op and pass the whole thing to expand_expr_stmt. */
10803 ffecom_expand_let_stmt (ffebld dest, ffebld source)
10810 if (ffeinfo_basictype (ffebld_info (dest)) != FFEINFO_basictypeCHARACTER)
10815 /* This attempts to replicate the test below, but must not be
10816 true when the test below is false. (Always err on the side
10817 of creating unused temporaries, to avoid ICEs.) */
10818 if (ffebld_op (dest) != FFEBLD_opSYMTER
10819 || ((dest_tree = ffesymbol_hook (ffebld_symter (dest)).decl_tree)
10820 && (TREE_CODE (dest_tree) != VAR_DECL
10821 || TREE_ADDRESSABLE (dest_tree))))
10823 ffecom_prepare_expr_ (source, dest);
10828 ffecom_prepare_expr_ (source, NULL);
10832 ffecom_prepare_expr_w (NULL_TREE, dest);
10834 /* For COMPLEX assignment like C1=C2, if partial overlap is possible,
10835 create a temporary through which the assignment is to take place,
10836 since MODIFY_EXPR doesn't handle partial overlap properly. */
10837 if (ffebld_basictype (dest) == FFEINFO_basictypeCOMPLEX
10838 && ffecom_possible_partial_overlap_ (dest, source))
10840 assign_temp = ffecom_make_tempvar ("complex_let",
10842 [ffebld_basictype (dest)]
10843 [ffebld_kindtype (dest)],
10844 FFETARGET_charactersizeNONE,
10848 assign_temp = NULL_TREE;
10850 ffecom_prepare_end ();
10852 dest_tree = ffecom_expr_w (NULL_TREE, dest);
10853 if (dest_tree == error_mark_node)
10856 if ((TREE_CODE (dest_tree) != VAR_DECL)
10857 || TREE_ADDRESSABLE (dest_tree))
10858 source_tree = ffecom_expr_ (source, dest_tree, dest, &dest_used,
10862 assert (! dest_used);
10864 source_tree = ffecom_expr (source);
10866 if (source_tree == error_mark_node)
10870 expr_tree = source_tree;
10871 else if (assign_temp)
10873 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
10876 expand_expr_stmt (expr_tree);
10877 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
10882 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
10886 expand_expr_stmt (expr_tree);
10890 ffecom_prepare_let_char_ (ffebld_size_known (dest), source);
10891 ffecom_prepare_expr_w (NULL_TREE, dest);
10893 ffecom_prepare_end ();
10895 ffecom_char_args_ (&dest_tree, &dest_length, dest);
10896 ffecom_let_char_ (dest_tree, dest_length, ffebld_size_known (dest),
10900 /* ffecom_expr -- Transform expr into gcc tree
10903 ffebld expr; // FFE expression.
10904 tree = ffecom_expr(expr);
10906 Recursive descent on expr while making corresponding tree nodes and
10907 attaching type info and such. */
10910 ffecom_expr (ffebld expr)
10912 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, FALSE, FALSE);
10915 /* Like ffecom_expr, but return tree usable for assigned GOTO or FORMAT. */
10918 ffecom_expr_assign (ffebld expr)
10920 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, TRUE, FALSE);
10923 /* Like ffecom_expr_rw, but return tree usable for ASSIGN. */
10926 ffecom_expr_assign_w (ffebld expr)
10928 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, TRUE, FALSE);
10931 /* Transform expr for use as into read/write tree and stabilize the
10932 reference. Not for use on CHARACTER expressions.
10934 Recursive descent on expr while making corresponding tree nodes and
10935 attaching type info and such. */
10938 ffecom_expr_rw (tree type, ffebld expr)
10940 assert (expr != NULL);
10941 /* Different target types not yet supported. */
10942 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
10944 return stabilize_reference (ffecom_expr (expr));
10947 /* Transform expr for use as into write tree and stabilize the
10948 reference. Not for use on CHARACTER expressions.
10950 Recursive descent on expr while making corresponding tree nodes and
10951 attaching type info and such. */
10954 ffecom_expr_w (tree type, ffebld expr)
10956 assert (expr != NULL);
10957 /* Different target types not yet supported. */
10958 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
10960 return stabilize_reference (ffecom_expr (expr));
10963 /* Do global stuff. */
10966 ffecom_finish_compile (void)
10968 assert (ffecom_outer_function_decl_ == NULL_TREE);
10969 assert (current_function_decl == NULL_TREE);
10971 ffeglobal_drive (ffecom_finish_global_);
10974 /* Public entry point for front end to access finish_decl. */
10977 ffecom_finish_decl (tree decl, tree init, bool is_top_level)
10979 assert (!is_top_level);
10980 finish_decl (decl, init, FALSE);
10983 /* Finish a program unit. */
10986 ffecom_finish_progunit (void)
10988 ffecom_end_compstmt ();
10990 ffecom_previous_function_decl_ = current_function_decl;
10991 ffecom_which_entrypoint_decl_ = NULL_TREE;
10993 finish_function (0);
10996 /* Wrapper for get_identifier. pattern is sprintf-like. */
10999 ffecom_get_invented_identifier (const char *pattern, ...)
11005 va_start (ap, pattern);
11006 if (vasprintf (&nam, pattern, ap) == 0)
11009 decl = get_identifier (nam);
11011 IDENTIFIER_INVENTED (decl) = 1;
11016 ffecom_gfrt_basictype (ffecomGfrt gfrt)
11018 assert (gfrt < FFECOM_gfrt);
11020 switch (ffecom_gfrt_type_[gfrt])
11022 case FFECOM_rttypeVOID_:
11023 case FFECOM_rttypeVOIDSTAR_:
11024 return FFEINFO_basictypeNONE;
11026 case FFECOM_rttypeFTNINT_:
11027 return FFEINFO_basictypeINTEGER;
11029 case FFECOM_rttypeINTEGER_:
11030 return FFEINFO_basictypeINTEGER;
11032 case FFECOM_rttypeLONGINT_:
11033 return FFEINFO_basictypeINTEGER;
11035 case FFECOM_rttypeLOGICAL_:
11036 return FFEINFO_basictypeLOGICAL;
11038 case FFECOM_rttypeREAL_F2C_:
11039 case FFECOM_rttypeREAL_GNU_:
11040 return FFEINFO_basictypeREAL;
11042 case FFECOM_rttypeCOMPLEX_F2C_:
11043 case FFECOM_rttypeCOMPLEX_GNU_:
11044 return FFEINFO_basictypeCOMPLEX;
11046 case FFECOM_rttypeDOUBLE_:
11047 case FFECOM_rttypeDOUBLEREAL_:
11048 return FFEINFO_basictypeREAL;
11050 case FFECOM_rttypeDBLCMPLX_F2C_:
11051 case FFECOM_rttypeDBLCMPLX_GNU_:
11052 return FFEINFO_basictypeCOMPLEX;
11054 case FFECOM_rttypeCHARACTER_:
11055 return FFEINFO_basictypeCHARACTER;
11058 return FFEINFO_basictypeANY;
11063 ffecom_gfrt_kindtype (ffecomGfrt gfrt)
11065 assert (gfrt < FFECOM_gfrt);
11067 switch (ffecom_gfrt_type_[gfrt])
11069 case FFECOM_rttypeVOID_:
11070 case FFECOM_rttypeVOIDSTAR_:
11071 return FFEINFO_kindtypeNONE;
11073 case FFECOM_rttypeFTNINT_:
11074 return FFEINFO_kindtypeINTEGER1;
11076 case FFECOM_rttypeINTEGER_:
11077 return FFEINFO_kindtypeINTEGER1;
11079 case FFECOM_rttypeLONGINT_:
11080 return FFEINFO_kindtypeINTEGER4;
11082 case FFECOM_rttypeLOGICAL_:
11083 return FFEINFO_kindtypeLOGICAL1;
11085 case FFECOM_rttypeREAL_F2C_:
11086 case FFECOM_rttypeREAL_GNU_:
11087 return FFEINFO_kindtypeREAL1;
11089 case FFECOM_rttypeCOMPLEX_F2C_:
11090 case FFECOM_rttypeCOMPLEX_GNU_:
11091 return FFEINFO_kindtypeREAL1;
11093 case FFECOM_rttypeDOUBLE_:
11094 case FFECOM_rttypeDOUBLEREAL_:
11095 return FFEINFO_kindtypeREAL2;
11097 case FFECOM_rttypeDBLCMPLX_F2C_:
11098 case FFECOM_rttypeDBLCMPLX_GNU_:
11099 return FFEINFO_kindtypeREAL2;
11101 case FFECOM_rttypeCHARACTER_:
11102 return FFEINFO_kindtypeCHARACTER1;
11105 return FFEINFO_kindtypeANY;
11110 ffecom_init_0 (void)
11119 tree double_ftype_double, double_ftype_double_double;
11120 tree float_ftype_float, float_ftype_float_float;
11121 tree ldouble_ftype_ldouble, ldouble_ftype_ldouble_ldouble;
11122 tree ffecom_tree_ptr_to_fun_type_void;
11124 /* This block of code comes from the now-obsolete cktyps.c. It checks
11125 whether the compiler environment is buggy in known ways, some of which
11126 would, if not explicitly checked here, result in subtle bugs in g77. */
11128 if (ffe_is_do_internal_checks ())
11130 static const char names[][12]
11132 {"bar", "bletch", "foo", "foobar"};
11137 name = bsearch ("foo", &names[0], ARRAY_SIZE (names), sizeof (names[0]),
11138 (int (*)(const void *, const void *)) strcmp);
11139 if (name != &names[2][0])
11141 assert ("bsearch doesn't work, #define FFEPROJ_BSEARCH 0 in proj.h"
11146 ul = strtoul ("123456789", NULL, 10);
11147 if (ul != 123456789L)
11149 assert ("strtoul doesn't have enough range, #define FFEPROJ_STRTOUL 0\
11150 in proj.h" == NULL);
11154 fl = atof ("56.789");
11155 if ((fl < 56.788) || (fl > 56.79))
11157 assert ("atof not type double, fix your #include <stdio.h>"
11163 ffecom_outer_function_decl_ = NULL_TREE;
11164 current_function_decl = NULL_TREE;
11165 named_labels = NULL_TREE;
11166 current_binding_level = NULL_BINDING_LEVEL;
11167 free_binding_level = NULL_BINDING_LEVEL;
11168 /* Make the binding_level structure for global names. */
11170 global_binding_level = current_binding_level;
11171 current_binding_level->prep_state = 2;
11173 build_common_tree_nodes (1);
11175 /* Define `int' and `char' first so that dbx will output them first. */
11176 pushdecl (build_decl (TYPE_DECL, get_identifier ("int"),
11177 integer_type_node));
11178 /* CHARACTER*1 is unsigned in ICHAR contexts. */
11179 char_type_node = make_unsigned_type (CHAR_TYPE_SIZE);
11180 pushdecl (build_decl (TYPE_DECL, get_identifier ("char"),
11182 pushdecl (build_decl (TYPE_DECL, get_identifier ("long int"),
11183 long_integer_type_node));
11184 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned int"),
11185 unsigned_type_node));
11186 pushdecl (build_decl (TYPE_DECL, get_identifier ("long unsigned int"),
11187 long_unsigned_type_node));
11188 pushdecl (build_decl (TYPE_DECL, get_identifier ("long long int"),
11189 long_long_integer_type_node));
11190 pushdecl (build_decl (TYPE_DECL, get_identifier ("long long unsigned int"),
11191 long_long_unsigned_type_node));
11192 pushdecl (build_decl (TYPE_DECL, get_identifier ("short int"),
11193 short_integer_type_node));
11194 pushdecl (build_decl (TYPE_DECL, get_identifier ("short unsigned int"),
11195 short_unsigned_type_node));
11197 /* Set the sizetype before we make other types. This *should* be the
11198 first type we create. */
11201 (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE))));
11202 ffecom_typesize_pointer_
11203 = TREE_INT_CST_LOW (TYPE_SIZE (sizetype)) / BITS_PER_UNIT;
11205 build_common_tree_nodes_2 (0);
11207 /* Define both `signed char' and `unsigned char'. */
11208 pushdecl (build_decl (TYPE_DECL, get_identifier ("signed char"),
11209 signed_char_type_node));
11211 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned char"),
11212 unsigned_char_type_node));
11214 pushdecl (build_decl (TYPE_DECL, get_identifier ("float"),
11216 pushdecl (build_decl (TYPE_DECL, get_identifier ("double"),
11217 double_type_node));
11218 pushdecl (build_decl (TYPE_DECL, get_identifier ("long double"),
11219 long_double_type_node));
11221 /* For now, override what build_common_tree_nodes has done. */
11222 complex_integer_type_node = ffecom_make_complex_type_ (integer_type_node);
11223 complex_float_type_node = ffecom_make_complex_type_ (float_type_node);
11224 complex_double_type_node = ffecom_make_complex_type_ (double_type_node);
11225 complex_long_double_type_node
11226 = ffecom_make_complex_type_ (long_double_type_node);
11228 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex int"),
11229 complex_integer_type_node));
11230 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex float"),
11231 complex_float_type_node));
11232 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex double"),
11233 complex_double_type_node));
11234 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex long double"),
11235 complex_long_double_type_node));
11237 pushdecl (build_decl (TYPE_DECL, get_identifier ("void"),
11239 /* We are not going to have real types in C with less than byte alignment,
11240 so we might as well not have any types that claim to have it. */
11241 TYPE_ALIGN (void_type_node) = BITS_PER_UNIT;
11242 TYPE_USER_ALIGN (void_type_node) = 0;
11244 string_type_node = build_pointer_type (char_type_node);
11246 ffecom_tree_fun_type_void
11247 = build_function_type (void_type_node, NULL_TREE);
11249 ffecom_tree_ptr_to_fun_type_void
11250 = build_pointer_type (ffecom_tree_fun_type_void);
11252 endlink = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
11254 t = tree_cons (NULL_TREE, float_type_node, endlink);
11255 float_ftype_float = build_function_type (float_type_node, t);
11256 t = tree_cons (NULL_TREE, float_type_node, t);
11257 float_ftype_float_float = build_function_type (float_type_node, t);
11259 t = tree_cons (NULL_TREE, double_type_node, endlink);
11260 double_ftype_double = build_function_type (double_type_node, t);
11261 t = tree_cons (NULL_TREE, double_type_node, t);
11262 double_ftype_double_double = build_function_type (double_type_node, t);
11264 t = tree_cons (NULL_TREE, long_double_type_node, endlink);
11265 ldouble_ftype_ldouble = build_function_type (long_double_type_node, t);
11266 t = tree_cons (NULL_TREE, long_double_type_node, t);
11267 ldouble_ftype_ldouble_ldouble = build_function_type (long_double_type_node,
11270 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11271 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11273 ffecom_tree_type[i][j] = NULL_TREE;
11274 ffecom_tree_fun_type[i][j] = NULL_TREE;
11275 ffecom_tree_ptr_to_fun_type[i][j] = NULL_TREE;
11276 ffecom_f2c_typecode_[i][j] = -1;
11279 /* Set up standard g77 types. Note that INTEGER and LOGICAL are set
11280 to size FLOAT_TYPE_SIZE because they have to be the same size as
11281 REAL, which also is FLOAT_TYPE_SIZE, according to the standard.
11282 Compiler options and other such stuff that change the ways these
11283 types are set should not affect this particular setup. */
11285 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER1]
11286 = t = make_signed_type (FLOAT_TYPE_SIZE);
11287 pushdecl (build_decl (TYPE_DECL, get_identifier ("integer"),
11289 type = ffetype_new ();
11291 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER1,
11293 ffetype_set_ams (type,
11294 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11295 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11296 ffetype_set_star (base_type,
11297 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11299 ffetype_set_kind (base_type, 1, type);
11300 ffecom_typesize_integer1_ = ffetype_size (type);
11301 assert (ffetype_size (type) == sizeof (ffetargetInteger1));
11303 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER1]
11304 = t = make_unsigned_type (FLOAT_TYPE_SIZE); /* HOLLERITH means unsigned. */
11305 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned"),
11308 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER2]
11309 = t = make_signed_type (CHAR_TYPE_SIZE);
11310 pushdecl (build_decl (TYPE_DECL, get_identifier ("byte"),
11312 type = ffetype_new ();
11313 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER2,
11315 ffetype_set_ams (type,
11316 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11317 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11318 ffetype_set_star (base_type,
11319 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11321 ffetype_set_kind (base_type, 3, type);
11322 assert (ffetype_size (type) == sizeof (ffetargetInteger2));
11324 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER2]
11325 = t = make_unsigned_type (CHAR_TYPE_SIZE);
11326 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned byte"),
11329 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER3]
11330 = t = make_signed_type (CHAR_TYPE_SIZE * 2);
11331 pushdecl (build_decl (TYPE_DECL, get_identifier ("word"),
11333 type = ffetype_new ();
11334 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER3,
11336 ffetype_set_ams (type,
11337 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11338 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11339 ffetype_set_star (base_type,
11340 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11342 ffetype_set_kind (base_type, 6, type);
11343 assert (ffetype_size (type) == sizeof (ffetargetInteger3));
11345 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER3]
11346 = t = make_unsigned_type (CHAR_TYPE_SIZE * 2);
11347 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned word"),
11350 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER4]
11351 = t = make_signed_type (FLOAT_TYPE_SIZE * 2);
11352 pushdecl (build_decl (TYPE_DECL, get_identifier ("integer4"),
11354 type = ffetype_new ();
11355 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER4,
11357 ffetype_set_ams (type,
11358 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11359 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11360 ffetype_set_star (base_type,
11361 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11363 ffetype_set_kind (base_type, 2, type);
11364 assert (ffetype_size (type) == sizeof (ffetargetInteger4));
11366 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER4]
11367 = t = make_unsigned_type (FLOAT_TYPE_SIZE * 2);
11368 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned4"),
11372 if (ffe_is_do_internal_checks ()
11373 && LONG_TYPE_SIZE != FLOAT_TYPE_SIZE
11374 && LONG_TYPE_SIZE != CHAR_TYPE_SIZE
11375 && LONG_TYPE_SIZE != SHORT_TYPE_SIZE
11376 && LONG_TYPE_SIZE != LONG_LONG_TYPE_SIZE)
11378 fprintf (stderr, "Sorry, no g77 support for LONG_TYPE_SIZE (%d bits) yet.\n",
11383 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL1]
11384 = t = make_signed_type (FLOAT_TYPE_SIZE);
11385 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical"),
11387 type = ffetype_new ();
11389 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL1,
11391 ffetype_set_ams (type,
11392 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11393 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11394 ffetype_set_star (base_type,
11395 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11397 ffetype_set_kind (base_type, 1, type);
11398 assert (ffetype_size (type) == sizeof (ffetargetLogical1));
11400 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL2]
11401 = t = make_signed_type (CHAR_TYPE_SIZE);
11402 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical2"),
11404 type = ffetype_new ();
11405 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL2,
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, 3, type);
11414 assert (ffetype_size (type) == sizeof (ffetargetLogical2));
11416 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL3]
11417 = t = make_signed_type (CHAR_TYPE_SIZE * 2);
11418 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical3"),
11420 type = ffetype_new ();
11421 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL3,
11423 ffetype_set_ams (type,
11424 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11425 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11426 ffetype_set_star (base_type,
11427 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11429 ffetype_set_kind (base_type, 6, type);
11430 assert (ffetype_size (type) == sizeof (ffetargetLogical3));
11432 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL4]
11433 = t = make_signed_type (FLOAT_TYPE_SIZE * 2);
11434 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical4"),
11436 type = ffetype_new ();
11437 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL4,
11439 ffetype_set_ams (type,
11440 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11441 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11442 ffetype_set_star (base_type,
11443 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11445 ffetype_set_kind (base_type, 2, type);
11446 assert (ffetype_size (type) == sizeof (ffetargetLogical4));
11448 ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]
11449 = t = make_node (REAL_TYPE);
11450 TYPE_PRECISION (t) = FLOAT_TYPE_SIZE;
11451 pushdecl (build_decl (TYPE_DECL, get_identifier ("real"),
11454 type = ffetype_new ();
11456 ffeinfo_set_type (FFEINFO_basictypeREAL, FFEINFO_kindtypeREAL1,
11458 ffetype_set_ams (type,
11459 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11460 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11461 ffetype_set_star (base_type,
11462 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11464 ffetype_set_kind (base_type, 1, type);
11465 ffecom_f2c_typecode_[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]
11466 = FFETARGET_f2cTYREAL;
11467 assert (ffetype_size (type) == sizeof (ffetargetReal1));
11469 ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREALDOUBLE]
11470 = t = make_node (REAL_TYPE);
11471 TYPE_PRECISION (t) = FLOAT_TYPE_SIZE * 2; /* Always twice REAL. */
11472 pushdecl (build_decl (TYPE_DECL, get_identifier ("double precision"),
11475 type = ffetype_new ();
11476 ffeinfo_set_type (FFEINFO_basictypeREAL, FFEINFO_kindtypeREALDOUBLE,
11478 ffetype_set_ams (type,
11479 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11480 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11481 ffetype_set_star (base_type,
11482 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11484 ffetype_set_kind (base_type, 2, type);
11485 ffecom_f2c_typecode_[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2]
11486 = FFETARGET_f2cTYDREAL;
11487 assert (ffetype_size (type) == sizeof (ffetargetReal2));
11489 ffecom_tree_type[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL1]
11490 = t = ffecom_make_complex_type_ (ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]);
11491 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex"),
11493 type = ffetype_new ();
11495 ffeinfo_set_type (FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREAL1,
11497 ffetype_set_ams (type,
11498 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11499 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11500 ffetype_set_star (base_type,
11501 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11503 ffetype_set_kind (base_type, 1, type);
11504 ffecom_f2c_typecode_[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL1]
11505 = FFETARGET_f2cTYCOMPLEX;
11506 assert (ffetype_size (type) == sizeof (ffetargetComplex1));
11508 ffecom_tree_type[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREALDOUBLE]
11509 = t = ffecom_make_complex_type_ (ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2]);
11510 pushdecl (build_decl (TYPE_DECL, get_identifier ("double complex"),
11512 type = ffetype_new ();
11513 ffeinfo_set_type (FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREALDOUBLE,
11515 ffetype_set_ams (type,
11516 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11517 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11518 ffetype_set_star (base_type,
11519 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11521 ffetype_set_kind (base_type, 2,
11523 ffecom_f2c_typecode_[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL2]
11524 = FFETARGET_f2cTYDCOMPLEX;
11525 assert (ffetype_size (type) == sizeof (ffetargetComplex2));
11527 /* Make function and ptr-to-function types for non-CHARACTER types. */
11529 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11530 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11532 if ((t = ffecom_tree_type[i][j]) != NULL_TREE)
11534 if (i == FFEINFO_basictypeINTEGER)
11536 /* Figure out the smallest INTEGER type that can hold
11537 a pointer on this machine. */
11538 if (GET_MODE_SIZE (TYPE_MODE (t))
11539 >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
11541 if ((ffecom_pointer_kind_ == FFEINFO_kindtypeNONE)
11542 || (GET_MODE_SIZE (TYPE_MODE (ffecom_tree_type[i][ffecom_pointer_kind_]))
11543 > GET_MODE_SIZE (TYPE_MODE (t))))
11544 ffecom_pointer_kind_ = j;
11547 else if (i == FFEINFO_basictypeCOMPLEX)
11548 t = void_type_node;
11549 /* For f2c compatibility, REAL functions are really
11550 implemented as DOUBLE PRECISION. */
11551 else if ((i == FFEINFO_basictypeREAL)
11552 && (j == FFEINFO_kindtypeREAL1))
11553 t = ffecom_tree_type
11554 [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2];
11556 t = ffecom_tree_fun_type[i][j] = build_function_type (t,
11558 ffecom_tree_ptr_to_fun_type[i][j] = build_pointer_type (t);
11562 /* Set up pointer types. */
11564 if (ffecom_pointer_kind_ == FFEINFO_basictypeNONE)
11565 fatal_error ("no INTEGER type can hold a pointer on this configuration");
11566 else if (0 && ffe_is_do_internal_checks ())
11567 fprintf (stderr, "Pointer type kt=%d\n", ffecom_pointer_kind_);
11568 ffetype_set_kind (ffeinfo_type (FFEINFO_basictypeINTEGER,
11569 FFEINFO_kindtypeINTEGERDEFAULT),
11571 ffeinfo_type (FFEINFO_basictypeINTEGER,
11572 ffecom_pointer_kind_));
11574 if (ffe_is_ugly_assign ())
11575 ffecom_label_kind_ = ffecom_pointer_kind_; /* Require ASSIGN etc to this. */
11577 ffecom_label_kind_ = FFEINFO_kindtypeINTEGERDEFAULT;
11578 if (0 && ffe_is_do_internal_checks ())
11579 fprintf (stderr, "Label type kt=%d\n", ffecom_label_kind_);
11581 ffecom_integer_type_node
11582 = ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER1];
11583 ffecom_integer_zero_node = convert (ffecom_integer_type_node,
11584 integer_zero_node);
11585 ffecom_integer_one_node = convert (ffecom_integer_type_node,
11588 /* Yes, the "FLOAT_TYPE_SIZE" references below are intentional.
11589 Turns out that by TYLONG, runtime/libI77/lio.h really means
11590 "whatever size an ftnint is". For consistency and sanity,
11591 com.h and runtime/f2c.h.in agree that flag, ftnint, and ftlen
11592 all are INTEGER, which we also make out of whatever back-end
11593 integer type is FLOAT_TYPE_SIZE bits wide. This change, from
11594 LONG_TYPE_SIZE, for TYLONG and TYLOGICAL, was necessary to
11595 accommodate machines like the Alpha. Note that this suggests
11596 f2c and libf2c are missing a distinction perhaps needed on
11597 some machines between "int" and "long int". -- burley 0.5.5 950215 */
11599 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, FLOAT_TYPE_SIZE,
11600 FFETARGET_f2cTYLONG);
11601 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, SHORT_TYPE_SIZE,
11602 FFETARGET_f2cTYSHORT);
11603 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, CHAR_TYPE_SIZE,
11604 FFETARGET_f2cTYINT1);
11605 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, LONG_LONG_TYPE_SIZE,
11606 FFETARGET_f2cTYQUAD);
11607 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, FLOAT_TYPE_SIZE,
11608 FFETARGET_f2cTYLOGICAL);
11609 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, SHORT_TYPE_SIZE,
11610 FFETARGET_f2cTYLOGICAL2);
11611 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, CHAR_TYPE_SIZE,
11612 FFETARGET_f2cTYLOGICAL1);
11613 /* ~~~Not really such a type in libf2c, e.g. I/O support? */
11614 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, LONG_LONG_TYPE_SIZE,
11615 FFETARGET_f2cTYQUAD);
11617 /* CHARACTER stuff is all special-cased, so it is not handled in the above
11618 loop. CHARACTER items are built as arrays of unsigned char. */
11620 ffecom_tree_type[FFEINFO_basictypeCHARACTER]
11621 [FFEINFO_kindtypeCHARACTER1] = t = char_type_node;
11622 type = ffetype_new ();
11624 ffeinfo_set_type (FFEINFO_basictypeCHARACTER,
11625 FFEINFO_kindtypeCHARACTER1,
11627 ffetype_set_ams (type,
11628 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11629 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11630 ffetype_set_kind (base_type, 1, type);
11631 assert (ffetype_size (type)
11632 == sizeof (((ffetargetCharacter1) { 0, NULL }).text[0]));
11634 ffecom_tree_fun_type[FFEINFO_basictypeCHARACTER]
11635 [FFEINFO_kindtypeCHARACTER1] = ffecom_tree_fun_type_void;
11636 ffecom_tree_ptr_to_fun_type[FFEINFO_basictypeCHARACTER]
11637 [FFEINFO_kindtypeCHARACTER1]
11638 = ffecom_tree_ptr_to_fun_type_void;
11639 ffecom_f2c_typecode_[FFEINFO_basictypeCHARACTER][FFEINFO_kindtypeCHARACTER1]
11640 = FFETARGET_f2cTYCHAR;
11642 ffecom_f2c_typecode_[FFEINFO_basictypeANY][FFEINFO_kindtypeANY]
11645 /* Make multi-return-value type and fields. */
11647 ffecom_multi_type_node_ = make_node (UNION_TYPE);
11651 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11652 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11656 if (ffecom_tree_type[i][j] == NULL_TREE)
11657 continue; /* Not supported. */
11658 sprintf (&name[0], "bt_%s_kt_%s",
11659 ffeinfo_basictype_string ((ffeinfoBasictype) i),
11660 ffeinfo_kindtype_string ((ffeinfoKindtype) j));
11661 ffecom_multi_fields_[i][j] = build_decl (FIELD_DECL,
11662 get_identifier (name),
11663 ffecom_tree_type[i][j]);
11664 DECL_CONTEXT (ffecom_multi_fields_[i][j])
11665 = ffecom_multi_type_node_;
11666 DECL_ALIGN (ffecom_multi_fields_[i][j]) = 0;
11667 DECL_USER_ALIGN (ffecom_multi_fields_[i][j]) = 0;
11668 TREE_CHAIN (ffecom_multi_fields_[i][j]) = field;
11669 field = ffecom_multi_fields_[i][j];
11672 TYPE_FIELDS (ffecom_multi_type_node_) = field;
11673 layout_type (ffecom_multi_type_node_);
11675 /* Subroutines usually return integer because they might have alternate
11678 ffecom_tree_subr_type
11679 = build_function_type (integer_type_node, NULL_TREE);
11680 ffecom_tree_ptr_to_subr_type
11681 = build_pointer_type (ffecom_tree_subr_type);
11682 ffecom_tree_blockdata_type
11683 = build_function_type (void_type_node, NULL_TREE);
11685 builtin_function ("__builtin_atanf", float_ftype_float,
11686 BUILT_IN_ATANF, BUILT_IN_NORMAL, "atanf", NULL_TREE);
11687 builtin_function ("__builtin_atan", double_ftype_double,
11688 BUILT_IN_ATAN, BUILT_IN_NORMAL, "atan", NULL_TREE);
11689 builtin_function ("__builtin_atanl", ldouble_ftype_ldouble,
11690 BUILT_IN_ATANL, BUILT_IN_NORMAL, "atanl", NULL_TREE);
11692 builtin_function ("__builtin_atan2f", float_ftype_float_float,
11693 BUILT_IN_ATAN2F, BUILT_IN_NORMAL, "atan2f", NULL_TREE);
11694 builtin_function ("__builtin_atan2", double_ftype_double_double,
11695 BUILT_IN_ATAN2, BUILT_IN_NORMAL, "atan2", NULL_TREE);
11696 builtin_function ("__builtin_atan2l", ldouble_ftype_ldouble_ldouble,
11697 BUILT_IN_ATAN2L, BUILT_IN_NORMAL, "atan2l", NULL_TREE);
11699 builtin_function ("__builtin_cosf", float_ftype_float,
11700 BUILT_IN_COSF, BUILT_IN_NORMAL, "cosf", NULL_TREE);
11701 builtin_function ("__builtin_cos", double_ftype_double,
11702 BUILT_IN_COS, BUILT_IN_NORMAL, "cos", NULL_TREE);
11703 builtin_function ("__builtin_cosl", ldouble_ftype_ldouble,
11704 BUILT_IN_COSL, BUILT_IN_NORMAL, "cosl", NULL_TREE);
11706 builtin_function ("__builtin_expf", float_ftype_float,
11707 BUILT_IN_EXPF, BUILT_IN_NORMAL, "expf", NULL_TREE);
11708 builtin_function ("__builtin_exp", double_ftype_double,
11709 BUILT_IN_EXP, BUILT_IN_NORMAL, "exp", NULL_TREE);
11710 builtin_function ("__builtin_expl", ldouble_ftype_ldouble,
11711 BUILT_IN_EXPL, BUILT_IN_NORMAL, "expl", NULL_TREE);
11713 builtin_function ("__builtin_floorf", float_ftype_float,
11714 BUILT_IN_FLOORF, BUILT_IN_NORMAL, "floorf", NULL_TREE);
11715 builtin_function ("__builtin_floor", double_ftype_double,
11716 BUILT_IN_FLOOR, BUILT_IN_NORMAL, "floor", NULL_TREE);
11717 builtin_function ("__builtin_floorl", ldouble_ftype_ldouble,
11718 BUILT_IN_FLOORL, BUILT_IN_NORMAL, "floorl", NULL_TREE);
11720 builtin_function ("__builtin_fmodf", float_ftype_float_float,
11721 BUILT_IN_FMODF, BUILT_IN_NORMAL, "fmodf", NULL_TREE);
11722 builtin_function ("__builtin_fmod", double_ftype_double_double,
11723 BUILT_IN_FMOD, BUILT_IN_NORMAL, "fmod", NULL_TREE);
11724 builtin_function ("__builtin_fmodl", ldouble_ftype_ldouble_ldouble,
11725 BUILT_IN_FMODL, BUILT_IN_NORMAL, "fmodl", NULL_TREE);
11727 builtin_function ("__builtin_logf", float_ftype_float,
11728 BUILT_IN_LOGF, BUILT_IN_NORMAL, "logf", NULL_TREE);
11729 builtin_function ("__builtin_log", double_ftype_double,
11730 BUILT_IN_LOG, BUILT_IN_NORMAL, "log", NULL_TREE);
11731 builtin_function ("__builtin_logl", ldouble_ftype_ldouble,
11732 BUILT_IN_LOGL, BUILT_IN_NORMAL, "logl", NULL_TREE);
11734 builtin_function ("__builtin_powf", float_ftype_float_float,
11735 BUILT_IN_POWF, BUILT_IN_NORMAL, "powf", NULL_TREE);
11736 builtin_function ("__builtin_pow", double_ftype_double_double,
11737 BUILT_IN_POW, BUILT_IN_NORMAL, "pow", NULL_TREE);
11738 builtin_function ("__builtin_powl", ldouble_ftype_ldouble_ldouble,
11739 BUILT_IN_POWL, BUILT_IN_NORMAL, "powl", NULL_TREE);
11741 builtin_function ("__builtin_sinf", float_ftype_float,
11742 BUILT_IN_SINF, BUILT_IN_NORMAL, "sinf", NULL_TREE);
11743 builtin_function ("__builtin_sin", double_ftype_double,
11744 BUILT_IN_SIN, BUILT_IN_NORMAL, "sin", NULL_TREE);
11745 builtin_function ("__builtin_sinl", ldouble_ftype_ldouble,
11746 BUILT_IN_SINL, BUILT_IN_NORMAL, "sinl", NULL_TREE);
11748 builtin_function ("__builtin_sqrtf", float_ftype_float,
11749 BUILT_IN_SQRTF, BUILT_IN_NORMAL, "sqrtf", NULL_TREE);
11750 builtin_function ("__builtin_sqrt", double_ftype_double,
11751 BUILT_IN_SQRT, BUILT_IN_NORMAL, "sqrt", NULL_TREE);
11752 builtin_function ("__builtin_sqrtl", ldouble_ftype_ldouble,
11753 BUILT_IN_SQRTL, BUILT_IN_NORMAL, "sqrtl", NULL_TREE);
11755 builtin_function ("__builtin_tanf", float_ftype_float,
11756 BUILT_IN_TANF, BUILT_IN_NORMAL, "tanf", NULL_TREE);
11757 builtin_function ("__builtin_tan", double_ftype_double,
11758 BUILT_IN_TAN, BUILT_IN_NORMAL, "tan", NULL_TREE);
11759 builtin_function ("__builtin_tanl", ldouble_ftype_ldouble,
11760 BUILT_IN_TANL, BUILT_IN_NORMAL, "tanl", NULL_TREE);
11762 pedantic_lvalues = FALSE;
11764 ffecom_f2c_make_type_ (&ffecom_f2c_integer_type_node,
11767 ffecom_f2c_make_type_ (&ffecom_f2c_address_type_node,
11770 ffecom_f2c_make_type_ (&ffecom_f2c_real_type_node,
11773 ffecom_f2c_make_type_ (&ffecom_f2c_doublereal_type_node,
11774 FFECOM_f2cDOUBLEREAL,
11776 ffecom_f2c_make_type_ (&ffecom_f2c_complex_type_node,
11779 ffecom_f2c_make_type_ (&ffecom_f2c_doublecomplex_type_node,
11780 FFECOM_f2cDOUBLECOMPLEX,
11782 ffecom_f2c_make_type_ (&ffecom_f2c_longint_type_node,
11785 ffecom_f2c_make_type_ (&ffecom_f2c_logical_type_node,
11788 ffecom_f2c_make_type_ (&ffecom_f2c_flag_type_node,
11791 ffecom_f2c_make_type_ (&ffecom_f2c_ftnlen_type_node,
11794 ffecom_f2c_make_type_ (&ffecom_f2c_ftnint_type_node,
11798 ffecom_f2c_ftnlen_zero_node
11799 = convert (ffecom_f2c_ftnlen_type_node, integer_zero_node);
11801 ffecom_f2c_ftnlen_one_node
11802 = convert (ffecom_f2c_ftnlen_type_node, integer_one_node);
11804 ffecom_f2c_ftnlen_two_node = build_int_2 (2, 0);
11805 TREE_TYPE (ffecom_f2c_ftnlen_two_node) = ffecom_integer_type_node;
11807 ffecom_f2c_ptr_to_ftnlen_type_node
11808 = build_pointer_type (ffecom_f2c_ftnlen_type_node);
11810 ffecom_f2c_ptr_to_ftnint_type_node
11811 = build_pointer_type (ffecom_f2c_ftnint_type_node);
11813 ffecom_f2c_ptr_to_integer_type_node
11814 = build_pointer_type (ffecom_f2c_integer_type_node);
11816 ffecom_f2c_ptr_to_real_type_node
11817 = build_pointer_type (ffecom_f2c_real_type_node);
11819 ffecom_float_zero_ = build_real (float_type_node, dconst0);
11820 ffecom_double_zero_ = build_real (double_type_node, dconst0);
11822 REAL_VALUE_TYPE point_5;
11824 REAL_ARITHMETIC (point_5, RDIV_EXPR, dconst1, dconst2);
11825 ffecom_float_half_ = build_real (float_type_node, point_5);
11826 ffecom_double_half_ = build_real (double_type_node, point_5);
11829 /* Do "extern int xargc;". */
11831 ffecom_tree_xargc_ = build_decl (VAR_DECL,
11832 get_identifier ("f__xargc"),
11833 integer_type_node);
11834 DECL_EXTERNAL (ffecom_tree_xargc_) = 1;
11835 TREE_STATIC (ffecom_tree_xargc_) = 1;
11836 TREE_PUBLIC (ffecom_tree_xargc_) = 1;
11837 ffecom_tree_xargc_ = start_decl (ffecom_tree_xargc_, FALSE);
11838 finish_decl (ffecom_tree_xargc_, NULL_TREE, FALSE);
11840 #if 0 /* This is being fixed, and seems to be working now. */
11841 if ((FLOAT_TYPE_SIZE != 32)
11842 || (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node))) != 32))
11844 warning ("configuration: REAL, INTEGER, and LOGICAL are %d bits wide,",
11845 (int) FLOAT_TYPE_SIZE);
11846 warning ("and pointers are %d bits wide, but g77 doesn't yet work",
11847 (int) TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node))));
11848 warning ("properly unless they all are 32 bits wide");
11849 warning ("Please keep this in mind before you report bugs.");
11853 #if 0 /* Code in ste.c that would crash has been commented out. */
11854 if (TYPE_PRECISION (ffecom_f2c_ftnlen_type_node)
11855 < TYPE_PRECISION (string_type_node))
11856 /* I/O will probably crash. */
11857 warning ("configuration: char * holds %d bits, but ftnlen only %d",
11858 TYPE_PRECISION (string_type_node),
11859 TYPE_PRECISION (ffecom_f2c_ftnlen_type_node));
11862 #if 0 /* ASSIGN-related stuff has been changed to accommodate this. */
11863 if (TYPE_PRECISION (ffecom_integer_type_node)
11864 < TYPE_PRECISION (string_type_node))
11865 /* ASSIGN 10 TO I will crash. */
11866 warning ("configuration: char * holds %d bits, but INTEGER only %d --\n\
11867 ASSIGN statement might fail",
11868 TYPE_PRECISION (string_type_node),
11869 TYPE_PRECISION (ffecom_integer_type_node));
11873 /* ffecom_init_2 -- Initialize
11875 ffecom_init_2(); */
11878 ffecom_init_2 (void)
11880 assert (ffecom_outer_function_decl_ == NULL_TREE);
11881 assert (current_function_decl == NULL_TREE);
11882 assert (ffecom_which_entrypoint_decl_ == NULL_TREE);
11884 ffecom_master_arglist_ = NULL;
11886 ffecom_primary_entry_ = NULL;
11887 ffecom_is_altreturning_ = FALSE;
11888 ffecom_func_result_ = NULL_TREE;
11889 ffecom_multi_retval_ = NULL_TREE;
11892 /* ffecom_list_expr -- Transform list of exprs into gcc tree
11895 ffebld expr; // FFE opITEM list.
11896 tree = ffecom_list_expr(expr);
11898 List of actual args is transformed into corresponding gcc backend list. */
11901 ffecom_list_expr (ffebld expr)
11904 tree *plist = &list;
11905 tree trail = NULL_TREE; /* Append char length args here. */
11906 tree *ptrail = &trail;
11909 while (expr != NULL)
11911 tree texpr = ffecom_arg_expr (ffebld_head (expr), &length);
11913 if (texpr == error_mark_node)
11914 return error_mark_node;
11916 *plist = build_tree_list (NULL_TREE, texpr);
11917 plist = &TREE_CHAIN (*plist);
11918 expr = ffebld_trail (expr);
11919 if (length != NULL_TREE)
11921 *ptrail = build_tree_list (NULL_TREE, length);
11922 ptrail = &TREE_CHAIN (*ptrail);
11931 /* ffecom_list_ptr_to_expr -- Transform list of exprs into gcc tree
11934 ffebld expr; // FFE opITEM list.
11935 tree = ffecom_list_ptr_to_expr(expr);
11937 List of actual args is transformed into corresponding gcc backend list for
11938 use in calling an external procedure (vs. a statement function). */
11941 ffecom_list_ptr_to_expr (ffebld expr)
11944 tree *plist = &list;
11945 tree trail = NULL_TREE; /* Append char length args here. */
11946 tree *ptrail = &trail;
11949 while (expr != NULL)
11951 tree texpr = ffecom_arg_ptr_to_expr (ffebld_head (expr), &length);
11953 if (texpr == error_mark_node)
11954 return error_mark_node;
11956 *plist = build_tree_list (NULL_TREE, texpr);
11957 plist = &TREE_CHAIN (*plist);
11958 expr = ffebld_trail (expr);
11959 if (length != NULL_TREE)
11961 *ptrail = build_tree_list (NULL_TREE, length);
11962 ptrail = &TREE_CHAIN (*ptrail);
11971 /* Obtain gcc's LABEL_DECL tree for label. */
11974 ffecom_lookup_label (ffelab label)
11978 if (ffelab_hook (label) == NULL_TREE)
11980 char labelname[16];
11982 switch (ffelab_type (label))
11984 case FFELAB_typeLOOPEND:
11985 case FFELAB_typeNOTLOOP:
11986 case FFELAB_typeENDIF:
11987 sprintf (labelname, "%" ffelabValue_f "u", ffelab_value (label));
11988 glabel = build_decl (LABEL_DECL, get_identifier (labelname),
11990 DECL_CONTEXT (glabel) = current_function_decl;
11991 DECL_MODE (glabel) = VOIDmode;
11994 case FFELAB_typeFORMAT:
11995 glabel = build_decl (VAR_DECL,
11996 ffecom_get_invented_identifier
11997 ("__g77_format_%d", (int) ffelab_value (label)),
11998 build_type_variant (build_array_type
12002 TREE_CONSTANT (glabel) = 1;
12003 TREE_STATIC (glabel) = 1;
12004 DECL_CONTEXT (glabel) = current_function_decl;
12005 DECL_INITIAL (glabel) = NULL;
12006 make_decl_rtl (glabel, NULL);
12007 expand_decl (glabel);
12009 ffecom_save_tree_forever (glabel);
12013 case FFELAB_typeANY:
12014 glabel = error_mark_node;
12018 assert ("bad label type" == NULL);
12022 ffelab_set_hook (label, glabel);
12026 glabel = ffelab_hook (label);
12032 /* Stabilizes the arguments. Don't use this if the lhs and rhs come from
12033 a single source specification (as in the fourth argument of MVBITS).
12034 If the type is NULL_TREE, the type of lhs is used to make the type of
12035 the MODIFY_EXPR. */
12038 ffecom_modify (tree newtype, tree lhs, tree rhs)
12040 if (lhs == error_mark_node || rhs == error_mark_node)
12041 return error_mark_node;
12043 if (newtype == NULL_TREE)
12044 newtype = TREE_TYPE (lhs);
12046 if (TREE_SIDE_EFFECTS (lhs))
12047 lhs = stabilize_reference (lhs);
12049 return ffecom_2s (MODIFY_EXPR, newtype, lhs, rhs);
12052 /* Register source file name. */
12055 ffecom_file (const char *name)
12057 ffecom_file_ (name);
12060 /* ffecom_notify_init_storage -- An aggregate storage is now fully init'ed
12063 ffecom_notify_init_storage(st);
12065 Gets called when all possible units in an aggregate storage area (a LOCAL
12066 with equivalences or a COMMON) have been initialized. The initialization
12067 info either is in ffestorag_init or, if that is NULL,
12068 ffestorag_accretion:
12070 ffestorag_init may contain an opCONTER or opARRTER. opCONTER may occur
12071 even for an array if the array is one element in length!
12073 ffestorag_accretion will contain an opACCTER. It is much like an
12074 opARRTER except it has an ffebit object in it instead of just a size.
12075 The back end can use the info in the ffebit object, if it wants, to
12076 reduce the amount of actual initialization, but in any case it should
12077 kill the ffebit object when done. Also, set accretion to NULL but
12078 init to a non-NULL value.
12080 After performing initialization, DO NOT set init to NULL, because that'll
12081 tell the front end it is ok for more initialization to happen. Instead,
12082 set init to an opANY expression or some such thing that you can use to
12083 tell that you've already initialized the object.
12086 Support two-pass FFE. */
12089 ffecom_notify_init_storage (ffestorag st)
12091 ffebld init; /* The initialization expression. */
12093 if (ffestorag_init (st) == NULL)
12095 init = ffestorag_accretion (st);
12096 assert (init != NULL);
12097 ffestorag_set_accretion (st, NULL);
12098 ffestorag_set_accretes (st, 0);
12099 ffestorag_set_init (st, init);
12103 /* ffecom_notify_init_symbol -- A symbol is now fully init'ed
12106 ffecom_notify_init_symbol(s);
12108 Gets called when all possible units in a symbol (not placed in COMMON
12109 or involved in EQUIVALENCE, unless it as yet has no ffestorag object)
12110 have been initialized. The initialization info either is in
12111 ffesymbol_init or, if that is NULL, ffesymbol_accretion:
12113 ffesymbol_init may contain an opCONTER or opARRTER. opCONTER may occur
12114 even for an array if the array is one element in length!
12116 ffesymbol_accretion will contain an opACCTER. It is much like an
12117 opARRTER except it has an ffebit object in it instead of just a size.
12118 The back end can use the info in the ffebit object, if it wants, to
12119 reduce the amount of actual initialization, but in any case it should
12120 kill the ffebit object when done. Also, set accretion to NULL but
12121 init to a non-NULL value.
12123 After performing initialization, DO NOT set init to NULL, because that'll
12124 tell the front end it is ok for more initialization to happen. Instead,
12125 set init to an opANY expression or some such thing that you can use to
12126 tell that you've already initialized the object.
12129 Support two-pass FFE. */
12132 ffecom_notify_init_symbol (ffesymbol s)
12134 ffebld init; /* The initialization expression. */
12136 if (ffesymbol_storage (s) == NULL)
12137 return; /* Do nothing until COMMON/EQUIVALENCE
12138 possibilities checked. */
12140 if ((ffesymbol_init (s) == NULL)
12141 && ((init = ffesymbol_accretion (s)) != NULL))
12143 ffesymbol_set_accretion (s, NULL);
12144 ffesymbol_set_accretes (s, 0);
12145 ffesymbol_set_init (s, init);
12149 /* ffecom_notify_primary_entry -- Learn which is the primary entry point
12152 ffecom_notify_primary_entry(s);
12154 Gets called when implicit or explicit PROGRAM statement seen or when
12155 FUNCTION, SUBROUTINE, or BLOCK DATA statement seen, with the primary
12156 global symbol that serves as the entry point. */
12159 ffecom_notify_primary_entry (ffesymbol s)
12161 ffecom_primary_entry_ = s;
12162 ffecom_primary_entry_kind_ = ffesymbol_kind (s);
12164 if ((ffecom_primary_entry_kind_ == FFEINFO_kindFUNCTION)
12165 || (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE))
12166 ffecom_primary_entry_is_proc_ = TRUE;
12168 ffecom_primary_entry_is_proc_ = FALSE;
12170 if (!ffe_is_silent ())
12172 if (ffecom_primary_entry_kind_ == FFEINFO_kindPROGRAM)
12173 fprintf (stderr, "%s:\n", ffesymbol_text (s));
12175 fprintf (stderr, " %s:\n", ffesymbol_text (s));
12178 if (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE)
12183 for (list = ffesymbol_dummyargs (s);
12185 list = ffebld_trail (list))
12187 arg = ffebld_head (list);
12188 if (ffebld_op (arg) == FFEBLD_opSTAR)
12190 ffecom_is_altreturning_ = TRUE;
12198 ffecom_open_include (char *name, ffewhereLine l, ffewhereColumn c)
12200 return ffecom_open_include_ (name, l, c);
12203 /* ffecom_ptr_to_expr -- Transform expr into gcc tree with & in front
12206 ffebld expr; // FFE expression.
12207 tree = ffecom_ptr_to_expr(expr);
12209 Like ffecom_expr, but sticks address-of in front of most things. */
12212 ffecom_ptr_to_expr (ffebld expr)
12215 ffeinfoBasictype bt;
12216 ffeinfoKindtype kt;
12219 assert (expr != NULL);
12221 switch (ffebld_op (expr))
12223 case FFEBLD_opSYMTER:
12224 s = ffebld_symter (expr);
12225 if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC)
12229 ix = ffeintrin_gfrt_indirect (ffebld_symter_implementation (expr));
12230 assert (ix != FFECOM_gfrt);
12231 if ((item = ffecom_gfrt_[ix]) == NULL_TREE)
12233 ffecom_make_gfrt_ (ix);
12234 item = ffecom_gfrt_[ix];
12239 item = ffesymbol_hook (s).decl_tree;
12240 if (item == NULL_TREE)
12242 s = ffecom_sym_transform_ (s);
12243 item = ffesymbol_hook (s).decl_tree;
12246 assert (item != NULL);
12247 if (item == error_mark_node)
12249 if (!ffesymbol_hook (s).addr)
12250 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12254 case FFEBLD_opARRAYREF:
12255 return ffecom_arrayref_ (NULL_TREE, expr, 1);
12257 case FFEBLD_opCONTER:
12259 bt = ffeinfo_basictype (ffebld_info (expr));
12260 kt = ffeinfo_kindtype (ffebld_info (expr));
12262 item = ffecom_constantunion (&ffebld_constant_union
12263 (ffebld_conter (expr)), bt, kt,
12264 ffecom_tree_type[bt][kt]);
12265 if (item == error_mark_node)
12266 return error_mark_node;
12267 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12272 return error_mark_node;
12275 bt = ffeinfo_basictype (ffebld_info (expr));
12276 kt = ffeinfo_kindtype (ffebld_info (expr));
12278 item = ffecom_expr (expr);
12279 if (item == error_mark_node)
12280 return error_mark_node;
12282 /* The back end currently optimizes a bit too zealously for us, in that
12283 we fail JCB001 if the following block of code is omitted. It checks
12284 to see if the transformed expression is a symbol or array reference,
12285 and encloses it in a SAVE_EXPR if that is the case. */
12288 if ((TREE_CODE (item) == VAR_DECL)
12289 || (TREE_CODE (item) == PARM_DECL)
12290 || (TREE_CODE (item) == RESULT_DECL)
12291 || (TREE_CODE (item) == INDIRECT_REF)
12292 || (TREE_CODE (item) == ARRAY_REF)
12293 || (TREE_CODE (item) == COMPONENT_REF)
12295 || (TREE_CODE (item) == OFFSET_REF)
12297 || (TREE_CODE (item) == BUFFER_REF)
12298 || (TREE_CODE (item) == REALPART_EXPR)
12299 || (TREE_CODE (item) == IMAGPART_EXPR))
12301 item = ffecom_save_tree (item);
12304 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12309 assert ("fall-through error" == NULL);
12310 return error_mark_node;
12313 /* Obtain a temp var with given data type.
12315 size is FFETARGET_charactersizeNONE for a non-CHARACTER type
12316 or >= 0 for a CHARACTER type.
12318 elements is -1 for a scalar or > 0 for an array of type. */
12321 ffecom_make_tempvar (const char *commentary, tree type,
12322 ffetargetCharacterSize size, int elements)
12325 static int mynumber;
12327 assert (current_binding_level->prep_state < 2);
12329 if (type == error_mark_node)
12330 return error_mark_node;
12332 if (size != FFETARGET_charactersizeNONE)
12333 type = build_array_type (type,
12334 build_range_type (ffecom_f2c_ftnlen_type_node,
12335 ffecom_f2c_ftnlen_one_node,
12336 build_int_2 (size, 0)));
12337 if (elements != -1)
12338 type = build_array_type (type,
12339 build_range_type (integer_type_node,
12341 build_int_2 (elements - 1,
12343 t = build_decl (VAR_DECL,
12344 ffecom_get_invented_identifier ("__g77_%s_%d",
12349 t = start_decl (t, FALSE);
12350 finish_decl (t, NULL_TREE, FALSE);
12355 /* Prepare argument pointer to expression.
12357 Like ffecom_prepare_expr, except for expressions to be evaluated
12358 via ffecom_arg_ptr_to_expr. */
12361 ffecom_prepare_arg_ptr_to_expr (ffebld expr)
12363 /* ~~For now, it seems to be the same thing. */
12364 ffecom_prepare_expr (expr);
12368 /* End of preparations. */
12371 ffecom_prepare_end (void)
12373 int prep_state = current_binding_level->prep_state;
12375 assert (prep_state < 2);
12376 current_binding_level->prep_state = 2;
12378 return (prep_state == 1) ? TRUE : FALSE;
12381 /* Prepare expression.
12383 This is called before any code is generated for the current block.
12384 It scans the expression, declares any temporaries that might be needed
12385 during evaluation of the expression, and stores those temporaries in
12386 the appropriate "hook" fields of the expression. `dest', if not NULL,
12387 specifies the destination that ffecom_expr_ will see, in case that
12388 helps avoid generating unused temporaries.
12390 ~~Improve to avoid allocating unused temporaries by taking `dest'
12391 into account vis-a-vis aliasing requirements of complex/character
12395 ffecom_prepare_expr_ (ffebld expr, ffebld dest UNUSED)
12397 ffeinfoBasictype bt;
12398 ffeinfoKindtype kt;
12399 ffetargetCharacterSize sz;
12400 tree tempvar = NULL_TREE;
12402 assert (current_binding_level->prep_state < 2);
12407 bt = ffeinfo_basictype (ffebld_info (expr));
12408 kt = ffeinfo_kindtype (ffebld_info (expr));
12409 sz = ffeinfo_size (ffebld_info (expr));
12411 /* Generate whatever temporaries are needed to represent the result
12412 of the expression. */
12414 if (bt == FFEINFO_basictypeCHARACTER)
12416 while (ffebld_op (expr) == FFEBLD_opPAREN)
12417 expr = ffebld_left (expr);
12420 switch (ffebld_op (expr))
12423 /* Don't make temps for SYMTER, CONTER, etc. */
12424 if (ffebld_arity (expr) == 0)
12429 case FFEINFO_basictypeCOMPLEX:
12430 if (ffebld_op (expr) == FFEBLD_opFUNCREF)
12434 if (ffebld_op (ffebld_left (expr)) != FFEBLD_opSYMTER)
12437 s = ffebld_symter (ffebld_left (expr));
12438 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT
12439 || (ffesymbol_where (s) != FFEINFO_whereINTRINSIC
12440 && ! ffesymbol_is_f2c (s))
12441 || (ffesymbol_where (s) == FFEINFO_whereINTRINSIC
12442 && ! ffe_is_f2c_library ()))
12445 else if (ffebld_op (expr) == FFEBLD_opPOWER)
12447 /* Requires special treatment. There's no POW_CC function
12448 in libg2c, so POW_ZZ is used, which means we always
12449 need a double-complex temp, not a single-complex. */
12450 kt = FFEINFO_kindtypeREAL2;
12452 else if (ffebld_op (expr) != FFEBLD_opDIVIDE)
12453 /* The other ops don't need temps for complex operands. */
12456 /* ~~~Avoid making temps for some intrinsics, such as AIMAG(C),
12457 REAL(C). See 19990325-0.f, routine `check', for cases. */
12458 tempvar = ffecom_make_tempvar ("complex",
12460 [FFEINFO_basictypeCOMPLEX][kt],
12461 FFETARGET_charactersizeNONE,
12465 case FFEINFO_basictypeCHARACTER:
12466 if (ffebld_op (expr) != FFEBLD_opFUNCREF)
12469 if (sz == FFETARGET_charactersizeNONE)
12470 /* ~~Kludge alert! This should someday be fixed. */
12473 tempvar = ffecom_make_tempvar ("char", char_type_node, sz, -1);
12481 case FFEBLD_opCONCATENATE:
12483 /* This gets special handling, because only one set of temps
12484 is needed for a tree of these -- the tree is treated as
12485 a flattened list of concatenations when generating code. */
12487 ffecomConcatList_ catlist;
12488 tree ltmp, itmp, result;
12492 catlist = ffecom_concat_list_new_ (expr, FFETARGET_charactersizeNONE);
12493 count = ffecom_concat_list_count_ (catlist);
12498 = ffecom_make_tempvar ("concat_len",
12499 ffecom_f2c_ftnlen_type_node,
12500 FFETARGET_charactersizeNONE, count);
12502 = ffecom_make_tempvar ("concat_item",
12503 ffecom_f2c_address_type_node,
12504 FFETARGET_charactersizeNONE, count);
12506 = ffecom_make_tempvar ("concat_res",
12508 ffecom_concat_list_maxlen_ (catlist),
12511 tempvar = make_tree_vec (3);
12512 TREE_VEC_ELT (tempvar, 0) = ltmp;
12513 TREE_VEC_ELT (tempvar, 1) = itmp;
12514 TREE_VEC_ELT (tempvar, 2) = result;
12517 for (i = 0; i < count; ++i)
12518 ffecom_prepare_arg_ptr_to_expr (ffecom_concat_list_expr_ (catlist,
12521 ffecom_concat_list_kill_ (catlist);
12525 ffebld_nonter_set_hook (expr, tempvar);
12526 current_binding_level->prep_state = 1;
12531 case FFEBLD_opCONVERT:
12532 if (bt == FFEINFO_basictypeCHARACTER
12533 && ((ffebld_size_known (ffebld_left (expr))
12534 == FFETARGET_charactersizeNONE)
12535 || (ffebld_size_known (ffebld_left (expr)) >= sz)))
12536 tempvar = ffecom_make_tempvar ("convert", char_type_node, sz, -1);
12542 ffebld_nonter_set_hook (expr, tempvar);
12543 current_binding_level->prep_state = 1;
12546 /* Prepare subexpressions for this expr. */
12548 switch (ffebld_op (expr))
12550 case FFEBLD_opPERCENT_LOC:
12551 ffecom_prepare_ptr_to_expr (ffebld_left (expr));
12554 case FFEBLD_opPERCENT_VAL:
12555 case FFEBLD_opPERCENT_REF:
12556 ffecom_prepare_expr (ffebld_left (expr));
12559 case FFEBLD_opPERCENT_DESCR:
12560 ffecom_prepare_arg_ptr_to_expr (ffebld_left (expr));
12563 case FFEBLD_opITEM:
12569 item = ffebld_trail (item))
12570 if (ffebld_head (item) != NULL)
12571 ffecom_prepare_expr (ffebld_head (item));
12576 /* Need to handle character conversion specially. */
12577 switch (ffebld_arity (expr))
12580 ffecom_prepare_expr (ffebld_left (expr));
12581 ffecom_prepare_expr (ffebld_right (expr));
12585 ffecom_prepare_expr (ffebld_left (expr));
12596 /* Prepare expression for reading and writing.
12598 Like ffecom_prepare_expr, except for expressions to be evaluated
12599 via ffecom_expr_rw. */
12602 ffecom_prepare_expr_rw (tree type, ffebld expr)
12604 /* This is all we support for now. */
12605 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
12607 /* ~~For now, it seems to be the same thing. */
12608 ffecom_prepare_expr (expr);
12612 /* Prepare expression for writing.
12614 Like ffecom_prepare_expr, except for expressions to be evaluated
12615 via ffecom_expr_w. */
12618 ffecom_prepare_expr_w (tree type, ffebld expr)
12620 /* This is all we support for now. */
12621 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
12623 /* ~~For now, it seems to be the same thing. */
12624 ffecom_prepare_expr (expr);
12628 /* Prepare expression for returning.
12630 Like ffecom_prepare_expr, except for expressions to be evaluated
12631 via ffecom_return_expr. */
12634 ffecom_prepare_return_expr (ffebld expr)
12636 assert (current_binding_level->prep_state < 2);
12638 if (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE
12639 && ffecom_is_altreturning_
12641 ffecom_prepare_expr (expr);
12644 /* Prepare pointer to expression.
12646 Like ffecom_prepare_expr, except for expressions to be evaluated
12647 via ffecom_ptr_to_expr. */
12650 ffecom_prepare_ptr_to_expr (ffebld expr)
12652 /* ~~For now, it seems to be the same thing. */
12653 ffecom_prepare_expr (expr);
12657 /* Transform expression into constant pointer-to-expression tree.
12659 If the expression can be transformed into a pointer-to-expression tree
12660 that is constant, that is done, and the tree returned. Else NULL_TREE
12663 That way, a caller can attempt to provide compile-time initialization
12664 of a variable and, if that fails, *then* choose to start a new block
12665 and resort to using temporaries, as appropriate. */
12668 ffecom_ptr_to_const_expr (ffebld expr)
12671 return integer_zero_node;
12673 if (ffebld_op (expr) == FFEBLD_opANY)
12674 return error_mark_node;
12676 if (ffebld_arity (expr) == 0
12677 && (ffebld_op (expr) != FFEBLD_opSYMTER
12678 || ffebld_where (expr) == FFEINFO_whereCOMMON
12679 || ffebld_where (expr) == FFEINFO_whereGLOBAL
12680 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
12684 t = ffecom_ptr_to_expr (expr);
12685 assert (TREE_CONSTANT (t));
12692 /* ffecom_return_expr -- Returns return-value expr given alt return expr
12694 tree rtn; // NULL_TREE means use expand_null_return()
12695 ffebld expr; // NULL if no alt return expr to RETURN stmt
12696 rtn = ffecom_return_expr(expr);
12698 Based on the program unit type and other info (like return function
12699 type, return master function type when alternate ENTRY points,
12700 whether subroutine has any alternate RETURN points, etc), returns the
12701 appropriate expression to be returned to the caller, or NULL_TREE
12702 meaning no return value or the caller expects it to be returned somewhere
12703 else (which is handled by other parts of this module). */
12706 ffecom_return_expr (ffebld expr)
12710 switch (ffecom_primary_entry_kind_)
12712 case FFEINFO_kindPROGRAM:
12713 case FFEINFO_kindBLOCKDATA:
12717 case FFEINFO_kindSUBROUTINE:
12718 if (!ffecom_is_altreturning_)
12719 rtn = NULL_TREE; /* No alt returns, never an expr. */
12720 else if (expr == NULL)
12721 rtn = integer_zero_node;
12723 rtn = ffecom_expr (expr);
12726 case FFEINFO_kindFUNCTION:
12727 if ((ffecom_multi_retval_ != NULL_TREE)
12728 || (ffesymbol_basictype (ffecom_primary_entry_)
12729 == FFEINFO_basictypeCHARACTER)
12730 || ((ffesymbol_basictype (ffecom_primary_entry_)
12731 == FFEINFO_basictypeCOMPLEX)
12732 && (ffecom_num_entrypoints_ == 0)
12733 && ffesymbol_is_f2c (ffecom_primary_entry_)))
12734 { /* Value is returned by direct assignment
12735 into (implicit) dummy. */
12739 rtn = ffecom_func_result_;
12741 /* Spurious error if RETURN happens before first reference! So elide
12742 this code. In particular, for debugging registry, rtn should always
12743 be non-null after all, but TREE_USED won't be set until we encounter
12744 a reference in the code. Perfectly okay (but weird) code that,
12745 e.g., has "GOTO 20;10 RETURN;20 RTN=0;GOTO 10", would result in
12746 this diagnostic for no reason. Have people use -O -Wuninitialized
12747 and leave it to the back end to find obviously weird cases. */
12749 /* Used to "assert(rtn != NULL_TREE);" here, but it's kind of a valid
12750 situation; if the return value has never been referenced, it won't
12751 have a tree under 2pass mode. */
12752 if ((rtn == NULL_TREE)
12753 || !TREE_USED (rtn))
12755 ffebad_start (FFEBAD_RETURN_VALUE_UNSET);
12756 ffebad_here (0, ffesymbol_where_line (ffecom_primary_entry_),
12757 ffesymbol_where_column (ffecom_primary_entry_));
12758 ffebad_string (ffesymbol_text (ffesymbol_funcresult
12759 (ffecom_primary_entry_)));
12766 assert ("bad unit kind" == NULL);
12767 case FFEINFO_kindANY:
12768 rtn = error_mark_node;
12775 /* Do save_expr only if tree is not error_mark_node. */
12778 ffecom_save_tree (tree t)
12780 return save_expr (t);
12783 /* Start a compound statement (block). */
12786 ffecom_start_compstmt (void)
12788 bison_rule_pushlevel_ ();
12791 /* Public entry point for front end to access start_decl. */
12794 ffecom_start_decl (tree decl, bool is_initialized)
12796 DECL_INITIAL (decl) = is_initialized ? error_mark_node : NULL_TREE;
12797 return start_decl (decl, FALSE);
12800 /* ffecom_sym_commit -- Symbol's state being committed to reality
12803 ffecom_sym_commit(s);
12805 Does whatever the backend needs when a symbol is committed after having
12806 been backtrackable for a period of time. */
12809 ffecom_sym_commit (ffesymbol s UNUSED)
12811 assert (!ffesymbol_retractable ());
12814 /* ffecom_sym_end_transition -- Perform end transition on all symbols
12816 ffecom_sym_end_transition();
12818 Does backend-specific stuff and also calls ffest_sym_end_transition
12819 to do the necessary FFE stuff.
12821 Backtracking is never enabled when this fn is called, so don't worry
12825 ffecom_sym_end_transition (ffesymbol s)
12829 assert (!ffesymbol_retractable ());
12831 s = ffest_sym_end_transition (s);
12833 if ((ffesymbol_kind (s) == FFEINFO_kindBLOCKDATA)
12834 && (ffesymbol_where (s) == FFEINFO_whereGLOBAL))
12836 ffecom_list_blockdata_
12837 = ffebld_new_item (ffebld_new_symter (s, FFEINTRIN_genNONE,
12838 FFEINTRIN_specNONE,
12839 FFEINTRIN_impNONE),
12840 ffecom_list_blockdata_);
12843 /* This is where we finally notice that a symbol has partial initialization
12844 and finalize it. */
12846 if (ffesymbol_accretion (s) != NULL)
12848 assert (ffesymbol_init (s) == NULL);
12849 ffecom_notify_init_symbol (s);
12851 else if (((st = ffesymbol_storage (s)) != NULL)
12852 && ((st = ffestorag_parent (st)) != NULL)
12853 && (ffestorag_accretion (st) != NULL))
12855 assert (ffestorag_init (st) == NULL);
12856 ffecom_notify_init_storage (st);
12859 if ((ffesymbol_kind (s) == FFEINFO_kindCOMMON)
12860 && (ffesymbol_where (s) == FFEINFO_whereLOCAL)
12861 && (ffesymbol_storage (s) != NULL))
12863 ffecom_list_common_
12864 = ffebld_new_item (ffebld_new_symter (s, FFEINTRIN_genNONE,
12865 FFEINTRIN_specNONE,
12866 FFEINTRIN_impNONE),
12867 ffecom_list_common_);
12873 /* ffecom_sym_exec_transition -- Perform exec transition on all symbols
12875 ffecom_sym_exec_transition();
12877 Does backend-specific stuff and also calls ffest_sym_exec_transition
12878 to do the necessary FFE stuff.
12880 See the long-winded description in ffecom_sym_learned for info
12881 on handling the situation where backtracking is inhibited. */
12884 ffecom_sym_exec_transition (ffesymbol s)
12886 s = ffest_sym_exec_transition (s);
12891 /* ffecom_sym_learned -- Initial or more info gained on symbol after exec
12894 s = ffecom_sym_learned(s);
12896 Called when a new symbol is seen after the exec transition or when more
12897 info (perhaps) is gained for an UNCERTAIN symbol. The symbol state when
12898 it arrives here is that all its latest info is updated already, so its
12899 state may be UNCERTAIN or UNDERSTOOD, it might already have the hook
12900 field filled in if its gone through here or exec_transition first, and
12903 The backend probably wants to check ffesymbol_retractable() to see if
12904 backtracking is in effect. If so, the FFE's changes to the symbol may
12905 be retracted (undone) or committed (ratified), at which time the
12906 appropriate ffecom_sym_retract or _commit function will be called
12909 If the backend has its own backtracking mechanism, great, use it so that
12910 committal is a simple operation. Though it doesn't make much difference,
12911 I suppose: the reason for tentative symbol evolution in the FFE is to
12912 enable error detection in weird incorrect statements early and to disable
12913 incorrect error detection on a correct statement. The backend is not
12914 likely to introduce any information that'll get involved in these
12915 considerations, so it is probably just fine that the implementation
12916 model for this fn and for _exec_transition is to not do anything
12917 (besides the required FFE stuff) if ffesymbol_retractable() returns TRUE
12918 and instead wait until ffecom_sym_commit is called (which it never
12919 will be as long as we're using ambiguity-detecting statement analysis in
12920 the FFE, which we are initially to shake out the code, but don't depend
12921 on this), otherwise go ahead and do whatever is needed.
12923 In essence, then, when this fn and _exec_transition get called while
12924 backtracking is enabled, a general mechanism would be to flag which (or
12925 both) of these were called (and in what order? neat question as to what
12926 might happen that I'm too lame to think through right now) and then when
12927 _commit is called reproduce the original calling sequence, if any, for
12928 the two fns (at which point backtracking will, of course, be disabled). */
12931 ffecom_sym_learned (ffesymbol s)
12933 ffestorag_exec_layout (s);
12938 /* ffecom_sym_retract -- Symbol's state being retracted from reality
12941 ffecom_sym_retract(s);
12943 Does whatever the backend needs when a symbol is retracted after having
12944 been backtrackable for a period of time. */
12947 ffecom_sym_retract (ffesymbol s UNUSED)
12949 assert (!ffesymbol_retractable ());
12951 #if 0 /* GCC doesn't commit any backtrackable sins,
12952 so nothing needed here. */
12953 switch (ffesymbol_hook (s).state)
12955 case 0: /* nothing happened yet. */
12958 case 1: /* exec transition happened. */
12961 case 2: /* learned happened. */
12964 case 3: /* learned then exec. */
12967 case 4: /* exec then learned. */
12971 assert ("bad hook state" == NULL);
12977 /* Create temporary gcc label. */
12980 ffecom_temp_label (void)
12983 static int mynumber = 0;
12985 glabel = build_decl (LABEL_DECL,
12986 ffecom_get_invented_identifier ("__g77_label_%d",
12989 DECL_CONTEXT (glabel) = current_function_decl;
12990 DECL_MODE (glabel) = VOIDmode;
12995 /* Return an expression that is usable as an arg in a conditional context
12996 (IF, DO WHILE, .NOT., and so on).
12998 Use the one provided for the back end as of >2.6.0. */
13001 ffecom_truth_value (tree expr)
13003 return ffe_truthvalue_conversion (expr);
13006 /* Return the inversion of a truth value (the inversion of what
13007 ffecom_truth_value builds).
13009 Apparently invert_truthvalue, which is properly in the back end, is
13010 enough for now, so just use it. */
13013 ffecom_truth_value_invert (tree expr)
13015 return invert_truthvalue (ffecom_truth_value (expr));
13018 /* Return the tree that is the type of the expression, as would be
13019 returned in TREE_TYPE(ffecom_expr(expr)), without otherwise
13020 transforming the expression, generating temporaries, etc. */
13023 ffecom_type_expr (ffebld expr)
13025 ffeinfoBasictype bt;
13026 ffeinfoKindtype kt;
13029 assert (expr != NULL);
13031 bt = ffeinfo_basictype (ffebld_info (expr));
13032 kt = ffeinfo_kindtype (ffebld_info (expr));
13033 tree_type = ffecom_tree_type[bt][kt];
13035 switch (ffebld_op (expr))
13037 case FFEBLD_opCONTER:
13038 case FFEBLD_opSYMTER:
13039 case FFEBLD_opARRAYREF:
13040 case FFEBLD_opUPLUS:
13041 case FFEBLD_opPAREN:
13042 case FFEBLD_opUMINUS:
13044 case FFEBLD_opSUBTRACT:
13045 case FFEBLD_opMULTIPLY:
13046 case FFEBLD_opDIVIDE:
13047 case FFEBLD_opPOWER:
13049 case FFEBLD_opFUNCREF:
13050 case FFEBLD_opSUBRREF:
13054 case FFEBLD_opNEQV:
13056 case FFEBLD_opCONVERT:
13063 case FFEBLD_opPERCENT_LOC:
13066 case FFEBLD_opACCTER:
13067 case FFEBLD_opARRTER:
13068 case FFEBLD_opITEM:
13069 case FFEBLD_opSTAR:
13070 case FFEBLD_opBOUNDS:
13071 case FFEBLD_opREPEAT:
13072 case FFEBLD_opLABTER:
13073 case FFEBLD_opLABTOK:
13074 case FFEBLD_opIMPDO:
13075 case FFEBLD_opCONCATENATE:
13076 case FFEBLD_opSUBSTR:
13078 assert ("bad op for ffecom_type_expr" == NULL);
13079 /* Fall through. */
13081 return error_mark_node;
13085 /* Return PARM_DECL for arg#1 of master fn containing alternate ENTRY points
13087 If the PARM_DECL already exists, return it, else create it. It's an
13088 integer_type_node argument for the master function that implements a
13089 subroutine or function with more than one entrypoint and is bound at
13090 run time with the entrypoint number (0 for SUBROUTINE/FUNCTION, 1 for
13091 first ENTRY statement, and so on). */
13094 ffecom_which_entrypoint_decl (void)
13096 assert (ffecom_which_entrypoint_decl_ != NULL_TREE);
13098 return ffecom_which_entrypoint_decl_;
13101 /* The following sections consists of private and public functions
13102 that have the same names and perform roughly the same functions
13103 as counterparts in the C front end. Changes in the C front end
13104 might affect how things should be done here. Only functions
13105 needed by the back end should be public here; the rest should
13106 be private (static in the C sense). Functions needed by other
13107 g77 front-end modules should be accessed by them via public
13108 ffecom_* names, which should themselves call private versions
13109 in this section so the private versions are easy to recognize
13110 when upgrading to a new gcc and finding interesting changes
13113 Functions named after rule "foo:" in c-parse.y are named
13114 "bison_rule_foo_" so they are easy to find. */
13117 bison_rule_pushlevel_ (void)
13119 emit_line_note (input_location);
13121 clear_last_expr ();
13122 expand_start_bindings (0);
13126 bison_rule_compstmt_ (void)
13129 int keep = kept_level_p ();
13131 /* Make the temps go away. */
13133 current_binding_level->names = NULL_TREE;
13135 emit_line_note (input_location);
13136 expand_end_bindings (getdecls (), keep, 0);
13137 t = poplevel (keep, 1, 0);
13142 /* Return a definition for a builtin function named NAME and whose data type
13143 is TYPE. TYPE should be a function type with argument types.
13144 FUNCTION_CODE tells later passes how to compile calls to this function.
13145 See tree.h for its possible values.
13147 If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME,
13148 the name to be called if we can't opencode the function. If
13149 ATTRS is nonzero, use that for the function's attribute list. */
13152 builtin_function (const char *name, tree type, int function_code,
13153 enum built_in_class class, const char *library_name,
13154 tree attrs ATTRIBUTE_UNUSED)
13156 tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
13157 DECL_EXTERNAL (decl) = 1;
13158 TREE_PUBLIC (decl) = 1;
13160 SET_DECL_ASSEMBLER_NAME (decl, get_identifier (library_name));
13161 make_decl_rtl (decl, NULL);
13163 DECL_BUILT_IN_CLASS (decl) = class;
13164 DECL_FUNCTION_CODE (decl) = function_code;
13169 /* Handle when a new declaration NEWDECL
13170 has the same name as an old one OLDDECL
13171 in the same binding contour.
13172 Prints an error message if appropriate.
13174 If safely possible, alter OLDDECL to look like NEWDECL, and return 1.
13175 Otherwise, return 0. */
13178 duplicate_decls (tree newdecl, tree olddecl)
13180 int types_match = 1;
13181 int new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL
13182 && DECL_INITIAL (newdecl) != 0);
13183 tree oldtype = TREE_TYPE (olddecl);
13184 tree newtype = TREE_TYPE (newdecl);
13186 if (olddecl == newdecl)
13189 if (TREE_CODE (newtype) == ERROR_MARK
13190 || TREE_CODE (oldtype) == ERROR_MARK)
13193 /* New decl is completely inconsistent with the old one =>
13194 tell caller to replace the old one.
13195 This is always an error except in the case of shadowing a builtin. */
13196 if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
13199 /* For real parm decl following a forward decl,
13200 return 1 so old decl will be reused. */
13201 if (types_match && TREE_CODE (newdecl) == PARM_DECL
13202 && TREE_ASM_WRITTEN (olddecl) && ! TREE_ASM_WRITTEN (newdecl))
13205 /* The new declaration is the same kind of object as the old one.
13206 The declarations may partially match. Print warnings if they don't
13207 match enough. Ultimately, copy most of the information from the new
13208 decl to the old one, and keep using the old one. */
13210 if (TREE_CODE (olddecl) == FUNCTION_DECL
13211 && DECL_BUILT_IN (olddecl))
13213 /* A function declaration for a built-in function. */
13214 if (!TREE_PUBLIC (newdecl))
13216 else if (!types_match)
13218 /* Accept the return type of the new declaration if same modes. */
13219 tree oldreturntype = TREE_TYPE (TREE_TYPE (olddecl));
13220 tree newreturntype = TREE_TYPE (TREE_TYPE (newdecl));
13222 if (TYPE_MODE (oldreturntype) == TYPE_MODE (newreturntype))
13224 /* Function types may be shared, so we can't just modify
13225 the return type of olddecl's function type. */
13227 = build_function_type (newreturntype,
13228 TYPE_ARG_TYPES (TREE_TYPE (olddecl)));
13232 TREE_TYPE (olddecl) = newtype;
13238 else if (TREE_CODE (olddecl) == FUNCTION_DECL
13239 && DECL_SOURCE_LINE (olddecl) == 0)
13241 /* A function declaration for a predeclared function
13242 that isn't actually built in. */
13243 if (!TREE_PUBLIC (newdecl))
13245 else if (!types_match)
13247 /* If the types don't match, preserve volatility indication.
13248 Later on, we will discard everything else about the
13249 default declaration. */
13250 TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
13254 /* Copy all the DECL_... slots specified in the new decl
13255 except for any that we copy here from the old type.
13257 Past this point, we don't change OLDTYPE and NEWTYPE
13258 even if we change the types of NEWDECL and OLDDECL. */
13262 /* Merge the data types specified in the two decls. */
13263 if (TREE_CODE (newdecl) != FUNCTION_DECL || !DECL_BUILT_IN (olddecl))
13264 TREE_TYPE (newdecl)
13265 = TREE_TYPE (olddecl)
13266 = TREE_TYPE (newdecl);
13268 /* Lay the type out, unless already done. */
13269 if (oldtype != TREE_TYPE (newdecl))
13271 if (TREE_TYPE (newdecl) != error_mark_node)
13272 layout_type (TREE_TYPE (newdecl));
13273 if (TREE_CODE (newdecl) != FUNCTION_DECL
13274 && TREE_CODE (newdecl) != TYPE_DECL
13275 && TREE_CODE (newdecl) != CONST_DECL)
13276 layout_decl (newdecl, 0);
13280 /* Since the type is OLDDECL's, make OLDDECL's size go with. */
13281 DECL_SIZE (newdecl) = DECL_SIZE (olddecl);
13282 DECL_SIZE_UNIT (newdecl) = DECL_SIZE_UNIT (olddecl);
13283 if (TREE_CODE (olddecl) != FUNCTION_DECL)
13284 if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl))
13286 DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl);
13287 DECL_USER_ALIGN (newdecl) |= DECL_USER_ALIGN (olddecl);
13291 /* Keep the old rtl since we can safely use it. */
13292 COPY_DECL_RTL (olddecl, newdecl);
13294 /* Merge the type qualifiers. */
13295 if (TREE_READONLY (newdecl))
13296 TREE_READONLY (olddecl) = 1;
13297 if (TREE_THIS_VOLATILE (newdecl))
13299 TREE_THIS_VOLATILE (olddecl) = 1;
13300 if (TREE_CODE (newdecl) == VAR_DECL)
13301 make_var_volatile (newdecl);
13304 /* Keep source location of definition rather than declaration.
13305 Likewise, keep decl at outer scope. */
13306 if ((DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0)
13307 || (DECL_CONTEXT (newdecl) != 0 && DECL_CONTEXT (olddecl) == 0))
13309 DECL_SOURCE_LINE (newdecl) = DECL_SOURCE_LINE (olddecl);
13310 DECL_SOURCE_FILE (newdecl) = DECL_SOURCE_FILE (olddecl);
13312 if (DECL_CONTEXT (olddecl) == 0
13313 && TREE_CODE (newdecl) != FUNCTION_DECL)
13314 DECL_CONTEXT (newdecl) = 0;
13317 /* Merge the unused-warning information. */
13318 if (DECL_IN_SYSTEM_HEADER (olddecl))
13319 DECL_IN_SYSTEM_HEADER (newdecl) = 1;
13320 else if (DECL_IN_SYSTEM_HEADER (newdecl))
13321 DECL_IN_SYSTEM_HEADER (olddecl) = 1;
13323 /* Merge the initialization information. */
13324 if (DECL_INITIAL (newdecl) == 0)
13325 DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
13327 /* Merge the section attribute.
13328 We want to issue an error if the sections conflict but that must be
13329 done later in decl_attributes since we are called before attributes
13331 if (DECL_SECTION_NAME (newdecl) == NULL_TREE)
13332 DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl);
13334 /* Copy the assembler name. */
13335 COPY_DECL_ASSEMBLER_NAME (olddecl, newdecl);
13337 if (TREE_CODE (newdecl) == FUNCTION_DECL)
13339 DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl);
13340 DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
13341 TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
13342 TREE_READONLY (newdecl) |= TREE_READONLY (olddecl);
13343 DECL_IS_MALLOC (newdecl) |= DECL_IS_MALLOC (olddecl);
13344 DECL_IS_PURE (newdecl) |= DECL_IS_PURE (olddecl);
13347 /* If cannot merge, then use the new type and qualifiers,
13348 and don't preserve the old rtl. */
13351 TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
13352 TREE_READONLY (olddecl) = TREE_READONLY (newdecl);
13353 TREE_THIS_VOLATILE (olddecl) = TREE_THIS_VOLATILE (newdecl);
13354 TREE_SIDE_EFFECTS (olddecl) = TREE_SIDE_EFFECTS (newdecl);
13357 /* Merge the storage class information. */
13358 /* For functions, static overrides non-static. */
13359 if (TREE_CODE (newdecl) == FUNCTION_DECL)
13361 TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl);
13362 /* This is since we don't automatically
13363 copy the attributes of NEWDECL into OLDDECL. */
13364 TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
13365 /* If this clears `static', clear it in the identifier too. */
13366 if (! TREE_PUBLIC (olddecl))
13367 TREE_PUBLIC (DECL_NAME (olddecl)) = 0;
13369 if (DECL_EXTERNAL (newdecl))
13371 TREE_STATIC (newdecl) = TREE_STATIC (olddecl);
13372 DECL_EXTERNAL (newdecl) = DECL_EXTERNAL (olddecl);
13373 /* An extern decl does not override previous storage class. */
13374 TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
13378 TREE_STATIC (olddecl) = TREE_STATIC (newdecl);
13379 TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
13382 /* If either decl says `inline', this fn is inline,
13383 unless its definition was passed already. */
13384 if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == 0)
13385 DECL_INLINE (olddecl) = 1;
13386 DECL_INLINE (newdecl) = DECL_INLINE (olddecl);
13388 /* Get rid of any built-in function if new arg types don't match it
13389 or if we have a function definition. */
13390 if (TREE_CODE (newdecl) == FUNCTION_DECL
13391 && DECL_BUILT_IN (olddecl)
13392 && (!types_match || new_is_definition))
13394 TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
13395 DECL_BUILT_IN_CLASS (olddecl) = NOT_BUILT_IN;
13398 /* If redeclaring a builtin function, and not a definition,
13400 Also preserve various other info from the definition. */
13401 if (TREE_CODE (newdecl) == FUNCTION_DECL && !new_is_definition)
13403 if (DECL_BUILT_IN (olddecl))
13405 DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl);
13406 DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
13409 DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
13410 DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
13411 DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl);
13412 DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
13415 /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
13416 But preserve olddecl's DECL_UID. */
13418 register unsigned olddecl_uid = DECL_UID (olddecl);
13420 memcpy ((char *) olddecl + sizeof (struct tree_common),
13421 (char *) newdecl + sizeof (struct tree_common),
13422 sizeof (struct tree_decl) - sizeof (struct tree_common));
13423 DECL_UID (olddecl) = olddecl_uid;
13429 /* Finish processing of a declaration;
13430 install its initial value.
13431 If the length of an array type is not known before,
13432 it must be determined now, from the initial value, or it is an error. */
13435 finish_decl (tree decl, tree init, bool is_top_level)
13437 register tree type = TREE_TYPE (decl);
13438 int was_incomplete = (DECL_SIZE (decl) == 0);
13439 bool at_top_level = (current_binding_level == global_binding_level);
13440 bool top_level = is_top_level || at_top_level;
13442 /* Caller should pass TRUE for is_top_level only if we wouldn't be at top
13444 assert (!is_top_level || !at_top_level);
13446 if (TREE_CODE (decl) == PARM_DECL)
13447 assert (init == NULL_TREE);
13448 /* Remember that PARM_DECL doesn't have a DECL_INITIAL field per se -- it
13449 overlaps DECL_ARG_TYPE. */
13450 else if (init == NULL_TREE)
13451 assert (DECL_INITIAL (decl) == NULL_TREE);
13453 assert (DECL_INITIAL (decl) == error_mark_node);
13455 if (init != NULL_TREE)
13457 if (TREE_CODE (decl) != TYPE_DECL)
13458 DECL_INITIAL (decl) = init;
13461 /* typedef foo = bar; store the type of bar as the type of foo. */
13462 TREE_TYPE (decl) = TREE_TYPE (init);
13463 DECL_INITIAL (decl) = init = 0;
13467 /* Deduce size of array from initialization, if not already known */
13469 if (TREE_CODE (type) == ARRAY_TYPE
13470 && TYPE_DOMAIN (type) == 0
13471 && TREE_CODE (decl) != TYPE_DECL)
13473 assert (top_level);
13474 assert (was_incomplete);
13476 layout_decl (decl, 0);
13479 if (TREE_CODE (decl) == VAR_DECL)
13481 if (DECL_SIZE (decl) == NULL_TREE
13482 && TYPE_SIZE (TREE_TYPE (decl)) != NULL_TREE)
13483 layout_decl (decl, 0);
13485 if (DECL_SIZE (decl) == NULL_TREE
13486 && (TREE_STATIC (decl)
13488 /* A static variable with an incomplete type is an error if it is
13489 initialized. Also if it is not file scope. Otherwise, let it
13490 through, but if it is not `extern' then it may cause an error
13492 (DECL_INITIAL (decl) != 0 || DECL_CONTEXT (decl) != 0)
13494 /* An automatic variable with an incomplete type is an error. */
13495 !DECL_EXTERNAL (decl)))
13497 assert ("storage size not known" == NULL);
13501 if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl))
13502 && (DECL_SIZE (decl) != 0)
13503 && (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST))
13505 assert ("storage size not constant" == NULL);
13510 /* Output the assembler code and/or RTL code for variables and functions,
13511 unless the type is an undefined structure or union. If not, it will get
13512 done when the type is completed. */
13514 if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)
13516 rest_of_decl_compilation (decl, NULL,
13517 DECL_CONTEXT (decl) == 0,
13520 if (DECL_CONTEXT (decl) != 0)
13522 /* Recompute the RTL of a local array now if it used to be an
13523 incomplete type. */
13525 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
13527 /* If we used it already as memory, it must stay in memory. */
13528 TREE_ADDRESSABLE (decl) = TREE_USED (decl);
13529 /* If it's still incomplete now, no init will save it. */
13530 if (DECL_SIZE (decl) == 0)
13531 DECL_INITIAL (decl) = 0;
13532 expand_decl (decl);
13534 /* Compute and store the initial value. */
13535 if (TREE_CODE (decl) != FUNCTION_DECL)
13536 expand_decl_init (decl);
13539 else if (TREE_CODE (decl) == TYPE_DECL)
13541 rest_of_decl_compilation (decl, NULL,
13542 DECL_CONTEXT (decl) == 0,
13546 /* At the end of a declaration, throw away any variable type sizes of types
13547 defined inside that declaration. There is no use computing them in the
13548 following function definition. */
13549 if (current_binding_level == global_binding_level)
13550 get_pending_sizes ();
13553 /* Finish up a function declaration and compile that function
13554 all the way to assembler language output. The free the storage
13555 for the function definition.
13557 This is called after parsing the body of the function definition.
13559 NESTED is nonzero if the function being finished is nested in another. */
13562 finish_function (int nested)
13564 register tree fndecl = current_function_decl;
13566 assert (fndecl != NULL_TREE);
13567 if (TREE_CODE (fndecl) != ERROR_MARK)
13570 assert (DECL_CONTEXT (fndecl) != NULL_TREE);
13572 assert (DECL_CONTEXT (fndecl) == NULL_TREE);
13575 /* TREE_READONLY (fndecl) = 1;
13576 This caused &foo to be of type ptr-to-const-function
13577 which then got a warning when stored in a ptr-to-function variable. */
13579 poplevel (1, 0, 1);
13581 if (TREE_CODE (fndecl) != ERROR_MARK)
13583 BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
13585 /* Must mark the RESULT_DECL as being in this function. */
13587 DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;
13589 /* Obey `register' declarations if `setjmp' is called in this fn. */
13590 /* Generate rtl for function exit. */
13591 expand_function_end ();
13593 /* If this is a nested function, protect the local variables in the stack
13594 above us from being collected while we're compiling this function. */
13596 ggc_push_context ();
13598 /* Run the optimizers and output the assembler code for this function. */
13599 rest_of_compilation (fndecl);
13601 /* Undo the GC context switch. */
13603 ggc_pop_context ();
13606 if (TREE_CODE (fndecl) != ERROR_MARK
13608 && DECL_SAVED_INSNS (fndecl) == 0)
13610 /* Stop pointing to the local nodes about to be freed. */
13611 /* But DECL_INITIAL must remain nonzero so we know this was an actual
13612 function definition. */
13613 /* For a nested function, this is done in pop_f_function_context. */
13614 /* If rest_of_compilation set this to 0, leave it 0. */
13615 if (DECL_INITIAL (fndecl) != 0)
13616 DECL_INITIAL (fndecl) = error_mark_node;
13617 DECL_ARGUMENTS (fndecl) = 0;
13622 /* Let the error reporting routines know that we're outside a function.
13623 For a nested function, this value is used in pop_c_function_context
13624 and then reset via pop_function_context. */
13625 ffecom_outer_function_decl_ = current_function_decl = NULL;
13629 /* Plug-in replacement for identifying the name of a decl and, for a
13630 function, what we call it in diagnostics. For now, "program unit"
13631 should suffice, since it's a bit of a hassle to figure out which
13632 of several kinds of things it is. Note that it could conceivably
13633 be a statement function, which probably isn't really a program unit
13634 per se, but if that comes up, it should be easy to check (being a
13635 nested function and all). */
13637 static const char *
13638 ffe_printable_name (tree decl, int v)
13640 /* Just to keep GCC quiet about the unused variable.
13641 In theory, differing values of V should produce different
13646 if (TREE_CODE (decl) == ERROR_MARK)
13647 return "erroneous code";
13648 return IDENTIFIER_POINTER (DECL_NAME (decl));
13652 /* g77's function to print out name of current function that caused
13656 ffe_print_error_function (diagnostic_context *context __attribute__((unused)),
13659 static ffeglobal last_g = NULL;
13660 static ffesymbol last_s = NULL;
13665 if ((ffecom_primary_entry_ == NULL)
13666 || (ffesymbol_global (ffecom_primary_entry_) == NULL))
13674 g = ffesymbol_global (ffecom_primary_entry_);
13675 if (ffecom_nested_entry_ == NULL)
13677 s = ffecom_primary_entry_;
13678 kind = _(ffeinfo_kind_message (ffesymbol_kind (s)));
13682 s = ffecom_nested_entry_;
13683 kind = _("In statement function");
13687 if ((last_g != g) || (last_s != s))
13690 fprintf (stderr, "%s: ", file);
13693 fprintf (stderr, _("Outside of any program unit:\n"));
13696 const char *name = ffesymbol_text (s);
13698 fprintf (stderr, "%s `%s':\n", kind, name);
13706 /* Similar to `lookup_name' but look only at current binding level. */
13709 lookup_name_current_level (tree name)
13713 if (current_binding_level == global_binding_level)
13714 return IDENTIFIER_GLOBAL_VALUE (name);
13716 if (IDENTIFIER_LOCAL_VALUE (name) == 0)
13719 for (t = current_binding_level->names; t; t = TREE_CHAIN (t))
13720 if (DECL_NAME (t) == name)
13726 /* Create a new `struct f_binding_level'. */
13728 static struct f_binding_level *
13729 make_binding_level (void)
13732 return ggc_alloc (sizeof (struct f_binding_level));
13735 /* Save and restore the variables in this file and elsewhere
13736 that keep track of the progress of compilation of the current function.
13737 Used for nested functions. */
13741 struct f_function *next;
13743 tree shadowed_labels;
13744 struct f_binding_level *binding_level;
13747 struct f_function *f_function_chain;
13749 /* Restore the variables used during compilation of a C function. */
13752 pop_f_function_context (void)
13754 struct f_function *p = f_function_chain;
13757 /* Bring back all the labels that were shadowed. */
13758 for (link = shadowed_labels; link; link = TREE_CHAIN (link))
13759 if (DECL_NAME (TREE_VALUE (link)) != 0)
13760 IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link)))
13761 = TREE_VALUE (link);
13763 if (current_function_decl != error_mark_node
13764 && DECL_SAVED_INSNS (current_function_decl) == 0)
13766 /* Stop pointing to the local nodes about to be freed. */
13767 /* But DECL_INITIAL must remain nonzero so we know this was an actual
13768 function definition. */
13769 DECL_INITIAL (current_function_decl) = error_mark_node;
13770 DECL_ARGUMENTS (current_function_decl) = 0;
13773 pop_function_context ();
13775 f_function_chain = p->next;
13777 named_labels = p->named_labels;
13778 shadowed_labels = p->shadowed_labels;
13779 current_binding_level = p->binding_level;
13784 /* Save and reinitialize the variables
13785 used during compilation of a C function. */
13788 push_f_function_context (void)
13790 struct f_function *p
13791 = (struct f_function *) xmalloc (sizeof (struct f_function));
13793 push_function_context ();
13795 p->next = f_function_chain;
13796 f_function_chain = p;
13798 p->named_labels = named_labels;
13799 p->shadowed_labels = shadowed_labels;
13800 p->binding_level = current_binding_level;
13804 push_parm_decl (tree parm)
13806 int old_immediate_size_expand = immediate_size_expand;
13808 /* Don't try computing parm sizes now -- wait till fn is called. */
13810 immediate_size_expand = 0;
13812 /* Fill in arg stuff. */
13814 DECL_ARG_TYPE (parm) = TREE_TYPE (parm);
13815 DECL_ARG_TYPE_AS_WRITTEN (parm) = TREE_TYPE (parm);
13816 TREE_READONLY (parm) = 1; /* All implementation args are read-only. */
13818 parm = pushdecl (parm);
13820 immediate_size_expand = old_immediate_size_expand;
13822 finish_decl (parm, NULL_TREE, FALSE);
13825 /* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL, if appropriate. */
13828 pushdecl_top_level (tree x)
13831 register struct f_binding_level *b = current_binding_level;
13832 register tree f = current_function_decl;
13834 current_binding_level = global_binding_level;
13835 current_function_decl = NULL_TREE;
13837 current_binding_level = b;
13838 current_function_decl = f;
13842 /* Store the list of declarations of the current level.
13843 This is done for the parameter declarations of a function being defined,
13844 after they are modified in the light of any missing parameters. */
13847 storedecls (tree decls)
13849 return current_binding_level->names = decls;
13852 /* Store the parameter declarations into the current function declaration.
13853 This is called after parsing the parameter declarations, before
13854 digesting the body of the function.
13856 For an old-style definition, modify the function's type
13857 to specify at least the number of arguments. */
13860 store_parm_decls (int is_main_program UNUSED)
13862 register tree fndecl = current_function_decl;
13864 if (fndecl == error_mark_node)
13867 /* This is a chain of PARM_DECLs from old-style parm declarations. */
13868 DECL_ARGUMENTS (fndecl) = storedecls (nreverse (getdecls ()));
13870 /* Initialize the RTL code for the function. */
13871 init_function_start (fndecl);
13873 /* Set up parameters and prepare for return, for the function. */
13874 expand_function_start (fndecl, 0);
13878 start_decl (tree decl, bool is_top_level)
13881 bool at_top_level = (current_binding_level == global_binding_level);
13882 bool top_level = is_top_level || at_top_level;
13884 /* Caller should pass TRUE for is_top_level only if we wouldn't be at top
13886 assert (!is_top_level || !at_top_level);
13888 if (DECL_INITIAL (decl) != NULL_TREE)
13890 assert (DECL_INITIAL (decl) == error_mark_node);
13891 assert (!DECL_EXTERNAL (decl));
13893 else if (top_level)
13894 assert ((TREE_STATIC (decl) == 1) || DECL_EXTERNAL (decl) == 1);
13896 /* For Fortran, we by default put things in .common when possible. */
13897 DECL_COMMON (decl) = 1;
13899 /* Add this decl to the current binding level. TEM may equal DECL or it may
13900 be a previous decl of the same name. */
13902 tem = pushdecl_top_level (decl);
13904 tem = pushdecl (decl);
13906 /* For a local variable, define the RTL now. */
13908 /* But not if this is a duplicate decl and we preserved the rtl from the
13909 previous one (which may or may not happen). */
13910 && !DECL_RTL_SET_P (tem))
13912 if (TYPE_SIZE (TREE_TYPE (tem)) != 0)
13914 else if (TREE_CODE (TREE_TYPE (tem)) == ARRAY_TYPE
13915 && DECL_INITIAL (tem) != 0)
13922 /* Create the FUNCTION_DECL for a function definition.
13923 DECLSPECS and DECLARATOR are the parts of the declaration;
13924 they describe the function's name and the type it returns,
13925 but twisted together in a fashion that parallels the syntax of C.
13927 This function creates a binding context for the function body
13928 as well as setting up the FUNCTION_DECL in current_function_decl.
13930 Returns 1 on success. If the DECLARATOR is not suitable for a function
13931 (it defines a datum instead), we return 0, which tells
13932 ffe_parse_file to report a parse error.
13934 NESTED is nonzero for a function nested within another function. */
13937 start_function (tree name, tree type, int nested, int public)
13941 int old_immediate_size_expand = immediate_size_expand;
13944 shadowed_labels = 0;
13946 /* Don't expand any sizes in the return type of the function. */
13947 immediate_size_expand = 0;
13952 assert (current_function_decl != NULL_TREE);
13953 assert (DECL_CONTEXT (current_function_decl) == NULL_TREE);
13957 assert (current_function_decl == NULL_TREE);
13960 if (TREE_CODE (type) == ERROR_MARK)
13961 decl1 = current_function_decl = error_mark_node;
13964 decl1 = build_decl (FUNCTION_DECL,
13967 TREE_PUBLIC (decl1) = public ? 1 : 0;
13969 DECL_INLINE (decl1) = 1;
13970 TREE_STATIC (decl1) = 1;
13971 DECL_EXTERNAL (decl1) = 0;
13973 announce_function (decl1);
13975 /* Make the init_value nonzero so pushdecl knows this is not tentative.
13976 error_mark_node is replaced below (in poplevel) with the BLOCK. */
13977 DECL_INITIAL (decl1) = error_mark_node;
13979 /* Record the decl so that the function name is defined. If we already have
13980 a decl for this name, and it is a FUNCTION_DECL, use the old decl. */
13982 current_function_decl = pushdecl (decl1);
13986 ffecom_outer_function_decl_ = current_function_decl;
13989 current_binding_level->prep_state = 2;
13991 if (TREE_CODE (current_function_decl) != ERROR_MARK)
13993 make_decl_rtl (current_function_decl, NULL);
13995 restype = TREE_TYPE (TREE_TYPE (current_function_decl));
13996 DECL_RESULT (current_function_decl)
13997 = build_decl (RESULT_DECL, NULL_TREE, restype);
14000 if (!nested && (TREE_CODE (current_function_decl) != ERROR_MARK))
14001 TREE_ADDRESSABLE (current_function_decl) = 1;
14003 immediate_size_expand = old_immediate_size_expand;
14006 /* Here are the public functions the GNU back end needs. */
14009 convert (tree type, tree expr)
14011 register tree e = expr;
14012 register enum tree_code code = TREE_CODE (type);
14014 if (type == TREE_TYPE (e)
14015 || TREE_CODE (e) == ERROR_MARK)
14017 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
14018 return fold (build1 (NOP_EXPR, type, e));
14019 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
14020 || code == ERROR_MARK)
14021 return error_mark_node;
14022 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
14024 assert ("void value not ignored as it ought to be" == NULL);
14025 return error_mark_node;
14027 if (code == VOID_TYPE)
14028 return build1 (CONVERT_EXPR, type, e);
14029 if ((code != RECORD_TYPE)
14030 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
14031 e = ffecom_1 (REALPART_EXPR, TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e))),
14033 if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)
14034 return fold (convert_to_integer (type, e));
14035 if (code == POINTER_TYPE)
14036 return fold (convert_to_pointer (type, e));
14037 if (code == REAL_TYPE)
14038 return fold (convert_to_real (type, e));
14039 if (code == COMPLEX_TYPE)
14040 return fold (convert_to_complex (type, e));
14041 if (code == RECORD_TYPE)
14042 return fold (ffecom_convert_to_complex_ (type, e));
14044 assert ("conversion to non-scalar type requested" == NULL);
14045 return error_mark_node;
14048 /* Return the list of declarations of the current level.
14049 Note that this list is in reverse order unless/until
14050 you nreverse it; and when you do nreverse it, you must
14051 store the result back using `storedecls' or you will lose. */
14056 return current_binding_level->names;
14059 /* Nonzero if we are currently in the global binding level. */
14062 global_bindings_p (void)
14064 return current_binding_level == global_binding_level;
14068 ffecom_init_decl_processing (void)
14075 /* Delete the node BLOCK from the current binding level.
14076 This is used for the block inside a stmt expr ({...})
14077 so that the block can be reinserted where appropriate. */
14080 delete_block (tree block)
14083 if (current_binding_level->blocks == block)
14084 current_binding_level->blocks = TREE_CHAIN (block);
14085 for (t = current_binding_level->blocks; t;)
14087 if (TREE_CHAIN (t) == block)
14088 TREE_CHAIN (t) = TREE_CHAIN (block);
14090 t = TREE_CHAIN (t);
14092 TREE_CHAIN (block) = NULL;
14093 /* Clear TREE_USED which is always set by poplevel.
14094 The flag is set again if insert_block is called. */
14095 TREE_USED (block) = 0;
14099 insert_block (tree block)
14101 TREE_USED (block) = 1;
14102 current_binding_level->blocks
14103 = chainon (current_binding_level->blocks, block);
14106 /* Each front end provides its own. */
14107 static bool ffe_init (void);
14108 static void ffe_finish (void);
14109 static bool ffe_post_options (const char **);
14110 static void ffe_print_identifier (FILE *, tree, int);
14112 struct language_function GTY(())
14117 #undef LANG_HOOKS_NAME
14118 #define LANG_HOOKS_NAME "GNU F77"
14119 #undef LANG_HOOKS_INIT
14120 #define LANG_HOOKS_INIT ffe_init
14121 #undef LANG_HOOKS_FINISH
14122 #define LANG_HOOKS_FINISH ffe_finish
14123 #undef LANG_HOOKS_INIT_OPTIONS
14124 #define LANG_HOOKS_INIT_OPTIONS ffe_init_options
14125 #undef LANG_HOOKS_HANDLE_OPTION
14126 #define LANG_HOOKS_HANDLE_OPTION ffe_handle_option
14127 #undef LANG_HOOKS_POST_OPTIONS
14128 #define LANG_HOOKS_POST_OPTIONS ffe_post_options
14129 #undef LANG_HOOKS_PARSE_FILE
14130 #define LANG_HOOKS_PARSE_FILE ffe_parse_file
14131 #undef LANG_HOOKS_MARK_ADDRESSABLE
14132 #define LANG_HOOKS_MARK_ADDRESSABLE ffe_mark_addressable
14133 #undef LANG_HOOKS_PRINT_IDENTIFIER
14134 #define LANG_HOOKS_PRINT_IDENTIFIER ffe_print_identifier
14135 #undef LANG_HOOKS_DECL_PRINTABLE_NAME
14136 #define LANG_HOOKS_DECL_PRINTABLE_NAME ffe_printable_name
14137 #undef LANG_HOOKS_PRINT_ERROR_FUNCTION
14138 #define LANG_HOOKS_PRINT_ERROR_FUNCTION ffe_print_error_function
14139 #undef LANG_HOOKS_TRUTHVALUE_CONVERSION
14140 #define LANG_HOOKS_TRUTHVALUE_CONVERSION ffe_truthvalue_conversion
14142 #undef LANG_HOOKS_TYPE_FOR_MODE
14143 #define LANG_HOOKS_TYPE_FOR_MODE ffe_type_for_mode
14144 #undef LANG_HOOKS_TYPE_FOR_SIZE
14145 #define LANG_HOOKS_TYPE_FOR_SIZE ffe_type_for_size
14146 #undef LANG_HOOKS_SIGNED_TYPE
14147 #define LANG_HOOKS_SIGNED_TYPE ffe_signed_type
14148 #undef LANG_HOOKS_UNSIGNED_TYPE
14149 #define LANG_HOOKS_UNSIGNED_TYPE ffe_unsigned_type
14150 #undef LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE
14151 #define LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE ffe_signed_or_unsigned_type
14153 /* We do not wish to use alias-set based aliasing at all. Used in the
14154 extreme (every object with its own set, with equivalences recorded) it
14155 might be helpful, but there are problems when it comes to inlining. We
14156 get on ok with flag_argument_noalias, and alias-set aliasing does
14157 currently limit how stack slots can be reused, which is a lose. */
14158 #undef LANG_HOOKS_GET_ALIAS_SET
14159 #define LANG_HOOKS_GET_ALIAS_SET hook_get_alias_set_0
14161 const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
14163 /* Table indexed by tree code giving a string containing a character
14164 classifying the tree code. Possibilities are
14165 t, d, s, c, r, <, 1, 2 and e. See tree.def for details. */
14167 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
14169 const char tree_code_type[] = {
14170 #include "tree.def"
14174 /* Table indexed by tree code giving number of expression
14175 operands beyond the fixed part of the node structure.
14176 Not used for types or decls. */
14178 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
14180 const unsigned char tree_code_length[] = {
14181 #include "tree.def"
14185 /* Names of tree components.
14186 Used for printing out the tree and error messages. */
14187 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
14189 const char *const tree_code_name[] = {
14190 #include "tree.def"
14195 ffe_post_options (const char **pfilename)
14197 const char *filename = *pfilename;
14199 /* Open input file. */
14200 if (filename == 0 || !strcmp (filename, "-"))
14203 filename = "stdin";
14206 finput = fopen (filename, "r");
14209 fatal_error ("can't open %s: %m", filename);
14218 #ifdef IO_BUFFER_SIZE
14219 setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
14222 ffecom_init_decl_processing ();
14224 /* If the file is output from cpp, it should contain a first line
14225 `# 1 "real-filename"', and the current design of gcc (toplev.c
14226 in particular and the way it sets up information relied on by
14227 INCLUDE) requires that we read this now, and store the
14228 "real-filename" info in master_input_filename. Ask the lexer
14229 to try doing this. */
14230 ffelex_hash_kludge (finput);
14232 push_srcloc (input_filename, 0);
14234 /* FIXME: The ffelex_hash_kludge code needs to be cleaned up to
14235 set the new file name. Maybe in ffe_post_options. */
14242 ffe_terminate_0 ();
14244 if (ffe_is_ffedebug ())
14245 malloc_pool_display (malloc_pool_image ());
14251 ffe_mark_addressable (tree exp)
14253 register tree x = exp;
14255 switch (TREE_CODE (x))
14258 case COMPONENT_REF:
14260 x = TREE_OPERAND (x, 0);
14264 TREE_ADDRESSABLE (x) = 1;
14271 if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
14272 && DECL_NONLOCAL (x))
14274 if (TREE_PUBLIC (x))
14276 assert ("address of global register var requested" == NULL);
14279 assert ("address of register variable requested" == NULL);
14281 else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x))
14283 if (TREE_PUBLIC (x))
14285 assert ("address of global register var requested" == NULL);
14288 assert ("address of register var requested" == NULL);
14290 put_var_into_stack (x, /*rescan=*/true);
14293 case FUNCTION_DECL:
14294 TREE_ADDRESSABLE (x) = 1;
14295 #if 0 /* poplevel deals with this now. */
14296 if (DECL_CONTEXT (x) == 0)
14297 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (x)) = 1;
14305 /* Exit a binding level.
14306 Pop the level off, and restore the state of the identifier-decl mappings
14307 that were in effect when this level was entered.
14309 If KEEP is nonzero, this level had explicit declarations, so
14310 and create a "block" (a BLOCK node) for the level
14311 to record its declarations and subblocks for symbol table output.
14313 If FUNCTIONBODY is nonzero, this level is the body of a function,
14314 so create a block as if KEEP were set and also clear out all
14317 If REVERSE is nonzero, reverse the order of decls before putting
14318 them into the BLOCK. */
14321 poplevel (int keep, int reverse, int functionbody)
14323 register tree link;
14324 /* The chain of decls was accumulated in reverse order.
14325 Put it into forward order, just for cleanliness. */
14327 tree subblocks = current_binding_level->blocks;
14330 int block_previously_created;
14332 /* Get the decls in the order they were written.
14333 Usually current_binding_level->names is in reverse order.
14334 But parameter decls were previously put in forward order. */
14337 current_binding_level->names
14338 = decls = nreverse (current_binding_level->names);
14340 decls = current_binding_level->names;
14342 /* Output any nested inline functions within this block
14343 if they weren't already output. */
14345 for (decl = decls; decl; decl = TREE_CHAIN (decl))
14346 if (TREE_CODE (decl) == FUNCTION_DECL
14347 && ! TREE_ASM_WRITTEN (decl)
14348 && DECL_INITIAL (decl) != 0
14349 && TREE_ADDRESSABLE (decl))
14351 /* If this decl was copied from a file-scope decl
14352 on account of a block-scope extern decl,
14353 propagate TREE_ADDRESSABLE to the file-scope decl.
14355 DECL_ABSTRACT_ORIGIN can be set to itself if warn_return_type is
14356 true, since then the decl goes through save_for_inline_copying. */
14357 if (DECL_ABSTRACT_ORIGIN (decl) != 0
14358 && DECL_ABSTRACT_ORIGIN (decl) != decl)
14359 TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1;
14360 else if (DECL_SAVED_INSNS (decl) != 0)
14362 push_function_context ();
14363 output_inline_function (decl);
14364 pop_function_context ();
14368 /* If there were any declarations or structure tags in that level,
14369 or if this level is a function body,
14370 create a BLOCK to record them for the life of this function. */
14373 block_previously_created = (current_binding_level->this_block != 0);
14374 if (block_previously_created)
14375 block = current_binding_level->this_block;
14376 else if (keep || functionbody)
14377 block = make_node (BLOCK);
14380 BLOCK_VARS (block) = decls;
14381 BLOCK_SUBBLOCKS (block) = subblocks;
14384 /* In each subblock, record that this is its superior. */
14386 for (link = subblocks; link; link = TREE_CHAIN (link))
14387 BLOCK_SUPERCONTEXT (link) = block;
14389 /* Clear out the meanings of the local variables of this level. */
14391 for (link = decls; link; link = TREE_CHAIN (link))
14393 if (DECL_NAME (link) != 0)
14395 /* If the ident. was used or addressed via a local extern decl,
14396 don't forget that fact. */
14397 if (DECL_EXTERNAL (link))
14399 if (TREE_USED (link))
14400 TREE_USED (DECL_NAME (link)) = 1;
14401 if (TREE_ADDRESSABLE (link))
14402 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (link)) = 1;
14404 IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = 0;
14408 /* If the level being exited is the top level of a function,
14409 check over all the labels, and clear out the current
14410 (function local) meanings of their names. */
14414 /* If this is the top level block of a function,
14415 the vars are the function's parameters.
14416 Don't leave them in the BLOCK because they are
14417 found in the FUNCTION_DECL instead. */
14419 BLOCK_VARS (block) = 0;
14422 /* Pop the current level, and free the structure for reuse. */
14425 register struct f_binding_level *level = current_binding_level;
14426 current_binding_level = current_binding_level->level_chain;
14428 level->level_chain = free_binding_level;
14429 free_binding_level = level;
14432 /* Dispose of the block that we just made inside some higher level. */
14434 && current_function_decl != error_mark_node)
14435 DECL_INITIAL (current_function_decl) = block;
14438 if (!block_previously_created)
14439 current_binding_level->blocks
14440 = chainon (current_binding_level->blocks, block);
14442 /* If we did not make a block for the level just exited,
14443 any blocks made for inner levels
14444 (since they cannot be recorded as subblocks in that level)
14445 must be carried forward so they will later become subblocks
14446 of something else. */
14447 else if (subblocks)
14448 current_binding_level->blocks
14449 = chainon (current_binding_level->blocks, subblocks);
14452 TREE_USED (block) = 1;
14457 ffe_print_identifier (FILE *file, tree node, int indent)
14459 print_node (file, "global", IDENTIFIER_GLOBAL_VALUE (node), indent + 4);
14460 print_node (file, "local", IDENTIFIER_LOCAL_VALUE (node), indent + 4);
14463 /* Record a decl-node X as belonging to the current lexical scope.
14464 Check for errors (such as an incompatible declaration for the same
14465 name already seen in the same scope).
14467 Returns either X or an old decl for the same name.
14468 If an old decl is returned, it may have been smashed
14469 to agree with what X says. */
14475 register tree name = DECL_NAME (x);
14476 register struct f_binding_level *b = current_binding_level;
14478 if ((TREE_CODE (x) == FUNCTION_DECL)
14479 && (DECL_INITIAL (x) == 0)
14480 && DECL_EXTERNAL (x))
14481 DECL_CONTEXT (x) = NULL_TREE;
14483 DECL_CONTEXT (x) = current_function_decl;
14487 if (IDENTIFIER_INVENTED (name))
14489 DECL_ARTIFICIAL (x) = 1;
14490 DECL_IN_SYSTEM_HEADER (x) = 1;
14493 t = lookup_name_current_level (name);
14495 assert ((t == NULL_TREE) || (DECL_CONTEXT (x) == NULL_TREE));
14497 /* Don't push non-parms onto list for parms until we understand
14498 why we're doing this and whether it works. */
14500 assert ((b == global_binding_level)
14501 || !ffecom_transform_only_dummies_
14502 || TREE_CODE (x) == PARM_DECL);
14504 if ((t != NULL_TREE) && duplicate_decls (x, t))
14507 /* If we are processing a typedef statement, generate a whole new
14508 ..._TYPE node (which will be just an variant of the existing
14509 ..._TYPE node with identical properties) and then install the
14510 TYPE_DECL node generated to represent the typedef name as the
14511 TYPE_NAME of this brand new (duplicate) ..._TYPE node.
14513 The whole point here is to end up with a situation where each and every
14514 ..._TYPE node the compiler creates will be uniquely associated with
14515 AT MOST one node representing a typedef name. This way, even though
14516 the compiler substitutes corresponding ..._TYPE nodes for TYPE_DECL
14517 (i.e. "typedef name") nodes very early on, later parts of the
14518 compiler can always do the reverse translation and get back the
14519 corresponding typedef name. For example, given:
14521 typedef struct S MY_TYPE; MY_TYPE object;
14523 Later parts of the compiler might only know that `object' was of type
14524 `struct S' if it were not for code just below. With this code
14525 however, later parts of the compiler see something like:
14527 struct S' == struct S typedef struct S' MY_TYPE; struct S' object;
14529 And they can then deduce (from the node for type struct S') that the
14530 original object declaration was:
14534 Being able to do this is important for proper support of protoize, and
14535 also for generating precise symbolic debugging information which
14536 takes full account of the programmer's (typedef) vocabulary.
14538 Obviously, we don't want to generate a duplicate ..._TYPE node if the
14539 TYPE_DECL node that we are now processing really represents a
14540 standard built-in type.
14542 Since all standard types are effectively declared at line zero in the
14543 source file, we can easily check to see if we are working on a
14544 standard type by checking the current value of lineno. */
14546 if (TREE_CODE (x) == TYPE_DECL)
14548 if (DECL_SOURCE_LINE (x) == 0)
14550 if (TYPE_NAME (TREE_TYPE (x)) == 0)
14551 TYPE_NAME (TREE_TYPE (x)) = x;
14553 else if (TREE_TYPE (x) != error_mark_node)
14555 tree tt = TREE_TYPE (x);
14557 tt = build_type_copy (tt);
14558 TYPE_NAME (tt) = x;
14559 TREE_TYPE (x) = tt;
14563 /* This name is new in its binding level. Install the new declaration
14565 if (b == global_binding_level)
14566 IDENTIFIER_GLOBAL_VALUE (name) = x;
14568 IDENTIFIER_LOCAL_VALUE (name) = x;
14571 /* Put decls on list in reverse order. We will reverse them later if
14573 TREE_CHAIN (x) = b->names;
14579 /* Nonzero if the current level needs to have a BLOCK made. */
14582 kept_level_p (void)
14586 for (decl = current_binding_level->names;
14588 decl = TREE_CHAIN (decl))
14590 if (TREE_USED (decl) || TREE_CODE (decl) != VAR_DECL
14591 || (DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl)))
14592 /* Currently, there aren't supposed to be non-artificial names
14593 at other than the top block for a function -- they're
14594 believed to always be temps. But it's wise to check anyway. */
14600 /* Enter a new binding level.
14601 If TAG_TRANSPARENT is nonzero, do so only for the name space of variables,
14602 not for that of tags. */
14605 pushlevel (int tag_transparent)
14607 register struct f_binding_level *newlevel = NULL_BINDING_LEVEL;
14609 assert (! tag_transparent);
14611 if (current_binding_level == global_binding_level)
14616 /* Reuse or create a struct for this binding level. */
14618 if (free_binding_level)
14620 newlevel = free_binding_level;
14621 free_binding_level = free_binding_level->level_chain;
14625 newlevel = make_binding_level ();
14628 /* Add this level to the front of the chain (stack) of levels that
14631 *newlevel = clear_binding_level;
14632 newlevel->level_chain = current_binding_level;
14633 current_binding_level = newlevel;
14636 /* Set the BLOCK node for the innermost scope
14637 (the one we are currently in). */
14640 set_block (tree block)
14642 current_binding_level->this_block = block;
14643 current_binding_level->names = chainon (current_binding_level->names,
14644 BLOCK_VARS (block));
14645 current_binding_level->blocks = chainon (current_binding_level->blocks,
14646 BLOCK_SUBBLOCKS (block));
14650 ffe_signed_or_unsigned_type (int unsignedp, tree type)
14654 if (! INTEGRAL_TYPE_P (type))
14656 if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node))
14657 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
14658 if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
14659 return unsignedp ? unsigned_type_node : integer_type_node;
14660 if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node))
14661 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
14662 if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node))
14663 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
14664 if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node))
14665 return (unsignedp ? long_long_unsigned_type_node
14666 : long_long_integer_type_node);
14668 type2 = ffe_type_for_size (TYPE_PRECISION (type), unsignedp);
14669 if (type2 == NULL_TREE)
14676 ffe_signed_type (tree type)
14678 tree type1 = TYPE_MAIN_VARIANT (type);
14679 ffeinfoKindtype kt;
14682 if (type1 == unsigned_char_type_node || type1 == char_type_node)
14683 return signed_char_type_node;
14684 if (type1 == unsigned_type_node)
14685 return integer_type_node;
14686 if (type1 == short_unsigned_type_node)
14687 return short_integer_type_node;
14688 if (type1 == long_unsigned_type_node)
14689 return long_integer_type_node;
14690 if (type1 == long_long_unsigned_type_node)
14691 return long_long_integer_type_node;
14692 #if 0 /* gcc/c-* files only */
14693 if (type1 == unsigned_intDI_type_node)
14694 return intDI_type_node;
14695 if (type1 == unsigned_intSI_type_node)
14696 return intSI_type_node;
14697 if (type1 == unsigned_intHI_type_node)
14698 return intHI_type_node;
14699 if (type1 == unsigned_intQI_type_node)
14700 return intQI_type_node;
14703 type2 = ffe_type_for_size (TYPE_PRECISION (type1), 0);
14704 if (type2 != NULL_TREE)
14707 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
14709 type2 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
14711 if (type1 == type2)
14712 return ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
14718 /* Prepare expr to be an argument of a TRUTH_NOT_EXPR,
14719 or validate its data type for an `if' or `while' statement or ?..: exp.
14721 This preparation consists of taking the ordinary
14722 representation of an expression expr and producing a valid tree
14723 boolean expression describing whether expr is nonzero. We could
14724 simply always do build_binary_op (NE_EXPR, expr, integer_zero_node, 1),
14725 but we optimize comparisons, &&, ||, and !.
14727 The resulting type should always be `integer_type_node'. */
14730 ffe_truthvalue_conversion (tree expr)
14732 if (TREE_CODE (expr) == ERROR_MARK)
14735 #if 0 /* This appears to be wrong for C++. */
14736 /* These really should return error_mark_node after 2.4 is stable.
14737 But not all callers handle ERROR_MARK properly. */
14738 switch (TREE_CODE (TREE_TYPE (expr)))
14741 error ("struct type value used where scalar is required");
14742 return integer_zero_node;
14745 error ("union type value used where scalar is required");
14746 return integer_zero_node;
14749 error ("array type value used where scalar is required");
14750 return integer_zero_node;
14757 switch (TREE_CODE (expr))
14759 /* It is simpler and generates better code to have only TRUTH_*_EXPR
14760 or comparison expressions as truth values at this level. */
14762 case COMPONENT_REF:
14763 /* A one-bit unsigned bit-field is already acceptable. */
14764 if (1 == TREE_INT_CST_LOW (DECL_SIZE (TREE_OPERAND (expr, 1)))
14765 && TREE_UNSIGNED (TREE_OPERAND (expr, 1)))
14771 /* It is simpler and generates better code to have only TRUTH_*_EXPR
14772 or comparison expressions as truth values at this level. */
14774 if (integer_zerop (TREE_OPERAND (expr, 1)))
14775 return build_unary_op (TRUTH_NOT_EXPR, TREE_OPERAND (expr, 0), 0);
14777 case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
14778 case TRUTH_ANDIF_EXPR:
14779 case TRUTH_ORIF_EXPR:
14780 case TRUTH_AND_EXPR:
14781 case TRUTH_OR_EXPR:
14782 case TRUTH_XOR_EXPR:
14783 TREE_TYPE (expr) = integer_type_node;
14790 return integer_zerop (expr) ? integer_zero_node : integer_one_node;
14793 return real_zerop (expr) ? integer_zero_node : integer_one_node;
14796 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 0)))
14797 return build (COMPOUND_EXPR, integer_type_node,
14798 TREE_OPERAND (expr, 0), integer_one_node);
14800 return integer_one_node;
14803 return ffecom_2 ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))
14804 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
14806 ffe_truthvalue_conversion (TREE_OPERAND (expr, 0)),
14807 ffe_truthvalue_conversion (TREE_OPERAND (expr, 1)));
14813 /* These don't change whether an object is nonzero or zero. */
14814 return ffe_truthvalue_conversion (TREE_OPERAND (expr, 0));
14818 /* These don't change whether an object is zero or nonzero, but
14819 we can't ignore them if their second arg has side-effects. */
14820 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)))
14821 return build (COMPOUND_EXPR, integer_type_node, TREE_OPERAND (expr, 1),
14822 ffe_truthvalue_conversion (TREE_OPERAND (expr, 0)));
14824 return ffe_truthvalue_conversion (TREE_OPERAND (expr, 0));
14828 /* Distribute the conversion into the arms of a COND_EXPR. */
14829 tree arg1 = TREE_OPERAND (expr, 1);
14830 tree arg2 = TREE_OPERAND (expr, 2);
14831 if (! VOID_TYPE_P (TREE_TYPE (arg1)))
14832 arg1 = ffe_truthvalue_conversion (arg1);
14833 if (! VOID_TYPE_P (TREE_TYPE (arg2)))
14834 arg2 = ffe_truthvalue_conversion (arg2);
14835 return fold (build (COND_EXPR, integer_type_node,
14836 TREE_OPERAND (expr, 0), arg1, arg2));
14840 /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
14841 since that affects how `default_conversion' will behave. */
14842 if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE
14843 || TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)
14845 /* fall through... */
14847 /* If this is widening the argument, we can ignore it. */
14848 if (TYPE_PRECISION (TREE_TYPE (expr))
14849 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
14850 return ffe_truthvalue_conversion (TREE_OPERAND (expr, 0));
14854 /* With IEEE arithmetic, x - x may not equal 0, so we can't optimize
14856 if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
14857 && TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE)
14859 /* fall through... */
14861 /* This and MINUS_EXPR can be changed into a comparison of the
14863 if (TREE_TYPE (TREE_OPERAND (expr, 0))
14864 == TREE_TYPE (TREE_OPERAND (expr, 1)))
14865 return ffecom_2 (NE_EXPR, integer_type_node,
14866 TREE_OPERAND (expr, 0),
14867 TREE_OPERAND (expr, 1));
14868 return ffecom_2 (NE_EXPR, integer_type_node,
14869 TREE_OPERAND (expr, 0),
14870 fold (build1 (NOP_EXPR,
14871 TREE_TYPE (TREE_OPERAND (expr, 0)),
14872 TREE_OPERAND (expr, 1))));
14875 if (integer_onep (TREE_OPERAND (expr, 1)))
14880 #if 0 /* No such thing in Fortran. */
14881 if (warn_parentheses && C_EXP_ORIGINAL_CODE (expr) == MODIFY_EXPR)
14882 warning ("suggest parentheses around assignment used as truth value");
14890 if (TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE)
14892 ((TREE_SIDE_EFFECTS (expr)
14893 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
14895 ffe_truthvalue_conversion (ffecom_1 (REALPART_EXPR,
14896 TREE_TYPE (TREE_TYPE (expr)),
14898 ffe_truthvalue_conversion (ffecom_1 (IMAGPART_EXPR,
14899 TREE_TYPE (TREE_TYPE (expr)),
14902 return ffecom_2 (NE_EXPR, integer_type_node,
14904 convert (TREE_TYPE (expr), integer_zero_node));
14908 ffe_type_for_mode (enum machine_mode mode, int unsignedp)
14914 if (mode == TYPE_MODE (integer_type_node))
14915 return unsignedp ? unsigned_type_node : integer_type_node;
14917 if (mode == TYPE_MODE (signed_char_type_node))
14918 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
14920 if (mode == TYPE_MODE (short_integer_type_node))
14921 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
14923 if (mode == TYPE_MODE (long_integer_type_node))
14924 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
14926 if (mode == TYPE_MODE (long_long_integer_type_node))
14927 return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node;
14929 #if HOST_BITS_PER_WIDE_INT >= 64
14930 if (mode == TYPE_MODE (intTI_type_node))
14931 return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
14934 if (mode == TYPE_MODE (float_type_node))
14935 return float_type_node;
14937 if (mode == TYPE_MODE (double_type_node))
14938 return double_type_node;
14940 if (mode == TYPE_MODE (long_double_type_node))
14941 return long_double_type_node;
14943 if (mode == TYPE_MODE (build_pointer_type (char_type_node)))
14944 return build_pointer_type (char_type_node);
14946 if (mode == TYPE_MODE (build_pointer_type (integer_type_node)))
14947 return build_pointer_type (integer_type_node);
14949 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
14950 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
14952 if (((t = ffecom_tree_type[i][j]) != NULL_TREE)
14953 && (mode == TYPE_MODE (t)))
14955 if ((i == FFEINFO_basictypeINTEGER) && unsignedp)
14956 return ffecom_tree_type[FFEINFO_basictypeHOLLERITH][j];
14966 ffe_type_for_size (unsigned bits, int unsignedp)
14968 ffeinfoKindtype kt;
14971 if (bits == TYPE_PRECISION (integer_type_node))
14972 return unsignedp ? unsigned_type_node : integer_type_node;
14974 if (bits == TYPE_PRECISION (signed_char_type_node))
14975 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
14977 if (bits == TYPE_PRECISION (short_integer_type_node))
14978 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
14980 if (bits == TYPE_PRECISION (long_integer_type_node))
14981 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
14983 if (bits == TYPE_PRECISION (long_long_integer_type_node))
14984 return (unsignedp ? long_long_unsigned_type_node
14985 : long_long_integer_type_node);
14987 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
14989 type_node = ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
14991 if ((type_node != NULL_TREE) && (bits == TYPE_PRECISION (type_node)))
14992 return unsignedp ? ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt]
15000 ffe_unsigned_type (tree type)
15002 tree type1 = TYPE_MAIN_VARIANT (type);
15003 ffeinfoKindtype kt;
15006 if (type1 == signed_char_type_node || type1 == char_type_node)
15007 return unsigned_char_type_node;
15008 if (type1 == integer_type_node)
15009 return unsigned_type_node;
15010 if (type1 == short_integer_type_node)
15011 return short_unsigned_type_node;
15012 if (type1 == long_integer_type_node)
15013 return long_unsigned_type_node;
15014 if (type1 == long_long_integer_type_node)
15015 return long_long_unsigned_type_node;
15016 #if 0 /* gcc/c-* files only */
15017 if (type1 == intDI_type_node)
15018 return unsigned_intDI_type_node;
15019 if (type1 == intSI_type_node)
15020 return unsigned_intSI_type_node;
15021 if (type1 == intHI_type_node)
15022 return unsigned_intHI_type_node;
15023 if (type1 == intQI_type_node)
15024 return unsigned_intQI_type_node;
15027 type2 = ffe_type_for_size (TYPE_PRECISION (type1), 1);
15028 if (type2 != NULL_TREE)
15031 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
15033 type2 = ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
15035 if (type1 == type2)
15036 return ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
15042 /* From gcc/cccp.c, the code to handle -I. */
15044 /* Skip leading "./" from a directory name.
15045 This may yield the empty string, which represents the current directory. */
15047 static const char *
15048 skip_redundant_dir_prefix (const char *dir)
15050 while (dir[0] == '.' && dir[1] == '/')
15051 for (dir += 2; *dir == '/'; dir++)
15053 if (dir[0] == '.' && !dir[1])
15058 /* The file_name_map structure holds a mapping of file names for a
15059 particular directory. This mapping is read from the file named
15060 FILE_NAME_MAP_FILE in that directory. Such a file can be used to
15061 map filenames on a file system with severe filename restrictions,
15062 such as DOS. The format of the file name map file is just a series
15063 of lines with two tokens on each line. The first token is the name
15064 to map, and the second token is the actual name to use. */
15066 struct file_name_map
15068 struct file_name_map *map_next;
15073 #define FILE_NAME_MAP_FILE "header.gcc"
15075 /* Current maximum length of directory names in the search path
15076 for include files. (Altered as we get more of them.) */
15078 static int max_include_len = 0;
15080 struct file_name_list
15082 struct file_name_list *next;
15084 /* Mapping of file names for this directory. */
15085 struct file_name_map *name_map;
15086 /* Nonzero if name_map is valid. */
15090 static struct file_name_list *include = NULL; /* First dir to search */
15091 static struct file_name_list *last_include = NULL; /* Last in chain */
15093 /* I/O buffer structure.
15094 The `fname' field is nonzero for source files and #include files
15095 and for the dummy text used for -D and -U.
15096 It is zero for rescanning results of macro expansion
15097 and for expanding macro arguments. */
15098 #define INPUT_STACK_MAX 400
15099 static struct file_buf {
15101 /* Filename specified with #line command. */
15102 const char *nominal_fname;
15103 /* Record where in the search path this file was found.
15104 For #include_next. */
15105 struct file_name_list *dir;
15107 ffewhereColumn column;
15108 } instack[INPUT_STACK_MAX];
15110 static int last_error_tick = 0; /* Incremented each time we print it. */
15112 /* Current nesting level of input sources.
15113 `instack[indepth]' is the level currently being read. */
15114 static int indepth = -1;
15116 typedef struct file_buf FILE_BUF;
15118 /* Nonzero means -I- has been seen,
15119 so don't look for #include "foo" the source-file directory. */
15120 static int ignore_srcdir;
15122 #ifndef INCLUDE_LEN_FUDGE
15123 #define INCLUDE_LEN_FUDGE 0
15126 static void append_include_chain (struct file_name_list *first,
15127 struct file_name_list *last);
15128 static FILE *open_include_file (char *filename,
15129 struct file_name_list *searchptr);
15130 static void print_containing_files (ffebadSeverity sev);
15131 static char *read_filename_string (int ch, FILE *f);
15132 static struct file_name_map *read_name_map (const char *dirname);
15134 /* Append a chain of `struct file_name_list's
15135 to the end of the main include chain.
15136 FIRST is the beginning of the chain to append, and LAST is the end. */
15139 append_include_chain (struct file_name_list *first,
15140 struct file_name_list *last)
15142 struct file_name_list *dir;
15144 if (!first || !last)
15150 last_include->next = first;
15152 for (dir = first; ; dir = dir->next) {
15153 int len = strlen (dir->fname) + INCLUDE_LEN_FUDGE;
15154 if (len > max_include_len)
15155 max_include_len = len;
15161 last_include = last;
15164 /* Try to open include file FILENAME. SEARCHPTR is the directory
15165 being tried from the include file search path. This function maps
15166 filenames on file systems based on information read by
15170 open_include_file (char *filename, struct file_name_list *searchptr)
15172 register struct file_name_map *map;
15173 register char *from;
15176 if (searchptr && ! searchptr->got_name_map)
15178 searchptr->name_map = read_name_map (searchptr->fname
15179 ? searchptr->fname : ".");
15180 searchptr->got_name_map = 1;
15183 /* First check the mapping for the directory we are using. */
15184 if (searchptr && searchptr->name_map)
15187 if (searchptr->fname)
15188 from += strlen (searchptr->fname) + 1;
15189 for (map = searchptr->name_map; map; map = map->map_next)
15191 if (! strcmp (map->map_from, from))
15193 /* Found a match. */
15194 return fopen (map->map_to, "r");
15199 /* Try to find a mapping file for the particular directory we are
15200 looking in. Thus #include <sys/types.h> will look up sys/types.h
15201 in /usr/include/header.gcc and look up types.h in
15202 /usr/include/sys/header.gcc. */
15203 p = strrchr (filename, '/');
15204 #ifdef DIR_SEPARATOR
15205 if (! p) p = strrchr (filename, DIR_SEPARATOR);
15207 char *tmp = strrchr (filename, DIR_SEPARATOR);
15208 if (tmp != NULL && tmp > p) p = tmp;
15214 && searchptr->fname
15215 && strlen (searchptr->fname) == (size_t) (p - filename)
15216 && ! strncmp (searchptr->fname, filename, (int) (p - filename)))
15218 /* FILENAME is in SEARCHPTR, which we've already checked. */
15219 return fopen (filename, "r");
15225 map = read_name_map (".");
15229 dir = (char *) xmalloc (p - filename + 1);
15230 memcpy (dir, filename, p - filename);
15231 dir[p - filename] = '\0';
15233 map = read_name_map (dir);
15236 for (; map; map = map->map_next)
15237 if (! strcmp (map->map_from, from))
15238 return fopen (map->map_to, "r");
15240 return fopen (filename, "r");
15243 /* Print the file names and line numbers of the #include
15244 commands which led to the current file. */
15247 print_containing_files (ffebadSeverity sev)
15249 FILE_BUF *ip = NULL;
15255 /* If stack of files hasn't changed since we last printed
15256 this info, don't repeat it. */
15257 if (last_error_tick == input_file_stack_tick)
15260 for (i = indepth; i >= 0; i--)
15261 if (instack[i].fname != NULL) {
15266 /* Give up if we don't find a source file. */
15270 /* Find the other, outer source files. */
15271 for (i--; i >= 0; i--)
15272 if (instack[i].fname != NULL)
15278 str1 = "In file included";
15290 /* xgettext:no-c-format */
15291 ffebad_start_msg ("%A from %B at %0%C", sev);
15292 ffebad_here (0, ip->line, ip->column);
15293 ffebad_string (str1);
15294 ffebad_string (ip->nominal_fname);
15295 ffebad_string (str2);
15299 /* Record we have printed the status as of this time. */
15300 last_error_tick = input_file_stack_tick;
15303 /* Read a space delimited string of unlimited length from a stdio
15307 read_filename_string (int ch, FILE *f)
15313 set = alloc = xmalloc (len + 1);
15314 if (! ISSPACE (ch))
15317 while ((ch = getc (f)) != EOF && ! ISSPACE (ch))
15319 if (set - alloc == len)
15322 alloc = xrealloc (alloc, len + 1);
15323 set = alloc + len / 2;
15333 /* Read the file name map file for DIRNAME. */
15335 static struct file_name_map *
15336 read_name_map (const char *dirname)
15338 /* This structure holds a linked list of file name maps, one per
15340 struct file_name_map_list
15342 struct file_name_map_list *map_list_next;
15343 char *map_list_name;
15344 struct file_name_map *map_list_map;
15346 static struct file_name_map_list *map_list;
15347 register struct file_name_map_list *map_list_ptr;
15351 int separator_needed;
15353 dirname = skip_redundant_dir_prefix (dirname);
15355 for (map_list_ptr = map_list; map_list_ptr;
15356 map_list_ptr = map_list_ptr->map_list_next)
15357 if (! strcmp (map_list_ptr->map_list_name, dirname))
15358 return map_list_ptr->map_list_map;
15360 map_list_ptr = ((struct file_name_map_list *)
15361 xmalloc (sizeof (struct file_name_map_list)));
15362 map_list_ptr->map_list_name = xstrdup (dirname);
15363 map_list_ptr->map_list_map = NULL;
15365 dirlen = strlen (dirname);
15366 separator_needed = dirlen != 0 && dirname[dirlen - 1] != '/';
15367 if (separator_needed)
15368 name = concat (dirname, "/", FILE_NAME_MAP_FILE, NULL);
15370 name = concat (dirname, FILE_NAME_MAP_FILE, NULL);
15371 f = fopen (name, "r");
15374 map_list_ptr->map_list_map = NULL;
15379 while ((ch = getc (f)) != EOF)
15382 struct file_name_map *ptr;
15386 from = read_filename_string (ch, f);
15387 while ((ch = getc (f)) != EOF && ISSPACE (ch) && ch != '\n')
15389 to = read_filename_string (ch, f);
15391 ptr = ((struct file_name_map *)
15392 xmalloc (sizeof (struct file_name_map)));
15393 ptr->map_from = from;
15395 /* Make the real filename absolute. */
15400 if (separator_needed)
15401 ptr->map_to = concat (dirname, "/", to, NULL);
15403 ptr->map_to = concat (dirname, to, NULL);
15407 ptr->map_next = map_list_ptr->map_list_map;
15408 map_list_ptr->map_list_map = ptr;
15410 while ((ch = getc (f)) != '\n')
15417 map_list_ptr->map_list_next = map_list;
15418 map_list = map_list_ptr;
15420 return map_list_ptr->map_list_map;
15424 ffecom_file_ (const char *name)
15428 /* Do partial setup of input buffer for the sake of generating
15429 early #line directives (when -g is in effect). */
15431 fp = &instack[++indepth];
15432 memset ((char *) fp, 0, sizeof (FILE_BUF));
15435 fp->nominal_fname = fp->fname = name;
15439 ffecom_close_include_ (FILE *f)
15444 input_file_stack_tick++;
15446 ffewhere_line_kill (instack[indepth].line);
15447 ffewhere_column_kill (instack[indepth].column);
15451 ffecom_decode_include_option (const char *dir)
15453 if (! ignore_srcdir && !strcmp (dir, "-"))
15457 struct file_name_list *dirtmp = (struct file_name_list *)
15458 xmalloc (sizeof (struct file_name_list));
15459 dirtmp->next = 0; /* New one goes on the end */
15460 dirtmp->fname = dir;
15461 dirtmp->got_name_map = 0;
15462 append_include_chain (dirtmp, dirtmp);
15466 /* Open INCLUDEd file. */
15469 ffecom_open_include_ (char *name, ffewhereLine l, ffewhereColumn c)
15472 size_t flen = strlen (fbeg);
15473 struct file_name_list *search_start = include; /* Chain of dirs to search */
15474 struct file_name_list dsp[1]; /* First in chain, if #include "..." */
15475 struct file_name_list *searchptr = 0;
15476 char *fname; /* Dynamically allocated fname buffer */
15483 dsp[0].fname = NULL;
15485 /* If -I- was specified, don't search current dir, only spec'd ones. */
15486 if (!ignore_srcdir)
15488 for (fp = &instack[indepth]; fp >= instack; fp--)
15494 if ((nam = fp->nominal_fname) != NULL)
15496 /* Found a named file. Figure out dir of the file,
15497 and put it in front of the search list. */
15498 dsp[0].next = search_start;
15499 search_start = dsp;
15501 ep = strrchr (nam, '/');
15502 #ifdef DIR_SEPARATOR
15503 if (ep == NULL) ep = strrchr (nam, DIR_SEPARATOR);
15505 char *tmp = strrchr (nam, DIR_SEPARATOR);
15506 if (tmp != NULL && tmp > ep) ep = tmp;
15510 ep = strrchr (nam, ']');
15511 if (ep == NULL) ep = strrchr (nam, '>');
15512 if (ep == NULL) ep = strrchr (nam, ':');
15513 if (ep != NULL) ep++;
15518 fname = xmalloc (n + 1);
15519 strncpy (fname, nam, n);
15521 dsp[0].fname = fname;
15522 if (n + INCLUDE_LEN_FUDGE > max_include_len)
15523 max_include_len = n + INCLUDE_LEN_FUDGE;
15526 dsp[0].fname = NULL; /* Current directory */
15527 dsp[0].got_name_map = 0;
15533 /* Allocate this permanently, because it gets stored in the definitions
15535 fname = xmalloc (max_include_len + flen + 4);
15536 /* + 2 above for slash and terminating null. */
15537 /* + 2 added for '.h' on VMS (to support '#include filename') (NOT USED
15540 /* If specified file name is absolute, just open it. */
15543 #ifdef DIR_SEPARATOR
15544 || *fbeg == DIR_SEPARATOR
15548 strncpy (fname, (char *) fbeg, flen);
15550 f = open_include_file (fname, NULL);
15556 /* Search directory path, trying to open the file.
15557 Copy each filename tried into FNAME. */
15559 for (searchptr = search_start; searchptr; searchptr = searchptr->next)
15561 if (searchptr->fname)
15563 /* The empty string in a search path is ignored.
15564 This makes it possible to turn off entirely
15565 a standard piece of the list. */
15566 if (searchptr->fname[0] == 0)
15568 strcpy (fname, skip_redundant_dir_prefix (searchptr->fname));
15569 if (fname[0] && fname[strlen (fname) - 1] != '/')
15570 strcat (fname, "/");
15571 fname[strlen (fname) + flen] = 0;
15576 strncat (fname, fbeg, flen);
15578 /* Change this 1/2 Unix 1/2 VMS file specification into a
15579 full VMS file specification */
15580 if (searchptr->fname && (searchptr->fname[0] != 0))
15582 /* Fix up the filename */
15583 hack_vms_include_specification (fname);
15587 /* This is a normal VMS filespec, so use it unchanged. */
15588 strncpy (fname, (char *) fbeg, flen);
15590 #if 0 /* Not for g77. */
15591 /* if it's '#include filename', add the missing .h */
15592 if (strchr (fname, '.') == NULL)
15593 strcat (fname, ".h");
15597 f = open_include_file (fname, searchptr);
15599 if (f == NULL && errno == EACCES)
15601 print_containing_files (FFEBAD_severityWARNING);
15602 /* xgettext:no-c-format */
15603 ffebad_start_msg ("At %0, INCLUDE file %A exists, but is not readable",
15604 FFEBAD_severityWARNING);
15605 ffebad_string (fname);
15606 ffebad_here (0, l, c);
15617 /* A file that was not found. */
15619 strncpy (fname, (char *) fbeg, flen);
15621 print_containing_files (ffebad_severity (FFEBAD_OPEN_INCLUDE));
15622 ffebad_start (FFEBAD_OPEN_INCLUDE);
15623 ffebad_here (0, l, c);
15624 ffebad_string (fname);
15628 if (dsp[0].fname != NULL)
15629 free ((char *) dsp[0].fname);
15634 if (indepth >= (INPUT_STACK_MAX - 1))
15636 print_containing_files (FFEBAD_severityFATAL);
15637 /* xgettext:no-c-format */
15638 ffebad_start_msg ("At %0, INCLUDE nesting too deep",
15639 FFEBAD_severityFATAL);
15640 ffebad_string (fname);
15641 ffebad_here (0, l, c);
15646 instack[indepth].line = ffewhere_line_use (l);
15647 instack[indepth].column = ffewhere_column_use (c);
15649 fp = &instack[indepth + 1];
15650 memset ((char *) fp, 0, sizeof (FILE_BUF));
15651 fp->nominal_fname = fp->fname = fname;
15652 fp->dir = searchptr;
15655 input_file_stack_tick++;
15660 /**INDENT* (Do not reformat this comment even with -fca option.)
15661 Data-gathering files: Given the source file listed below, compiled with
15662 f2c I obtained the output file listed after that, and from the output
15663 file I derived the above code.
15665 -------- (begin input file to f2c)
15671 double precision D1,D2
15673 call getem(A1,A2,C1,C2,I1,I2,R1,R2,D1,D2)
15700 c FFEINTRIN_impACOS
15701 call fooR(ACOS(R1))
15702 c FFEINTRIN_impAIMAG
15703 call fooR(AIMAG(C1))
15704 c FFEINTRIN_impAINT
15705 call fooR(AINT(R1))
15706 c FFEINTRIN_impALOG
15707 call fooR(ALOG(R1))
15708 c FFEINTRIN_impALOG10
15709 call fooR(ALOG10(R1))
15710 c FFEINTRIN_impAMAX0
15711 call fooR(AMAX0(I1,I2))
15712 c FFEINTRIN_impAMAX1
15713 call fooR(AMAX1(R1,R2))
15714 c FFEINTRIN_impAMIN0
15715 call fooR(AMIN0(I1,I2))
15716 c FFEINTRIN_impAMIN1
15717 call fooR(AMIN1(R1,R2))
15718 c FFEINTRIN_impAMOD
15719 call fooR(AMOD(R1,R2))
15720 c FFEINTRIN_impANINT
15721 call fooR(ANINT(R1))
15722 c FFEINTRIN_impASIN
15723 call fooR(ASIN(R1))
15724 c FFEINTRIN_impATAN
15725 call fooR(ATAN(R1))
15726 c FFEINTRIN_impATAN2
15727 call fooR(ATAN2(R1,R2))
15728 c FFEINTRIN_impCABS
15729 call fooR(CABS(C1))
15730 c FFEINTRIN_impCCOS
15731 call fooC(CCOS(C1))
15732 c FFEINTRIN_impCEXP
15733 call fooC(CEXP(C1))
15734 c FFEINTRIN_impCHAR
15735 call fooA(CHAR(I1))
15736 c FFEINTRIN_impCLOG
15737 call fooC(CLOG(C1))
15738 c FFEINTRIN_impCONJG
15739 call fooC(CONJG(C1))
15742 c FFEINTRIN_impCOSH
15743 call fooR(COSH(R1))
15744 c FFEINTRIN_impCSIN
15745 call fooC(CSIN(C1))
15746 c FFEINTRIN_impCSQRT
15747 call fooC(CSQRT(C1))
15748 c FFEINTRIN_impDABS
15749 call fooD(DABS(D1))
15750 c FFEINTRIN_impDACOS
15751 call fooD(DACOS(D1))
15752 c FFEINTRIN_impDASIN
15753 call fooD(DASIN(D1))
15754 c FFEINTRIN_impDATAN
15755 call fooD(DATAN(D1))
15756 c FFEINTRIN_impDATAN2
15757 call fooD(DATAN2(D1,D2))
15758 c FFEINTRIN_impDCOS
15759 call fooD(DCOS(D1))
15760 c FFEINTRIN_impDCOSH
15761 call fooD(DCOSH(D1))
15762 c FFEINTRIN_impDDIM
15763 call fooD(DDIM(D1,D2))
15764 c FFEINTRIN_impDEXP
15765 call fooD(DEXP(D1))
15767 call fooR(DIM(R1,R2))
15768 c FFEINTRIN_impDINT
15769 call fooD(DINT(D1))
15770 c FFEINTRIN_impDLOG
15771 call fooD(DLOG(D1))
15772 c FFEINTRIN_impDLOG10
15773 call fooD(DLOG10(D1))
15774 c FFEINTRIN_impDMAX1
15775 call fooD(DMAX1(D1,D2))
15776 c FFEINTRIN_impDMIN1
15777 call fooD(DMIN1(D1,D2))
15778 c FFEINTRIN_impDMOD
15779 call fooD(DMOD(D1,D2))
15780 c FFEINTRIN_impDNINT
15781 call fooD(DNINT(D1))
15782 c FFEINTRIN_impDPROD
15783 call fooD(DPROD(R1,R2))
15784 c FFEINTRIN_impDSIGN
15785 call fooD(DSIGN(D1,D2))
15786 c FFEINTRIN_impDSIN
15787 call fooD(DSIN(D1))
15788 c FFEINTRIN_impDSINH
15789 call fooD(DSINH(D1))
15790 c FFEINTRIN_impDSQRT
15791 call fooD(DSQRT(D1))
15792 c FFEINTRIN_impDTAN
15793 call fooD(DTAN(D1))
15794 c FFEINTRIN_impDTANH
15795 call fooD(DTANH(D1))
15798 c FFEINTRIN_impIABS
15799 call fooI(IABS(I1))
15800 c FFEINTRIN_impICHAR
15801 call fooI(ICHAR(A1))
15802 c FFEINTRIN_impIDIM
15803 call fooI(IDIM(I1,I2))
15804 c FFEINTRIN_impIDNINT
15805 call fooI(IDNINT(D1))
15806 c FFEINTRIN_impINDEX
15807 call fooI(INDEX(A1,A2))
15808 c FFEINTRIN_impISIGN
15809 call fooI(ISIGN(I1,I2))
15813 call fooL(LGE(A1,A2))
15815 call fooL(LGT(A1,A2))
15817 call fooL(LLE(A1,A2))
15819 call fooL(LLT(A1,A2))
15820 c FFEINTRIN_impMAX0
15821 call fooI(MAX0(I1,I2))
15822 c FFEINTRIN_impMAX1
15823 call fooI(MAX1(R1,R2))
15824 c FFEINTRIN_impMIN0
15825 call fooI(MIN0(I1,I2))
15826 c FFEINTRIN_impMIN1
15827 call fooI(MIN1(R1,R2))
15829 call fooI(MOD(I1,I2))
15830 c FFEINTRIN_impNINT
15831 call fooI(NINT(R1))
15832 c FFEINTRIN_impSIGN
15833 call fooR(SIGN(R1,R2))
15836 c FFEINTRIN_impSINH
15837 call fooR(SINH(R1))
15838 c FFEINTRIN_impSQRT
15839 call fooR(SQRT(R1))
15842 c FFEINTRIN_impTANH
15843 call fooR(TANH(R1))
15844 c FFEINTRIN_imp_CMPLX_C
15845 call fooC(cmplx(C1,C2))
15846 c FFEINTRIN_imp_CMPLX_D
15847 call fooZ(cmplx(D1,D2))
15848 c FFEINTRIN_imp_CMPLX_I
15849 call fooC(cmplx(I1,I2))
15850 c FFEINTRIN_imp_CMPLX_R
15851 call fooC(cmplx(R1,R2))
15852 c FFEINTRIN_imp_DBLE_C
15853 call fooD(dble(C1))
15854 c FFEINTRIN_imp_DBLE_D
15855 call fooD(dble(D1))
15856 c FFEINTRIN_imp_DBLE_I
15857 call fooD(dble(I1))
15858 c FFEINTRIN_imp_DBLE_R
15859 call fooD(dble(R1))
15860 c FFEINTRIN_imp_INT_C
15862 c FFEINTRIN_imp_INT_D
15864 c FFEINTRIN_imp_INT_I
15866 c FFEINTRIN_imp_INT_R
15868 c FFEINTRIN_imp_REAL_C
15869 call fooR(real(C1))
15870 c FFEINTRIN_imp_REAL_D
15871 call fooR(real(D1))
15872 c FFEINTRIN_imp_REAL_I
15873 call fooR(real(I1))
15874 c FFEINTRIN_imp_REAL_R
15875 call fooR(real(R1))
15877 c FFEINTRIN_imp_INT_D:
15879 c FFEINTRIN_specIDINT
15880 call fooI(IDINT(D1))
15882 c FFEINTRIN_imp_INT_R:
15884 c FFEINTRIN_specIFIX
15885 call fooI(IFIX(R1))
15886 c FFEINTRIN_specINT
15889 c FFEINTRIN_imp_REAL_D:
15891 c FFEINTRIN_specSNGL
15892 call fooR(SNGL(D1))
15894 c FFEINTRIN_imp_REAL_I:
15896 c FFEINTRIN_specFLOAT
15897 call fooR(FLOAT(I1))
15898 c FFEINTRIN_specREAL
15899 call fooR(REAL(I1))
15902 -------- (end input file to f2c)
15904 -------- (begin output from providing above input file as input to:
15905 -------- `f2c | gcc -E -C - | sed -e "s:/[*]*://:g" -e "s:[*]*[/]://:g" \
15906 -------- -e "s:^#.*$::g"')
15908 // -- translated by f2c (version 19950223).
15909 You must link the resulting object file with the libraries:
15910 -lf2c -lm (in that order)
15914 // f2c.h -- Standard Fortran to C header file //
15916 /// barf [ba:rf] 2. "He suggested using FORTRAN, and everybody barfed."
15918 - From The Shogakukan DICTIONARY OF NEW ENGLISH (Second edition) //
15923 // F2C_INTEGER will normally be `int' but would be `long' on 16-bit systems //
15924 // we assume short, float are OK //
15925 typedef long int // long int // integer;
15926 typedef char *address;
15927 typedef short int shortint;
15928 typedef float real;
15929 typedef double doublereal;
15930 typedef struct { real r, i; } complex;
15931 typedef struct { doublereal r, i; } doublecomplex;
15932 typedef long int // long int // logical;
15933 typedef short int shortlogical;
15934 typedef char logical1;
15935 typedef char integer1;
15936 // typedef long long longint; // // system-dependent //
15941 // Extern is for use with -E //
15955 typedef long int // int or long int // flag;
15956 typedef long int // int or long int // ftnlen;
15957 typedef long int // int or long int // ftnint;
15960 //external read, write//
15969 //internal read, write//
15999 //rewind, backspace, endfile//
16011 ftnint *inex; //parameters in standard's order//
16037 union Multitype { // for multiple entry points //
16048 typedef union Multitype Multitype;
16050 typedef long Long; // No longer used; formerly in Namelist //
16052 struct Vardesc { // for Namelist //
16058 typedef struct Vardesc Vardesc;
16065 typedef struct Namelist Namelist;
16074 // procedure parameter types for -A and -C++ //
16079 typedef int // Unknown procedure type // (*U_fp)();
16080 typedef shortint (*J_fp)();
16081 typedef integer (*I_fp)();
16082 typedef real (*R_fp)();
16083 typedef doublereal (*D_fp)(), (*E_fp)();
16084 typedef // Complex // void (*C_fp)();
16085 typedef // Double Complex // void (*Z_fp)();
16086 typedef logical (*L_fp)();
16087 typedef shortlogical (*K_fp)();
16088 typedef // Character // void (*H_fp)();
16089 typedef // Subroutine // int (*S_fp)();
16091 // E_fp is for real functions when -R is not specified //
16092 typedef void C_f; // complex function //
16093 typedef void H_f; // character function //
16094 typedef void Z_f; // double complex function //
16095 typedef doublereal E_f; // real function with -R not specified //
16097 // undef any lower-case symbols that your C compiler predefines, e.g.: //
16100 // (No such symbols should be defined in a strict ANSI C compiler.
16101 We can avoid trouble with f2c-translated code by using
16126 // Main program // MAIN__()
16128 // System generated locals //
16131 doublereal d__1, d__2;
16133 doublecomplex z__1, z__2, z__3;
16137 // Builtin functions //
16140 double pow_ri(), pow_di();
16144 double acos(), r_imag(), r_int(), log(), r_lg10(), r_mod(), r_nint(),
16145 asin(), atan(), atan2(), c_abs();
16146 void c_cos(), c_exp(), c_log(), r_cnjg();
16147 double cos(), cosh();
16148 void c_sin(), c_sqrt();
16149 double d_dim(), exp(), r_dim(), d_int(), d_lg10(), d_mod(), d_nint(),
16150 d_sign(), sin(), sinh(), sqrt(), tan(), tanh();
16151 integer i_dim(), i_dnnt(), i_indx(), i_sign(), i_len();
16152 logical l_ge(), l_gt(), l_le(), l_lt();
16156 // Local variables //
16157 extern // Subroutine // int fooa_(), fooc_(), food_(), fooi_(), foor_(),
16158 fool_(), fooz_(), getem_();
16159 static char a1[10], a2[10];
16160 static complex c1, c2;
16161 static doublereal d1, d2;
16162 static integer i1, i2;
16163 static real r1, r2;
16166 getem_(a1, a2, &c1, &c2, &i1, &i2, &r1, &r2, &d1, &d2, 10L, 10L);
16174 d__1 = (doublereal) i1;
16175 q__1.r = c1.r / d__1, q__1.i = c1.i / d__1;
16185 c_div(&q__1, &c1, &c2);
16187 q__1.r = c1.r / r1, q__1.i = c1.i / r1;
16189 z__1.r = c1.r / d1, z__1.i = c1.i / d1;
16192 i__1 = pow_ii(&i1, &i2);
16194 r__1 = pow_ri(&r1, &i1);
16196 d__1 = pow_di(&d1, &i1);
16198 pow_ci(&q__1, &c1, &i1);
16200 d__1 = (doublereal) r1;
16201 d__2 = (doublereal) r2;
16202 r__1 = pow_dd(&d__1, &d__2);
16204 d__2 = (doublereal) r1;
16205 d__1 = pow_dd(&d__2, &d1);
16207 d__1 = pow_dd(&d1, &d2);
16209 d__2 = (doublereal) r1;
16210 d__1 = pow_dd(&d1, &d__2);
16212 z__2.r = c1.r, z__2.i = c1.i;
16213 z__3.r = c2.r, z__3.i = c2.i;
16214 pow_zz(&z__1, &z__2, &z__3);
16215 q__1.r = z__1.r, q__1.i = z__1.i;
16217 z__2.r = c1.r, z__2.i = c1.i;
16218 z__3.r = r1, z__3.i = 0.;
16219 pow_zz(&z__1, &z__2, &z__3);
16220 q__1.r = z__1.r, q__1.i = z__1.i;
16222 z__2.r = c1.r, z__2.i = c1.i;
16223 z__3.r = d1, z__3.i = 0.;
16224 pow_zz(&z__1, &z__2, &z__3);
16226 // FFEINTRIN_impABS //
16227 r__1 = (doublereal)(( r1 ) >= 0 ? ( r1 ) : -( r1 )) ;
16229 // FFEINTRIN_impACOS //
16232 // FFEINTRIN_impAIMAG //
16233 r__1 = r_imag(&c1);
16235 // FFEINTRIN_impAINT //
16238 // FFEINTRIN_impALOG //
16241 // FFEINTRIN_impALOG10 //
16242 r__1 = r_lg10(&r1);
16244 // FFEINTRIN_impAMAX0 //
16245 r__1 = (real) (( i1 ) >= ( i2 ) ? ( i1 ) : ( i2 )) ;
16247 // FFEINTRIN_impAMAX1 //
16248 r__1 = (doublereal)(( r1 ) >= ( r2 ) ? ( r1 ) : ( r2 )) ;
16250 // FFEINTRIN_impAMIN0 //
16251 r__1 = (real) (( i1 ) <= ( i2 ) ? ( i1 ) : ( i2 )) ;
16253 // FFEINTRIN_impAMIN1 //
16254 r__1 = (doublereal)(( r1 ) <= ( r2 ) ? ( r1 ) : ( r2 )) ;
16256 // FFEINTRIN_impAMOD //
16257 r__1 = r_mod(&r1, &r2);
16259 // FFEINTRIN_impANINT //
16260 r__1 = r_nint(&r1);
16262 // FFEINTRIN_impASIN //
16265 // FFEINTRIN_impATAN //
16268 // FFEINTRIN_impATAN2 //
16269 r__1 = atan2(r1, r2);
16271 // FFEINTRIN_impCABS //
16274 // FFEINTRIN_impCCOS //
16277 // FFEINTRIN_impCEXP //
16280 // FFEINTRIN_impCHAR //
16281 *(unsigned char *)&ch__1[0] = i1;
16283 // FFEINTRIN_impCLOG //
16286 // FFEINTRIN_impCONJG //
16287 r_cnjg(&q__1, &c1);
16289 // FFEINTRIN_impCOS //
16292 // FFEINTRIN_impCOSH //
16295 // FFEINTRIN_impCSIN //
16298 // FFEINTRIN_impCSQRT //
16299 c_sqrt(&q__1, &c1);
16301 // FFEINTRIN_impDABS //
16302 d__1 = (( d1 ) >= 0 ? ( d1 ) : -( d1 )) ;
16304 // FFEINTRIN_impDACOS //
16307 // FFEINTRIN_impDASIN //
16310 // FFEINTRIN_impDATAN //
16313 // FFEINTRIN_impDATAN2 //
16314 d__1 = atan2(d1, d2);
16316 // FFEINTRIN_impDCOS //
16319 // FFEINTRIN_impDCOSH //
16322 // FFEINTRIN_impDDIM //
16323 d__1 = d_dim(&d1, &d2);
16325 // FFEINTRIN_impDEXP //
16328 // FFEINTRIN_impDIM //
16329 r__1 = r_dim(&r1, &r2);
16331 // FFEINTRIN_impDINT //
16334 // FFEINTRIN_impDLOG //
16337 // FFEINTRIN_impDLOG10 //
16338 d__1 = d_lg10(&d1);
16340 // FFEINTRIN_impDMAX1 //
16341 d__1 = (( d1 ) >= ( d2 ) ? ( d1 ) : ( d2 )) ;
16343 // FFEINTRIN_impDMIN1 //
16344 d__1 = (( d1 ) <= ( d2 ) ? ( d1 ) : ( d2 )) ;
16346 // FFEINTRIN_impDMOD //
16347 d__1 = d_mod(&d1, &d2);
16349 // FFEINTRIN_impDNINT //
16350 d__1 = d_nint(&d1);
16352 // FFEINTRIN_impDPROD //
16353 d__1 = (doublereal) r1 * r2;
16355 // FFEINTRIN_impDSIGN //
16356 d__1 = d_sign(&d1, &d2);
16358 // FFEINTRIN_impDSIN //
16361 // FFEINTRIN_impDSINH //
16364 // FFEINTRIN_impDSQRT //
16367 // FFEINTRIN_impDTAN //
16370 // FFEINTRIN_impDTANH //
16373 // FFEINTRIN_impEXP //
16376 // FFEINTRIN_impIABS //
16377 i__1 = (( i1 ) >= 0 ? ( i1 ) : -( i1 )) ;
16379 // FFEINTRIN_impICHAR //
16380 i__1 = *(unsigned char *)a1;
16382 // FFEINTRIN_impIDIM //
16383 i__1 = i_dim(&i1, &i2);
16385 // FFEINTRIN_impIDNINT //
16386 i__1 = i_dnnt(&d1);
16388 // FFEINTRIN_impINDEX //
16389 i__1 = i_indx(a1, a2, 10L, 10L);
16391 // FFEINTRIN_impISIGN //
16392 i__1 = i_sign(&i1, &i2);
16394 // FFEINTRIN_impLEN //
16395 i__1 = i_len(a1, 10L);
16397 // FFEINTRIN_impLGE //
16398 L__1 = l_ge(a1, a2, 10L, 10L);
16400 // FFEINTRIN_impLGT //
16401 L__1 = l_gt(a1, a2, 10L, 10L);
16403 // FFEINTRIN_impLLE //
16404 L__1 = l_le(a1, a2, 10L, 10L);
16406 // FFEINTRIN_impLLT //
16407 L__1 = l_lt(a1, a2, 10L, 10L);
16409 // FFEINTRIN_impMAX0 //
16410 i__1 = (( i1 ) >= ( i2 ) ? ( i1 ) : ( i2 )) ;
16412 // FFEINTRIN_impMAX1 //
16413 i__1 = (integer) (doublereal)(( r1 ) >= ( r2 ) ? ( r1 ) : ( r2 )) ;
16415 // FFEINTRIN_impMIN0 //
16416 i__1 = (( i1 ) <= ( i2 ) ? ( i1 ) : ( i2 )) ;
16418 // FFEINTRIN_impMIN1 //
16419 i__1 = (integer) (doublereal)(( r1 ) <= ( r2 ) ? ( r1 ) : ( r2 )) ;
16421 // FFEINTRIN_impMOD //
16424 // FFEINTRIN_impNINT //
16425 i__1 = i_nint(&r1);
16427 // FFEINTRIN_impSIGN //
16428 r__1 = r_sign(&r1, &r2);
16430 // FFEINTRIN_impSIN //
16433 // FFEINTRIN_impSINH //
16436 // FFEINTRIN_impSQRT //
16439 // FFEINTRIN_impTAN //
16442 // FFEINTRIN_impTANH //
16445 // FFEINTRIN_imp_CMPLX_C //
16448 q__1.r = r__1, q__1.i = r__2;
16450 // FFEINTRIN_imp_CMPLX_D //
16451 z__1.r = d1, z__1.i = d2;
16453 // FFEINTRIN_imp_CMPLX_I //
16456 q__1.r = r__1, q__1.i = r__2;
16458 // FFEINTRIN_imp_CMPLX_R //
16459 q__1.r = r1, q__1.i = r2;
16461 // FFEINTRIN_imp_DBLE_C //
16462 d__1 = (doublereal) c1.r;
16464 // FFEINTRIN_imp_DBLE_D //
16467 // FFEINTRIN_imp_DBLE_I //
16468 d__1 = (doublereal) i1;
16470 // FFEINTRIN_imp_DBLE_R //
16471 d__1 = (doublereal) r1;
16473 // FFEINTRIN_imp_INT_C //
16474 i__1 = (integer) c1.r;
16476 // FFEINTRIN_imp_INT_D //
16477 i__1 = (integer) d1;
16479 // FFEINTRIN_imp_INT_I //
16482 // FFEINTRIN_imp_INT_R //
16483 i__1 = (integer) r1;
16485 // FFEINTRIN_imp_REAL_C //
16488 // FFEINTRIN_imp_REAL_D //
16491 // FFEINTRIN_imp_REAL_I //
16494 // FFEINTRIN_imp_REAL_R //
16498 // FFEINTRIN_imp_INT_D: //
16500 // FFEINTRIN_specIDINT //
16501 i__1 = (integer) d1;
16504 // FFEINTRIN_imp_INT_R: //
16506 // FFEINTRIN_specIFIX //
16507 i__1 = (integer) r1;
16509 // FFEINTRIN_specINT //
16510 i__1 = (integer) r1;
16513 // FFEINTRIN_imp_REAL_D: //
16515 // FFEINTRIN_specSNGL //
16519 // FFEINTRIN_imp_REAL_I: //
16521 // FFEINTRIN_specFLOAT //
16524 // FFEINTRIN_specREAL //
16530 -------- (end output file from f2c)
16534 #include "gt-f-com.h"
16535 #include "gtype-f.h"